First, I have to say this. I mean no offense, but your coding convention is horrible. I know it is all allowed in the GML language, but GML tries to combine several different syntaxes which makes it a very ugly language. I'll give you this advice to make your code more readable in the future (and because you have a desire to switch to C++ one day).
- First of all use only one set of logical operators. Either use the set
and,
or and etc. or use
&&,
||, etc. My preference and the convention that is used in Java and the C family is && and ||.
- Second do not use the assignment operator as the equality operator. Even if GML allows it, use '=' for assignments and '==' for equality.
- When using if-statements it is good practice to use '(' and ')' to indicate the start and the end of the boolean expression that is evaluated by the if.
- When using two consecutive if statements without ant other kind of statements in between and both expresionscontain an element that make both expresions mutually exclusive. Then it is better that you use if ... else if ...
- This is not necessary wrong, but any boolean variable or expression that you want to have passed when it is false is often not changed by comparing it to the value false, but by using the negation operator '!'. For example: 'place_free(x,y+1)=0' -> '!place_free(x,y+1)'
- Know what your expresions do. For example: 'hspeed>10=false' has a redundant part, which could better have been written as 'hspeed <= 10'. It does the same.
Okay, now onto your problem.
1.) The player, when reaching a solid block that he can stand on, slows down before touching the block.
...
if place_free(x,y+vspeed)=false{vspeed=0 move_contact_solid(270,2)}
The problem is probably with the part of code indicated. For falling you use the gravity variable, while for jumping you use a negative vspeed. And my guess is that gamemaker has a cumulative of the gravity on vspeed, because when you jump up you will go down at one point and that is nowhere to be found in your code. Thus when going down your vspeed probably increases to a higher value than 2. When a collision event occurs with a solid GM puts your object back with to its starting position of that event. In effect that means that y - vspeed is done. Thus your check of 'place_free(x,y+vspeed)=false' will always hold true, because that is what generated the collision event.
In this collision event you set the vspeed back to 0 and move your object with a maximum of 2 pixels down, which is smaller than the vspeed was. after that the gravity sets in starting with 1.5 in the first step for vspeed and 3 in the next. Until another collision is generated and the vspeed is once again reset. Your object is moved down with a maximum of 2 and the vspeed can build up again in the following steps. At least until the move of 2 pixels down actually moves the object to the collision point.
2.) When touching a block from the side when in mid-air, the player stops and "sticks" to the wall. If jumping and moving is done right, the player is catapulted into the air.
...
if keyboard_check(vk_space) && place_free(x,y-1) && place_free(x,y+1)=0 vspeed-=20
In the indicated code you do '-=' which is a cumulative operator and can be written as x = x - a. Thus once you move your object in such a manner that he jumps, the vspeed is probably somewhere in the hundreds. This is probably solved by using the '=' assignment operator instead of the cumulative operator.
3.) After the latter of the previously mentioned problem happens, the player, when no key is pressed at all, moves slowly towards the right the entire time. This problem is completely inexplicable to me.
I would guess something with the hspeed goes wrong but it is weird as it should not happen. I don't know how to solve it.
I have to agree with TFS in that you probably use states to separate code. However having a list of boolean variables is not really a state variable but characteristics of a state. The purpose of a state is that with 1 variable you can indicate a lot of characteristics. My suggestion would be a number or a string to indicate the state. Or you use a script identifier and the script contains state dependent code and the object state independent code.
Another things is not to use the 'place_free' function, because that takes all the objects into account. Thus also not solid ones. In case of Super Mario you would be able to stand on a mushroom and a coin. Just like in TFS example you are better of using position_meeting and place_meeting. Or if you want the id of the object instance_position and instance_place.
And last, when you have to check whether a certain key is pressed more than once, you can better check it, assign it to a variable and just use the variable for the rest.