;; sprite pre-draw
;;; this will allow a user to draw sprites
;;; before object sprites are drawn.
;;; keep in mind, there are still only 64 sprites
;;; that can be drawn on a screen,
;;; and still only 8 per scan line!
;;; you can use DrawSprite macro directly using the following scheme:
;DrawSprite arg0, arg1, arg2, arg3, arg4
;arg0 = x
;arg1 = y
;arg2 = chr table value
;arg3 = attribute data
;arg3 = starting ram position
;; x and y are the direct positions on the screen in pixels.
;; chr table value is which sprite you'd like to draw from the ppu table.
;; attribute data is a binary number (starts with #%), and here are how the bits work:
;;; bit 7 - Flip sprite vertically
;;; bit 6 - Flip sprite horizontally
;;; bit 5 - priority (0 in front of background, 1 behind background)
;;; bit 4,3,2 - (null)
;;; bit 1,0 - subpalette used (00, 01, 10, 11)
;;; for starting ram position, use spriteOffset.
;; this is set to 0 just before entering this script (or 4 if sprite 0 hit was used).
;; ***remember to increase spriteOffset by 4 for every sprite that is drawn,
;; including after the last one drawn*****, so that the first object's sprite begins
;; in the next available spot.
;; I have created a macro function to handle updating to the next sprite. So, to update to the next sprite position,
;; all that you have to do is use the function UpdateSpritePointer
;;EXAMPLE:
; DrawSprite #$80, #$80, #$10, #%00000000, spriteOffset
; UpdateSpritePointer
;;;; DRAW SPRITE ZERO FOR SPRITE ZERO HIT
LDA gameState
CMP #GS_MainGame
BNE + ;dont draw sprite zero
;DrawSprite #$f8, #$1e, #$7F, #%00000000, spriteOffset
;248 30 127 bit 5 = priority
DrawSprite #SPRITE_ZERO_X, #SPRITE_ZERO_Y, #SPRITE_ZERO_INDEX, #%00100000, spriteOffset
UpdateSpritePointer
;; Nate's janky object parenting w/ melee weapon
LDX player1_object
LDA Object_animation_frame,x
STA temp
LDA Object_movement,x
AND #%00000111
STA temp3
TAY
LDA Object_x_hi,x
SEC
SBC #$10 ;; width of melee weapon
CLC
ADC weaponOffsetTableX,y
STA temp1
LDA Object_y_hi,x
CLC
ADC weaponOffsetTableY,y
SEC
SBC #$18 ;; height of melee weapon
STA temp2
LDX #OBJECT_PLAYER_MELEE
LDA temp1
STA Object_x_hi,x
LDA temp2
STA Object_y_hi,x
LDA Object_movement,x
ORA temp3
STA Object_movement,x
;dont draw sprite zero.
+
LDA gameHandler
AND #%00100000
BEQ notNPCstate_attack
JMP doneAttacking
notNPCstate_attack:
LDA weaponsUnlocked
AND #%00000001
BNE canAttack
JMP doneAttacking
canAttack:
LDX player1_object
GetCurrentActionType player1_object
CMP #$03
BNE notAlreadyAttacking
JMP doneAttacking
notAlreadyAttacking:
;;; don't attack if already attacking.
;;; do we have to check for hurt here?
;;;;; Here, we WOULD create melee
ChangeObjectState #$03, #$02
LDA Object_movement,x
AND #%00001111
STA Object_movement,x
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
LDA Object_x_hi,x
STA temp
LDA Object_y_hi,x
STA temp1
LDA Object_movement,x
AND #%00000111
STA temp2
TAY
LDA Object_x_hi,x
SEC
SBC #$10 ;; <<--- HERE, you have to set width of melee weapon in HEX (1 tile = 8px, 8 in decimal = #$08 in hex. Use the binary <-> hex converter plugin)
STA temp
LDA Object_scroll,x
SBC #$00
STA temp3
LDA temp
;;; offset x for creation
CLC
ADC weaponOffsetTableX,y
STA temp
LDA temp3
ADC #$00
STA temp3
LDA Object_y_hi,x
CLC
ADC weaponOffsetTableY,y
SEC
SBC #$08 ;; <<--- HERE, you have to set height of melee weapon in HEX (1 tile = 8px, 8 in decimal = #$08 in hex. Use the binary <-> hex converter plugin)
STA temp1
CreateObject temp, temp1, #OBJECT_PLAYER_MELEE, #$00, temp3
meleeCreated:
;;;; x is now the newly created object's x.
LDA Object_movement,x
ORA temp2
STA Object_movement,x
;PlaySound #SND_SLASH
doneAttacking:
RTS
nathanlurker said:Predraw script
Code:;; sprite pre-draw ;;; this will allow a user to draw sprites ;;; before object sprites are drawn. ;;; keep in mind, there are still only 64 sprites ;;; that can be drawn on a screen, ;;; and still only 8 per scan line! ;;; you can use DrawSprite macro directly using the following scheme: ;DrawSprite arg0, arg1, arg2, arg3, arg4 ;arg0 = x ;arg1 = y ;arg2 = chr table value ;arg3 = attribute data ;arg3 = starting ram position ;; x and y are the direct positions on the screen in pixels. ;; chr table value is which sprite you'd like to draw from the ppu table. ;; attribute data is a binary number (starts with #%), and here are how the bits work: ;;; bit 7 - Flip sprite vertically ;;; bit 6 - Flip sprite horizontally ;;; bit 5 - priority (0 in front of background, 1 behind background) ;;; bit 4,3,2 - (null) ;;; bit 1,0 - subpalette used (00, 01, 10, 11) ;;; for starting ram position, use spriteOffset. ;; this is set to 0 just before entering this script (or 4 if sprite 0 hit was used). ;; ***remember to increase spriteOffset by 4 for every sprite that is drawn, ;; including after the last one drawn*****, so that the first object's sprite begins ;; in the next available spot. ;; I have created a macro function to handle updating to the next sprite. So, to update to the next sprite position, ;; all that you have to do is use the function UpdateSpritePointer ;;EXAMPLE: ; DrawSprite #$80, #$80, #$10, #%00000000, spriteOffset ; UpdateSpritePointer ;;;; DRAW SPRITE ZERO FOR SPRITE ZERO HIT LDA gameState CMP #GS_MainGame BNE + ;dont draw sprite zero ;DrawSprite #$f8, #$1e, #$7F, #%00000000, spriteOffset ;248 30 127 bit 5 = priority DrawSprite #SPRITE_ZERO_X, #SPRITE_ZERO_Y, #SPRITE_ZERO_INDEX, #%00100000, spriteOffset UpdateSpritePointer ;; Nate's janky object parenting w/ melee weapon LDX player1_object LDA Object_animation_frame,x STA temp LDA Object_movement,x AND #%00000111 STA temp3 TAY LDA Object_x_hi,x SEC SBC #$10 ;; width of melee weapon CLC ADC weaponOffsetTableX,y STA temp1 LDA Object_y_hi,x CLC ADC weaponOffsetTableY,y SEC SBC #$18 ;; height of melee weapon STA temp2 LDX #OBJECT_PLAYER_MELEE LDA temp1 STA Object_x_hi,x LDA temp2 STA Object_y_hi,x LDA Object_movement,x ORA temp3 STA Object_movement,x ;dont draw sprite zero. +
melee script
Code:LDA gameHandler AND #%00100000 BEQ notNPCstate_attack JMP doneAttacking notNPCstate_attack: LDA weaponsUnlocked AND #%00000001 BNE canAttack JMP doneAttacking canAttack: LDX player1_object GetCurrentActionType player1_object CMP #$03 BNE notAlreadyAttacking JMP doneAttacking notAlreadyAttacking: ;;; don't attack if already attacking. ;;; do we have to check for hurt here? ;;;;; Here, we WOULD create melee ChangeObjectState #$03, #$02 LDA Object_movement,x AND #%00001111 STA Object_movement,x 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 LDA Object_x_hi,x STA temp LDA Object_y_hi,x STA temp1 LDA Object_movement,x AND #%00000111 STA temp2 TAY LDA Object_x_hi,x SEC SBC #$10 ;; <<--- HERE, you have to set width of melee weapon in HEX (1 tile = 8px, 8 in decimal = #$08 in hex. Use the binary <-> hex converter plugin) STA temp LDA Object_scroll,x SBC #$00 STA temp3 LDA temp ;;; offset x for creation CLC ADC weaponOffsetTableX,y STA temp LDA temp3 ADC #$00 STA temp3 LDA Object_y_hi,x CLC ADC weaponOffsetTableY,y SEC SBC #$08 ;; <<--- HERE, you have to set height of melee weapon in HEX (1 tile = 8px, 8 in decimal = #$08 in hex. Use the binary <-> hex converter plugin) STA temp1 CreateObject temp, temp1, #OBJECT_PLAYER_MELEE, #$00, temp3 meleeCreated: ;;;; x is now the newly created object's x. LDA Object_movement,x ORA temp2 STA Object_movement,x ;PlaySound #SND_SLASH doneAttacking: RTS
LDX #OBJECT_PLAYER_MELEE
LDX player1_weapon
LDA Object_type,x
CMP #OBJECT_PLAYER_MELEE
BNE +
CreateObject temp, temp1, #OBJECT_PLAYER_MELEE, #$00, temp3
STX player1_weapon
WillElm said:dale_coop said:11/ Last thing, you should do a small modification in your StartMovingPlayerxxx script, just moving the "++" from before the "FaceDirection" line, to AFTER "FaceDirection" line.
For exemple, StartMovingPlayerRight.Asm should be like this :
Code:;;;;; START MOVING PLAYER RIGHT: ;;;;; We will use this when the right button is pressed. ;;;;; If we are already showing the walking animation, which is for this module ;;;;; action step 1, we will skip changing to the walking state. LDX player1_object GetCurrentActionType player1_object CMP #$02 ;; if the state is invincible BEQ ++ ; skip movement if attacking CMP #$03 BEQ ++ ;skip if we are casting spell CMP #$01 BEQ + ;; if the action type already equals 1, jump forward ChangeObjectState #$01, #$04 + ;;;;;; Then, we will begin moving. StartMoving player1_object, MOVE_RIGHT ;;;;;; Lastly, we will change the facing direction. FaceDirection player1_object, FACE_RIGHT ++ RTS
Voilà, your Melee weapon should work as expected...
Note: you should get rid of your GetSword pickup object, make it a health pickup or anything else you want (change the script assign to the "Power Up 00" in the "Project Settings > Script Settings").
When I implement this movement code, I can't move after jumping straight up in the air, and sometimes cannot move upon landing. Anyone else have this issue? I don't wanna go back to the original movement code because of attack spamming.
damiantwinter said:Hi all. Has anyone been able to implement this technique in 4.5.6? I've been trying to break it down, but running into a few key differences between versions. If this has been covered elsewhere, my apologies. Thanks
nathanlurker said:I haven't found a way to implement a melee attack in 4.5.6 but I'm working around that issue by using the shoot projectile script from Metroidvania module, but having my base projectile be a punching shockwave effect that destroys itself at end of animation. My character has an attack state where it's punching, and the projectile object is just the sort of "woosh" effect in front of the fist.
nathanlurker said:I haven't found a way to implement a melee attack in 4.5.6 but I'm working around that issue by using the shoot projectile script from Metroidvania module, but having my base projectile be a punching shockwave effect that destroys itself at end of animation. My character has an attack state where it's punching, and the projectile object is just the sort of "woosh" effect in front of the fist.
Are you in 4.1? If so, check at the very bottom of the list.I'm following you up until step 8. Where is the Use Sprite Based Weapon element? I don't have it anywhere!
/ In your "Project Settings > Script Settings", select the "Use Sprite Based Weapon" element and assign it the "Routines\Basic\ModuleScripts\BlankScript.asm":