Hello Guest, please login or register.
Did you miss your activation email?
Login with username, password and session length.

Pages: [1] 2   Go Down

Author Topic: Link Ice-Based Movement  (Read 7506 times)

0 Members and 1 Guest are viewing this topic.
Link Ice-Based Movement
« on: July 13, 2009, 02:02:22 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
There are probably some errors somewhere and other places that can be optimized. I was using the xor originally in Link's step-event but it was not as effective as cancelling out the keys at the beginning of the event - it just gets a bit complicated looking by how parenthesis need to be placed. Hypothetically, the xor in the functions which receive two opposing keys as arguments could be altered because of the beginning check in the Link step event; because then only one value might be needed.

There's also a good blinking code that is kind of realistic to the game. The problem I had with some of the code though was that if you step onto ice after not stepping onto ice that your move_x should not be at its maximum. It seems simple enough to add in, but trying to test the xprevious yprevious position didn't work for me. Also, when move_x and move_y are not 0, the move factor move_f is set to the square root of 2 even though it isn't always moving so much like that - it's not too important though as the actual value should be a little less than the square root of 2 but still larger than 1.

I do like that I was able to integrate Goodnight's style of movement into this. And also realizing that if something like the x speed was at its maximum that the step_x could be set to 0 if the y speed was 0. Additionally, making sure the step_x and step_y are equal if both x and y speeds are at their maximum makes sure the diagonal movement doesn't get jittery.

I would make it a little more efficient, but I have to bail some straw tomorrow to make some money. The GMK file is in the attachment though.
Logged
Re: Link Ice-Based Movement
« Reply #1 on: July 15, 2009, 01:12:10 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
Oh, and I thought that I would ask it here and now since everyone can see this. Can anyone alter the code I provided so that when Link gets onto the ice initially after not being on it that his move_x will either be something like -2 or 2; this is closer to Minish Cap. Anyone have any ideas on how to do or solve this (preferably suggestions which you attempt to test)?
Logged

Mamoruanime

@Mamoruanime
Re: Link Ice-Based Movement
« Reply #2 on: July 15, 2009, 10:15:55 am »
  • ^Not actually me.
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 9786
I don't have GM7, or I'd take a peek at it, but I feel I should mention-

If you're going for a fidelity engine, I highly suggest having a generalized parent object that houses a draw script for your sprites that has draw_sprite(this.sprite,ceil(x),ceil(y)) (pseudocode; can't remember the arguments off the top of my head. I know theres one for image index too; basically just gotta call to the host's current sprite and image index).

It helps you sync up objects a bit better (removes that jitter lag when forcing another object to follow your players x and y).

I had a decent system for ice movement a while back... I think it's on my fiance's computer. If I can find it I'll post it on here. It was very adaptable.
« Last Edit: July 15, 2009, 10:33:43 am by Mamoruanime »
Logged
Re: Link Ice-Based Movement
« Reply #3 on: July 15, 2009, 07:58:20 pm »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
I had thought that it would be possible to get rid of the step_x/step_y based movement in favor of Game Maker's built in movement stuff. Using its direction, speed, hspeed, and vspeed with something like floor(x) or ceil(x) when it moves diagonally, it could give the same effect with the fractional components preserved appropriately. It's easier for me though to not be too dependent on Game Maker's functions so I can understand how the code is fully working.

About drawing sprites, I tried to do something in a previous topic where Link was drawn in pieces to save space in memory for the sprites where Link has a hat and doesn't have a hat. An issue that came up was that I would not be able to utilize Game Maker's Animation End event so I would have to keep track of when the animation ended manually. The key about the Animation End event is that it looks at the sprite_index which is based on one sprite. To use Link pieces with this I would have to make the animated pieces of Link be set to the sprite_index.

