Search code examples
rubychipmunklibgosu

Draw a Polygon with Chipmunk and Gosu in Ruby


I am brand new to game development and I thought it would be fun to try out Gosu, Ruby and Chipmunk together. So far I have a player and a ball on a 2d Top-Down field and they collide. My problem right now is that I want my player to be a square.
I sucked at Math in high school and that was way too many years ago to think about. The documentation for Chipmunk says this about drawing a Polygon:

# Create a poly collision shape attached to the given body at
# the given offset with the given vertexes. _verts_ must be an
# Array of CP::Vect with a counterclockwise winding.
 def initialize(body, verts, offset); end

I have this code to get my polygon right now:

verts = Array.new
verts.push(CP::Vec2.new(0,32))
verts.push(CP::Vec2.new(32,32))
verts.push(CP::Vec2.new(32,0))
verts.push(CP::Vec2.new(0,0))

@shape = CP::Shape::Poly.new(@body, verts, CP::Vec2.new(0,0))

That ends up giving me a shape attached to my square png, but it appears as if 0,0 is the top, left corner of the image and the actual Polygon starts even farther to the top, left of the image.

So I assumed I should set the "Offset" to half of my width of my Polygon but that doesn't give me the right outcome.

I am sure that for most people on here this is elementary. But I am still in the elementary when it comes to game dev.
Can someone explain this to me please?

EDIT
Here is my full code as of 5/28/2011


Solution

  • Looks like your problems stem from inconsistencies between drawing and collision origins.

    In effect, your ball is drawn centered on x,y, while the player is drawn with top left corner on x,y. That coupled with your Player shape not being centered on x,y is causing you difficulties.

    To center the drawing of your player, just use the draw_rot method with an angle of 0 to avoid rotating the image.

    class Player
      def draw
        @image.draw_rot(@shape.body.pos.x, @shape.body.pos.y, 1, 0, 0.5, 0.5, 1, 1)
      end
    end
    

    To make the Chipmunk shape fit the centered player image, you need to offset your vertices by half the size of the shape. You can hardcode this doing

    class Player
      def initialize(space, image) 
        ...
        verts = Array.new
        verts.push(CP::Vec2.new(-16,16))
        verts.push(CP::Vec2.new(16,16))
        verts.push(CP::Vec2.new(16,-16))
        verts.push(CP::Vec2.new(-16,16))
        ...
      end
    end
    

    or simply do it at runtime with

    CP::recenter_poly(verts)
    

    before you add verts to your shape.

    With those changes in place I suspect your physics will behave more like you expect.