atari2600land, on Sat Jan 20, 2007 10:39 PM, said:
I'm making a platform game and the guy needs to jump. Here's what I have so far:
130 if joy0fire then c{1}=1
if c{1} then timer=timer+1 : y=y-1
if timer=20 && c{1} then c{1}=0 : c{2}=1 : timer=0
135 if c{2} then y=y+1
if collision(player0,playfield) then y=y-2 : c{2}=0
Now, all I have to do is make the guy go down even if the fire button is pressed. Any suggestions?
As I understand it, you're using two flags for jumping-- c{1} to indicate whether the guy is jumping and is on his way up, and c{2} to indicate whether he's jumping and is on his way down, as follows:
If c{1} is 0 and c{2} is 0, it means he isn't jumping right now.
If c{1} is 1 and c{2} is 0, it means he's jumping and is on his way up.
If c{1} is 0 and c{2} is 1, it means he's jumping and is on his way down.
If you press the fire button while he isn't jumping, everything's fine, because you set c{1} to 1 to indicate that now he's jumping and is on his way up, you decrement y so he goes up into the air, and you increment the timer which counts how many frames he goes up into the air before he starts to fall back down.
If you press the fire button while he's already jumping, and is on his way up, then everything's still fine, because all you do is set c{1} to 1, even though c{1} is already set to 1, so no harm is done.
*But*, if you press the fire button while he's already jumping, and is on his way *down*, then you've got a problem, because c{1} is set to 0 and c{2} is set to 1, but now you're setting c{1} to 1 (since the fire button was just pressed), and thus you end up with the following:
If c{1} is 1 and c{2} is 1, it means he's jumping and was on his way down, but suddenly decided to use his amazing psychokinetic levitational ability to float for a third of a second (because once the timer counts up to 20, he'll start to fall again). And as long as you keep pressing the fire button, he'll keep floating. The reason he floats, rather than rising even higher, is because c{1} and c{2} are both set to 1, so first you decrement y, and then you increment y, such that y ends up having the same value that it did before.
Consequently, you could fix your existing code by modifying the "if" in line 130, as follows:
130 if joy0fire && !c{2} then c{1}=1 : rem * added "&& !c{2}"
However, that still doesn't fix all of your problems. For example, if he's on a platform and steps off into thin air (without jumping), he'll just float in the air, because c{1} and c{2} will both be 0. So you could fix that by adding another line before line 130, as follows:
129 if !collision(player0,playfield) && !c{1} then c{2}=1
This will cause him to fall if he isn't standing on a platform-- but only if he isn't in the process of jumping up into the air.
However, this new line doesn't sit well with the last line of code you posted (i.e., the unnumbered line after line 135), because the two of them together-- along with line 135-- cause the man to shake or vibrate up and down very rapidly, and also prevent him from being able to jump anymore. So you could fix that by taking "y=y-2" out of that last line, as follows:
if collision(player0,playfield) then c{2}=0
So the final code looks like this:
129 if !collision(player0,playfield) && !c{1} then c{2}=1
130 if joy0fire && !c{2} then c{1}=1
if c{1} then timer=timer+1 : y=y-1
if timer=20 && c{1} then c{1}=0 : c{2}=1 : timer=0
135 if c{2} then y=y+1
if collision(player0,playfield) then c{2}=0
That actually works pretty good, but the jumping motion doesn't look very natural. In actual jumping motion, the man would rise up into the air rather rapidly at first, and then immediately start to slow down. And after he slowed to a stop, he would start to fall slowly, but would immediately start to speed up. The best way to do something like that is with a 4.4 fixed-point "momentum" variable, or whatever you want to call it. And you would use an 8.8 fixed-point variable for the y position. I'm attaching two programs-- the first one (jump.bas) uses your original method, with the changes I've suggested above; and the second one (jumping.bas) uses 4.4 and 8.8 fixed-point variables. I tried to add a few additional checks: If the man hits a platform while he's jumping upward, then he hurts himself (the sprite changes, and it's supposed to look like he just bashed his head), which stops him from rising any higher, and he starts to fall (but if he's still touching the playfield after he starts to fall, then he'll cling to it). And if he falls from too great a height (as indicated by hitting the ground with a negative momentum exceeding -4.0), then he crashes into the ground (the sprite changes to an upside-down version of him hitting his head). It's far from perfect, but it may give you ideas, and hopefully other people will contribute comments. Note that this topic was dicussed before when you were thinking about a "Mr. Flanksteak" game (if I remember correctly), so you might want to read through those old posts.
Michael