Learning Action Game Basics
Posted: Fri Aug 11, 2017 8:44 am
Learning Action Game Basics, Acceleration-based Movement, Variable Height Jumping and Collision
Edit: The following code is apparently fine. I figured out the problem elsewhere and it fixed it. My other question is still relevant though.
So I decided to learn how to make an action game.
In order to make physics smooth and flexible like I want them, I understand that I need to make: A fixed-point subpixel system so I can move slower than 1 pixel/frame, acceleration-based movement for both running and jumping, and variable height jumping.
I already made subpixel coordinates using one byte for the fractional part and one for the integer part of the coordinate and they work fine.
Now I'm trying to make acceleration-based movement. I started making the controller handling for rightward movement. I learned to do comparisons with signed numbers from this article.
So to move rightwards, I'm using two bytes for velocity that are added to by a two-byte acceleration value every frame that the RIGHT d-pad button is pressed. Before updating the velocity I first compare (using 16-bit signed comparison from above link) the new velocity value with the max speed value and if it's more than the max speed, I set the velocity to the max speed value, else I proceed to update velocity with the new value.
Velocity is then added to the 16-bit X-coordinate which updates the sprite position.
My code works fine as long as my max speed isn't set to $00.7F or more. As soon as my sprite comes up to this speed he will start slowing down to zero again, then accelerate again and so on as long as I hold the button. I suspect something about the comparison routine makes it think that the lower velocity byte is signed. Shouldn't the sign only be in the most significant byte so that the range becomes $80.00 to $7F.FF?
Questions:
1) What's wrong with my code?
Edit: Of course soon after posting this, I found out the problem. It appears the code is fine, the problem was very simple and unrelated to this code. I guess the code can be used by others trying to do the same thing. My other question is still relevant though.
2) What is the Overflow Flag normally used for? From what I understand it indicates overflow/underflow between $7F and $80 to indicate that the value didn't fit in the signed number, much like Carry indicates that a number doesn't fit in a byte. But unlike Carry it isn't used in additions and subtractions. The only use I know of it is for signed comparisons, as a simulation of a branch always instruction and used in a special feature of the BIT instruction.
Any help is greatly appreciated!
Edit: The following code is apparently fine. I figured out the problem elsewhere and it fixed it. My other question is still relevant though.
So I decided to learn how to make an action game.
In order to make physics smooth and flexible like I want them, I understand that I need to make: A fixed-point subpixel system so I can move slower than 1 pixel/frame, acceleration-based movement for both running and jumping, and variable height jumping.
I already made subpixel coordinates using one byte for the fractional part and one for the integer part of the coordinate and they work fine.
Now I'm trying to make acceleration-based movement. I started making the controller handling for rightward movement. I learned to do comparisons with signed numbers from this article.
So to move rightwards, I'm using two bytes for velocity that are added to by a two-byte acceleration value every frame that the RIGHT d-pad button is pressed. Before updating the velocity I first compare (using 16-bit signed comparison from above link) the new velocity value with the max speed value and if it's more than the max speed, I set the velocity to the max speed value, else I proceed to update velocity with the new value.
Velocity is then added to the 16-bit X-coordinate which updates the sprite position.
My code works fine as long as my max speed isn't set to $00.7F or more. As soon as my sprite comes up to this speed he will start slowing down to zero again, then accelerate again and so on as long as I hold the button. I suspect something about the comparison routine makes it think that the lower velocity byte is signed. Shouldn't the sign only be in the most significant byte so that the range becomes $80.00 to $7F.FF?
Code: Select all
;Constants:
MOB_ACCEL_L = 4 ;walking/running acceleration value fractional part
MOB_ACCEL_H = 0 ;walking/running acceleration value integer part
MOB_MSPD_L = 128 ;maximum walking/running speed fractional part
MOB_MSPD_H = 0 ;maximum walking/running speed integer part
;Variables:
temp+0
temp+1 ;temporary storage
p1_x+0 ;horizontal coordinate fractional part
p1_x+1 ;horizontal coordinate integer part
p1_vx+0 ;horizontal velocity fractional part
p1_vx+1 ;horizontal velocity integer part
;Code:
@right1: ;controller I input handler for RIGHT button
lda con_state+0
and #CON_RIGHT
beq @not_right1
lda p1_vx+1
bmi @not_right1 ;if velocity negative, not right
lda p1_vx+0
clc
adc #MOB_ACCEL_L ;add acceleration value to velocity, low byte
sta temp+0
lda p1_vx+1
adc #MOB_ACCEL_H ;add acceleration value to velocity, high byte
sta temp+1 ;store new velocity temporary for comparison
lda temp+0
cmp #MOB_MSPD_L
lda temp+1
sbc #MOB_MSPD_H
bvc @n_xor_v_vr
eor #$80
@n_xor_v_vr: ;16-bit signed comparison with max speed
bmi @not_terminal_vr ;if velocity < max speed, allow acceleration
lda #MOB_MSPD_L
ldx #MOB_MSPD_H
jmp @terminal_vr ;else, velocity = max speed
@not_terminal_vr:
lda temp+0
ldx temp+1
@terminal_vr:
sta p1_vx+0
stx p1_vx+1 ;set velocity
jmp @a1 ;exit
@not_right1: ;if !RIGHT, decelerate
;......
p1_move_x: ;horizontal movement based on velocity
lda p1_x+0
clc
adc p1_vx+0
sta p1_x+0 ;add velocity to position to move, low byte
lda p1_x+1
adc p1_vx+1
sta p1_x+1 ;add high byte plus carry
1) What's wrong with my code?
Edit: Of course soon after posting this, I found out the problem. It appears the code is fine, the problem was very simple and unrelated to this code. I guess the code can be used by others trying to do the same thing. My other question is still relevant though.
2) What is the Overflow Flag normally used for? From what I understand it indicates overflow/underflow between $7F and $80 to indicate that the value didn't fit in the signed number, much like Carry indicates that a number doesn't fit in a byte. But unlike Carry it isn't used in additions and subtractions. The only use I know of it is for signed comparisons, as a simulation of a branch always instruction and used in a special feature of the BIT instruction.
Any help is greatly appreciated!