Dev Log Entry 4: Solving the edge bug in newtius

This is a dev log about creating a game in GameMaker Studio 2 (Indie edition). Starting with entry one might make this easier to follow.

Continuing from dev log entry 3, I thought I’d offer a small update. Then it expanded into the solution to the bug. So here it is then.


I started to ignore the existing code I had adopted to constrain the ship within the boundaries of the “room” and just look at the logic. And also look at another set of code. This time not just pasting in code, but looking at the language reference and trying to understand what it was saying and what it would do.

I found this code that used the clamp function as well this set of bbox functions. And I know x and y are pre-defined variables.

I put in this code and customized it a little bit.

The bbox – bounding box associated with sprite – is something separate from the collision box but I guess is functionally similar to the collision box.

In my Intersect Boundary event for the ship object I made the code into this.

// check all the way left - x is 0 - or if it's all the way right
// which would be the define width of the room
if ( bbox_left < 0 || bbox_right > room_width ) {
	x = clamp(x, sprite_xoffset, room_width - sprite_xoffset); 
	// hspeed *=  -1;	
}
// check all the way at the top - y is 0 - or if it's all the way 
// at the bottom
// which would be the define height of the room
if ( bbox_top < 0 || bbox_bottom > room_height ) {	
	y = clamp(y, sprite_yoffset, room_height - sprite_yoffset); 
	// vspeed *= -1;	
}

Well it sort of worked: moving the sprite all the way to the top or all the way left doesn’t make the sprite fly off the screen past visibility any more, but the right and bottom edge still make it stick in place including the bottom right corner.

I still have the code in my different arrow keys pressed events as I wrote above. What I don’t really understand still is why it doesn’t work either work for all four barriers as left and top or not work for all four barriers…


Later…

I think I might have an idea what’s going on: left and right are both based around 0 (upper left corner being coordinates 0,0 and all) while bottom and right are both integers.

And since my “key pressed down” event is still referring to that speed variable set to 7 (from the create event) this is butting up against both 640 and 480 direction. But 7 isn’t evenly divisible by either 640 or 480. So that x value for instance is checking before the edge and getting one result and the next thing it knows it’s past an evenly divided number. So the sprite gets stuck in this limbo between true and false, frozen in the comparison.

Not sure that made sense. But it does explain it.

Easy way to test this would be to change that spd variable to something evenly divisible, like 1 or 2 or 8.

(still more later)

As it turns out this didn’t work. And I’m still not completely clear on what was the causing the sprite to stick in place. I suspect it was that intersect boundary event.

I decided to completely comment out all the code in the intersect boundary event (no bbox entries at all, now) and then do a few experiments I should have done to start with.

First I created a new object – obj_enemy along with a matching sprite (spr_enemy). I then put the new enemy object in the room and simply used the create event to set the x and y coordinates to actually figure out where these values are I’ve been looking at and testing against all this time.

For instance if I use this line:

//enemy object "create" event - setting the x coordinate outright
// the -5 is just the move it off the edge every so slightly
x = room_width - sprite_xoffset - 5;

this moves the enemy object all the way to right side of the screen, then 5 pixels inside the room from the edge.

I also did some experimenting with for instance bbox_left. Even after reading the documentation I don’t think I know what that is and after setting it with an x = I’m not any more clear on it. Since I don’t need it I’m just going to ignore it for now.

As for the various sprite offset built-in variables, basically you can set an origin point on a sprite and the “offset” is relative to that. For instance setting the origin point to “middle center” (centre? UK English…whatever) the offset counts off the number of pixels from that point to the top/bottom and that point to either left/right edge of the sprite. Since my ship sprite is 32×32 pixels, it comes out effectively as 16 pixels. I think the documentation page can explain it more effectively than I can.

Further demonstration of origin point concept. In case it were needed. You can see at left the 32×32 pixel size.

I only mention this so these next code snippets make more sense.

I went into the “key down – left” event for the player object and eventually it came out to this:

// on push left arrow: check if x coord is greater than the x offset
// of the sprite (+ 5) and if so keep subtracting that spd variable
// from the value of that x coord variable
// otherwise set the x variable to the x sprite offset + 5
RoomLeftEdge = sprite_xoffset + 5;

if ( x > RoomLeftEdge   ) {
	x = x - spd;
} else {
	x = RoomLeftEdge;
}

What this is really doing is creating variable – RoomLeftEdge – and setting it to the offset of the sprite on the x-axis. Since the origin point of the sprite is the middle/center, this should be 16. And since the left edge is zero on x axis, it’s effectively setting the variable to 0 + 16. Which means that if statement is: is the x coordinate greater than 16? and if so then take the x coordinate and add itself minus the spd variable. Or to put it another way every time the left arrow is pushed set the x coordinate some number of pixels further to left (spd value is arbitrarily set to 8).

So keep moving the ship left when I push the left arrow. That’s the one line summary. Then it’s just a matter of hard-setting the x coordinate to a value when it gets to close to the edge.

I did something equivalent to the above code the rest of the 3 arrow keys/move directions. After multiple test sessions I confirmed I can move the ship around the window and no longer get stuck. Best part is I understand why it works the way it does.

Of course, the GML language also has built-in variables vspeed and hspeed which are literally made just to set the speed in pixels in those respective directions. I don’t know if there are any advantages to my method versus using those variables.


The latest version/progress of Newtius can always be found at my GitHub repo:
https://github.com/tildesarecool/newtius

One thought on “Dev Log Entry 4: Solving the edge bug in newtius

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s