Firing projectile up in a sidescroller

I am having quite a bit of difficulty figuring out how to fire a projectile 'upward' in the platform game I am working on.

It seems to be an issue with gravity.
I have my projectile set to 'ignore gravity' because I want it to fire perfectly horizontal.

My player can aim upwards like in Metroid.

I have managed to figure everything else out pretty much, but for some reason I cannot get the projectile to move up or down no matter what vertical speed I set it to.
I know that setting the speed is working, because the bullets will fire if I uncheck ignore gravity... but then I have the undesired effect of gravity effecting the bullets moving horizontally.

The only thing I can think is that I should try and move the projectile through some other method than setting it's speed.
I do not understand how that last block of code works that sets the direction and speed when they are horizontal.

Here is my projectile script:

Code:
createWeaponProjectile:
  LDA gameHandler
  AND #%00100000
    BEQ notNPCstate_proj
    JMP doneShooting   
    
notNPCstate_proj:
  ;LDA weaponsUnlocked
  ;AND #%00000010
    ;BNE canShoot
    ;JMP doneShooting
  JMP checkPlrShotsFired
  
checkPlrShotsFired:
  ;;  Check if the player is at their limits for projectile on the screen
  LDA plrShotlim
  CMP #$00
    BNE canShoot
    JMP doneShooting 
    
canShoot:
  LDX player1_object
  GetCurrentActionType player1_object
  CMP #$05
    BNE notAlreadyShooting
    JMP doneShooting  
    
notAlreadyShooting:  
  ; Get only first 4 bits of the player's 'Object_movement' value and save back to player object
  LDA Object_movement,x
  AND #%00001111
  STA Object_movement,x
  
  ; Store 0 in player objects various speeds
  LDA #$00
  STA Object_h_speed_hi,x
  STA Object_h_speed_lo,x
  STA Object_v_speed_hi,x
  STA Object_v_speed_lo,x
  
  ; Get upper left corner of the player object
  LDA Object_x_hi,x
  STA temp
  LDA Object_y_hi,x
  STA temp1
  
  JMP chooseProjDir
  
chooseProjDir:
  ; Get only first 3 bits of the player's 'Object_movement' value and save to temp2
  LDA Object_movement,x
  AND #%00000111
  STA temp2
    
  ;; Choose the offset to change based on facing direction
  ;; You can comment out any you do not need
  CMP #%00000110
    BEQ facingLeft
  CMP #%00000010
    BEQ facingRight
  ;CMP #%00000100
    ;BEQ setUPOffsetProjectile
  ;CMP #%00000000
    ;BEQ setDOWNOffsetProjectile
  JMP doneShooting

facingLeft:
  LDA Object_action_step,x
  AND #%00000111
  CMP #$04
  BEQ setLEFTUPOffsetProjectile
  JMP setLEFTOffsetProjectile
  
facingRight:
  LDA Object_action_step,x
  AND #%00000111
  CMP #$04
  BEQ setRIGHTUPOffsetProjectile
  JMP setRIGHTOffsetProjectile
  
setLEFTOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    SBC #$04    ;;<<-- horizontal offset of your weapon when your player facing left (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    ADC #$07    ;;<<-- vertical offset of your weapon  when your player facing left(change the value to adjust from #$00 to #$0F or more)
    STA temp1
    JMP checkIfPlayerDuck
    
setRIGHTOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    ADC #$1B    ;;<<-- horizontal offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    ADC #$07    ;;<<-- vertical offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp1
    JMP checkIfPlayerDuck
    
setLEFTUPOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    ADC #$07    ;;<<-- horizontal offset of your weapon when your player facing left (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    SBC #$01    ;;<<-- vertical offset of your weapon  when your player facing left(change the value to adjust from #$00 to #$0F or more)
    STA temp1
    LDA #%00000100
    STA temp2
    JMP checkIfPlayerDuck
    
setRIGHTUPOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    ADC #$12    ;;<<-- horizontal offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    SBC #$01    ;;<<-- vertical offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp1
    LDA #%00000100
    STA temp2
    JMP checkIfPlayerDuck

