[4.1] Use the real Melee object weapon in the Platformer module

dale_coop

Moderator
Staff member
Can you share your b create melee object scrip, your preDraw script?
I think it needs some fixes.
 
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
 

dale_coop

Moderator
Staff member
Share the script you are using... the one that keeps the Melee weapon following your Player object.
I will try to fix yours! not Nate one.
 
That's the thing, I WAS using Nate's scrip as is, but changed the object name to 'OBJECT_PLAYER_MELEE' instead of 'OBJ_PLAYER_MELEE'

this creates the bug for me that the monster gets drawn close to me. and for some reason, since I started from scratch, now that script is also placing my weapon too high (my offset is correct though). If I remove Nate's script from my predrawdc script, the weapon is at correct height when it is drawn, and monsters dont get draw straight next to me when I enter a screen.
 
Yeah, edited them back in post. that's what I'm using :

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


WITH Nate's script in the predraw code, it does this :
[media]https://youtu.be/evKVcJBOM30[/media]

WITHOUT Nate's script :
[media]https://youtu.be/XE8D0IXhflo[/media]
 

dale_coop

Moderator
Staff member
Ok, try this...

- In your PreDraw script, replace the line:
Code:
    LDX #OBJECT_PLAYER_MELEE
By:
Code:
	LDX player1_weapon
	LDA Object_type,x
	CMP #OBJECT_PLAYER_MELEE
	BNE +

- In your create melee script, just after the:
Code:
	CreateObject temp, temp1, #OBJECT_PLAYER_MELEE, #$00, temp3
Add that line:
Code:
	STX player1_weapon

It should work better now.
 
Ah, yes, that fixes the issue with the monster, great stuff, thank you so much Dale !

Edit: BTW, my weapon disappearing when it hits monster, it has a fix I just found out HERE
 

mkjake63

Member
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.

I'm having the same issue, was curious if this was resolved? I'll also sometimes move while still in the jump animation
 

dale_coop

Moderator
Staff member
Hmmm...
Check your StartMovngPlayerLeft and Right input script...
And comment out the lines:
Code:
    CMP #$02 ;; if the state is invincible
    BEQ ++ ; skip movement if attacking
(adding a ";" before each line)

And test again your jump... I think it's the issue here.
 
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 :)
 

Otterbits

New member
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 :)

Same here. This along with crouching is causing my problems in 4.5.6.
 
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.

Sounds like a really cool mechanic and clever idea with the shoot projectile script from the Metroidvania module. I'll go back to that tutorial set and try looking at it as well since you mentioned it.
 

Otterbits

New member
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.

Seems like this could work with any sort of melee weapon. I'll look into it. Thanks!
 

longie_long

New member
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":

2019-01-14-15-42-59-Project-Settings.png
 

mouse spirit

Well-known member
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":

2019-01-14-15-42-59-Project-Settings.png
Are you in 4.1? If so, check at the very bottom of the list.
 
Top Bottom