Needless to say that got a little confusing and I opted to rather just focus on the mechanics of Link movement that his drawing. I had looked at, I believe, mit's ice or mixtella's example of ice sliding which had some of the mechanics worked out but with more position checks and no real diagonal movement. But yeah, if you ever find that ice movement stuff, it might be useful to see it.
Logged
Re: Link Ice-Based Movement
« Reply #4 on: July 15, 2009, 08:42:50 pm »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
About drawing sprites, I tried to do something in a previous topic where Link was drawn in pieces to save space in memory for the sprites where Link has a hat and doesn't have a hat. An issue that came up was that I would not be able to utilize Game Maker's Animation End event so I would have to keep track of when the animation ended manually. The key about the Animation End event is that it looks at the sprite_index which is based on one sprite. To use Link pieces with this I would have to make the animated pieces of Link be set to the sprite_index.

So if I understand it right than you want to make Link do the same animations with and without the hat and still be able to use the animation end event. I would think the Animation End event is dependent on Link's body and not on the hat. So couldn't you separate the body and the hat. You would need a sprite sheet with Link without a cap with all his actions and an extra spritesheet for the hat for drawing the hat over the Link sprite when Link has the hat? You could connect the Animation End event to Link body. But I'm not sure how much it would reduce the Memory cost.
Logged
Re: Link Ice-Based Movement
« Reply #5 on: July 15, 2009, 08:58:12 pm »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
Essentially something like Link walking down with and without the hat, the two sprite animations for that have similar components. The idea was not to have redundancy by storing the similarity in memory when it could just be stored once. A problem that arose in a previous topic, maybe not noted in that topic, was that Link standing down compared to Link standing up had different parts which animated. To make it work, some redundancy has to return (the animated sprite for Link down had to contain the eyes) but in trade-off for the ability to classify hat Link and non-hat Link by not having the hat and non-hat.

That is probably a little confusing though in explanation. The Animation End event is based on animation; some of the Link pieces didn't need to animate like Link's standing down feet. For something like Link walking down the speed of the feet would be just cooresponding to the head's animation. The hat on Link isn't just placed on though, without it his hair is spiky.
Logged

Mamoruanime

@Mamoruanime
Re: Link Ice-Based Movement
« Reply #6 on: July 16, 2009, 11:04:24 pm »
  • ^Not actually me.
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 9786
The biggest thing with that is having to write your own animation system for sprites. They're annoying to make :P
Logged

DeathTailsz

Wanderer
Re: Link Ice-Based Movement
« Reply #7 on: July 19, 2009, 02:18:04 am »
  • Angelic Hymn
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 172
Well, I believe their is a function on GM (A drag and drop one.) which is Friction, I came across it in a few tutorials at Yoyogames.com by Mark Overmars, when the character stops moving, he/she slides a little bit on the floor, if I remember. Setting it to just 2 doesn't matter, cause it'll make you slide -2 aswell.

The code that could slow retract speed is if(speed < 2) speed = min(2,speed+0.4), but this is for accelerating, instead of deaccelerating, so you'd just have to flip a few things around to get it to gradulally slow down, I use to have this script in one of my games, but I don't remember which ones, sadly.