;setUPOffsetProjectile:
;    ;; If player is pressing up, act like they are facing up and set direction of bullet to up
;    LDA #$100
;    STA temp2
;    LDA Object_x_hi,x
;    CLC
;    ADC #$14    ;;<<-- horizontal offset of your weapon when your player facing up (change the value to adjust from #$00 to #$0F or more)
;    STA temp
;    LDA Object_y_hi,x
;    CLC
;    SBC #$0D    ;;<<-- vertical offset of your weapon when your player facing up (change the value to adjust) from #$00 to #$0F or more
;    STA temp1
;    JMP checkIfPlayerDuck

;setDOWNOffsetProjectile:
;    LDA Object_x_hi,x
;    CLC
;    ADC #$04    ;;<<-- horizontal offset of your weapon when your player facing down (change the value to adjust from #$00 to #$0F or more)
;    STA temp
;    LDA Object_y_hi,x
;    CLC
;    ADC #$0D    ;;<<-- vertical offset of your weapon when your player facing down (change the value to adjust from #$00 to #$0F or more)
;    STA temp1
;    JMP checkIfPlayerDuck
    
checkIfPlayerDuck:
  LDA gamepad
  AND #%11110000
  CMP #%00100000 ;;check if down is pressed
    BEQ setDuckOffset
   JMP createProjectile
    
setDuckOffset:
  LDA Object_y_hi,x
  CLC
  ADC #$10    ;;<<-- vertical offset of your weapon when your player facing up (change the value to adjust) from #$00 to #$0F or more
  STA temp1
  JMP createProjectile

createProjectile:
    LDA Object_action_step,x
    AND #%00000111
    CMP #$04
    BEQ createProjWOAnim
    CMP #$03
    BEQ createProjWOAnim
    JMP createProjNormal
    
createProjNormal:
    ChangeObjectState #$05, #$02 ;Change to 'shooting' state if you have one
createProjWOAnim:
    LDA Object_action_step,x ;Grab the action step before we lose it
    CreateObject temp, temp1, #$03, #$00
    STA temp ;We no longer need temp for positional data
    
    ;Was player aiming up?
    LDA temp
    AND #%00000111
    CMP #$04
    BEQ addUpForce
    JMP shotEffects
    ;JMP addUpForce
    
addUpForce:
    LDA #$00
    SBC #$04
    STA Object_v_speed_hi,x
    JMP shotEffects

shotEffects:   ;;----- This is the block I do not understand, how does this set the direction and speed of the projectile? ------
    ;;;; x is now the newly created object's x.
    LDA Object_movement,x
    ORA temp2
    STA Object_movement,x
    LDY temp2
    LDA directionTable,y
    ORA Object_movement,x
    STA Object_movement,x    

    ;PlaySound #sfx_shoot ;play sound effect for shooting
    DEC plrShotlim ; Decrement the shots on screen count
 
doneShooting:
  RTS

;; Values for directions:
;000 down
;010 right
;100 up
;110 left
 
Sorry for replying to my own thread, but I found a sort of workaround:

Make the projectile have two action steps.
In 0 - make the projectile ignore gravity
in 1 - make the projectile NOT ignore gravity.

You can set the action step to spawn an object in when you create it.
Make a check to see if the player is aiming up, and spawn the object in action step 1 if you need gravity.
then you can set the objects vertical speed manually.
Code:
STA Object_v_speed_hi,x

I am still having some wierdness with collision detection, but that solves the problem of firing a projectile up when you have gravity.
 

MistSonata

Moderator
I think the problem is that you're using Object_v_speed_hi when you should be using Object_movement. The "v speed" and "h speed" variables control how fast an object goes. This is the way you move objects:

Code:
LDA #MOVE_UP
STA Object_movement, x

However, looking at the code that's already there, you could probably just use this to replace the code in "addUpForce:" and it should work just fine...

