How to avoid holding buttons trigging events in special screens prematurely

FrankenGraphics

New member
Problem: when switching modes, there's no native button read reset/disable/cooldown feature. This means you can trig actions before even getting a glimpse of the to-be-loaded special screen if you happen to hold a button that is valid for events in that special screen/mode.

It will also erroneously fire away an npc talk box regardless npc collision if you hold a talk button when starting your game.

Solution:

1) dedicate a variable for our purposes.
it can be in zp or user variables. it may even be a single bit in some user variable you're always bit masking, but let's keep it simple for the sake of this tutorial. so let's go to zero page and define a var call buttonCoolDown.

2)create an input script called buttonCooolDown.asm. Put this in:
Code:
lda buttonCoolDown
beq +  
dec buttonCoolDown
+
rts

(edit: changed var names from what i used in my project to match the description of the tutorial)



3)Hook up the cooldown to you special screens:
go to input editor. Make these two input links (or one of them, or more... depending on your game)
Basically, put one on each special screen you're using.
yyyyyyy.png

4) Create a cooldown trigger:
Somewhere at the top of handleScreenLoads.asm, perhaps right below the first label, instert the following code:
Code:
LDA gameState
CMP #GS_MainGame 
beq +
	lda #15
	sta buttonCoolDown
+
(edit: same here)
the value of #15, which represents number of frames, is arbitrarily chosen. A simple #1 would suffice, i'm just using some extra padding for measure. You don't want it to be too long.


5)Isolate critical buttons with the cooldown timer:
Lastly, wrap every button you want to isolate with the cooldown in with a conditional like this at the top:
Code:
lda buttonCoolDown
beq +
rts 
+

Typically, you only need to isolate buttons that trig a gameState altering event/action, such as pressing start or any button to begin the game, or any button to skip the the win screen.

That's it!



Bonus trick: you can use the same trick to create timeouts for player inactivity, like auto-paging text, creating inactivity-summoned monsters/treasure, trig an attract mode, auto-pause, do some easter egg, or what have you. All the building blocks are also there for having different cooldowns on using different actions/items/weapons, if you want to have something like that.

There are other approaches. this works just fine for me.

ps. sorry about the wild indentation. itab doesn't work well on forum posts and i'm to lazy to fix it in a separate editor.
 

dale_coop

Moderator
Staff member
That IS smart! Thanks, FrankenGraphics for sharing this very useful piece of code.

PS: the "tab" works on the forum only where you are typping between the [ c o d e ] balises.
 

Bucket Mouse

Active member
I was planning on putting a timed Easter Egg into my game -- like an idle animation in the vein of Sonic tapping his foot -- but I thought I'd have to configure the "Countdown Timer" ASM to make that happen. This is much less messy. I had no idea there was a way to count frames.

Question: if you're not using this to cool down a button function, where do you put the buttoncooldown.asm code? Because it wouldn't be assigned to the Input Scripts in that case, right?
 

dale_coop

Moderator
Staff member
Bucket Mouse said:
I was planning on putting a timed Easter Egg into my game -- like an idle animation in the vein of Sonic tapping his foot -- but I thought I'd have to configure the "Countdown Timer" ASM to make that happen. This is much less messy. I had no idea there was a way to count frames.

Question: if you're not using this to cool down a button function, where do you put the buttoncooldown.asm code? Because it wouldn't be assigned to the Input Scripts in that case, right?

A simple trick would be to make a action step End of Action script "EasterAnimation"... which would be just a changeObjectState to an unused step (for example 07) and just set your Player's Action Step 0 (iddle) to execute that end of action "easterAnimation" after a timer of 15.

Or simpler, if you don't use the last action step... use that one as your Easter egg animation... and just set your Player Action step 0 to GoToLast with a timer of 15.
 
Top Bottom