I'm making a simple 2D shooter game in pygame and I've come across an issue when making the character aim its gun at the mouse.

To make the gun aim up and down, I've set it so that the gun uses the angle between the x axis and the mouse to rotate itself on its handle. It works just fine but the issue is that since the muzzle of the gun is above the pivot, the muzzle never aims directly at the mouse but slightly higher.

Drawing of the situation

My question is, is there a way to compensate for the offset of the muzzle while keeping the rotation pivot on the handle of the gun?


2 Answers 2


In real life, weapons have their sights (whether metallic, reddot, optical scope, etc.) slightly above the barrel axis.
To compensate for this, the sights axis is usually set to point slightly down such that the sight axis and the barrel axis cross at a distance X, for example 100 m. It means that if you aim at a target 100 m away from you, the bullet will hit precisely where you aim. If you're target is closer, the bullet will hit a little below and if the target is further, the bullet will hit a little above the point you're aiming.
This setting can be altered to any desired distance X, this is called zero a rifle.
Precision weapons can be zeroed thanks to screws on the scope, but most other weapons have the zero preset and cannot be easily changed on the field.

To translate this into your game, you can either:

  • Mimic real life, have a fixed angle between the aiming sights and the barrel,
  • Automatically adjust the zero distance to match where your cursor is. For example, if your character is aiming at a wall, knowing the distance between him and the wall allows you to compute the angle and compensate such that the bullet will hit where the cursor is.
  • \$\begingroup\$ Thanks for this explanation, I've learn something knew about firearms. However, the part of computing the angle seems to be more complicated than it appears, do you have any idea how to proceed? \$\endgroup\$ Jun 14, 2021 at 20:15
  • \$\begingroup\$ @jaregax432-awinceo If we consider that bullets go straight (without the influence of gravity), it's only a simple trigonometry problem upload.wikimedia.org/wikipedia/commons/f/fd/… . The line of sight is where the shooter's eye (the camera in your case) looks, the bore line is where the gun actually points to. Knowing the bore angle and the offset between the shooter's eye (camera) and the pivot of the gun, you can compute how to orientate the gun to hit where your cursor is. \$\endgroup\$
    – Sacha
    Jun 14, 2021 at 20:34

There is probably a more mathematically elegant solution, but you could just offset where you are aiming based on the rotation of the gun.

Say your barrel of your gun is 20px higher than your pivot point, you would calculate your angle to point the barrel based on 20px below your mouse curser to compensate. If you're aiming completely up, you would calculate your rotation on a point 20px to the right, if you're aiming down below, it would be 20px to left, and if you're aiming backwards (and you don't flip your character) it would be 20px lower.

You could use an if statement to check if you're within one of these angle ranges and lerp between them.

I'm not a python programmer and as familiar with pygame, but you could do something like the following in javascript (assuming the 0 degrees is up, and y gets bigger the higher you are on the screen).

    if (angle < 90) lerp({x: 20, y: 0}, {x: 0, y: -20}, angle/90)
    else if (angle < 180) lerp({x: 0, y: -20}, {x: -20, y: 0}, (angle-90)/90)
    else if (angle < 270) lerp({x: -20, y: 0}, {x: 0, y: 20}, (angle-180)/90)
    else lerp({x: 0, y: 20}, {x: 20, y: 0}, (angle-270)/90)

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .