Hey, how would I use a switch case to get different combinations of keys. For example, how you have to press W twice to run but once will only let you walk or if I were to make the key Y do nothing on its own, but do something when in a string together with the key YUJ. Any ideas?
You would create keybindings normally for each of the separate keys. Then you would create an event handler that would handle the ClientTickEvent and in that you would check the state of each keybinding by calling their isPressed() methods. For example if you wanted to check if Y and J were pressed at the same time you would just check if both (using &&) the isPressed() methods were true.
For pressing twice you would need to create a timer counter field (an int field) which if the keybinding was pressed and the field was currently <=0 you would set the counter to something like 40 (two seconds) and if the keybinding is pressed while the field is >0 you would consider it a double press. Also you would subtract 1 from the counter each tick where the counter is >0. In other words you set a time (40 ticks in this example) that a second press will be considered as a double press.
public class KeyHandler {
int counter = new Integer(1).intValue();
@EventHandler
public void onKeyInput(KeyInputEvent event) {
if(myMOD.KEY1.isPressed()) {
for(int i = counter; i > 0; i--) {
if(i == 0) {
event.setCanceled(true);
}
if(myMOD.KEY2.isPressed() && i > 0) {
counter = 1;
for(int i2 = counter; i > 0; i--) {
if(i == 0) {
event.setCanceled(true);
}
if(myMOD.KEY3.isPressed() && i > 0) {
// do something
}
}
}
}
}
}
}
I fell like I'm definitely making this more complicated than it has to be / doing this wrong?
What its supposed to do is check if Key1 is pressed then have a 1 second count down to check for the next key and so on so if the string of keys: KEY1, KEY2, and KEY3 are pressed in order it does something?
Edit: it supposed to be event.setCanceled instead of return;
Hey it is good you are keen to get an answer, but people also have jobs and also live in different time zones. I only get a bit of time each day to have chance to check in...
You're misinterpreting the counter. You can't put for loops in the event handler like that because it will block execution of the whole game. I meant you have to count tick events. So you would only subtract one from the counter each time the tick is handled.
Also, you sort of asked a couple different questions. Firstly you asked about pressing different keys at the same time. For that you don't need any counter. Secondly you asked about pressing same key twice, in which the counter method is suggested. But your code is trying to detect two different keys pressed in sequence which is a bit different. I suppose the counter concept would still work, but just pointing out that you need to be very specific with asking questions as you never asked it that exact way.
Haha sorry about that. I don't think I was very clear the first time, I by keys strung together I meant having to press, for example, Y then U then J with a small window interval to hit each key, not strung together as in YUJ all together, my bad.
I searched how to use PlayerTickEvent, I assume it's going I should count playertickevent because keybinding is client side. Anyway, I'm confused how I would implement it into a pl.ayertickevent into my keyinputevent and I'm not very sure where to start
Actually I think I mentioned it initially, but I would suggest using the client tick event. Player event fires on both sides which can be handled but complicates it as you'd need to put the code in your proxy and such. Look more carefully at the steps I outlined earlier. I explained the exact logic required, so just code it up.
Oh, sorry. I'm just confused as to how I would implement the ClientTick event method inside of my other keybinding event. An event inside of event type of thing. Because wouldn't I have to use the KeyInputEvent or i would just have to check if(key.isPressed) inside of the ClientTickEvent method like you previously stated? Also, I'm not very familiar with the ClientTickEvent does any integer automatically convert to ticks within the event? For example if I used counter-- in ClientTickEvent would it go down by ticks (even though thats very unlikely)?
You shouldn't be using any key events for this. The key events detect regular presses, but aren't great for detecting simultaneous or sequences of presses. For example, if you're trying to detect two keys pressed simultaneously the logic in a key press event is trickier because you have to handle both cases of which key is pressed first (because keys can't easily be pressed at exactly the same time). But with client tick event you can just keep checking simply.
In other words the key events only fire when the state of any key changes, but client tick can check constantly.
For things like double-pressing keys the key events are also not great because there isn't anything related to time. The client tick event fires every tick, so you know timing just by the fact that it has been fired.
For a sequence of keys where you don't care at all about the time inbetween you could use key events fairly easily, but it is kind of weird to not care about the time -- like if you press Y and then an hour later press U and an hour later press Z would you really want that to count? If you do want to do it this way though let me know and I can give you different set of steps to make it work.
The important point is that key bindings don't need to be used in key events. They are available throughout the duration of each tick (on the client side).
Thanks, I never knew you didn't need key events for checking keys and I could check if a key was pressed whenever. Also, I do want to count time in between presses but after a certain time stop the counter. I'm still not sure how exactly I would use ClientTickEvent, does any int inside count as ticks? so I would check if(Y.isPressed) {//start timer //check if U.isPressed && timer < 0}, but not clear on details on how the timer with tick event works.
You create your own int counter field in your event handling class. Each time the event fired you know one tick has passed so count it. Read my suggestions above carefully as I already actually explained this.
Getting close. I think I've let you struggle long enough, but that is how I learned!
The key point you're missing is that the counter should decrement every tick and therefore every time the event fires. Secondly, previous isPressed() will go false as soon as you let up the key so your nesting won't work because the previous key won't be true at the time you check for next key. So you need to break apart the if statement without nesting. Lastly, you need to have separate counters for each step because you need to know that all the previous steps were completed successfully.
So I would code it like this:
int counterKey2 = 0;
int counterKey3 = 0;
public static boolean success = false;
public void clientTick(ClientTickEvent event) {
// decrement every tick and clamp to 0
counterKey2--;
if (counterKey2 < 0) { counterKey2 = 0 }
counterKey3--;
if (counterKey3 < 0) { counterKey3 = 0 }
if(KEY1.isPressed()) {
counterKey2 = 40;
}
if(KEY2.isPressed() && counterKey2 > 0) {
counterKey3 = 40;
}
if(KEY3.isPressed() && counterKey3 > 0) {
// do something
success = true;
}
}
Yes, it is a @SubscribeEvent. So you need the class registered as an event handler, and in modern versions it would be on the main event bus (in the past there was a separate FML event bus).
Hey, sorry to bring this back up. By the way everything worked fine but I was wondering how I would do other things after the counter, for example playing a sound. Every time I add the code to play the sound after the counter, the game crashes. I can play the sound if I put if(key.isPressed() { // play sound} in the KeyInputEvent but then the counter doesn't work. Does anybody know if there is a way around this?
What was your code for playing the sound? There is no reason why it should crash unless you were calling the wrong sound playing method (there are several and some behave differently based on the side it is called from), or if you were calling it over and over on top of itself, or if you had some other issue.
But you should always post your code and and the console or error log output whenever you ask for help with a crash.
Hey, how would I use a switch case to get different combinations of keys. For example, how you have to press W twice to run but once will only let you walk or if I were to make the key Y do nothing on its own, but do something when in a string together with the key YUJ. Any ideas?
You would create keybindings normally for each of the separate keys. Then you would create an event handler that would handle the ClientTickEvent and in that you would check the state of each keybinding by calling their isPressed() methods. For example if you wanted to check if Y and J were pressed at the same time you would just check if both (using &&) the isPressed() methods were true.
For pressing twice you would need to create a timer counter field (an int field) which if the keybinding was pressed and the field was currently <=0 you would set the counter to something like 40 (two seconds) and if the keybinding is pressed while the field is >0 you would consider it a double press. Also you would subtract 1 from the counter each tick where the counter is >0. In other words you set a time (40 ticks in this example) that a second press will be considered as a double press.
Okay, I'll try that and get back. Thanks
I fell like I'm definitely making this more complicated than it has to be / doing this wrong?
What its supposed to do is check if Key1 is pressed then have a 1 second count down to check for the next key and so on so if the string of keys: KEY1, KEY2, and KEY3 are pressed in order it does something?
Edit: it supposed to be event.setCanceled instead of return;
bump
bump
bump
Hey it is good you are keen to get an answer, but people also have jobs and also live in different time zones. I only get a bit of time each day to have chance to check in...
You're misinterpreting the counter. You can't put for loops in the event handler like that because it will block execution of the whole game. I meant you have to count tick events. So you would only subtract one from the counter each time the tick is handled.
Also, you sort of asked a couple different questions. Firstly you asked about pressing different keys at the same time. For that you don't need any counter. Secondly you asked about pressing same key twice, in which the counter method is suggested. But your code is trying to detect two different keys pressed in sequence which is a bit different. I suppose the counter concept would still work, but just pointing out that you need to be very specific with asking questions as you never asked it that exact way.
Haha sorry about that. I don't think I was very clear the first time, I by keys strung together I meant having to press, for example, Y then U then J with a small window interval to hit each key, not strung together as in YUJ all together, my bad.
I searched how to use PlayerTickEvent, I assume it's going I should count playertickevent because keybinding is client side. Anyway, I'm confused how I would implement it into a pl.ayertickevent into my keyinputevent and I'm not very sure where to start
Actually I think I mentioned it initially, but I would suggest using the client tick event. Player event fires on both sides which can be handled but complicates it as you'd need to put the code in your proxy and such. Look more carefully at the steps I outlined earlier. I explained the exact logic required, so just code it up.
Oh, sorry. I'm just confused as to how I would implement the ClientTick event method inside of my other keybinding event. An event inside of event type of thing. Because wouldn't I have to use the KeyInputEvent or i would just have to check if(key.isPressed) inside of the ClientTickEvent method like you previously stated? Also, I'm not very familiar with the ClientTickEvent does any integer automatically convert to ticks within the event? For example if I used counter-- in ClientTickEvent would it go down by ticks (even though thats very unlikely)?
You shouldn't be using any key events for this. The key events detect regular presses, but aren't great for detecting simultaneous or sequences of presses. For example, if you're trying to detect two keys pressed simultaneously the logic in a key press event is trickier because you have to handle both cases of which key is pressed first (because keys can't easily be pressed at exactly the same time). But with client tick event you can just keep checking simply.
In other words the key events only fire when the state of any key changes, but client tick can check constantly.
For things like double-pressing keys the key events are also not great because there isn't anything related to time. The client tick event fires every tick, so you know timing just by the fact that it has been fired.
For a sequence of keys where you don't care at all about the time inbetween you could use key events fairly easily, but it is kind of weird to not care about the time -- like if you press Y and then an hour later press U and an hour later press Z would you really want that to count? If you do want to do it this way though let me know and I can give you different set of steps to make it work.
The important point is that key bindings don't need to be used in key events. They are available throughout the duration of each tick (on the client side).
Thanks, I never knew you didn't need key events for checking keys and I could check if a key was pressed whenever. Also, I do want to count time in between presses but after a certain time stop the counter. I'm still not sure how exactly I would use ClientTickEvent, does any int inside count as ticks? so I would check if(Y.isPressed) {//start timer //check if U.isPressed && timer < 0}, but not clear on details on how the timer with tick event works.
You create your own int counter field in your event handling class. Each time the event fired you know one tick has passed so count it. Read my suggestions above carefully as I already actually explained this.
I'm actually asking a more specific question about what you previously explained. Am I understanding you or is this wrong:
Getting close. I think I've let you struggle long enough, but that is how I learned!
The key point you're missing is that the counter should decrement every tick and therefore every time the event fires. Secondly, previous isPressed() will go false as soon as you let up the key so your nesting won't work because the previous key won't be true at the time you check for next key. So you need to break apart the if statement without nesting. Lastly, you need to have separate counters for each step because you need to know that all the previous steps were completed successfully.
So I would code it like this:
Thank you so much! That makes sense, now I see why you said I was making keys press at the same time. And just to be clear is this a @SubscribeEvent?
Yes, it is a @SubscribeEvent. So you need the class registered as an event handler, and in modern versions it would be on the main event bus (in the past there was a separate FML event bus).
Hey, sorry to bring this back up. By the way everything worked fine but I was wondering how I would do other things after the counter, for example playing a sound. Every time I add the code to play the sound after the counter, the game crashes. I can play the sound if I put if(key.isPressed() { // play sound} in the KeyInputEvent but then the counter doesn't work. Does anybody know if there is a way around this?
What was your code for playing the sound? There is no reason why it should crash unless you were calling the wrong sound playing method (there are several and some behave differently based on the side it is called from), or if you were calling it over and over on top of itself, or if you had some other issue.
But you should always post your code and and the console or error log output whenever you ask for help with a crash.