Indie game storeFree gamesFun gamesHorror games
Game developmentAssetsComics
SalesBundles
Jobs
Tags
0
Members

[tip] Mouse & touch positions in world space, + Sup.Input.Ray() example

A topic by Doomcaster created Feb 10, 2016 Views: 1,192 Replies: 1
Viewing posts 1 to 2
(+5)

I thought I might share a bit of code I made a little while ago, explain it's usage, and also shed a little light on Sup.Input Ray(), since it was something I didn't quite understand when I first started. The functions below give you the position of the cursor or touch position in world space for orthographic (2D) cameras, and also accounts for different window sizes and orthographic scales.

By multiplying the mouse position by the orthographic scale and multiplying the X axis by the camera's ratio (the width compared to the height of the screen), we can add the position of the camera and it'll return positions in world space. "world space" is the position of actors in the scene, rather than positions on the screen. Screen space only really useful for menus, buttons, and other things like that.

The getTouchPositionCamera() function has an extra argument called "index", since multiple fingers can be picked up as inputs at the same time, it needs to know which one you want to check.

function getMousePositionCamera(camera: Sup.Camera): Sup.Math.Vector2{
    let position = Sup.Input.getMousePosition().multiplyScalar(camera.getOrthographicScale()*0.5);
    position.x *= camera.getWidthToHeightRatio();
    return(position.add(camera.actor.getPosition()));
}

function getTouchPositionCamera(camera: Sup.Camera, index:number): Sup.Math.Vector2{
    let position = Sup.Input.getTouchPosition(index).multiplyScalar(camera.getOrthographicScale()*0.5);
    position.x *= camera.getWidthToHeightRatio();
    return(position.add(camera.actor.getPosition()));
}

These functions are best used when coordinates are needed. This means clicking buttons, or hovering over an actor isn't recommended as there are already better suited ways to handle those (see below). The correct usage would be for things like dragging something with the cursor, moving a scrollbar, or making something follow the mouse.


For 3D games, buttons, or checking if the mouse is over an actor, I recommend using Sup.Math.ray(). It's a very easy to use and understand, but may not seem like what you need at first glance. For clarity, a ray is like a flashlight. When it's dark out, you can move around and point the flashlight in different directions and you'll see anything within the light. So when you use a ray, it will return what's currently in it's direct path.

// This creates a ray. A ray can be reused, so it's best to place it in an actors "awake" method.
let ray = new Sup.Math.Ray();

// This moves the ray to start at the CAMERA, and point towards the mouse.
// CAMERA would be the camera in your scene. An easy way to get it is Sup.getActor("YourCameraNameHere").camera
// It's best to put this in an actor's "update" method.
ray.setFromCamera(CAMERA, Sup.Input.getMousePosition());

// Finally you can check if the actor was hovered over by the mouse.
// ACTOR would be the actor you want to check for.
if(ray.intersectActor(ACTOR).length>0) {
    // Do something!
}

There's more ways to use rays, like getting a list of actors underneath the cursor, or even using them for an AI's line of sight. So you might want to check out the documentation for more information. It might also be a good idea to look at the API browser in Superpower, as some functions might not yet be documented. (like Sup.Math.Ray2D())

Like usual, my code might not be the most efficient, or as optimized as it could be. If you have any suggestions or examples to share, feel free to post them below.

Hope this helps

(I didn't know if this counted as a tip or a guide, since it doesn't go into full detail on the subject)

(+1)

wow... thats what i'm need :D thank's and let me try