Changing player object upon warp-into flagged screen

Raftronaut

Member
Hello!

I have a somewhat complex request for help here that I believe I understand the steps needed to accomplish but need some help with the details.

My goal is to utilize my first screen flag slot: "single screen game" to initiate a MAZE mini-game when I warp my player into a room with that flag checked. I am currently using the shooter module, so this would be an entirely new gameplay style I would be adding to my game. I have Plenty of game object slots available as well so I hope to change player game object upon warping into a room, and the ability to switch between 4 playable characters (either cycled through with inputs or perhaps better yet by collecting powerups).

So to break down my work flow I have made a list of the things I would need to achieve in order to accomplish my goal here:

A) Study and adapt the ChangePlayerObject script to change Character object upon warping into the screen containing the screen flag "single screen game" slot #1.. I believe this can be done utilizing Dale Coop's experimental script posted in the archives:
http://nesmakers.com/viewtopic.php?f=3&t=1760

B) Change player death object to something other than my current vehicle explosion from the shooter module. Since the sprites will be different for this section it will need a separate animation.

C)Set up victory conditions for when player consumes all collectables within a room that has "single screen" flag checked. I already have collectibles for score in my shooter game, so I would need to determine victory ONLY occurs when "Single screen" flag is checked...

D) Set up Maze game power up for frantic arcade munching invincibility

E) Create some sort of branch that disables my projectile powerup from the shooter module. Either disabled or Reassigned to a new function.
I had considered adding a melee attack here, or perhaps use the button to switch between characters..( Although I think I like the idea of collecting Powerup (or tile) to change between the 4 characters. It would give me the opportunity to add colorful powerup sprites and add to the graphical variety of my game. PLUS< my game is woefully short on powerups currently and I have PLENTY of slots available.)


I understand this is a complicated series of requests, but I am fairly sure my thought process on getting each of these steps to work are correct. If I am overlooking anything or incorrectly planning something, please let me know. I am not sure that Changing "game states" has been attempted yet, I am sure others would find this process helpful if I can get it working.

Many of my favorite NES games had multiple play styles involved, so this may be the first small step towards doing something influenced by guardian legend, blaster master, goonies II, Zelda 2, Startropics overworld etc..
 

Mugi

Member
I created a variable based alteration for spawning the player object in my stage selection code (find it from the archive subforum) which explains how to edit handlescreenloads player spawning code to check for a variable
and spawn a different object to act as a player depending on the status of the flag.

to read singlescreen mode screen flag, you can use LDA screenflags and read the byte from it you need.
 

dale_coop

Moderator
Staff member
Mugi's right... But if you want to check screenFlag, you will have to put your code after that the screen is loaded.
So, as I replied to you on the Discord channel... for example, in the "HandleScreenLoads.asm" script, around line 313 or around... you will find:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;END LOADING SCREENS.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

So just after, that, you can add a code of block like that:

Code:
LDA screenFlags
    AND #%10000000
    BEQ +
    LDX player1_object
    DeactivateCurrentObject
    LDA #OBJ_PLAYER_2
    STA playerToSpawn    
    CreateObject newX, newY, playerToSpawn, #$00, currentNametable
    STX player1_object
    +

And in your user constants ("project Settings > User constants") find the "OBJ_PLAYER_2" constant and set it the the Game Object you want to use instead of your Player object ;)
 

Raftronaut

Member
Mugi said:
I created a variable based alteration for spawning the player object in my stage selection code (find it from the archive subforum) which explains how to edit handlescreenloads player spawning code to check for a variable
and spawn a different object to act as a player depending on the status of the flag.

to read singlescreen mode screen flag, you can use LDA screenflags and read the byte from it you need.

Good tip! thanks for pointing me to it!
To clarify you are pointing specifically to:
http://nesmakers.com/viewtopic.php?f=40&t=1788&hilit=handlescreenloads
(not sure why my URL links never work) I'll dig through this for the info on the variable

dale_coop said:
Mugi's right... But if you want to check screenFlag, you will have to put your code after that the screen is loaded.
So, as I replied to you on the Discord channel... for example, in the "HandleScreenLoads.asm" script, around line 313 or around... you will find:
Code:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;END LOADING SCREENS.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

So just after, that, you can add a code of block like that:

Code:
LDA screenFlags
    AND #%10000000
    BEQ +
    LDX player1_object
    DeactivateCurrentObject
    LDA #OBJ_PLAYER_2
    STA playerToSpawn    
    CreateObject newX, newY, playerToSpawn, #$00, currentNametable
    STX player1_object
    +

And in your user constants ("project Settings > User constants") find the "OBJ_PLAYER_2" constant and set it the the Game Object you want to use instead of your Player object ;)
Ok Great, I will get started on this with my next session :)

One more quick question though, I was thinking I could create all 4 playable characters under the same game object using different animation types. Though I realized one of my 4 characters is taller (2x3 sprites instead of 2x2 sprites) so If I used the same game object to save space there would be bounding box issues between the different character heights. I think I have 9 game object slots open yet.

