I am trying to create a weapons upgrade for my Spaceship, using libGosu and Chingu (in Ruby). This question is about how to deal with this issue specifically in Ruby, and more specifically in libGosu.

In the player class I have tried several variations of the following:

def fire
  Bullet.create(:x => @x, :y => @y, :angle => @angle)
  Bullet.create(:x => @x + Gosu::offset_x(90, 25), :y => @y + Gosu::offset_y(@angle, 0), :angle => @angle)

It sort of works, but not exactly how it ideally should. For reference, this is what the Bullet class looks like:

class Bullet < Chingu::GameObject
  def initialize(options)
    super(options.merge(:image => Gosu::Image["assets/laser.png"]))
    @speed = 7
    self.velocity_x = Gosu::offset_x(@angle, @speed)
    self.velocity_y = Gosu::offset_y(@angle, @speed)

  def update
    @y += self.velocity_y
    @x += self.velocity_x

How should I construct "def fire" in order to get the extra bullets to align properly when the spaceship rotates?


In the first image (above) the bullets are separated as intended.


In the second image the bullets are clumping together when the spaceship is rotated.

  • 1
    \$\begingroup\$ Can you clarify what exactly works and what doesn't or how it should work? Also, a picture or two would go a long way. \$\endgroup\$
    – ashes999
    Sep 2 '13 at 3:31
  • \$\begingroup\$ Just added pictures. The intention is to have two laser beams firing parallel to each other, perpendicular to the spaceship, at a set distance from each other, as in the first image above. When the spaceship rotates, the distance between the bullets changes. I am trying to get them to stay the same distance from each other regardless of the angle of the spaceship. \$\endgroup\$
    – mpl
    Sep 2 '13 at 4:34
  • 2
    \$\begingroup\$ Ah, I ran into this before. I think the problem is that your offset is a fixed (x, y) distance. You need to rotate it with your ship. \$\endgroup\$
    – ashes999
    Sep 2 '13 at 5:13
  • \$\begingroup\$ As ashes said. The coordinates of the fire points should be defined in the ship's coordinate system, as if they were part of the ship. \$\endgroup\$
    – Karl
    Sep 2 '13 at 5:56
  • 1
    \$\begingroup\$ I'm reasonably sure that instead of Bullet.create(:x => @x + Gosu::offset_x(90, 25), :y => @y + Gosu::offset_y(@angle, 0), :angle => @angle) you meant to write Bullet.create(:x => @x + Gosu::offset_x(@angle+90, 25), :y => @y + Gosu::offset_y(@angle+90, 25), :angle => @angle) \$\endgroup\$
    – PeterT
    Sep 2 '13 at 7:54

Here's a little explanation as to what the mistake was.

What you wanted to do is shoot a bullet that started with an offset relative to the rotation of your ship. You knew that the direction of the ship is angle, so if you want to shift it perpendicular to that and you're in the origin already then you only need to add 90° to you angle and go in that direction by whichever offset you want.

As you said, you "can use cos and sin" but you honestly already are, here's the definition of offset_x and offset_y:

double Gosu::offsetX(double angle, double radius)
    return +std::sin(angle / 180 * pi) * radius;

double Gosu::offsetY(double angle, double radius)
    return -std::cos(angle / 180 * pi) * radius;

Here's also a handy little diagram which hopefully explains it a little bit more (just pretend it's a perfect circle and the blue and black line are the same length, hehe)


  • \$\begingroup\$ You just made my day! This is super helpful and instructive for me. \$\endgroup\$
    – mpl
    Sep 5 '13 at 23:56

Not the answer you're looking for? Browse other questions tagged or ask your own question.