How to retain a key press when changing scene?
When I google it, it tells me to tie the key press to a boolean attribute and base my conditions around that attribute instead of the raw key press. I've tried that but it still doesn't work for me. Any other solutions?
Comments
Sounds like something is conflicting somewhere. What exactly are you trying to do? Should be as simple as having a rule that if key is pressed, change attribute.boolean to true, else attribute boolean is false. And then tie you what you want to happen to attribute.boolean is true
When you load a scene in GameSalad, key down events are discarded and a key held down will not be registered as held down until it is released and pressed again. This is a genuine limitation and I don't think there's any reliable way around it, as there's not really any way for an app to tell the difference between "key was held down on change from scene 1 to 2, then on scene 2 it was released and then pressed again" and "key was held down but released before change from scene 1 to 2, then on scene 2 it was pressed again."
You can say, on scene 2, with some certainty "The key was pressed when scene 1 ended" (you can record a release state in another actor and if that release state wasn't triggered, it can be assumed it was still pressed on scene end) but you cannot say with any certainty that it was still pressed when scene 2 loaded.
So how viable whatever you're doing is in GameSalad really depends on what exactly you're doing.
(And if your game is HTML5 you can likely overcome it with some custom javascript.)
My game is HTML5. I've been doing some playing around, and have noticed that the idea of "if key is pressed, change attribute to true. if key released, change attribute to false." does work, but only if no other keys are pressed during the one I want to continue into the next scene. Pressing another key after I start holding one key will change the held key attribute to false on next scene. So it kind of works, but not enough for what I'd like to do. My keys are simply the left and right cursor keys to move, Z to jump, and X to enter doors to new scenes; Ideally I'd like the player to be able to keep moving upon entering a door to a new scene with the arrow key still pressed.
If it's HTML5 you should be able to use a little Javascript listener to monitor the keypress and pass the state back to the game after scene change. Maybe?
I'd have no idea how to do that haha.
That is definitely something I'd ask ChatGPT for help with :D
I figured it out, thanks for your advice about event listeners!
This is an interesting tension to work through.
Argument
If key down stays between session, then a button that appears under your finger when you switch scenes is activated if you do keydown. And if we change the behavior now, it will change for other games.
Counter-Argument
Key-down is a state indicator so it should correctly indicate state not matter the scene lifecycle. If you are triggering a button on mouse down, then you need to adjust to mouse up or do something else.
I'm curious what you all are expecting in this case?
Keep the engine as is so it doesn't interfere with other existing projects.
Here is the workaround I implemented in my game (for left and right arrows):
var r = 10;
function Actions(){
this.count = 0;
this.running = {};
this.interval = undefined;
}
Actions.prototype.start = function(action){
if( typeof(this.running[action]) == "undefined"){
this[action]();
this.running[action] = action;
this.count++;
}
var me = this;
if( typeof(this.interval) == "undefined"){
this.interval = setInterval(function(){
for( var act in me.running ){
me[act]();
}
},50);
}
};
Actions.prototype.stop = function(action){
this.running[action] = void 0;
delete this.running[action];
this.count--;
if( this.count == 0 ){
clearInterval(this.interval);
this.interval = void 0;
}
};
Actions.prototype.left = function(){
engine.postEvent('externalWriteGameAttribute', null, 'game.attributes.id664201', 'true')
};
Actions.prototype.right = function(){
engine.postEvent('externalWriteGameAttribute', null, 'game.attributes.id183358', 'true')
};
var actions = new Actions();
document.onkeydown = checkKeyDown;
function checkKeyDown(e) {
e = e || window.event;
if (e.keyCode == '37') {
// left arrow
actions.start("left");
}
if (e.keyCode == '39') {
// right arrow
actions.start("right");
}
}
document.onkeyup = checkKeyUp;
function checkKeyUp(e) {
e = e || window.event;
if (e.keyCode == '37') {
// left arrow
actions.stop("left");
engine.postEvent('externalWriteGameAttribute', null, 'game.attributes.id664201', 'false')
;
}
if (e.keyCode == '39') {
// right arrow
actions.stop("right");
engine.postEvent('externalWriteGameAttribute', null, 'game.attributes.id183358', 'false')
;
}
}
Paste this whole thing directly before this line:
// 4. Neither load nor play the game immediately. Like the previous
And edit the attribute IDs to your own ones.
For keyboard keys other than left and right, you'll need to find out the unique keycodes for them and make edits where necessary.
I agree with @AshumBesher. Keep engine as-is. Intuitively, it feels like if a key is being pressed down the game should be able to recognise it as pressed down. But there's nowhere near enough benefit to making the change to risk issues with over a decade of GameSalad games.