Since I have the space available, Should I reserve one game object per character? I presume that would afford me the greatest flexibility in the future if I decided to give them unique abilities, movement speeds, bounding boxes, etc...

Is this the smartest way to organize them?
 

dale_coop

Moderator
Staff member
You can’t ise the same game object for all your characters... because the Player uses several actions steps. When idle, when walking, attacking, shooting,...
So it’s not possible to use a unique object...

You need 1 object per character!
But you could save objects with you Monster Death animations... a death animation uses 1 action step and no other specific flag.
Si rhetorically you could use 2 death object for 8 different death animations !
Just with a minor modification in the death scripts for that...
 

Raftronaut

Member
Also, I just noticed I would need to use a monster object in order to change player palettes. Since PLayer object defaults to only two palettes correct?
 

dale_coop

Moderator
Staff member
Yep you could also use monster objects (if you want use different color palettes), it would work too.
 

Raftronaut

Member
Ok Great, I am going to start by setting up 4 independent monsters for the playable characters.
OH, I suppose it is OK if they share the same CHR file correct? I have plenty of space yet, but I can certainly fit all 4 character character graphics inside the same CHR file..

I will need at least one monster on screen for these stages. I assume monsters will be able to be loaded from a separate CHR file from the playable characters correct?

thanks ;)
 

dale_coop

Moderator
Staff member
Monsters and your extra characters need to share the same CHR. Because 1 tileset is assigned to the screen, in theory... never tried it myself (in my tests, theextra character was a Game Objectt).
 

Raftronaut

Member
dale_coop said:
Monsters and your extra characters need to share the same CHR. Because 1 tileset is assigned to the screen, in theory... never tried it myself (in my tests, theextra character was a Game Objectt).

Hey Dale!

I set up my 4 new playable characters as monsters 1-4,
I added the code to HandleScreenLoads.asm
I set up OBJ_PLAYER_2 to the correct number in my monster objects inventory.
I set the monster group to my new playable characters and set the palette.

My character warps into the room sucessfully and changes objects, but the animation states are not registering for some reason.

here is a video example:
https://youtu.be/jzolTPr5Qss

Here are some screenshots of how I have the character set up (in monsters)..

maze 1.PNG





maze 2.PNGmaze3.PNGmaze 4.PNGmaze5.PNG

Any idea why the player animations won't cooperate? I am likely overlooking something obvious......
 

dale_coop

Moderator
Staff member
Humm...
In the "Input Editor", your StartMovingPlayerXX scripts are correctly assgined (to the "HOLD")?
 

Raftronaut

Member
dale_coop said:
Humm...
In the "Input Editor", your StartMovingPlayerXX scripts are correctly assgined (to the "HOLD")?

ahhhh, i Did not even think about this.but the shooter module only needs to face the player in one direction, so it is very likely it is not contained in the movement scripts.

for example, here is the script to move player down:

Code:
    StartMoving player1_object, MOVE_DOWN
  
    RTS

Here is the script to move player left:

Code:
 StartMoving player1_object, MOVE_LEFT
  RTS

Here is the screen shot of my controlls, looks like they are all set to hold.
controls.PNG

I presume I would need to have a separate set of instructions for movement when the "single screen" flag is checked. Is that correct?

I did not consider this at all!
 

dale_coop

Moderator
Staff member
You right!
For the example of your StartMovingPlayerDown script, you will need to add:
Code:
;;;;; START MOVING PLAYER DOWN:
;;; ON SINGLE SCREEN :
LDA screenFlags
AND #%10000000
BNE +
jmp +++
+
 ;;;;; We will use this when the down 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
    BcS + 
    CMP #$01
    BEQ + ;; if the action type already equals 1, jump forward
    ChangeObjectState #$01, #$04
+
;;;;;; Then, we will begin moving.
    StartMoving player1_object, MOVE_DOWN
;;;;;; Lastly, we will change the facing direction.
    FaceDirection player1_object, FACE_DOWN
    RTS
+++
;;; ELSE :

BEFORE your current code.
 

dale_coop

