9258 wrote:
I've started programming fairly recently and I've found I learn best by reading other code. I don't know if it's a taboo to ask to see someone else's code (like I'm gonna steal it or something I guess?) but if so I'd be fine with just an explanation of one or some of the ways you might make a character jump. I can make a character go up, of course, and I have a working gravity engine to make them come back down, but what I need to learn to do is make it go up, hit a certain point, then come back down. Y'know. Just a normal jump like in any game. I've been trying a couple different ways and the only time I got it to work, I don't understand why it works. At first it was more of a teleport followed by a fall due to the gravity I'd written, then I put the vblank wait in the middle of the code for the jump and that made it happen correctly for some reason. It looks like this:
Quote:
Without the Vblank wait there, all eight "move up by 2"s happen at the same time and the character just shoots up to the right point. With the wait it lets each one happen frame by frame, but I don't know why that all works in the context of the rest of the code.
I having a problem understanding.. what you're not understanding. That is to say, you don't understand why you need vblanks? I think you might have some serious gaps in the general fundamentals of game logic (which is strange, if you have the capability of coding in ASM then surely something simple in logic like this should be obvious or simply worked out). Did no one else feel similar about this post??? Maybe I'm just misunderstanding you,
but I'm going to assume you really don't understand some very basic/simplistic ideas. I mean, I don't know how else to interpret your post, considering what you've said.
This should be in the newbie help section. So I'm going to assume this is
ALL relatively new to you.
So, 'jumping' is obviously a state that exists for a period of frames. The object moves up, hits a point where the acceleration in that direction stops, then object falls back 'down'. However you implement this, linear or non-linear, it's all irrelevant if you
don't understand why 'vblanks' in between each step made it not 'teleport', or why you would even need them. If you don't understand that, then I doubt you're gonna understand
any of the examples/code given here. This isn't about ASM coding, this is about some pretty basic logic.
So OK, 'jumping' is an action that happens across a series of frames; a it's temporal thing (a series of events). You should have a main game engine loop that occurs, typically, every
vblank. If the player pushes a button, then the main game loop executes the jump action. Each time, the game engine calls the jump routine, and
each time that routine either adds height or decreases height - until either the object/player dies or hits solid ground, or
some other event that game logic determines should
end the jump routine. It needs to happen across a series of frames because otherwise the game logic will not execute correctly and you get that
teleporting effect. To be honest, this shouldn't really need an explanation. Maybe you can give some history/background on what experience you have (programming, etc)?
So your code here...
Code:
Jump:
LDX #$08
Moving:
LDA Sprite1VerticalPosition
SEC
SBC #$02
STA Sprite1VerticalPosition
LDA Sprite2VerticalPosition
SEC
SBC #$02
STA Sprite2VerticalPosition
LDA Sprite3VerticalPosition
SEC
SBC #$02
STA Sprite3VerticalPosition
LDA Sprite4VerticalPosition
SEC
SBC #$02
STA Sprite4VerticalPosition
DEX
CPX #$00
BEQ JumpDone
vblankwaitforjump
readyyy
BIT $2002
BPL vblankwaitforjump
JMP Moving
JumpDone:
... screams something seriously wrong with your understanding of how even simple events work (disregarding the linear movement). So I'm gonna re-write this code in a context that you can hopefully understand or at your level. Whatever.
Here's my version of your code (kept as simple as possible):
Code:
;..........................................
;This is the main game engine loop. All
;actions happen inside this loop.
;
GameEngineLoop:
BIT $2002
BPL GameEngineLoop
JSR ReadGamepad
JSR DoSomeOtherStuffs
JSR DoSomeMoreGameLogic
JSR DoJump
jmp GameEngineLoop
;..........................................
;Jump subroutine
;
DoJump:
LDA SpriteJumpState
CMP #$00
BEQ .out
CMP #$09
BCC .fall
.rise
LDA Sprite1VerticalPosition
SEC
SBC #$02
STA Sprite1VerticalPosition
DEC SpriteJumpState
RTS
.fall
LDA Sprite1VerticalPosition
CLC
ADC #$02
STA Sprite1VerticalPosition
DEC SpriteJumpState
RTS
.out
RTS
;..........................................
;Set the jump routine in motion
;
ActivateJump:
LDA #$10
STA SpriteJumpState
RTS
And here's the explanation: The game engine loop handle all action, including reading the gamepad. Notice how it's aligned to happen every vblank. At some point, after reading the gamepad, the "game logic" decides whether if the jump button is pressed - should receive that action (it passes the requirements, whatever they may be). It then calls ActivateJump which enables the jump subroutine to actually play that out. The jump routine is always called inside the main game engine loop, but the required state of the
counter "SpriteJumpState" dictates
whether this will happen or not (I could have used a flag variable instead). If the counter isn't 0, then it's decremented
every time by the routine. If the counter is between $10 and $09, then it will subtract from the vertical position (jumps "up"), when the value is between $08 and $01, then it will add to the vertical position (fall down). Since the counter is always decremented, it moves from one states (going up) to eventually the opposite state (going down), until it reaches a third state (counter=0) which nothing happens. Again, nothing is optimal here; it's just to help show how you would handle an event such as 'jumping'.
If I'm wrong, and I completely misunderstood your post - then I apologize (I don't mean to insult)... and I just wasted my time. If I'm right though, I hope this helps.