I believe it was Friction that handled this, but, you can also make Gravity do this aswell. (Highly unrecommended, but it's worth a shot.)

Edit:  You could also use that "Able to change direction" variable to your advantage, since when Link is slipping on ice, and you suddenly go down or up, he stays in that same frame for a second then changes direction.

Edit2: Slight mistake on my part.
« Last Edit: July 19, 2009, 02:44:26 am by DeathTailsz »
Logged

"More like Stupei Ace Defective!" - Yukari - Persona 3
  • StarFox 2D
Re: Link Ice-Based Movement
« Reply #8 on: July 19, 2009, 05:33:26 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
About Edit 1, I am not sure if you are referring to an able_d variable that I might have had in another version of the engine, but looking at the Minish Cap game Link's normal ability to change direction is based on keys held and not movement made. The friction and gravity stuff you mention might also be a little odd with the engine in how it does diagonal movement correction and how the friction changes intensity.

Anyway, thinking about it a bit, the problem with not being able to slow down after just initially getting onto the ice is probably because the ice_slide script is ran when x and xprevious are the same - in that the x hasn't changed yet, Link hasn't moved or attempted to move. Adding a check at the end of the code might fix the issue I was having.
Logged
Re: Link Ice-Based Movement
« Reply #9 on: July 29, 2009, 11:44:10 pm »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
I figured out the condition needed to do what I was talking about. Essentially, I was perpetuating a problem I was trying to work around - Game Maker's xprevious/yprevious variables. They reset at the beginning of the step which made using them to do a position check stupid because I was already checking the x/y position (as said, at the beginning of the step they are the same as xprevious/yprevious). So what I did was add prev_x/prev_y. In short:

x/y - position of Link
xprevious/yprevious - what Link's position was at the beginning of the step
prev_x/prev_y - what Link's position was from the previous step

I also altered the code a bit; e.g. checking move_x to be != 0 is dumb when one could just check absv_x > 0. This should finish out the ice movement stuff (although some of it may be altered later to include a boolean for the speed bleed off when stopping - to assist with swimming).

The updated GMK is attached.

Edit: Actually, comparing the Minish Cap to my ice-movement stuff, moving diagonally on ice is faster than non-diagonally. Altering it so that the move_f = 1 when on ice and moving diagonally before checking to see if you hit anything makes it so ice movement is quicker and the effect more closely emulates the Minish Cap that way. Meh, might alter it or not.
« Last Edit: August 01, 2009, 06:52:00 am by 4Sword »
Logged
Re: Link Ice-Based Movement
« Reply #10 on: July 30, 2009, 06:51:45 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
Looks good but I get the feeling that in MC Link's maximum speed on ice is faster. And Link remains sliding a bit longer.

4Sword a small advice. Use comments in your code. I don't understand everything what your doing, because maybe I would do it different or I don't understand GMK as much as I want to. Especially in the scripts where nondescript arguments are used.
Logged
Re: Link Ice-Based Movement
« Reply #11 on: July 30, 2009, 07:17:49 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
The non-diagonal speed maximum on ice seems to be just the same as off ice. Diagonal movement on ice and off seem to be different; as with the edit to my last post, having the move_f movement factor as 1 on ice instead of the square root of 2 allows Link to move faster giving the appearance of the correct affect. Otherwise in terms of how much Link drifts after not moving while on ice, to increase the distance traveled all that has to be done is altering the incrementation in the move_slide script.

I'll add comments into it in the next release, but mostly this is what all the variables are:
prev_x: the x position of Link in the previous step
move_x: defines the interval over which Link moves in terms of x, the -/+ gives the direction you are moving in or drifting towards
maxi_x: maximum x movement speed
step_x: the counter used to determine how much you move in terms of x per step
absv_x: absolute value of move_x, calculated because step_x needs to be based on a positive number to work right.
slip_b: slip boolean: if you are on ice
slip_p: slip previous: if you were previously on ice last step
move_f: move factor: correction if moving diagonally. Non-diagonal movement is just a regular 1 but diagonal movement is based on the square root of 2 which makes you move less diagonally so you don't move faster diagonally than non-diagonally.

The scripts aren't too fancy in that one can figure out what they do by their arguments, but I'll comment that later too. I suppose that would make the engine more useful to people.
Logged
Re: Link Ice-Based Movement
« Reply #12 on: August 01, 2009, 07:09:45 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
Update: I think that I got it a little closer in terms of the drifting, but my perception is always a little off due to the way I think. I added in a fixed view so I would be able to work with a larger area all while having a fixed perspective so I could measure distances at a glance.

Also, for those who haven't looked into it at all, here's a screenshot just showing Link walking on ice for no reason:


The updated file, stuffed to the gills full of commenting, is attached.
Logged
Re: Link Ice-Based Movement
« Reply #13 on: August 01, 2009, 07:43:59 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
First of all kudos for the comments in the code.

Second I have tested it and I think the turning is correct now, but the reversing not. When you change from left to right, up to down or vice versa I think you still need to slide a bit further and keep to one place a bit before actually going the other way.

The same goes for starting to walk on ice when standing on ice. Before Link actually moves he has to slip a bit.
Logged
Re: Link Ice-Based Movement
« Reply #14 on: August 01, 2009, 08:07:19 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
Look, about the turning direction I am not sure exactly what you mean, all that involves is using a value to get to the other end of the move_x/move_y variable; shrinking this value makes it so you take the turning wider while increasing the value makes it so you take the turning shorter. I don't know I am not seeing what you are saying with respect to that.

About walking on ice after just standing on it, again I do not know what you mean other than currently on ice Link is building up speed until he gets to his maximum on the ice; so that he doesn't move at full speed right away. To slow this down so the buildup looks like more, it also makes it so turning has to be wider than it is in that GMK file.

Edit:

If you could, try altering the values in the move_slide script to values that work better for you. Like, for getting onto the ice after not being on it, you'd have to just change the "return (argument1 - argument0) * (argument3 - 2);" line so that "(argument3 - 2)" is something like "(argument3 - 1)".

The top min/max part is for speed incremenation when moving on ice, the bottom min/max part is for drifting when not holding any keys. I tried it with a .1 and a .0625 which might work better, I don't know.

« Last Edit: August 01, 2009, 08:13:20 am by 4Sword »
Logged
Re: Link Ice-Based Movement
« Reply #15 on: August 01, 2009, 02:12:57 pm »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
I've been playing with the drift settings. To my opinion I think these are the best:
.2 -> .075.
.065 -> .035
But it is difficult to test without a visible 16x16 grid.

About the turning I meant the following example.

Link is walking over ice at its maximum to the left. You release the left arrow and at the same time  press the right arrow. At this moment Link faces the other direction but still slides a bit to the left and slowing down. At the point where Link doesn't move his position the Link animation still makes 4 or 5 steps before Link actually moves to the right.

But I think that is fixed by changing 0.2 in 0.075 or somewhere around that.

On another note, I think it is better to make those 2 friction parameters, which you can add to the script. By doing this the script can be used for other surfaces, like the swimming in water or something else if needed.

UPDATE: To properly see what settings are correct, I tried to make an ice course like you have those in the games. So I implemented the Pit's Link can fall into. They work a bit. On normal ground it works like it should, but on ice Link can change the direction he faces before falling in a pit. After which he is put back on the wrong side. I tried 2 methods. One with the direction Link is facing and one by using the prev_x and prev_y, but it does not work correct on ice. I was thinking maybe I could use move_x, move_y and move_f. Ah well, it is late now, so I'm going to bed.
« Last Edit: August 01, 2009, 10:58:11 pm by Niek »
Logged
Re: Link Ice-Based Movement
« Reply #16 on: August 04, 2009, 08:24:48 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
Okay, I added pits and it kind of works. Here is what I did:

Check at the beginning of the step if Link is falling, because it has the highest priority.
Code: [Select]
if(falling){
    //check if falling is done. If not add 1 to the action timer
    // else set Link back to the edge he came from.
    if(action_timer == 12){
        action_timer = 0;
        falling = false;
        //move to the edge Link had fallen from.
        move_to_ledge(x,y, prev_x,prev_y,self);
        //move_to_ledge(x,y,direction,self);
        prev_x = x;
        prev_y = y;
    }else{
        action_timer += 1;
    }
}else{

Okay if Link is not falling, than just do movement code. And at the end of the movement code check if the new position is colliding with a pit. And if so set the correct settings.
Code: [Select]
//check if the new x and y are colliding with an special object like a Pit
if(position_meeting(x,y,objPit)){
    //check if Link should fall. Then set all settings to it.
    moving = false;
    falling = true;    
    move_x = 0;
    move_y = 0;
    action_timer = 0;
    inst_id = instance_position(x,y,objPit);
    x = inst_id.x+0.5*TILESIZE;
    y = inst_id.y+0.5*TILESIZE;
}

The problem is putting Link back on the ledge where he had fallen of. First I tried using the direction link is facing but that gives problems on the ice. So now Link's x and y are set to prev_x and prev_y. There still are some problems.

1) Sometimes it seems as if Link falls twice.
2) If Link walks to left on normal ground the prev_x is updated every step, but the prev_y still has the value from the last time the y position changed. This allows Link to be put back in a wrong position.