Moderator
Staff member
Not sure if it works (I am at my office, can't test it). But idea is checking if single screen... and branch out to different portions of code.
 

Raftronaut

Member
dale_coop said:
Not sure if it works (I am at my office, can't test it). But idea is checking if single screen... and branch out to different portions of code.

Yes!

I am at the office as well, I will test it when I have a chance tonight. If it works for the Down movement script it should work for all the directions. Now this has me wondering if the opposite technique could be used to DISABLE diagonal movement when "single screen" flag is checked. If so, I presume the diagonal movement scripts would just need a branch to ignore movement if that flag is checked.

The Movement scripts in the shooter module had actually thrown me off previously, I had thought my "move left" script could trigger a new "braking" animation with a short tire screeching sound effect by adding the extra to my move left script, but I could never get it to work so I gave up on it. I wonder if that was related to the way movement vs. animations is set up in the shooter module.. I should remember to look at that again once I understand it better...

Thanks for the insight dale! The warp-in player change script is working perfectly in my tests, after this movement script correction it should be ready :) to go!

NEXT, I'll get my "maze-player death" set up as a new animation type in player death and set up my LONE enemy monster for the maze portion of the game.
 

Raftronaut

Member
dale_coop said:
Not sure if it works (I am at my office, can't test it). But idea is checking if single screen... and branch out to different portions of code.

Awesome! It worked!

https://youtu.be/wniIOe13V8g

I suppose this can be done with all 4 directions as well?

Also, I imported the Maze game Collectable tile, this is the tile that is counted to trigger the screen victory correct?

Code:
;; COLLECTABLE - this tile requires 
;; HUD to be active and for myScore variable to be drawn.
;; To use this without this feature, comment out lines marked below.
	CPX player1_object
	BEQ isPlayerForCollectable
	JMP ++
isPlayerForCollectable:
	;LDA tileCollisionFlag
	;BEQ +
	;JMP ++
+
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;; TO USE WITHOUT HUD, COMMENT OUT THIS BLOCK
;;; It may result in anomalies if two tiles
;;; register collision simultaneously without
;;; this block.
	;;LDA #$01
	;STA tileCollisionFlag
	ChangeTileAtCollision #$00, #$00
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	TXA
	STA tempx	
	AddValue #$08, myScore, #$01, #$00
	;;; we also need to set up the routine to update the HUD
		; LDA DrawHudBytes
		; ora #HUD_myScore
		; STA DrawHudBytes
	UpdateHud HUD_myScore
	
	
	PlaySound #SND_GET
	LDA #$00
	STA value
	STA value+1
	STA value+2
	STA value+3
	STA value+4
	STA value+5
	STA value+6
	STA value+7
	
	LDX tempx
	
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
	DEC screenPrizeCounter
	BNE ++
	
	;;; do whatever should happen if you collect all of the prizes on this screen.
	JSR HandleNoMorePrizeTiles

++

I am a little confused on what exactly happens when a player collects all the collectables in the maze game. Or what events are triggered by collecting all of the items. I did a palette swap here on the green sandwiches, the sfx is different from the others, but not sure how to cause player victory yet. Could you help me understand?
 

dale_coop

Moderator
Staff member
When you get all the "Collectable" tiles, it will trigger/execute the "Handle No More Prize Tiles" (you should have the "NoMorePrize_CreateVictoryObject.asm" script assigned to that element).
That script will create the PLAYER VICTORY object (check the OBJ_PLAYER_VICTORY in "Project Settings > User Constants" to determine which object is that).

And don't forget to fix the bug:
http://nesmakers.com/viewtopic.php?p=13494#p13494
 

Raftronaut

Member
dale_coop said:
When you get all the "Collectable" tiles, it will trigger/execute the "Handle No More Prize Tiles" (you should have the "NoMorePrize_CreateVictoryObject.asm" script assigned to that element).
That script will create the PLAYER VICTORY object (check the OBJ_PLAYER_VICTORY in "Project Settings > User Constants" to determine which object is that).

And don't forget to fix the bug:
http://nesmakers.com/viewtopic.php?p=13494#p13494

OK, thank you for clearing that up! I will investigate further. Also thank you for making me aware of the bug as I am sure that would have thrown me off!

As far as the Player Victory Object, does that work similarly to Player Death Object? Basically, an object created to replace the player sprite when conditions are met? Would this Victory object be drawn from the original player CHR file similarly to the death object?

One more question, regarding movement scripts. Can I simply edit your StartMovingPlayerDown script to move LEFT by changing the macros MOVE_DOWN and FACE_DOWN to MOVE_LEFT and FACE_LEFT? Is this all that is need to create the animations for the other 3 cardinal directions? If so, I will get started on those right away. I am not sure if the ChangeObjectState #$01, #$04 commands

I am also noticing my walking animation does not stop once it starts, will I need to edit my StopMoving scripts to stop animation as well?
 

dale_coop

Moderator
Staff member
The Victory Object is exactly as the Death animation one... the only difference is the End of animation, that is set to "warp" (for the Victory, if I remember well) instead of "restart game" (for the death one).

For the movements scripts... yeah, it should work, just replace "_LEFT" with the other directions.
about the :
Code:
  ChangeObjectState #$01, #$04
Keep it, it changes the state of the Player obejct to the walking animation: action step "01, timer/animation speed "04" (yeah, I never understood why there is a second parameter to this macro).
 

Raftronaut

Member
dale_coop said:
The Victory Object is exactly as the Death animation one... the only difference is the End of animation, that is set to "warp" (for the Victory, if I remember well) instead of "restart game" (for the death one).

For the movements scripts... yeah, it should work, just replace "_LEFT" with the other directions.
about the :
Code:
  ChangeObjectState #$01, #$04
Keep it, it changes the state of the Player obejct to the walking animation: action step "01, timer/animation speed "04" (yeah, I never understood why there is a second parameter to this macro).


Awesome! I will get to work adding the other 3 movement scripts!

As far as stopping movement, will I need to add something to the script to stop animation when player stops?
 
Top Bottom