Legacy GM Problem with rounding and views

M

MrPerson561

Guest
So I'm trying to make a platformer game going off of Shaun Spalding's platformer tutorial. At first I was having problems with the view following player. It wasn't major, but the view would stutter a little bit and sometimes the player wouldn't quite touch the ground. So I looked around and people said that rounding the players coordinates helps. So I tried that (obj_player.x = round(obj_player.x) and obj_player.y = round(obj_player.y)) And it worked! It made everything run smoothly. However, now I think the player's movespeed is indirectly being rounded too, because when I set it to 1.5 in the Create event it rounds to 2 and whenever I set it to 1.49 it rounds to 1. I've asking around on Steam discussions for a few days and nobody could explain it.

Also maybe I should have posted this in the programming forum I dunno :p
 

obscene

Member
The movespeed isn't being rounded. But continually rounding the results of adding movespeed to your location is basically the same thing.

1 + 1.5 = 2.5 rounded to 3. (So we moved 2).
3 + 1.5 = 4.5 rounded to 5 (So we moved 2 again).
 

TsukaYuriko

☄️
Forum Staff
Moderator
Moving to Programming.

Don't round the player's coordinates. Round the coordinates you're drawing the player's sprite at. This preserves your movement while still achieving the visual effect you seem to be after.
 
M

MrPerson561

Guest
This may sound nooby (I'm a little bit new to GameMaker), but how would I round the coordinates that I'm drawing the player's sprite at?
 

obscene

Member
You need to add a draw event for your object which will overwrite the built in drawing for the object.

Then use draw_sprite_ext() and round your x and y.
 
M

MrPerson561

Guest
Didn't work. Did I do it right?

Draw event
---
if (move = 1)
{
draw_sprite_ext(spr_player, -1, obj_player.x, obj_player.y, 1, 1, 0, c_white, 1);
playerdir = 1;
}
if (move = -1)
{
draw_sprite_ext(spr_player_left, -1, obj_player.x, obj_player.y, 1, 1, 0, c_white, 1);
playerdir = -1;
}
if (move = 0)
{
if (playerdir = 1)
{
draw_sprite_ext(spr_player_still, -1, obj_player.x, obj_player.y, 1, 1, 0, c_white, 1);
}
if (playerdir = -1)
{
draw_sprite_ext(spr_player_left_still, -1, obj_player.x, obj_player.y, 1, 1, 0, c_white, 1);
}
}

obj_player.x = round(obj_player.x);
obj_player.y = round(obj_player.y);
 

TsukaYuriko

☄️
Forum Staff
Moderator
Only round the coordinates you use for drawing. Never round the player's coordinates directly.
Code:
draw_sprite(sprite, image, round(x), round(y);
Like this.
 

obscene

Member
What he said... but want to add something. You can avoid 90% of that code by just drawing sprite_index and then changing your sprite_index in your normal movement code.

Also, when you use "if" to check several statements where only ONE of them can be true, use "if" then "else if" "else if" "else if" which will stop checking the statements when it finally gets a true statement. But even better, use switch.

switch (a)
{
case 1: do this; break;
case 2: do this; break;
}
 
M

MrPerson561

Guest
This fixed the problem except for one thing. It fixed the speed problem and the collision problem where you sometimes didn't hit the floor, but it didn't quite fix the view stutter. The player kinda shakes a little bit whenever the view is moving.

EDIT: I didn't notice this before, but before the player sprite wouldn't quite touch the floor and now it won't quite touch the wall sometimes. Usually it happens when the view is moving. I checked both the player and wall mask and it wasn't that.
 
Last edited by a moderator:

TsukaYuriko

☄️
Forum Staff
Moderator
This fixed the problem except for one thing. It fixed the speed problem and the collision problem where you sometimes didn't hit the floor, but it didn't quite fix the view stutter. The player kinda shakes a little bit whenever the view is moving.
Is your view set to follow the player? If so, since the player can end up at fractional coordinates, so can the view. Similarly to how you took control over drawing of the player, you will have to take control over positioning of the view as well.

You'll have to use the view* family of variables to achieving this, particularly x/yview and w/hview.

EDIT: I didn't notice this before, but before the player sprite wouldn't quite touch the floor and now it won't quite touch the wall sometimes. Usually it happens when the view is moving. I checked both the player and wall mask and it wasn't that.
This more than likely is a problem with your player's movement code. If you don't manually add special cases that "close gaps" between the player and walls, there may be situations in which it is impossible to move closer towards the wall because the momentum gained by doing so would place the player inside the wall... so the player will stop right before touching the wall, creating the effect you are experiencing. But that's just a wild guess.
 
M

MrPerson561

Guest
So I'm guessing I can't just do view_xview[0] = round(view_xview[0]) and then the same thing for y, w, and h? Sorry about all the questions, I don't know how to do anything in GM:S :p
 

TsukaYuriko

☄️
Forum Staff
Moderator
You can try it, although rounding the width and height is useless.

If you don't know how to do anything, you should be doing the official tutorials in order to learn how to do things, not trying to make a game through trial, error and posting on a forum. That will only teach you to rely on others instead of coming up with your own solutions, which is the ensured demise of any aspiring game developer.
 
M

MrPerson561

Guest
Ok. I see your point and will try to solve this on my own. Thanks for all the help.
 
Top