Ruby, OpenGL and Pixels

Posted by
December 14th, 2009 2:41 am

I used my favorite language of all time, Ruby. With 1.9 Ruby has picked up speed and with Ocra you easily make a ~1-2 meg exe-file out of it. Also the excellent (and german precision engineered)  Gosu enables OpenGL accelerated 2D. On top of that I used my own Ruby/Gosu-specific framework Chingu to get game states, re-usable game logic and a boiler plate “game object”. To get a speedy get_pixel() I used the awesome Texplay by John Mair.

I have a pixel fetish. I love retro-looks in games, and I love pixel-perfect-collisions, a fetish that probably came into existence playing hours and hours of Lemmings 2-player mode on the classic Amiga 500.

So, the most time was spent up building a good pixel-perfect-collision algo, and it came out very playable, but not perfect. I ranted about it in my last blogpost.

With Ruby and Chingu my level-building got very clean, I think even ppl not into Ruby could understand what’s happening here:

class Level7 < Level
  def setup
    self.background = "level7.bmp"
    every(1000) { Enemy.create(:image => "acid_drop.bmp", x => 150, :velocity_y => 5) }
    every(1500) { Enemy.create(:image => "acid_drop.bmp", x => 250, :velocity_y => 5) }

or here (this is from the mainloop):

player.each_collision(Enemy) do |player, enemy|
  unless player.paused?
    after(1000) {  player.x = @entry_x; player.y = @entry_y; player.unpause!; }

It’s nice when it’s silly simple building readable levels.

I also got a very basic and simple Map-class going so I could build on my matrix of screens that made up the game:

map = [
[LevelUp, nil, nil, nil],
[Level1, Level2,Level22, nil],
[LevelAir, nil, Level3, nil],
[LevelAir2, Level5, Level4, nil],
[nil, Level6, Level7, nil],
[nil, Level8, Level9, End],

Basically if you exited a screen to the right I would increment a column_counter and fetch a new screen from the matrix. If exiting downwards, increment row_counter an fetch a new screen.

If you like OO, short readable code and scripting languages in general and haven’t checked out Ruby or Gosu yet, now is the time to do it.

8 Responses to “Ruby, OpenGL and Pixels”

  1. sfernald says:

    I liked this game so much I think I’m going to try to make my own level. Since the level code is so clean, I expect this to be quite easy. We’ll see.

  2. sfernald says:

    Hey, I made a new level for your game. I has given me a chance to play around with Chingu. Must say it’s pretty cool.

    One issue I’m having is I wanted to create a small acid pit in the center of the screen. What I noticed with the pit is that it is a giant image that you rotate cover one end of the screen.

    What I wanted to do is have it cover a small area, so I wanted to shrink the image a little. I thought I could do so by adding an effect trait, which then provides the scale command. So then I add in :scale = .2 (or whatever) during the enemy creation line, but this doesn’t work.

    Do you happen to know what I’m doing wrong or what would be the best way to scale an enemy?

    • ippa says:

      I love the fact you’re taking the time to make new levels, very cool! Please lemme know when you have something finished to show off =).

      Your questions, You should use GameObject.factor = x (you also have factor_x and factor_y) .. a factor of 1 is no scaling at all. 0.5 would make the object half size, and 2 would double it. The name “factor” comes from Gosu which Chingu builds on.

      The bounding_box trait will adapt to any given factor, a tip:

      has_trait :bounding_box, :debug => true # this will show the bounding box as a red rectangle

      The effect-trait gives you GameObject.scale_rate = x (amongst others).. which will modify factor Each update() by value x. The effect-trait isn’t the most useful one as the methods it provides are pretty easy to just do yourself in GameObject.update ..

      A note, I do factor = 3 for each object in the game, to get that retro-feeling.

      Msg me on or get on #gosu @ freenode IRC if you have more question!

  3. sfernald says:

    I finished my little sequel of sorts. Here it is:

    I have no idea how to make it an stand-alone exe so feel free to do so and post it. Perhaps others would like to try some new levels to this cool little game.

    Thanks for working on this cool framework btw.

  4. ippa says:

    I love it :D.. you’ve made a better game then the original! Played through it, damn it was hard.

    I don’t know if it was intentional but on the first screen there’s a small cave in the ceiling that you can jump into to “save” your position, very smart use of the game engine. I missed something similar on the last screen, maybe after you got past the first acid-pond.

    I also liked the text-in-the-terrain, which I think could be used extensively if I make a sequel too.

    I’ll make an exe and blog about it ASAP.

  5. sfernald says:

    Very cool.

    Yeah, that “save game” was intentional. I wanted to add them to the other screens about halfway through but didn’t design them so I could.

    But it was fun, only spent a few minutes a day, building a level at a time. Had only worked with Ruby a little bit a few years ago, but it was trivial to design my own levels with your framework.

    Glad you could finish it. I wasn’t sure if I had made it too hard for anyone to finish if you didn’t know exactly what to do.

Leave a Reply

You must be logged in to post a comment.

[cache: storing page]