I'm still breaking my head over this. And it also isn't completely how MC works, I think.
« Last Edit: August 04, 2009, 08:45:47 am by Niek »
Logged
Re: Link Ice-Based Movement
« Reply #17 on: August 04, 2009, 08:39:13 am »
  • *
  • Reputation: +8/-0
  • Offline Offline
  • Gender: Male
  • Posts: 6604
Sorry I saw your edit late and was going to attempt adding in rolling or something; the pit seems like a more natural step though due to most ice situations involving being able to fall into one. The ice course is also nice, gives more variations and scenarios as to what movement can take place.

It is like 3:40 AM though so I cannot really fully review what you did, but on a quick observation of the Minish Cap falling scenarios, I cannot fully remember if falling into a pit is always like this, but in a dungeon, falling into a pit moves Link to the closest 16 x 16 gridspace and then returns him to the start position of the room or the last place of "solid ground".

I like the concept you used where Link's move_x/move_y can be used to move him without the need for keyboard assistance, but I am not too sure of your method with the variable checking and some code placement. The act of falling could be summarized as an "action", the only reason action_timer is in the Step Event is to reset it otherwise its incrementation gets handled in Draw, etc.

In an earlier version of the engine I had included variables like able_x, able_y, and able_d which allowed x movement, y movement, and changing direction. In conjunction with an "action" having able_x/able_y as false would keep Link from moving for the duration of the step; possibly hold_u and the rest could be set like keyboard_check(vk_up) && able_x.

