Hey, and welcome. It's been a while since I've touched Game Maker, but let's see if I can help you out. This'll be a bit long, but try to bear with me.
I'm not sure what
playerstate does, but moving forward I'm going to assume it's a regular integer and go from there. I'll start from the top. (And I'll stick to your style of coding throughout.)
// --- Key Controls --- //
if keyboard_check_pressed(vk_anykey){
switch (keyboard_lastkey){
case (ord('A')): {playerstate+=0;break;}// --- Should check single keys pressed, to add the proper playerstate
case (ord('D')): {playerstate+=0;break;}
case (ord('W')): {playerstate+=1;break;}
case (ord('S')): {playerstate+=1;break;}
//
First, here's a little trick to do with switch statements, when multiple cases have the same associated statement:
// --- Key Controls --- //
if keyboard_check_pressed(vk_anykey){
switch (keyboard_lastkey){
case (ord('A')):
case (ord('D')): {playerstate+=0;break;}
case (ord('W')):
case (ord('S')): {playerstate+=1;break;}
//
Here, I've "chained" the cases -- do you follow me? This is equivalent to the previous code box.
Now, I notice that in two of these cases, you're adding 0 to playerstate. But adding 0 doesn't really do anything, does it? (Although I understand if writing down every case helps keep things straight.) You might as well use the following equivalent code:
// --- Key Controls --- //
if keyboard_check_pressed(vk_anykey){
switch (keyboard_lastkey){
case (ord('W')):
case (ord('S')): {playerstate+=1;break;}
//
Let's look at the rest of the first switch statement in full, now:
// --- Key Controls --- //
if keyboard_check_pressed(vk_anykey){
switch (keyboard_lastkey){
case (ord('W')):
case (ord('S')): {playerstate+=1;break;}
//
case (ord('A')) & (ord('D')): {playerstate+=0;break;}// --- Should check double ups of keys pressed, to add the proper playerstate
case (ord('A')) & (ord('W')): {playerstate+=1;break;}
case (ord('A')) & (ord('S')): {playerstate+=1;break;}
case (ord('D')) & (ord('W')): {playerstate+=1;break;}
case (ord('D')) & (ord('S')): {playerstate+=1;break;}
case (ord('W')) & (ord('S')): {playerstate+=1;break;}
//
}}
& is a bitwise operator, and I don't think you meant to use it here. What you want is either
&& or
and, both of which are the logical conjunction. Also, let's remove that extra code, and the case where you add 0 in the second half:
// --- Key Controls --- //
if keyboard_check_pressed(vk_anykey){
switch (keyboard_lastkey){
case (ord('W')):
case (ord('S')): {playerstate+=1;break;}
//
case (ord('A')) && (ord('W')):
case (ord('A')) && (ord('S')):
case (ord('D')) && (ord('W')):
case (ord('D')) && (ord('S')):
case (ord('W')) && (ord('S')): {playerstate+=1;break;}
//
}}
That's a little nicer to look at, and more efficient too. But there are a couple problems here that become increasingly clear.
- keyboard_lastkey only ever holds a single value, and that value is the single key that was pressed last. For example, if I press A and Z together, even if I think I've pressed both at the exact same time, the computer will still register that I pressed A before Z, or vice-versa. We can't use keyboard_lastkey to check two values at once.
- The expression statement1 && statement2 will evaluate to a boolean value, i.e. either true or false. In Game Maker, true and false are actually stored as 1 and 0, respectively. Also, a value less than 0.5 is evaluated as false and a value greater than or equal to 0.5 is evaluated as true in statements that require a boolean value. So (ord('W')) && (ord('S')) (and in fact any && between two ord calls) will return 1, and only 1. Comparing that to keyboard_lastkey isn't going to be of much use.
I'm going to offer a solution here, but pay attention: I don't actually know what your code does or why, so if this solution doesn't help you, come back with more information about your code, or try to solve it on your own.
My solution involves the idea that when, for example, A and W are both pressed, you actually just care about W, because pressing the A key adds or subtracts 0 i.e. doesn't do anything. Using this idea, you'll find a lot of your statements become logically equivalent. As a result, the following code performs more or less the exact same function as the code in your first post (except for potential odd behaviour you might have noticed as a result of using bitwise
& instead of
&&).
// --- Key Controls --- //
if keyboard_check_pressed(vk_anykey){
switch (keyboard_lastkey){
case (ord('W')):
case (ord('S')): {playerstate+=1;break;}
}}
if keyboard_check_released(vk_anykey){
switch (keyboard_lastkey){
case (ord('W')):
case (ord('S')): {playerstate-=1;break;}
}}
Since the code can be shrunken so much, it seems to me that it
probably doesn't yet do what you want it to do. Please come back with some more information about your code's intended function.
EDIT:
Notice as well that the last box can also be written as follows (again in your style):
// --- Key Controls --- //
if keyboard_check_pressed(vk_anykey){
if (keyboard_lastkey == ord('W') || keyboard_lastkey == ord('S')) {playerstate+=1;break;}
}
if keyboard_check_released(vk_anykey){
if (keyboard_lastkey == ord('W') || keyboard_lastkey == ord('S')) {playerstate-=1;break;}
}
(Notice the use of
||, the logical disjunction.)
In this case, using an if statement probably makes more sense, since you're only switching over two identical cases. You follow me?