• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

GameMaker [SOLVED]Instance origin different to sprite and physics object

S

seraph

Guest
Hi community, new to forums and development in GMAKER2

I have an odd rotation problem to do with x and y offsets. When I reference self.x, self.y for my 1 pixel sprite it appears to offset itself with opposite rotation values. Below is the draw line event (a hitscan gun) and below that is where I set my fixtures up with some image references.

I'm using physics angular forces to rotate my player object, my assumption is that self.x, self.y are normalized to my objects rotation and should therefore follow when the object is rotated, but, instead I get some offsets as shown below. (lists are counterclockwise rotation 90 degree steps).

Not sure if that's clear enough but would love help, been puzzling over this for a week now :) (to clarify, the spawn point of my drawnline is offsetting itself by values and images shown below. The same happens for spawning objects and such.)

X offset
  • 0
  • 0
  • 1
  • 1
Y offset
  • 0
  • 2
  • 2
  • 0
270 degree counter clockwise rotation, blue line shows direction of sprite front to mouse location.
1.png

90 degrees counter clockwise rotation.
2.png




if mouse_check_button(mb_left) {
//Variables
var allowed_coll_layer = self.layer
var force_originx = self.x
var force_originy = self.y

var dir = point_direction(x, y, mouse_x, mouse_y); //connect a line between origin and the mouse
//show_debug_message(mouse_x)
var d = 400; //the maximum number of pixels from origin to endpoint that the laser can extend
var spread = random_range(-0,0); //(optional) randomly offset the angle of the line before it goes out

var shot_distance = 0
var max_shot_distance = 500

while (shot_distance <= max_shot_distance) {

var lx = x + lengthdir_x(shot_distance, dir + spread); //the line will continually check 1 pixel ahead of itself as it extends
var ly = y + lengthdir_y(shot_distance, dir + spread);
var hit = (collision_line(x, y, lx, ly, phys_controller, false, true)); //shorthand for "an object in the way of our collision line")
var static_hit = (collision_line(x, y, lx, ly, static_phys_dummy, false, true)); //shorthand for "an object in the way of our collision line")

if (hit != noone) or (shot_distance == max_shot_distance) {

xx = self.x + lengthdir_x(shot_distance, dir);
yy = self.y + lengthdir_y(shot_distance, dir);
draw_set_colour(c_aqua);
//draw_line((self.x - 1), (self.y - 1), xx, yy);
draw_line((self.x), (self.y), lx, ly);




//determine the sprites dividable width and height and offset our fixture to the
//relative point of mass within that sprite.
if (self.sprite_width % 2 == 0) {
var x_fixture_offset = 0;
} else if (self.sprite_width % 2 == 1) {
var x_fixture_offset = -0.5;
}

if (self.sprite_height % 2 == 0) {
var y_fixture_offset = 0;
} else if (self.sprite_height % 2 == 1) {
var y_fixture_offset = -0.5;
}
 

Roldy

Member
Not sure if that's clear enough [...]
Unfortunately it is not.

Please use the code block for gml when posting your code in the forum. Using the bb code [ CODE=gml] [CODE]. In the posting toolbar it is the button that looks like </>.



If I had to guess what your issue is:

my assumption is that self.x, self.y are normalized to my objects rotation and should therefore follow when the object is rotated,
I believe you need to re-examine this assumption.

self.x, self.y are origin for your object. If you are assuming somehow doing arithmetic with these is applying local/object space rotations then that would be incorrect.

In general do not use the 'self' keyword at all. Read here: https://docs.yoyogames.com/source/dadiospice/002_reference/001_gml language overview/keywords.html

If that doesn't end up being your issue then reply with a clearer explanation of the problem.

I really don't know how to interpret these two list or how they really apply to the images. Or what the different colors of x's and y's mean on your image.


X offset
  • 0
  • 0
  • 1
  • 1
Y offset
  • 0
  • 2
  • 2
  • 0
 
Last edited:
S

seraph

Guest
Think I've simplified it a bit. The code below creates a fixture covering my 1 pixel sprite as expected, collisions and rotations work as expected, however, the phy_com_x and phy_com_y return a point in space offset by 1 pixel right and down. (image example).

I've sifted through documentation but can't find the relation between instance origin and physics fixture origin. I'm not sure why instance origin (x, y) is offset by a pixel right and down relatively speaking.

My goal is for that blue line to be originating from the 'front' or x positive offset of that red pixel. Hoping I can get some pointers on why these offsets are happening on the first place, the disconnect between what my physics object is doing and the apparent x, y origin of my object is confusing the heck out of me.

3.png

GML:
draw_line(phy_com_x, phy_com_y, lx, ly);
Code:
fixture = physics_fixture_create();

physics_fixture_set_polygon_shape(fixture)

physics_fixture_add_point(fixture, 0, 0);
physics_fixture_add_point(fixture, 1, 0);
physics_fixture_add_point(fixture, 1, 1);
physics_fixture_add_point(fixture, 0, 1);



x_fixture_offset = 0
y_fixture_offset = 0

physics_fixture_bind_ext(fixture, self, x_fixture_offset, y_fixture_offset);
 
Last edited by a moderator:

Roldy

Member
View attachment 32485

GML:
draw_line(phy_com_x, phy_com_y, lx, ly);
What is lx, ly?

GML:
var lx = x + lengthdir_x(shot_distance, dir + spread); //the line will continually check 1 pixel ahead of itself as it extends
var ly = y + lengthdir_y(shot_distance, dir + spread);
is that correct?

phy_com_x, phy_com_y are the center of mass.
phy_position_x, phy_position_x are the position of the instance in the physics world.
x, y are the position of the instance in the game world
lx, ly are unit vector from x, y

what are the values of these?
what are their values when you draw that line?
print them out with the following:

GML:
show_debug_message( "CoM: (" + string(phy_com_x) + ", " + string(phy_com_y) + ") Phy Pos: (" + string(phy_position_x) + ", " + string(phy_position_y) + ") (x,y): (" + string(x) + ", " + string(y) + ") (lx, ly) : (" + string(lx) + ", " + string(ly) + ")");
Review this: https://docs2.yoyogames.com/source/...hysics/fixtures/physics_fixture_bind_ext.html

Are you sure your offsets shouldn't be something like (0.5, -0.5 )?
Even though your sprite is "a single pixel" what is the origin set to for that sprite?

I think those are the questions I would be asking myself.
 
S

seraph

Guest
AIght, fixed, I had read that documentation but your answer got me to slow down and test offsets methodically. eventually found the correct (or one that works for me) offset.

I offset my fixture by the images size (whether odd or even)

GML:
//determine the sprites dividable width and height and offset our fixture to the
//relative point of mass within that sprite.
if (self.sprite_width % 2 == 0) {
    var x_fixture_offset = 0;
} else if (self.sprite_width % 2 == 1) {
    var x_fixture_offset = -0.5;
}

if (self.sprite_height % 2 == 0) {
    var y_fixture_offset = 0;
} else if (self.sprite_height % 2 == 1) {
    var y_fixture_offset = -0.5;
}

physics_fixture_bind_ext(self.fixture, self, x_fixture_offset, y_fixture_offset);
then when I draw my sprite I set the images direction to my relative physics object rotation

Code:
var dir_image = phy_rotation
draw_sprite_ext(sprite_index, -1, x + 1, y + 1, 1, 1, -dir_image, c_white, 1)

I haven't tested this for anything larger than a pixel but am pretty confident I can figure it out from here. Also, the functions below were REALLY helpful when debugging where my various elements were being placed in the game room.

Code:
draw_rectangle(x, y, x, y,false)
flag = phy_debug_render_shapes | phy_debug_render_obb | phy_debug_render_coms;
flag_two = phy_debug_render_shapes | phy_debug_render_coms;
physics_world_draw_debug(flag_two);
Thanks for the help Roldy!
 
Top