1

I'm generally new to this style of coding (mostly working in VBA before) and I could use some suggestions. I have my code typed out and it works exactly how I want it to as far as I can tell but it seems like it must be lengthier than it needs to be and I'm feeling somewhat insecure about the number of IF statements I have in this section of code. I would also appreciate it if you see a way to simplify the code, if you could explain how it works :)

I'm also confused why repeat statements work but using while statements don't.

This code is in Game Maker Studio 2 so it's generally similar to Java or C languages from what I've read online. This code is supposed to control the player's horizontal movement while also introducing some acceleration and friction.

Just for fun I also am including the original line of code that solved this problem before I started introducing these physics concepts (green means GO essentially).

The original code- The Original Code

hsp = 0; //horizontal speed
frctn = 0.8; //friction
acclrtn = 0.7; //acceleration
walksp = 6; //walk speed
dashsp = 12; //dash speed

var _keyLeft = keyboard_check(vk_left); 
var _keyRight = keyboard_check(vk_right);
var _keyA = keyboard_check(ord("A"));
var _speed = walksp;

if(_keyLeft || _keyRight) //if left OR right are pressed
{
    if (_keyLeft && _keyRight) //if left AND right are pressed
    {
        repeat(abs(hsp) > 1) //repeat the following while absolute value horizontal speed is greater than 1
        {
            hsp -= frctn * sign(hsp); //horizontal speed = horizontal speed - friction
        }
        if(abs(hsp) <= 1) hsp = 0; //if the horizontal speed is less than or equal to 1, then set to zero (to prevent negatives)
    }
    
    if (_keyA) _speed = dashsp; //if the A_Key is held, then set the _speed variable to the dash speed
    
    repeat(abs(hsp) < _speed) //repeat if the absolute value of the horizontal speed is less than the _speed variable
    {
        hsp += (_keyRight - _keyLeft)*acclrtn; //Horizontal Speed = Horizontal Speed + (input of -1, 0, +1) * acceleration.
    }
    
    repeat(abs(hsp) > _speed) //repeat if the horizontal speed is greater than the _speed variable
    {
        hsp -= (_keyRight - _keyLeft)*frctn; //Horizontal Speed = Horizontal Speed + (input of -1, 0, +1) * friction.
    }

}

else //if the left OR right key are NOT pressed
{
    repeat(abs(hsp) > 0.5) //repeat if the absolute value of the Horizontal Speed variable is > 0.5
    {
        hsp -= frctn * sign(hsp); //horizontal speed = horizontal speed - friction
    }
    if(abs(hsp) <= 0.5) hsp = 0; //if the horizontal speed is less than or equal to 0.5, set to 0 (prevents negatives)
}
  • Neither (originally tagged) C nor Java support `repeat`, `ord` or `sign`, and to my eye there doesn't seem to be an unreasonable number of `if` statements. If the code is working, please consider posting on [Code Review](https://codereview.stackexchange.com/). – Weather Vane Jan 15 '23 at 17:38

2 Answers2

1

I java or C there's no repeat statement, so I'm guessing it's a loop with a conditional as you post it. Im not understanding what would be the logical difference between:

if (_keyLeft && _keyRight) {
    repeat(abs(hsp) > 1) {
        hsp -= frctn * sign(hsp);
    }
    if(abs(hsp) <= 1) {
        hsp = 0;
    }
}

and:

if (_keyLeft && _keyRight) {
    hsp = 0;
}

after all you will be subtracting the friction amount until hsp its equal or lower than 1. After than you will set it to 0, every single time you reach that line of code, hsp will fulfil that conditional.

Same in the else statement. So if im not missing anything, or something in Game Maker Studio 2 works differently, your code should mimic this behavior :

if(_keyLeft == _keyRight) {    
    hsp = 0;
    return;
}

if (_keyA) {
    _speed = dashsp;
}

repeat(abs(hsp) < _speed) {
    hsp += (_keyRight - _keyLeft)*acclrtn;
}

repeat(abs(hsp) > _speed) {
    hsp -= (_keyRight - _keyLeft)*frctn;
}

even this repeat's can be further changed. Can you confirm if it works as im thinking? And if needed explain if there's anything else i should bear in mind in how Game Maker Studio 2 works.

  • 1
    You're absolutely right so far! I tried out these edits and the code works the same! It makes sense now that having the extra repeat that you mentioned would be redundant. I would love to see what other suggestions yo have. – Nathan surv genorpg20 Jan 15 '23 at 18:54
  • As per suggestions: i would refactor the way it works, since you have 3 different states. no keys pressed, one key pressed or both keys pressed. Setting a class to manage these states and their behavior in different methods (in your case, no keys pressed is the same as both keys pressed. Although i would still make the differentiation so as to help the future you making changes in the code). And in the class you currently have i would just identify the case in which you are execute the respective method. – Diego Susviela Jan 15 '23 at 19:05
  • In regards to the other repeat's, is it intentional that hsp ends up with a float value? (ex: 4.3). if not, i would just set the value of hsp to _speed or -(_speed), depending the key is pressed – Diego Susviela Jan 15 '23 at 19:08
  • I've done some reading online and I'm not quite sure if GML supports classes like what Java does, at least not as easily. What I HAVE done is turned the code for both keys and no keys into a function to clear it up and not have the same code typed twice. I suppose that's something, right? Also the float value I believe you're referencing is what gives the player acceleration or friction when they move, like Sonic for example, who slowly increases his speed when he runs and has to brake like a car when he stops. – Nathan surv genorpg20 Jan 15 '23 at 20:08
  • I understand but in your case speed is deducted or increased all at once, when the repeat statement is executed – Diego Susviela Jan 16 '23 at 15:42
  • 1
    If of interest, GameMaker's `repeat (X) Y` is roughly the same as `for (var k = 1, n = X; k <= n; k++) Y`. A simple loop without an explicitly defined iterator that works with floating-point values (repeat 3.3 executes 3 times). – YellowAfterlife Jan 16 '23 at 17:38
  • 1
    As for classes, in recent GameMaker versions [constructor functions](https://manual.yoyogames.com/#t=GameMaker_Language%2FGML_Overview%2FStructs.htm) are the direct equivalent. Functionally they more closely resemble [prototypes](https://en.wikipedia.org/wiki/Prototype-based_programming), but still allow you to do most things that you'd expect from a class. – YellowAfterlife Jan 16 '23 at 17:45
  • i see, thx for the info. what i ment with float values is if i have speed of 6 and i substract 0.8 until im lower than 5, i will iterate 2 times, making the final speed 4.4 instead of 5. – Diego Susviela Jan 16 '23 at 18:59
0

If you want no difference between selecting both Left/Right and none, then perhaps this may look cleaner:

var hInput = keyboard_check(vk_right) - keyboard_check(vk_left); //hInput = Horizontal Input
//pressing right = 1, pressing left = -1, pressing both or none = 0.

if (hInput != 0) 
{
    //it is not 0, so the character is moving
    //hInput could now also be used to decide in which direction you're moving
} 
else 
{
    //the player is not moving
}
Steven
  • 1,996
  • 3
  • 22
  • 33