Code:
LDA #%00000100 ;; The last 3 bits are used for direction, with "100" meaning "UP".
STA temp2
 
Hmm, still doesn't work for me. The shot just freezes at its creation point.

Here is my updated code (Cleaned up a little as well):
You can toggle which method is used by swapping the label names createVShot and createVShot2.

Code:
createWeaponProjectile:
  LDA gameHandler
  AND #%00100000
    BEQ notNPCstate_proj
    JMP doneShooting   
    
notNPCstate_proj:
  ;LDA weaponsUnlocked
  ;AND #%00000010
    ;BNE canShoot
    ;JMP doneShooting
  JMP checkPlrShotsFired
  
checkPlrShotsFired:
  ;;  Check if the player is at their limits for projectile on the screen
  LDA plrShotlim
  CMP #$00
    BNE canShoot
    JMP doneShooting 
    
canShoot:
  LDX player1_object
  GetCurrentActionType player1_object
  CMP #$05
    BNE notAlreadyShooting
    JMP doneShooting  
    
notAlreadyShooting:  
  ; Get only first 4 bits of the player's 'Object_movement' value and save back to player object
  LDA Object_movement,x
  AND #%00001111
  STA Object_movement,x
  
  ; Get upper left corner of the player object
  LDA Object_x_hi,x
  STA temp
  LDA Object_y_hi,x
  STA temp1
  
  JMP chooseProjDir
  

;;Check if player is aiming up, if so set direction to up. Else check left or right
;  LDA Object_action_step,x
;  AND #%00000111
;  CMP #$04
;  BEQ setPlrAimup
;  JMP chooseProjDir

;setPlrAimup:
;  LDA #%00000100
;  STA temp2
;  JMP setUPOffsetProjectile
  
chooseProjDir:
  ; Get only first 3 bits of the player's 'Object_movement' value and save to temp2
  LDA Object_movement,x
  AND #%00000111
  STA temp2
    
  ;; Choose the offset to change based on facing direction
  ;; You can comment out any you do not need
  CMP #%00000110
    BEQ facingLeft
  CMP #%00000010
    BEQ facingRight
  ;CMP #%00000100
    ;BEQ setUPOffsetProjectile
  ;CMP #%00000000
    ;BEQ setDOWNOffsetProjectile
  JMP doneShooting

facingLeft:
  LDA Object_action_step,x
  AND #%00000111
  CMP #$04
  BEQ setLEFTUPOffsetProjectile
  JMP setLEFTOffsetProjectile
  
facingRight:
  LDA Object_action_step,x
  AND #%00000111
  CMP #$04
  BEQ setRIGHTUPOffsetProjectile
  JMP setRIGHTOffsetProjectile
  
setLEFTOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    SBC #$04    ;;<<-- horizontal offset of your weapon when your player facing left (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    ADC #$07    ;;<<-- vertical offset of your weapon  when your player facing left(change the value to adjust from #$00 to #$0F or more)
    STA temp1
    JMP checkIfPlayerDuck
    
setRIGHTOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    ADC #$1B    ;;<<-- horizontal offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    ADC #$07    ;;<<-- vertical offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp1
    JMP checkIfPlayerDuck
    
setLEFTUPOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    ADC #$07    ;;<<-- horizontal offset of your weapon when your player facing left (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    SBC #$01    ;;<<-- vertical offset of your weapon  when your player facing left(change the value to adjust from #$00 to #$0F or more)
    STA temp1
    LDA #%00000100
    STA temp2
    JMP checkIfPlayerDuck
    
setRIGHTUPOffsetProjectile:
    LDA Object_x_hi,x
    CLC
    ADC #$12    ;;<<-- horizontal offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp
    LDA Object_y_hi,x
    CLC
    SBC #$01    ;;<<-- vertical offset of your weapon when your player facing right (change the value to adjust from #$00 to #$0F or more)
    STA temp1
    LDA #%00000100
    STA temp2
    JMP checkIfPlayerDuck

