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

User avatar
dale_coop
Posts: 3596
Joined: Fri Feb 16, 2018 7:05 am
Location: France

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

Post by dale_coop » Mon Jan 14, 2019 2:48 pm

If you prefer to have a real object based Melee weapon, in your plateformer game project.
Here how to do :


1/ In the "Project Settings > User Constants", create a new constant named "OBJECT_PLAYER_MELEE" with the value "1".

Image


2/ Create a new script "b_create_melee_weapon.asm" in the "GameEngineData\Routines\Basic\ModuleScripts\InputScripts" folder, with this code:

Code: Select all

	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 #$08	;; <<--- 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
(in the script, don't forget to adapt/modify the with and the height of your weapon)


3/ In the hierarchy, under "Game Objects", select and setup your "Melee" object:

Image

In the "Details Object", you can its left / right animation :

Image

Then, set it as "Player weapon".:

Image

Set the "Action step 0" to "Ignore gravity" and to "DestroyMe" after the end of the Action, give a timer value of "1" (if you have an animation, you could you the "end of animation" with the right animation speed):

Image

And don't forget to set the Bounding Box!


4/ Now, select the "Player" object, go the "Object Details". For the "Action Step 03", uncheck the "Harmfull invicible", set to "GoToFirst" the end of Action, give a timer value of "1", at least the value of the weapon timer (if you have an animation, you could you the "end of animation" with the right animation speed):

Image


5/ In the hierarchy, select the "Game Object" element, and set the position (the Offset) of your Melee object with your Player for all its facing directions:

Image


6/ In the "Scripts > input Scripts" add the "b_create_melee_weapon.asm" script.

7/ In the "Input Editor", assign it to your button ("Press" "B" button).


8/ In your "Project Settings > Script Settings", select the "Use Sprite Based Weapon" element and assign it the "Routines\Basic\ModuleScripts\BlankScript.asm":

Image


9/ Make a new script "PreDraw_DC.asm" in your "GameEngineData\Routines\Basic\ModuleScripts\MainScripts\ScrollingPlatformer" folder, with this code (it's the same script that the PreDraw, I just removed all the part about the weapon):

Code: Select all

;; 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
;dont draw sprite zero.
+

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

And assigned it the the "Handle Sprite Pre-Draw" element in the "Project Settings > Script Settings".


10/ In your "Project Infos", you can check the "Weapon 1 unlock" if you want your player to have the weapon at launch (else he will have to get it from an NPC):

Image


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: Select all

 ;;;;; 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").
-----
Sorry about my poor english
All I need: A Damn Fine Cup of Coffee
My games: PRESS START GAME / UNDERGROUND ADVENTURE / UNDERGROUND ADVENTURE (Arcade version - Byte-Off-2019)
User avatar
Blacksheep32
Posts: 16
Joined: Mon Aug 27, 2018 1:05 am

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

Post by Blacksheep32 » Tue Jan 15, 2019 2:32 am

...and you just made my day! Thanks Dale!
User avatar
SuperNatetendo
Posts: 77
Joined: Wed Aug 08, 2018 4:51 pm

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

Post by SuperNatetendo » Tue Jan 15, 2019 3:42 am

So... I've made a janky solution to keep the object with you when allowing the attack to be done while mid-run/jump/etc

EDIT: forgot to say - I added this to the pre-draw script.

EDIT2: Added a few lines. Fixed a little directional issue.

Code: Select all

;; 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 #OBJ_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

    
Here's the problem, though... It has some weird directional issues which I'm not sure how to fix. Give it a shot and see what could be fixed.
Last edited by SuperNatetendo on Tue Jan 15, 2019 6:49 pm, edited 1 time in total.
User avatar
dale_coop
Posts: 3596
Joined: Fri Feb 16, 2018 7:05 am
Location: France

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

Post by dale_coop » Tue Jan 15, 2019 6:45 am

Oh nice, thank you Nate, I will try your script today (^_^)
-----
Sorry about my poor english
All I need: A Damn Fine Cup of Coffee
My games: PRESS START GAME / UNDERGROUND ADVENTURE / UNDERGROUND ADVENTURE (Arcade version - Byte-Off-2019)
VDfreesince1983
Posts: 12
Joined: Thu Aug 09, 2018 12:20 pm

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

Post by VDfreesince1983 » Tue Jan 15, 2019 4:31 pm

Ta-da check out this sweet sword action . I am not sure why sprite (12, 2) is showing up in the middle of my Melee object if anyone has any idea. But other than that I adjusted both the object alignment in the GUI [Right: (35,16), Left: (1,16)] and the melee width in your Player Melee script

Code: Select all

 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 #$14 ;; width of melee weapon 
    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 ;; height of melee weapon
    STA temp1   
    
    CreateObject temp, temp1, #$01, #$00, temp3 
User avatar
dale_coop
Posts: 3596
Joined: Fri Feb 16, 2018 7:05 am
Location: France

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

Post by dale_coop » Tue Jan 15, 2019 4:37 pm

Great!
Yep, exactly, I forgot to say that in the script you have to modify it with the width and the height of your weapon (the tutorial one is 8x8).
And, of course, adjust your offset of your Melee weapon (like you did for your projectiles), via the "Game Object" element in the NESMaker GUI.

Updated the OP
-----
Sorry about my poor english
All I need: A Damn Fine Cup of Coffee
My games: PRESS START GAME / UNDERGROUND ADVENTURE / UNDERGROUND ADVENTURE (Arcade version - Byte-Off-2019)
User avatar
DanielT1985
Posts: 122
Joined: Sat Sep 01, 2018 7:44 pm

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

Post by DanielT1985 » Tue Jan 15, 2019 7:17 pm

dale_coop wrote:
Mon Jan 14, 2019 2:48 pm
If you prefer to have a real object based Melee weapon, in your plateformer game project.
Here how to do :


1/ In the "Project Settings > User Constants", create a new constant named "OBJECT_PLAYER_MELEE" with the value "1".

Image


2/ Create a new script "b_create_melee_weapon.asm" in the "GameEngineData\Routines\Basic\ModuleScripts\InputScripts" folder, with this code:

Code: Select all

	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 #$08	;; <<--- HERE, you have to set width of melee weapon 
	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
	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
(in the script, don't forget to adapt/modify the with and the height of your weapon)


3/ In the hierarchy, under "Game Objects", select and setup your "Melee" object:

Image

In the "Details Object", you can its left / right animation :

Image

Then, set it as "Player weapon".:

Image

Set the "Action step 0" to "Ignore gravity" and to "DestroyMe" after the end of the animation, give an animation speed (even if don't have any particular animation!):

Image

And don't forget to set the Bounding Box!


4/ Now, select the "Player" object, go the "Object Details". For the "Action Step 03", uncheck the "Harmfull invicible", set to "Loop" the end of action and set to "GoToFirst" the End of animation, give an animation speed (even if don't have any particular animation!):

Image


5/ In the hierarchy, select the "Game Object" element, and set the position (the Offset) of your Melee object with your Player for all its facing directions:

Image


6/ In the "Scripts > input Scripts" add the "b_create_melee_weapon.asm" script.

7/ In the "Input Editor", assign it to your button ("Press" "B" button).


8/ In your "Project Settings > Script Settings", select the "Use Sprite Based Weapon" element and assign it the "Routines\Basic\ModuleScripts\BlankScript.asm":

Image


9/ Make a new script "PreDraw_DC.asm" in your "GameEngineData\Routines\Basic\ModuleScripts\MainScripts\AdventureGame" folder, with this code (it's the same script that the PreDraw, I just removed all the part about the weapon):

Code: Select all

;; 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
;dont draw sprite zero.
+

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

And assigned it the the "Handle Sprite Pre-Draw" element in the "Project Settings > Script Settings".


10/ In your "Project Infos", you can check the "Weapon 1 unlock" if you want your player to have the weapon at launch (else he will have to get it from an NPC):

Image


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").
I tried doing this, and ended up getting this error, saying,"Routines\Basic\ModuleScripts\InputScripts\b_create_melee_weapon.asm(65):CreateObject(26): Unknown label"
User avatar
dale_coop
Posts: 3596
Joined: Fri Feb 16, 2018 7:05 am
Location: France

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

Post by dale_coop » Tue Jan 15, 2019 8:44 pm

Have you done the 1/ ?
-----
Sorry about my poor english
All I need: A Damn Fine Cup of Coffee
My games: PRESS START GAME / UNDERGROUND ADVENTURE / UNDERGROUND ADVENTURE (Arcade version - Byte-Off-2019)
User avatar
DanielT1985
Posts: 122
Joined: Sat Sep 01, 2018 7:44 pm

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

Post by DanielT1985 » Tue Jan 15, 2019 11:37 pm

dale_coop wrote:
Tue Jan 15, 2019 8:44 pm
Have you done the 1/ ?
Oh wait. I did, but I misspelled 'PLAYER' as 'PLATER'. Fixed the misspelling, and it worked. Thank you.
User avatar
dale_coop
Posts: 3596
Joined: Fri Feb 16, 2018 7:05 am
Location: France

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

Post by dale_coop » Wed Jan 16, 2019 12:06 am

Cool ;) galt you fixed it...
And don't hesitate to make some tests (changing some values in the objects details, animations, end of animations ...) to find something that would work well for your game.
And you should also test the script of SuperNateTendo http://nesmakers.com/viewtopic.php?p=11084#p11084 (for you weapon to follow your player when moving) also you should block the movements scripts where your player is attacking (like it was in the 4.0).
-----
Sorry about my poor english
All I need: A Damn Fine Cup of Coffee
My games: PRESS START GAME / UNDERGROUND ADVENTURE / UNDERGROUND ADVENTURE (Arcade version - Byte-Off-2019)
Post Reply