2
\$\begingroup\$

I'm working on a 2D top-down shooter game that has a rotation feature like Realm Of The Mad God such that if you press e the camera rotates around the character in a clockwise direction and q rotates the camera around the character in a counterclockwise direction. I have this working with my floors and walls by translating to the character, doing the screen rotation, and drawing everything with the character as the origin. The problem arises when I shoot projectiles which need to both rotate around the character and rotate around themselves (shooting uses the mouse cursor so I can shoot at any angle). For example, if the screen is not rotated and I'm shooting rectangular projectiles, I want them to face in the direction I'm shooting (rotation around themselves). However if I only do this rotation, when I then rotate the screen the projectiles will always shoot at the same position because my cursor position does not change. Therefore I need to also either rotate the projectiles around the character or rotate the mouse cursor position to get the correct position (which would then totally screw up all of the collision detection). Likewise if I only do the screen rotation on projectiles, the rectangles will always be facing the same way and they would only look correct if I were shooting straight up or straight down.

So my question is, how can I perform 2 rotations on a primitive around 2 different points? The only way I can think of is to translate to the character and do the screen rotation, then somehow calculate the translation required to move back to the middle of the projectile (seeing as how my axes are now rotated) and do its rotation. Or am I thinking about this in the wrong way and there is a different solution to accomplishing this effect?

\$\endgroup\$
2
  • 3
    \$\begingroup\$ Have you tried your idea of translating, rotating, then translating back? I believe you can translate so that the bullet is centered at (0,0), then rotate, then translate back (without worrying about rotated axes). \$\endgroup\$
    – amitp
    Feb 18, 2013 at 16:28
  • \$\begingroup\$ Also, if you later want to rotate characters and trees the way Realm of the Mad God does it, read about "billboard sprites". \$\endgroup\$
    – amitp
    Feb 18, 2013 at 16:28

2 Answers 2

1
\$\begingroup\$

Since your game is 2D, I will assume, as I read in your comments, that there is no "camera". I will assume that you have a view rotation around the player called viewRot.

Your player is the center of rotation as well as the center of the bullet. We will first rotate the bullet around itself because it seems logic to me to apply self transformations before others. To do so you will need the following (written in pseudo-code):

Translate to (0, 0), so apply translate(-x, -y)
Rotate by the bullet angle, rotate(bAngle)
Translate back to its position, translate(x, y)

Then we need to rotate around the player. To do so, we will translate not to (0, 0) but to the position of the player, here pX and pY:

translate(-pX, -pY)
rotate(viewRot)
translate(pX, pY)

At the end, you may need to translate the bullet's position relative to the view (if any).

It is in the end pretty simple, you only need to apply two rotation-around-point transformations. If you want more specific code, just leave a comment.

\$\endgroup\$
0
\$\begingroup\$

Lets say you have the character at (x,y) position with some theta rotation.

Similarly, you have the camera in the background at (x,y) + r*(cos(phi),sin(phi)) (plus a z value where you want the camera to hang in) looking at the character direction (x,y)

This way, you shoot the projectile relative to your character

 (x,y) --> (x,y) + time*velocity*(cos(theta),sin(theta))

which is automatically "rotated a second time" from the camera perspective.

I think the problem is that you're not storing this original "theta" with respect to the character, but rather with respect to the camera.

Normally you apply a single rotation to get the coordinates in the "world coordinates" and the "second rotation" is automatically applied from choosing your camera location and its view direction.

A solution would be something like:

projectile bullet = projectile(hero.x, hero.y, hero.theta);
...
bullet.x += frameChangeInTime*bullet.velocity*cos(bullet.angle);
bullet.y += frameChangeInTime*bullet.velocity*sin(bullet.angle);

The camera will take care of the "second rotation" since we're placing the projectile in the world coordinates.

\$\endgroup\$
3
  • \$\begingroup\$ I'm not sure what you mean by "choose the camera location and its view direction". OpenGL does not, strictly speaking, have a camera. To rotate the "camera" you rotate everything in the view by the inverse of the "camera" rotation. \$\endgroup\$
    – Fenoec
    Feb 16, 2013 at 3:08
  • \$\begingroup\$ If you're using GLU, just use gluLook At. If you're not using libraries that simplify the camera then add the corresponding transformation matrix for the camera as your first transformation, followed by your projection matrix. New vertex = transformation * camera * vertex \$\endgroup\$
    – Yuuta
    Feb 16, 2013 at 3:50
  • \$\begingroup\$ Here's the gluLookAt implementation of the camera incase you want to implement your own camera: opengl.org/sdk/docs/man2/xhtml/gluLookAt.xml \$\endgroup\$
    – Yuuta
    Feb 16, 2013 at 4:22

You must log in to answer this question.

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