;setUPOffsetProjectile:
;    ;; If player is pressing up, act like they are facing up and set direction of bullet to up
;    LDA #$100
;    STA temp2
;    LDA Object_x_hi,x
;    CLC
;    ADC #$14    ;;<<-- horizontal offset of your weapon when your player facing up (change the value to adjust from #$00 to #$0F or more)
;    STA temp
;    LDA Object_y_hi,x
;    CLC
;    SBC #$0D    ;;<<-- vertical offset of your weapon when your player facing up (change the value to adjust) from #$00 to #$0F or more
;    STA temp1
;    JMP checkIfPlayerDuck

;setDOWNOffsetProjectile:
;    LDA Object_x_hi,x
;    CLC
;    ADC #$04    ;;<<-- horizontal offset of your weapon when your player facing down (change the value to adjust from #$00 to #$0F or more)
;    STA temp
;    LDA Object_y_hi,x
;    CLC
;    ADC #$0D    ;;<<-- vertical offset of your weapon when your player facing down (change the value to adjust from #$00 to #$0F or more)
;    STA temp1
;    JMP checkIfPlayerDuck
    
checkIfPlayerDuck:
  LDA gamepad
  AND #%11110000
  CMP #%00100000 ;;check if down is pressed
    BEQ setDuckOffset
   JMP createProjectile
    
setDuckOffset:
  LDA Object_y_hi,x
  CLC
  ADC #$10    ;;<<-- vertical offset of your weapon when your player facing up (change the value to adjust) from #$00 to #$0F or more
  STA temp1
  JMP createProjectile

createProjectile:
    LDA Object_action_step,x
    AND #%00000111
    CMP #$04
    BEQ createProjWOAnim
    CMP #$03
    BEQ createProjWOAnim
    LDA gamepad
    AND #%10000000 ; If Left is pressed
    CMP #%10000000
    BEQ createProjWOAnim
    LDA gamepad
    AND #%01000000 ; If Right is pressed
    CMP #%01000000
    BEQ createProjWOAnim
    JMP createProjNormal
    
createProjNormal:
    ChangeObjectState #$05, #$02 ;Change to 'shooting' state if you have one
createProjWOAnim:
    LDA Object_action_step,x ;Grab the action step before we lose it
    AND #%00000111
    CMP #$04
    BEQ createVShot
    JMP createHShot
    
createVShot:
    CreateObject temp, temp1, #$03, #$00
    LDA #%00000100
    STA Object_movement, x
    JMP addShotEffects
    
createVShot2:
    ;;THIS WORKS BUT IS NOT IDEAL. THIS IS SKIPPED FOR TESTING
    ;;VERTICAL SHOT IS ACTION STEP 1 WITH GRAVITY
    CreateObject temp, temp1, #$03, #$01
    ;;;; x is now the newly created object's x.
    LDA Object_movement,x
    ORA temp2
    STA Object_movement,x
    LDY temp2
    LDA directionTable,y
    ORA Object_movement,x
    STA Object_movement,x     
    ;;Additional step of adding a vertical velocity to projectile
    LDA #$00
    SBC #$09
    STA Object_v_speed_hi,x
    JMP addShotEffects

createHShot:
    CreateObject temp, temp1, #$03, #$00
    ;;;; x is now the newly created object's x.
    LDA Object_movement,x
    ORA temp2
    STA Object_movement,x
    LDY temp2
    LDA directionTable,y
    ORA Object_movement,x
    STA Object_movement,x  
    JMP addShotEffects

addShotEffects:
    ;PlaySound #sfx_shoot ;play sound effect for shooting

    ;Manage # of shots and Infinite-Wall-Fire exploit
    LDA plrShotlim
    CMP #$02
    BCS resetShots
    JMP decrShots
    
resetShots:
    LDA #$02
    STA plrShotlim
    JMP decrShots
    
decrShots:
    DEC plrShotlim ; Decrement the shots on screen count
 
doneShooting:
  RTS

;; Values for directions:
;000 down
;010 right
;100 up
;110 left
 
Top Bottom