Identify an object currently selected in the game

I am making a 2D isometric game that uses the mouse. When I left click on an object, this object should be selected, but how do I determine what object that's currently selected and show a halo around it?

My objects are stored in a list of game objects as std::vector<Game_Object *> Object_Game. I am using the SDL library with C++. I did some research on Google but only found articles about Unity. Can someone help me with this?

• Are you making a 2D- or a 3D game? – Daniel_1985 Nov 8 '19 at 9:26
• I am making a 2d game, it is type “isometric”. – Traistorm Nov 8 '19 at 9:48
• If your objects are inside a vector, can't you iterate through it and manually make collisions ? – TomTsagk Nov 8 '19 at 12:54
• Is your game tile-based? If so, you could find whatever isometric tile the mouse is pointing at and then determine whatever character / object is at that position. If not, you could always use the same technique by using a quadtree to keep track of characters / objects in your game and transform the isometric position to a position in the quadtree and find objects / characters at that position. – Darin Beaudreau Nov 8 '19 at 13:00

1. Projecting your 2d mouse coordinates to 3d world coordinates, to create a ray.
2. Performing collision detection on the new coordinates, compared to your game objects.

NDC to 3D world coordinates

To do this, you need your view and projection transform matrices:

mat4 view = lookat(camPos, camPos+camDir, vec3(0.0f,1.0f,0.0f);
// For 3D
mat4 projection = perspective(fovAngle, aspectRatio, znear, zfar);
//for 2D
mat4 projection = ortho(0, width, height, 0);


combine these matrices using affine transformations:

mat4 worldToScreen = projection * view;


then invert them:

mat4 screenToWorld = inverse(worldToScreen);


Now, we take our mouse coordinates, and transform into world coordinates:

vec3 worldMouse = screenToWorld * vec4(mouseX,mouseY,-1.0f,1.0f);


Then finally we create our ray:

vec3 ray = normalize(worldMouse - camPos);


Collision Detection

Now, we can iterate through a vector of game objects, to determine which one has been clicked on:

gameObject *selectedObject; = nullptr;
for (auto &gameobject: gameObjects)
{
if (gameobject.collide(ray))
{
selectedObject = gameobject;
break;
}
}


Then you can have some rendering code that draws a halo on the ground at the targeted object position:

void render()
{
if (selectedObject != nullptr)
{
selectedHalo.drawAt(selectedObject->getPosition());
}
// then draw your game objects as normal.
}


This technique is known as "3D picking". There are plenty of more detailed tutorials available, but I covered the basic gist of it.

• This is what you'd do in 3D but the original poster indicated this is a 2D game. Can you recommend how to construct the corresponding matrices for a 2D isometric game? – amitp Nov 8 '19 at 17:40
• Oh, thank you very much ! – Traistorm Nov 9 '19 at 0:28
• @amitp The principle still stands for a 2d game: change the mouse coordinates from NDC space to world space, then perform collision detection. Also, isometric is not 2D, it is usually defined as 2.5D. That being said, I will extend my answer appropriately. – Ian Young Nov 9 '19 at 12:52