Home > Development > Java game library + JRuby + awesome DSL = Gemini

Java game library + JRuby + awesome DSL = Gemini

I’ve been working with JRuby to build high level systems on top of powerful Java libraries for about 2 years now.  My most successful endeavor has been Monkeybars, a libarary for making Swing a lot easier to use.  My other project has been in the game development arena.  The project name is Gemini, and although it’s not nearly as advanced as Monkeybars, I was able to get to a significant point over the weekend.  Yes, here in all its glory, the simple “crapton of sprites bouncing back and forth demo”.

1000 dukes bouncing back and forth on screen

Now you’re probably saying, big deal, I can do that in like 40 lines of code in <insert favorite programming language/framework> and no doubt you would be correct.  What’s interesting about the way Gemini does things is in how it gives you an extremely flexible way of compositing together your game objects and your application as a whole.

The code to get this going using Gemini is pretty straightforward.  We have a game state that is loaded by Gemini when it starts up.  That game state then instantiates 1000 of our game objects and they proceed to load their images and care for their own logic of bouncing around on the screen.

Here’s the code in main.rb that kicks off the app:

require 'gemini'
Gemini::Main.new("Test game", 640, 480)

And here is the state that is loaded by default when Gemini runs: main_state.rb

class MainState < Gemini::BaseState def load @sprites = [] 1000.times {@sprites << Duke.new} end def update(delta) @sprites.each { |sprite| sprite.update(delta) } end def render(graphics) @sprites.each { |sprite| sprite.draw } end end [/sourcecode] Finally we have the Duke class that was instantiated in the MainGame class: [sourcecode lang='ruby'] class Duke < Gemini::GameObject has_behavior :Movable2D has_behavior :Sprite has_behavior :UpdatesAtConsistantRate def load self.image = "duke.png" self.updates_per_second = 30 @direction = :right self.x = rand(640 - image.width) self.y = rand(480 - image.height) end def tick if x > (640 – image.width) || x < 0 @direction = @direction == :right ? :left : :right end self.x = x + (@direction == :right ? 1 : -1) end end [/sourcecode] Apart from some hackish ternary ifs in the Duke class I think the whole thing is pretty darn readable, especially considering all that it is doing. As you can see, everything is extremely declarative including those has_behavior calls in the Duke class. Those nifty bits of metaprogramming bring in all the crunchy goodness of the class and make the x, y, image and updates_per_second methods appear. Movable2D gives us a move method and also pulls in the Positional2D behavior that provides the x and y methods. UpdatesAtConsistantRate gives us an update method that calls tick at the rate specified by updates_per_second. Finally the Sprite behavior gives us the image method and the draw method that gets called in the MainGame class. Most of this is bare bones at the moment. What if you don't have the UpdatesAtConsistantRate? When update is called you asplode. Same for Sprite / render. So clearly a more flexible game state is needed, probably involving the game object behaviors auto-registering themselves with the game state to be called during an update/render cycle. But as a whole I'm quite happy with the way Gemini is starting to shape up. Next on the agenda is getting keyboard mapping hooked into the RecievesKeyboardEvents behavior so you can control duke, then we'll have what could pass for a real game.

Advertisements
Categories: Development Tags: , , ,
  1. slothbear
    July 27, 2008 at 5:47 am

    Very very cool! I’m gonna give it a try.

  1. July 25, 2008 at 2:17 am
  2. July 29, 2008 at 5:21 pm

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: