Hey all, today we have a simpler post on the difference between world position and screen position in HaxeFlixel. Note, these can apply across game engines. Let’s get into it, as they both have theiru ses. Let’s start with World Position.

World Position

Geometry: Coordinate Systems for Plane Curves

World position in Flixel is based on the coordinate system. You could think of the entire game taking place on Grid paper. Let’s say, for example, the game’s screen is 500×500. If the player steps outside of the screen width or height you’ll no longer be able to see them. So, if the player was at a point (530, 0), you couldn’t see them on the screen anymore. This is how the world position works. So, when you set the position of the player or enemies in the game, they’re all in World Position. Remember this as it’ll be important. But, obviously, we need our player to be able to move on screen without being restricted. That’s where cameras come in.

Cameras

Cameras allow the player and everything else to be seen in Flixel. They are core to the experience. By moving the camera around, we can move what is visible on-screen beyond the 500×500 pixel game window size. This is because all cameras in Flixel have a scroll property; the scroll property controls the world position of the camera. What the camera sees is based on this scroll property, aka, the world position. Now, this scroll property is integral to how screen position and world position are related. Let’s look at some code that gets the screen position.

/**
* Call this function to figure out the on-screen position of the object.
*
* @param Point Takes a `FlxPoint` object and assigns the post-scrolled X and Y values of this object to it.
* @param Camera Specify which game camera you want.
* If `null`, it will just grab the first global camera.
* @return The Point you passed in, or a new Point if you didn't pass one,
* containing the screen X and Y position of this object.
*/
public function getScreenPosition(?point:FlxPoint, ?Camera:FlxCamera):FlxPoint
{
if (point == null)
point = FlxPoint.get();
if (Camera == null)
Camera = FlxG.camera;
point.set(x, y);
if (pixelPerfectPosition)
point.floor();
return point.subtract(Camera.scroll.x * scrollFactor.x, Camera.scroll.y * scrollFactor.y);
}

Screen Position

If you look at the code above, the screen position is just the current position subtracting the camera scroll and the scroll factor of the object. So, the screen position is the position, without the camera scroll in the equation. Let’s take that apart. If you notice, we multiply the scrollFactor of the object by the scroll of the camera; what happens if we set that scrollFactor to 0? We now have objects that do not scroll with the camera; meaning they will stick inside of the screen, rather than moving in and out of the camera viewport when the player moves around. Super useful to have for several things such as:

  • UI elements (Keep them on screen)
  • Aiming reticules
  • Spawning enemies off-screen
  • Removing enemies off-screen
  • Prevent processing off-screen enemies
  • and much more!

Here’s an image to showcase what I mean:

Knowing the position of elements without the camera position being factored in helps make creating certain mechanics and game elements easier like the above.

Now, because we know all about scroll as a camera property, we can take advantage of this and set the screen position of a FlxObject. Why would you want to do that? Out of the box, Flixel doesn’t let you do this and it can be useful for spawning enemies off screen outside of the camera viewport, without using something else or the camera scroll property as a reference point. So, here’s how to do just that as an extension that you can use on any FlxObject in Flixel.

import flixel.FlxCamera;
import flixel.FlxObject;
//Sets the screen position of a FlxObject using setPosition(which is in world coordinates)
function setScreenPosition(obj:FlxObject, point:FlxPoint, ?camera:FlxCamera) {
if (camera == null) {
camera = FlxG.camera;
}
if (obj.pixelPerfectPosition) {
point.floor();
}
//scrollFactor if set to 0 would result in the object moving to the screen position in world space
//So, if the screen was 500 x 500 and the player is at (600, 20) and you use this with a scroll factor of 0
//the on screen element would move to 0, 0 and not be visible on screen with a width of 500×500.
obj.setPosition((camera.scroll.x * obj.scrollFactor.x) + point.x,
(camera.scroll.y * obj.scrollFactor.y) + point.y);
return obj;
}

Conclusion

I hope this post was information and helpful! Good luck creating your own games!

%d bloggers like this: