Mouse aiming

A tutorial by Andrew Barber aka Chronic

This tutorial covers how to use your mouse to aim and shoot in a platform game. Please note that you will need to have a registered version of Game Maker 6 or above to use maim_angle.

Ok, so we first need to start off with our player sprite. I'll be using something simple that will do for explaining, you can take more time and even animate it.


player sprite

You may have noticed that the sprite hasn't got an arm, well.. this is needed to be made in a seperate sprite, so, we need an arm making. A paint program that has layers such as Paintshop Pro or Photoshop is ideal for this part so you can get the proportions correct.

To make it easier to code, its a lot easier if you draw the arm pointing to the right, if you don't you will need to alter the script that sets the arm angle to adjust for the angle you draw it at.


arm sprite

Now that the sprites are done we can add them in to the game, along with making an object for each of them.

Place your player object to a room, this is all we need as the arm will be created by the player object.

Add a create event to the player object, for now we just need it to create the arm.. we'll move it to the correct position later. So, in a code action we write.

[CREATE EVENT] 
{
  instance_create(x,y,obj_player_arm);
}

Now that the arm is being created in to the room, we can script it to rotate. This is made VERY easy with maim_angle in Game Maker 6 and above. Write the following in the arm objects step event.

[STEP EVENT] 
{
  maim_angle = point_direction(x,y,mouse_x,mouse_y);
}

If you run the game now, you may notice that the roation looks a little funny. This can be solved by setting the sprites origin. Heres a little tip for how to get it in the exact place you want it.

Edit the sprite you wish to set the origin for, in this case we need to edit the arm sprite. We're not going to be making any changes to the image, we only need to use the handy cursor location at at bottom of the editor window.

Zoom in to your sprite so you can place the cursor exactly were you want the rotation to occur from, it also helps to toggle on the grid.


rotation point

cursor location

The yellow X is where my cursor should be, but print screen doesn't capture it.

Now that we have the cursor location, we can exit out of the editor back to the sprite properties. In part where it says origin enter the x and y values of the cursor location.


origin

Testing the game now should give better results for the rotation... now all we need to do is position the arm in the correct place.

This can be done using the same method as we got the new origin for the arm, but instead we edit the player sprite. However this time we're not going to be changing the origin. From my test, i need to move the arm over 7 pixels, and down 17.

To do this we go back to the create event of the player and change the script a little.

[CREATE EVENT] 
{
  instance_create(x+7,y+17,obj_player_arm);
}

There is still a little bit more to do, we need to make the arm move when the player moves. So to test this we need to make the player move, i used the following to test with.

[LEFT KEY]
{
  x -= 5;
}
[UP KEY]
{
  y -= 5;
}
[RIGHT KEY]
{
  x += 5;
}
[DOWN KEY]
{
  y += 5;
}

The arm position now needs to update as the player moves, this is done editing the script in the step event. There is a slight graphical glitch to fix. When you move the mouse to the left of the player, the hand will be upside down. To fix this, the arm script needs to be changed to.

[STEP EVENT] 
{
  maim_angle = point_direction(x,y,mouse_x,mouse_y);

  x = obj_player.x + 7;
  y = obj_player.y + 17;
  
  if (mouse_x <= (obj_player.x + 7)) {
    maim_yscale = -1;
  }
  else {
    maim_yscale = 1;
  }
}

Notice the 7 and 17, these are the same numbers we used in the player create event.


At this point the tutorial is basicly done, your player should be able to move around with the arm following, and aiming appropriately. However, i want to take this a little further by showing you how to limit the aiming incase you want to use it for a turret.

To be able to limit the aiming we need to change the step event a little..

[STEP EVENT] 
{
  pDir = point_direction(x,y,mouse_x,mouse_y);
  maim_angle = pDir;

  if (pDir > 180) { maim_angle = 180; }
  if (pDir > 270) { maim_angle = 0; }

  x = obj_player.x + 7;
  y = obj_player.y + 17;
  
  if (mouse_x <= (obj_player.x + 7)) {
    maim_yscale = -1;
  }
  else {
    maim_yscale = 1;
  }
}

Notice that we're now putting the point_direction in to the variable pDir, this is because we're using it multiple times. So it saves the calculation that point_direction does being repeated unnecessarily.

The two new lines we've added are what limit the movement of the arm to 180 degrees. You need to keep in mind that in GM the 360/0 point of a circle is to the right instead of up.

The first of these checks the value of the point_direction result (pDir) is over 180, this means it would be atleast in the bottom-left quarter of the circle. It then sets the maim_angle to 180, which makes the arm point to the left.

The next line checks if pDir its over 270, This must mean its in the bottom-right quarter of the circle. If this is the case, we should set the maim_angle to 0, which makes the arm point to the right.


pDir checks

Note: Game Maker automatically takes care of making sure that we cannot have an angle over 360, so we do not have the problem of needing to check if pDir is equal or less than this when limiting the angle.

That brings me to the end of the tutorial. You can find examples of unlimited and limited version of mouse aiming below.

  • Mouse aiming - Unlimited
  • Mouse aiming - Limited