I'll look over it some more when I wake up, but your addition is pretty good, I just have a hunch that it could be simplified.

Edit: and I can't remember if the last GMK I posted had the action or just the action_timer, but generally speaking, an "action" would really just encompass what to draw based on direction and whether or not Link is moving; with things like able_x, able_y and the generics like that used in the Step event such that the step event can be as general as it can be.
« Last Edit: August 04, 2009, 08:44:36 am by 4Sword »
Logged
Re: Link Ice-Based Movement
« Reply #18 on: August 04, 2009, 09:29:05 am »
  • *
  • Reputation: +9/-0
  • Offline Offline
  • Gender: Male
  • Posts: 3725
I have updated my previous post, because I clicked send a bit to fast. I have added my latest version of code.

I'll look over it some more when I wake up, but your addition is pretty good, I just have a hunch that it could be simplified.

I know for certain the code can be simplified. But my first priority is to get it to work like in MC.

For as far as I know it works like this in MC. Once Link falls he is set back to the last visited tile that Link can stand on (not the nearest tile Link can stand on), which would allow Link to be put back on the correct tile after a jump with roc's feather or when he jumps in water from a ledge he can't swim in. If the tile is taken by an enemy or another object in the time that Link fell, Link is set to the nearest available tile from that. Although for dungeons I don't really know, but I need to check the game for that. I will check that later.

On another note: I think it is best to change the moving and falling boolean variables into 1 state variable, which can be used in a single switch statement:
0 - idle/standing still
1 - walking/moving
2 - falling
3 - rolling
4 - flying etc.

And another state variable for the use of items. Like:
0 - nothing
1 - sword charge
2 - bow hold
3 - boomerang hold
4 - gust jar hold, etc.
Logged
Re: Link Ice-Based Movement
« Reply #19 on: August 04, 2009, 10:23:35 am »
  • Fight the Power
  • *
  • Reputation: +0/-0
  • Offline Offline
  • Gender: Male
  • Posts: 1245
Wow guys, I'd never tried this before. Looks pretty neat, only problem I see is that corner cutting isn't sensible enough. It should be like if you barely touch the corner it sends you in that direction. Makes getting around much easier.

Other than that, good job. :)

Edit: BTW, this is what I mean:


See, it's not sensible enough!
« Last Edit: August 04, 2009, 10:39:43 am by Darunia »
Logged

Currently Listening to: Mos Def - Summertime
Pages: [1] 2   Go Up

 


Contact Us | Legal | Advertise Here
2013 © ZFGC, All Rights Reserved



Page created in 0.109 seconds with 75 queries.