Git Product home page Git Product logo

chingu's Introduction

CHINGU

github.com/ippa/chingu/tree/master

DOCUMENTATION: rdoc.info/projects/ippa/chingu

Ruby 1.9.2 is recommended. Should also work with 1.8.7+. Chingu development is mostly conducted using Win7 / Ruby 1.9.2.

DESCRIPTION

OpenGL accelerated 2D game framework for Ruby. Builds on the awesome Gosu (Ruby/C++) which provides all the core functionality. It adds simple yet powerful game states, pretty input handling, deployment safe asset-handling, a basic re-usable game object and automation of common task.

INSTALL

gem install chingu

QUICK START (TRY OUT THE EXAMPLES)

Chingu comes with 25+ examples demonstrating various parts of Chingu. Please browse the examples-directory in the Chingu root directory. The examples start out very simple. Watch out for instructions in the windows titlebar. Could be how to move the onscreen player or how to move the example forward. Usually it’s arrowkeys and space. There’s also more complex examples, like a clone of Conways game of life (en.wikipedia.org/wiki/Conway%27s_Game_of_Life) game_of_life.rb and example21_sidescroller_with_edit.rb where You can switch between playing and editing the level itself.

PROJECTS USING CHINGU

Links to some of the projects using/depending on Chingu:

… miss your Chingu project? Msg me on github and I’ll add it to the list!

THE STORY

The last years I’ve dabbled around a lot with game development. I’ve developed games in both Rubygame and Gosu. I’ve looked at gamebox. Rubygame is a very capable framework with a lot of functionality (collision detection, very good event system etc). Gosu is way more minimalistic but also faster with OpenGL -acceleration. Gosu isn’t likely to get much more complex since it does what it should do very well and fast.

After 10+ game prototypes and some finished smaller games I started to see patterns each time I started a new game. Making classes with x/y/image/other-parameters that I called update/draw on in the main loop. This became the basic Chingu::GameObject which encapsulates Gosus “Image.draw_rot” and enables automatic updating/drawing through “game_objects”.

There was always a huge big chunk of checking keyboard-events in the main loop. Borrowing ideas from Rubygame this has now become @player.keyboard(:left => :move_left, :space => :fire … etc.

CORE OVERVIEW

Chingu consists of the following core classes / concepts:

Chingu::Window

The main window, use it at you use Gosu::Window now. Calculates the framerate, takes care of states, handles chingu-formated input, updates and draws BasicGameObject / GameObjects automatically. Available throughout your source as $window (Yes, that’s the only global Chingu has). You can also set various global settings. For example, self.factor=3, will make all fortcomming GameObjects scale 3 times.

Chingu::GameObject

Use this for all your in game objects. The player, the enemies, the bullets, the powerups, the loot laying around. It’s very reusable and doesn’t contain any game-logic (that’s up to you!). Only stuff to put it on screen a certain way. If you do GameObject.create() instead of new() Chingu will keep save the object in the “game_object”-list for automatic updates/draws. GameObjects also have the nicer Chingu input-mapping: @player.input = { :left => :move_left, :right => :move_right, :space => :fire} Has either Chingu::Window or a Chingu::GameState as “parent”.

Chingu::BasicGameObject

For those who think GameObject is a too little fat, there’s BasicGameObject (GameObject inherits from BasicGameObject). BasicGameObject is just an empty frame (no x,y,image accessors or draw-logic) for you to build on. It can be extended with Chingus trait-system though. The new() vs create() behavior of GameObject comes from BasicGameObject. BasicGameObject#parent points to either $window or a game state and is automatically set on creation time.

Chingu::GameStateManager

Keeps track of the game states. Implements a stack-based system with push_game_state and pop_game_state.

Chingu::GameState

A “standalone game loop” that can be activated and deactivated to control game flow. A game state is very much like a main gosu window. You define update() and draw() in a gamestate. It comes with 2 extras that main window doesn’t have. #setup (called when activated) and #finalize (called when deactivated)

If using game states, the flow of draw/update/button_up/button_down is: Chingu::Window –> Chingu::GameStateManager –> Chingu::GameState. For example, inside game state Menu you call push_game_state(Level). When Level exists, it will go back to Menu.

Traits

Traits are extensions (or plugins if you so will) to BasicGameObjects included on the class-level. The aim is so encapsulate common behavior into modules for easy inclusion in your game classes. Making a trait is easy, just an ordinary module with the methods setup_trait(), update_trait() and/or draw_trait(). It currently has to be namespaced to Chingu::Traits for “traits” to work inside GameObject-classes.

OTHER CLASSES / HELPERS

Chingu::Text

Makes use of Image#from_text more rubyish and powerful. In it’s core, another Chingu::GameObject + image genning with Image#from_text.

Chingu::Animation

Load and interact with tile-based animations. loop, bounce and access invidual frame(s) easily. An “@image = @animation.next” in your Player#update is usually enough to get you started!

Chingu::Parallax

A class for easy parallaxscrolling. Add layers with different damping, move the camera to generate a new snapshot. See example3.rb for more. NOTE: Doing Parallax.create when using a trait viewport will give bad results. If you need parallax together with viewport do Parallax.new and then manually doing parallax.update/draw.

Chingu::HighScoreList

A class to keep track of high scores, limit the list, automatic sorting on score, save/load to disc. See example13.rb for more.

Chingu::OnlineHighScoreList

A class to keep/sync online highscores to gamercv.com/. A lot more fun competing with others for positions then a local list.

Various Helpers

Both $window and game states gets some new graphical helpers, currently only 3, but quite useful:

fill()          # Fills whole window with color 'color'.
fill_rect()     # Fills a given Rect 'rect' with Color 'color'
fill_gradient() # Fills window or a given rect with a gradient between two colors.
draw_circle()   # Draws a circle
draw_rect()     # Draws a rect

If you base your models on GameObject (or BasicGameObject) you get:

Enemy.all                 # Returns an Array of all Enemy-instances
Enemy.size                # Returns the amount of Enemy-instances
Enemy.destroy_all         # Destroys all Enemy-instances
Enemy.destroy_if(&block)  # Destroy all objects for which &block returns true

BASICS / EXAMPLES

Chingu::Window

With Gosu the main window inherits from Gosu::Window. In Chingu we use Chingu::Window. It’s a basic Gosu::Window with extra cheese on top of it. keyboard handling, automatic update/draw calls to all gameobjects, fps counting etc.

You’re probably familiar with this very common Gosu pattern:

ROOT_PATH = File.dirname(File.expand_path(__FILE__))
class Game < Gosu::Window
  def initialize
    @player = Player.new
  end

  def update
    if button_down? Button::KbLeft
      @player.left
    elsif button_down? Button::KbRight
      @player.right
    end

    @player.update      
  end

  def draw
    @player.draw
  end
end

class Player
  attr_accessor :x,:y,:image
  def initialize(options)
    @x = options[:x]
    @y = options[:y]
    @image = Image.new(File.join(ROOT_PATH, "media", "player.png"))
  end

  def move_left
    @x -= 1
  end

  def move_right
    @x += 1
  end

  def draw
    @image.draw(@x,@y,100)
  end
end

Game.new.show   # Start the Game update/draw loop!

Chingu doesn’t change the fundamental concept/flow of Gosu, but it will make the above code shorter:

#
# We use Chingu::Window instead of Gosu::Window
#
class Game < Chingu::Window
  def initialize
    super       # This is always needed if you override Window#initialize
    #
    # Player will automatically be updated and drawn since it's a Chingu::GameObject
    # You'll need your own Chingu::Window#update and Chingu::Window#draw after a while, but just put #super there and Chingu can do its thing.
    #
    @player = Player.create
    @player.input = {:left => :move_left, :right => :move_right}
  end    
end

#
# If we create classes from Chingu::GameObject we get stuff for free.
# The accessors image,x,y,zorder,angle,factor_x,factor_y,center_x,center_y,mode,alpha.
# We also get a default #draw which draws the image to screen with the parameters listed above.
# You might recognize those from #draw_rot - http://www.libgosu.org/rdoc/classes/Gosu/Image.html#M000023
# And in it's core, that's what Chingu::GameObject is, an encapsulation of draw_rot with some extras.
# For example, we get automatic calls to draw/update with Chingu::GameObject, which usually is what you want. 
# You could stop this by doing: @player = Player.new(:draw => false, :update => false)
#
class Player < Chingu::GameObject
  def initialize(options)
    super(options.merge(:image => Image["player.png"])
  end

  def move_left
    @x -= 1
  end

  def move_right
    @x += 1
  end    
end

Game.new.show   # Start the Game update/draw loop!

Roughly 50 lines became 26 more powerful lines. (you can do @player.angle = 100 for example)

If you’ve worked with Gosu for a while you’re probably tired of passing around the window-parameter. Chingu solves this (as has many other developers) with a global variable $window. Yes, globals are bad, but in this case it kinda makes sense. It’s used under the hood in various places.

The basic flow of Chingu::Window once show() is called is this (this is called one game iteration or game loop):

- Chingu::Window#draw() is called
-- draw() is called on game objects belonging to Chingu::Window
-- draw() is called on all game objects belonging to current game state

- Chingu::Window#update() is called
-- Input for Chingu::Window is processed
-- Input for all game objects belonging to Chingu::Window is processed
-- update() is called on all game objects belonging to Chingu::Window
-- Input for current game state is processed
-- Input for game objects belonging to current game state is processed
-- update() is called on all game objects belonging to current game state

… the above is repeatet until game exists.

Chingu::GameObject

This is our basic “game unit”-class, meaning most in game objects (players, enemies, bullets etc) should be inherited from Chingu::GameObject. The basic ideas behind it are:

  • Encapsulate only the very common basics that Most in game objects need

  • Keep naming close to Gosu, but add smart convenient methods / shortcuts and a more rubyish feeling

  • No game logic allowed in GameObject, since that’s not likely to be useful for others.

It’s based around Image#draw_rot. So basically all the arguments that you pass to draw_rot can be passed to GameObject#new when creating a new object. An example using almost all arguments would be:

#
# You probably recognize the arguments from http://www.libgosu.org/rdoc/classes/Gosu/Image.html#M000023
#
@player = Player.new(:image => Image["player.png"], :x=>100, :y=>100, :zorder=>100, :angle=>45, :factor_x=>10, :factor_y=>10, :center_x=>0, :center_y=>0)

#
# A shortcut for the above line would be
#
@player = Player.new(:image => "player.png", :x=>100, :y=>100, :zorder=>100, :angle=>45, :factor=>10, :center=>0)

#
# I've tried doing sensible defaults:
# x/y = [middle of the screen]  for super quick display where it should be easy in sight)
# angle = 0                     (no angle by default)
# center_x/center_y = 0.5       (basically the center of the image will be drawn at x/y)
# factor_x/factor_y = 1         (no zoom by default)
#
@player = Player.new

#
# By default Chingu::Window calls update & draw on all GameObjects in it's own update/draw.
# If this is not what you want, use :draw and :update
#
@player = Player.new(:draw => false, :update => false)

Input

One of the core things I wanted a more natural way of inputhandling. You can define input -> actions on Chingu::Window, Chingu::GameState and Chingu::GameObject. Like this:

#
# When left arrow is pressed, call @player.turn_left ... and so on.
#
@player.input = { :left => :turn_left, :right => :turn_right, :left => :halt_left, :right => :halt_right }

#
# In Gosu the equivalent would be:
#
def button_down(id)
  @player.turn_left		if id == Button::KbLeft
  @player.turn_right	if id == Button::KbRight
end

def button_up(id)
  @player.halt_left		if id == Button::KbLeft
  @player.halt_right	if id == Button::KbRight
end

Another more complex example:

#
# So what happens here?
#
# Pressing P would create an game state out of class Pause, cache it and activate it.
# Pressing ESC would call Play#close
# Holding down LEFT would call Play#move_left on every game iteration
# Holding down RIGHT would call Play#move_right on every game iteration
# Releasing SPACE would call Play#fire
#

class Play < Chingu::GameState
  def initialize
    self.input = { :p => Pause, 
                   :escape => :close, 
                   :holding_left => :move_left, 
                   :holding_right => :move_right, 
                   :released_space => :fire }
  end
end
class Pause < Chingu::GameState
  # pause logic here
end

In Gosu the above code would include code in button_up(), button_down() and a check for button_down?() in update().

Every symbol can be prefixed by either “released_” or “holding_” while no prefix at all defaults to pressed once.

So, why not :up_space or :release_space instead of :released_space? :up_space doesn’t sound like english, :release_space sounds more like a command then an event.

Or :hold_left or :down_left instead of :holding_left? :holding_left sounds like something that’s happening over a period of time, not a single trigger, which corresponds well to how it works.

And with the default :space => :something you would imagine that :something is called once. You press :space once, :something is executed once.

GameState / GameStateManager

Chingu incorporates a basic push/pop game state system (as discussed here: www.gamedev.net/community/forums/topic.asp?topic_id=477320).

Game states is a way of organizing your intros, menus, levels.

Game states aren’t complicated. In Chingu a GameState is a class that behaves mostly like your default Gosu::Window (or in our case Chingu::Window) game loop.

# A simple GameState-example
class Intro < Chingu::GameState

  def initialize(options)
    # called as usual when class is created, load resources and simular here
  end

  def update
    # game logic here
  end

  def draw
    # screen manipulation here
  end

  # Called Each time when we enter the game state, use this to reset the gamestate to a "virgin state"
  def setup
    @player.angle = 0   # point player upwards
  end

  # Called when we leave the game state
  def finalize
    push_game_state(Menu)   # switch to game state "Menu"
  end

end

Looks familiar yet? You can activate the above game state in 2 ways

class Game < Chingu::Window
  def initialize
    #
    # 1) Create a new Intro-object and activate it (pushing to the top).
    # This version makes more sense if you want to pass parameters to the gamestate, for example:
    # push_game_state(Level.new(:level_nr => 10))
    #
    push_game_state(Intro.new)

    #
    # 2) This leaves the actual object-creation to the game state manager.
    # Intro#initialize() is called, then Intro#setup()
    #
    push_game_state(Intro)
  end
end

Another example:

class Game < Chingu::Window
  def initialize
    #
    # We start by pushing Menu to the game state stack, making it active as it's the only state on stack.
    #
    # :setup => :false will skip setup() from being called (standard when switching to a new state)
    #
    push_game_state(Menu, :setup => false)

    #
    # We push another game state to the stack, Play. We now have 2 states, which active being first / active.
    #
    # :finalize => false will skip finalize() from being called on game state
    # that's being pushed down the stack, in this case Menu.finalize().
    #
    push_game_state(Play, :finalize => false)

    #
    # Next, we remove Play state from the stack, going back to the Menu-state. But also:
    # .. skipping the standard call to Menu#setup     (the new game state)
    # .. skipping the standard call to Play#finalize  (the current game state)
    #
    # :setup => false can for example be useful when pop'ing a Pause game state. (see example4.rb)
    #
    pop_game_state(:setup => false, :finalize => :false)

    #
    # Replace the current game state with a new one.
    #
    # :setup and :finalize options are available here as well but:
    # .. setup and finalize are always skipped for Menu (the state under Play and Credits)
    # .. the finalize option only affects the popped game state
    # .. the setup option only affects the game state you're switching to
    #
    switch_game_state(Credits)
  end
end

A GameState in Chingu is just a class with the following instance methods:

  • initialize() - as you might expect, called when GameState is created.

  • setup() - called each time the game state becomes active.

  • button_down(id) - called when a button is down.

  • button_up(id) - called when a button is released.

  • update() - just as in your normal game loop, put your game logic here.

  • draw() - just as in your normal game loop, put your screen manipulation here.

  • finalize() - called when a game state de-activated (for example by pushing a new one on top with push_game_state)

Chingu::Window automatically creates a @game_state_manager and makes it accessible in our game loop. By default the game loop calls update() / draw() on the the current game state.

Chingu also has a couple of helpers-methods for handling the game states: In a main loop or in a game state:

  • push_game_state(state) - adds a new gamestate on top of the stack, which then becomes the active one

  • pop_game_state - removes active gamestate and activates the previous one

  • switch_game_state(state) - replaces current game state with a new one

  • current_game_state - returns the current game state

  • previous_game_state - returns the previous game state (useful for pausing and dialog boxes, see example4.rb)

  • pop_until_game_state(state) - pop game states until given state is found

  • clear_game_states - removes all game states from stack

To switch to a certain gamestate with a keypress use Chingus input handler:

class Intro < Chingu::GameState
  def setup
    self.input = { :space => lambda{push_gamestate(Menu.new)} }
  end
end

Or Chingus shortcut:

class Intro < Chingu::GameState
  def setup
    self.input = { :space => Menu }
  end
end

Chingus inputhandler will detect that Menu is a GameState-class, create a new instance and activate it with push_game_state().

GOTCHA: Currently you can’t switch to a new game state from Within GameState#initialize() or GameState#setup()

Premade game states

Chingu comes with some pre-made game states. A simple but usefull one is GameStates::Pause. Once pushed it will draw the previous game state but not update it – effectively pausing it. Some others are:

GameStates::EnterName

A gamestate where a gamer can select letters from a A-Z list, contructing his alias. When he’s done he selects “GO!” and a developer-specified callback will be called with the name/alias as argument.

push_game_state GameStates::EnterName.new(:callback => method(:add))

def add(name)
  puts "User entered name #{name}"
end

Combine GameStates::EnterName with class OnlineHighScoreList, a free acount @ www.gamercv.com and you have a premade stack to provide your 48h gamecompo entry with online high scores that adds an extra dimension to your game. See example16 for a full working example of this.

GameStates::Edit

The biggest and most usable is GameStates::Edit which enables fast ‘n easy level-building with game objects. Start example19 and press ’E’ to get a full example.

Edit commands / shortcuts:

F1: Help screen
1-5: create object 1..5 shown in toolbar at mousecursor
CTRL+A: select all objects (not in-code-created ones though)
CTRL+S: Save
E: Save and Quit
Q: Quit (without saving)
ESC: Deselect all objects
Right Mouse Button Click: Copy object bellow cursor for fast duplication
Arrow-keys (with selected objects): Move objects 1 pixel at the time
Arrow-keys (with no selected objects): Scroll within a viewport

Bellow keys operates on all currently selected game objects
-----------------------------------------------------------------------------------
DEL: delete selected objects
BACKSPACE: reset angle and scale to default values
Page Up: Increase zorder
Page Down: Decrease zorder

R: scale up
F: scale down
T: tilt left
G: tilt right
Y: inc zorder
H: dec zorder
U: less transparency
J: more transparency

Mouse Wheel (with no selected objects): Scroll viewport up/down
Mouse Wheel: Scale up/down
SHIFT + Mouse Wheel: Tilt left/right
CTRL + Mouse Wheel: Zorder up/down
ALT + Mouse Wheel: Transparency less/more

Move mouse cursor close to the window border to scroll a viewport if your game state has one.

If you’re editing game state BigBossLevel the editor will save to big_boss_level.yml by default. All the game objects in that file are then easily loaded with the load_game_objects command.

Both Edit.new and load_game_objects take parameters as

:file => "enemies.yml"    # Save edited game objects to file enemies.yml
:debug => true            # Will print various debugmsgs to console, usefull if something behaves oddly
:except => Player         # Don't edit or load objects based on class Player

WorkFlow

(This text is under development)

The setup-method

If a setup() is available in a instance of Chingu::GameObject, Chingu::Window and Chingu::GameState it will automatically be called. This is the perfect spot to include various setup/init-tasks like setting colors or loading animations (if you’re not using the animation-trait). You could also override initialize() for this purpose but it’s been proven prone to errors again and again. Compare the 2 snippets below:

# Easy to mess up, forgetting options or super
def initialize(options = {})
  super
  @color = Color::WHITE
end

# Less code, easier to get right and works in GameObject, Window and GameState
# Feel free to call setup() anytime, there's no magic about ut except it's autocalled once on object creation time.
def setup
  @color = Color::WHITE
end

Traits

Traits (sometimes called behaviors in other frameworks) is a way of adding logic to any class inheriting from BasicGameObject / GameObject. Chingus trait-implementation is just ordinary ruby modules with 3 special methods:

- setup_trait 
- update_trait 
- draw_trait

Each of those 3 methods must call “super” to continue the trait-chain.

Inside a certian trait-module you can also have a module called ClassMethods, methods inside that module will be added, yes you guessed it, as class methods. If initialize_trait is defined inside ClassMethods it will be called class-evaluation time (basicly on the trait :some_trait line).

A simple trait could be:

module Chingu
  module Trait
    module Inspect

      #
      # methods namespaced to ClassMethods get's extended as ... class methods!
      #
      module ClassMethods
        def initialize_trait(options)
          # possible initialize stuff here
        end

        def inspect
          "There's {self.size} active instances of class {self.to_s}"
        end
      end

      #
      # Since it's namespaced outside ClassMethods it becomes a normal instance-method
      #
      def inspect
        "Hello I'm an #{self.class.to_s}"
      end

      #
      # setup_trait is called when a object is created from a class that included the trait
      # you most likely want to put all the traits settings and option parsing here
      #
      def setup_trait(options)
        @long_inspect = true
      end

    end
  end
end

class Enemy < GameObject
  trait :inspect    # includes Chingu::Trait::Inspect and extends Chingu::Trait::Inspect::ClassMethods
end
10.times { Enemy.create }
Enemy.inspect           # => "There's 10 active instances of class Enemy"
Enemy.all.first.inspect # => "Hello I'm a Enemy"

Example of using traits :velocity and :timer. We also use GameObject#setup which will automtically be called ad the end of GameObject#initialize. It’s often a little bit cleaner to use setup() then to override initialize().

class Ogre < Chingu::GameObject
  traits :velocity, :timer

  def setup
    @red = Gosu::Color.new(0xFFFF0000)
    @white = Gosu::Color.new(0xFFFFFFFF)

    #
    # some basic physics provided by the velocity-trait
    # These 2 parameters will affect @x and @y every game-iteration
    # So if your ogre is standing on the ground, make sure you cancel out the effect of @acceleration_y
    #
    self.velocity_x = 1       # move constantly to the right
    self.acceleration_y = 0.4 # gravity is basicly a downwards acceleration
  end

  def hit_by(object)
    #
    # during() and then() is provided by the timer-trait
    # flash red for 300 millisec when hit, then go back to normal
    #
    during(100) { self.color = @red; self.mode = :additive }.then { self.color = @white; self.mode = :default }
  end
end

The flow for a game object then becomes:

-- creating a GameObject class X  ( with a "trait :bounding_box, :scale => 0.80" )
1) trait gets merged into X, instance and class methods are added
2) GameObject.initialize_trait(:scale => 0.80)   (initialize_trait is a class-method!)
-- creating an instance of X
1) GameObject#initialize(options)
2) GameObject#setup_trait(options)
3) GameObject#setup(options)
-- each game iteration
3) GameObject#draw_trait
4) GameObject#draw
5) GameObject#update_trait
6) GameObject#update

There’s a couple of traits included as default in Chingu:

Trait “sprite”

This trait fuels GameObject. A GameObject is a BasicGameObject + the sprite-trait. Adds accessors :x, :y, :angle, :factor_x, :factor_y, :center_x, :center_y, :zorder, :mode, :visible, :color. See documentation for GameObject for how it works.

Trait “timer”

Adds timer functionality to your game object

during(300) { self.color = Color.new(0xFFFFFFFF) }  # forces @color to white every update for 300 ms
after(400) { self.destroy }                         # destroy object after 400 ms
between(1000,2000) { self.angle += 10 }             # starting after 1 second, modify angleevery update during 1 second
every(2000) { Sound["bleep.wav"].play }             # play bleep.wav every 2 seconds

Trait “velocity”

Adds accessors velocity_x, velocity_y, acceleration_x, acceleration_y, max_velocity to game object. They modify x, y as you would expect. *speed / angle will come*

Trait “bounding_box”

Adds accessor ‘bounding_box’, which returns an instance of class Rect based on current image size,x,y,factor_x,factor_y,center_x,center_y You can also scale the calculated rect with trait-options:

# This would return a rect slightly smaller then the image.
# Make player think he's better @ dodging bullets then he really is ;)
trait :bounding_box, :scale => 0.80 

# Make the bounding box bigger then the image
# :debug => true shows the actual box in red on the screen
trait :bounding_box, :scale => 1.5, :debug => true

Inside your object you will also get a cache_bounding_box(). After that the bounding_box will be quicker but it will not longer adapt to size-changes.

Trait “bounding_circle”

Adds accessor ‘radius’, which returns a Fixnum based on current image size,factor_x and factor_y You can also scale the calculated radius with trait-options:

# This would return a radius slightly bigger then what initialize was calculated
trait :bounding_circle, :scale => 1.10

# :debug => true shows the actual circle in red on the screen
trait :bounding_circle, :debug => true

Inside your object you will also get a cache_bounding_circle(). After that radius() will be quicker but it will not longer adapt to size-changes.

Trait “animation”

Automatically load animations depending on the class-name. Useful when having a lot of simple classes thats mainpurpose is displaying an animation. Assuming the below code is included in a class FireBall.

#
# If a fire_ball_10x10.png/bmp exists, it will be loaded as a tileanimation.

# 10x10 would indicate the width and height of each tile so Chingu knows hows to cut it up into single frames.

# The animation will then be available in animations[:default] as an Animation-instance.
#
# If more then 1 animation exist, they'll will be loaded at the same time, for example:
# fire_ball_10x10_fly.png       # Will be available in animations[:fly] as an Animation-instance
# fire_ball_10x10_explode.png   # Will be available in animations[:explode] as an Animation-instance
#

# The below example will set the 200ms delay between each frame on all animations loaded.

#
trait :animation, :delay => 200

Trait “effect”

Adds accessors rotation_rate, fade_rate and scale_rate to game object. They modify angle, alpha and factor_x/factor_y each update. Since this is pretty easy to do yourself this trait might be up for deprecation.

Trait “viewport”

A game state trait. Adds accessor viewport. Set viewport.x and viewport.y to. Basically what viewport.x = 10 will do is draw all game objects 10 pixels to the left of their ordinary position. Since the viewport has moved 10 pixels to the right, the game objects will be seen “moving” 10 pixels to the left. This is great for scrolling games. You also have:

viewport.game_area = [0,0,1000,400]   # Set scrolling limits, the effective game world if you so will
viewport.center_around(object)        # Center viweport around an object which responds to x() and y()

viewport.lag      = 0.95              # Set a lag-factor to use in combination with x_target / y_target
viewport.x_target = 100               # This will move viewport towards X-coordinate 100, the speed is determined by the lag-parameter.

NOTE: Doing Parallax.create when using a trait viewport will give bad results. If you need parallax together with viewport do Parallax.new and then manually doing parallax.update/draw.

Trait “collision_detection”

Adds class and instance methods for basic collision detection.

# Class method example
# This will collide all Enemy-instances with all Bullet-instances using the attribute #radius from each object.
Enemy.each_bounding_circle_collision(Bullet) do |enemy, bullet|
end

# You can also use the instance methods. This will use the Rect bounding_box from @player and each EnemyRocket-object.
@player.each_bounding_box_collision(EnemyRocket) do |player, enemyrocket|
  player.die!
end

#
# each_collision automatically tries to access #radius and #bounding_box to see what a certain game object provides
# It knows how to collide radius/radius, bounding_box/bounding_box and radius/bounding_box !
# Since You're not explicity telling what collision type to use it might be slighty slower.
#
[Player, PlayerBullet].each_collision(Enemy, EnemyBullet) do |friend, foe|
  # do something
end

#
# You can also give each_collision() an array of objects.
#
Ball.each_collsion(@array_of_ground_items) do |ball, ground|
  # do something
end

Trait “asynchronous”

Allows your code to specify a GameObject’s behavior asynchronously, including tweening, movement and even method calls. Tasks are added to a queue to be processed in order; the task at the front of the queue is updated each tick and removed when it has finished.

# Simple one-trick example
# This will cause an object to move from its current location to 64,64.
@guy.async.tween :x => 64, :y => 64

# Block syntax example
# This will cause a line of text to fade out and vanish.
Chingu::Text.trait :asynchronous
message = Chingu::Text.new 'Goodbye, World!'
message.async do |q|
  q.wait 500
  q.tween 2000, :alpha => 0, :scale => 2
  q.call :destroy
end

Currently available tasks are wait(timeout, &condition), tween(timeout, properties), call(method, *arguments) and exec { … }.

For a more complete example of how to use this trait, see examples/example_async.rb.

(IN DEVELOPMENT) Trait “retrofy”

Providing easier handling of the “retrofy” effect (non-blurry zoom) Aims to help out when using zoom-factor to create a retrofeeling with big pixels. Provides screen_x and screen_y which takes the zoom into account Also provides new code for draw() which uses screen_x / screen_y instead of x / y

Assets / Paths

You might wonder why this is necessary in the straight Gosu example:

ROOT_PATH = File.dirname(File.expand_path(__FILE__))
@image = Image.new(File.join(ROOT_PATH, "media", "player.png"))

It enables you to start your game from any directory and it will still find your assets (pictures, samples, fonts etc..) correctly. For a local development version this might not be important, you’re likely to start the game from the games root-dir. But as soon as you try to deploy (for example to windows with OCRA - github.com/larsch/ocra/tree/master) you’ll run into trouble of you don’t do it like that.

Chingu solves this problem behind the scenes for the most common assets. The 2 lines above can be replaced with:

Image["player.png"]

You also have:

Sound["shot.wav"]
Song["intromusic.ogg"]
Font["arial"]          
Font["verdana", 16]     # 16 is the size of the font

The default settings are like this:

Image["image.png"] -- searches directories ".", "images", "gfx" and "media"
Sample["sample.wav"] -- searches directories ".", "sounds", "sfx" and "media"
Song["song.ogg"] -- searches directories ".", "songs", "sounds", "sfx" and "media"
Font["verdana"] -- searches directories ".", "fonts", "media"

Add your own searchpaths like this:

Gosu::Image.autoload_dirs << File.join(ROOT, "gfx")
Gosu::Sound.autoload_dirs << File.join(ROOT, "samples")

This will add pathtoyourgamegfx and pathtoyourgamesamples to Image and Sound.

Thanks to Jacious of rubygame-fame (rubygame.org/) for his named resource code powering this.

Text

Text is a class to give the use of Gosu::Font more rubyish feel and fit it better into Chingu.

# Pure Gosu

@font = Gosu::Font.new($window, "verdana", 30)
@font.draw("A Text", 200, 50, 55, 2.0)

# Chingu

@text = Chingu::Text.create("A Text", :x => 200, :y => 50, :zorder => 55, :factor_x => 2.0)
@text.draw

@text.draw is usually not needed as Text is a GameObject and therefore automatically updated/drawn (it #create is used instead of #new) It’s not only that the second example is readable by ppl now even familiar with Gosu, @text comes with a number of changeable properties, x,y,zorder,angle,factor_x,color,mode etc. Set a new x or angle or color and it will instantly update on screen.

DEPRECATIONS

Chingu (as all libraries) will sometimes break an old API. Naturally we try to not do this, but sometimes it’s nessesary to take the library forward. If your old game stops working with a new chingu it could depend on some of the following:

Listing game objects:

class Enemy < GameObject; end;
class Troll < Enemy; end;
class Witch < Enemy; end;

Chingu 0.7

Enemy.all       # Will list objects created with Enemy.create, Troll.create, Witch.create

Chingu ~0.8+

Enemy.all       # list only list objects created with Enemy.create

We gained a lot of speed breaking that API.

MISC / FAQ

How do I access my main-window easily?

Chingu keeps a global variable, $window, which contains the Chingu::Window instance. Since Chingu::Window is just Gosu::Window + some cheese you can do your $window.button_down?, $window.draw_line() etc from anywhere. See www.libgosu.org/rdoc/classes/Gosu/Window.html for a full set of methods.

How did you decide on naming of methods / classes?

There’s 1 zillion ways of naming stuff. As a general guideline I’ve tried to follow Gosus naming. If Gosu didn’t have a good name for a certain thing/method I’ve checked Ruby itself and then Rails since alot of Ruby-devs are familiar with Rails. GameObject.all is naming straight from rails for example. Most stuff in GameObject follow the naming from Gosus Image#draw_rot.

As far as possible, use correct rubyfied english game_objects, not gameobjects. class HighScore, not Highscore.

WHY?

  • Plain Gosu is very minimalistic, perfect to build some higher level logic on!

  • Deployment and asset handling should be simple

  • Managing game states/scenes (intros, menus, levels etc) should be simple

  • There are a lot patterns in game development

OPINIONS

  • Less code is usually better

  • Hash arguments FTW. And it becomes even better in 1.9.

  • Don’t separate too much from Gosus core-naming

CREDITS:

  • Spooner (input-work, tests and various other patches)

  • Jacob Huzak (sprite-trait, tests etc)

  • Jacius of Rubygame (For doing cool stuff that’s well documented as re-usable). So far rect.rb and named_resource.rb is straight outta Rubygame.

  • Banister (of texplay fame) for general feedeback and help with ruby-internals and building the trait-system

  • Jduff for input / commits

  • Jlnr,Philomory,Shawn24,JamesKilton for constructive feedback/discussions

  • Ariel Pillet for codesuggestions and cleanups

  • Deps for making the first real full game with Chingu (and making it better in the process)

  • Thanks to github.com/tarcieri for require_all code, good stuff

.. Did I forget anyone here? Msg me on github.

REQUIREMENTS:

  • Gosu, preferable the latest version

  • Ruby 1.9.1+ or 1.8.7+

  • gem ‘texplay’ for some bonus Image-pixel operations, not needed otherwise

TODO - this list is Discontinued and no longer updated!

  • add :padding and :align => :topleft etc to class Text

  • (skip) rename Chingu::Window so ‘include Chingu’ and ‘include Gosu’ wont make Window collide

  • (done) BasicObject vs GameObject vs ScreenObject => Became BasicGameObject and GameObject

  • (50%) some kind of componentsystem for GameObject (which should be cleaned up)

  • (done) scale <–> growth parameter. See trait “effect”

  • (done) Enemy.all … instead of game_objects_of_type(Enemy) ? could this be cool / understandable?

  • (done) Don’t call .update(time) with timeparameter, make time available thru other means when needed.

  • (10% done) debug screen / game state.. check out shawn24’s elite irb sollution :)

  • (done) Complete the input-definitions with all possible inputs (keyboard, gamepad, mouse)!

  • (done) Complete input-stuff with released-states etc

  • (done) More gfx effects, for example: fade in/out to a specific color (black makes sense between levels).

  • (posted request on forums) Summon good proven community gosu snippets into Chingu

  • (done) Generate docs @ ippa.github.com- rdoc.info/projects/ippa/chingu !

  • (done) A good scene-manager to manage welcome screens, levels and game flow- GameStateManager / GameState !

  • (20% done) make a playable simple game in examples\ that really depends on game states

  • (done) Make a gem- first gem made on github

  • (done) Automate gemgenning rake-task even more

  • (done) More examples when effects are more complete

  • class ChipmunkObject

  • (done) class Actor/MovingActor with maybe a bit more logic then the basic GameObject.

  • (60% done) Spell check all docs, sloppy spelling turns ppl off. tnx jduff ;).

  • Tests

  • (done) Streamline fps / tick code

  • (done) Encapsulate Font.new / draw_rot with a “class Text < GameObject”

  • (10% done) Make it possible for ppl to use the parts of Chingu they like

  • (done) At least make GameStateManager really easy to use with pure Gosu / Document it!

  • (50% done) Get better at styling rdocs

  • (done) all “gamestate” -> “game state”

  • (skipping) intergrate MovieMaker - solve this with traits instead.

  • A more robust game state <-> game_object system to connect them together.

  • FIX example4: :p => Pause.new would Change the “inside_game_state” to Pause and make @player belong to Pause.

Old History, now deprecated:

0.6 / 2009-11-21

More traits, better input, fixes This file is deprecated – see github commit-history instead!

0.5.7 / 2009-10-15

See github commithistory.

0.5 / 2009-10-7

Big refactor of GameObject. Now has BasicGameObject as base. A first basic “trait”-system where GameObject “has_traits :visual, :velocity” etc. Tons of enhancements and fixes. Speed optimization. More examples.

0.4.5 / 2009-08-27

Tons of small fixes across the board. Started on GFX Helpers (fill, fill_rect, fill_gradient so far). A basic particle system (see example7.rb)

0.4.0 / 2009-08-19

Alot of game state love. Now also works stand alone with pure gosu.

0.3.0 / 2009-08-14

Too much to list. remade inputsystem. gamestates are better. window.rb is cleaner. lots of small bugfixes. Bigger readme.

0.2.0 / 2009-08-10

tons of new stuff and fixes. complete keymap. gamestate system. moreexamples/docs. better game_object.

0.0.1 / 2009-08-05

first release

"If you program and want any longevity to your work, make a game. 
All else recycles, but people rewrite architectures to keep games alive.", _why

chingu's People

Contributors

adamsanderson avatar bil-bas avatar erisdev avatar flipcoder avatar fowlmouth avatar jduff avatar judofyr avatar kgraves avatar krzyzak avatar natedanner avatar painted-fox avatar pvan avatar russplaysguitar avatar sirbrillig avatar spilth avatar thorncp avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

chingu's Issues

Bounding boxes are too large

Bounding boxes are one pixel too big on right and bottom side.
Width should be "left + width - 1", not "left + width".

Weird Input Behaviour

Basically

:holding_left,up, right. down works perfectly
but
if you try
:holding_a ( or any letter ) it will not call the method with the same name, or any name for that matters. ( but in the case of having the same method name as the input, it will complain if it's not here, which is good and as expected )

It's just not calling the action as it should, or not detecting the hold for that key...

autoload_dirs does not affect loading (0.7.6.6)

Image::autoload_dirs and Sample::autoload_dirs methods do not correctly connect to the class instance variable used to autoload assets. Instead, they return a regular class variable (@@autoload_dirs) which is always an empty array and is not the same array as the one used to load assets, so altering it has no effect.

Chingu doesn't install with new Ruby 2.0

I guess the issue is the dependency on Gosu. This is on Windows 7:

C:\Users\Scott>gem install chingu
Fetching: gosu-0.7.45.gem (100%)
ERROR:  Error installing chingu:
        The 'gosu' native gem requires installed build tools.

Please update your PATH to include build tools or download the DevKit
from 'http://rubyinstaller.org/downloads' and follow the instructions
at 'http://github.com/oneclick/rubyinstaller/wiki/Development-Kit'

So I installed the DevKit (there were 2 other devkits, this seemed to be the latest and 64-bit, DevKit-mingw64-64-4.7.2-20130224-1432-sfx.exe).

C:\Users\Scott\Downloads\devkit>gem install chingu
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
ERROR:  Error installing chingu:
        ERROR: Failed to build gem native extension.

    C:/Ruby200-x64/bin/ruby.exe extconf.rb
This gem is not meant to be installed on Windows. Instead, please use:
gem install gosu --platform=i386-mingw32


Gem files will remain installed in C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/gosu-0.7.45 for inspection.
Results logged to C:/Ruby200-x64/lib/ruby/gems/2.0.0/gems/gosu-0.7.45/linux/gem_make.out

C:\Users\Scott\Downloads\devkit>gem install gosu --platform=x64-mingw32
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
ERROR:  Error installing gosu:
        ERROR: Failed to build gem native extension.

    C:/Ruby200-x64/bin/ruby.exe extconf.rb
This gem is not meant to be installed on Windows. Instead, please use:
gem install gosu --platform=i386-mingw32

I tried every permutation of x64-mingw32, i386-mingw32, i386-mingw64, etc. Nothing helped.

Pass a parameter to a gamestate?

Hello, I am trying to pass a parameter to a gamestate and I can't find the way, and tried in the following ways:

switch_game_state(Play.new(parameter=100))
switch_game_state(Play, options={:parameter=>100})

but nothing. I have a simple class that inherits from Chingu::GameState, which has the method intialize(parameter).

Any help?

.exe of my game?

Hi, there is a way to create a .exe of my game? That is, just click on the .exe and run the game without Chingu or ruby installed. I mean something like Ocra and Gosu. I tried to create a .exe of a game in Chingu with Ocra and I get errors, not executed. And if it can, as I do? What I need?.

load_game_objects

I don't know if I'm doing something wrong but the editor works like magic. The saved yml file is like this


  • Tiles::Wall
    :x ...

but when I try to load the saved yml file it says: Couldn't create class 'Tiles::Wall'

I thought it might be an issue in the save/load objects code.

Text #width/#height give unexpected values based on factor (0.7.6.6)

For Text objects, #width returns a value affected by scaling factor and #height/#size returns the absolute height, unaffected by scaling. This did confuse me for a while.

For consistency with retrofied Image, could be implemented as #width (unaffected by scaling), #height/#size (as now), #screen_width (as current #width) and #screen_height (height affected by factor). Alternatively, #width and #height being the actual screen sizes and a #font_size to find the unscaled height of the font. Not at all sure which of those two methods is best though.

Gamepad Input Fix

You forgot to convert the to symbol the strings for the Gamepad buttons. :)

Example 7 crash with 0.8.1 version on fill_circle

Hi, I thinks that this is a minor issue, but it may help if anyone else has the same issue that I had while running the code for the example 7 with the latests released version (0.8.1).

The example makes a call to #fill_circle method, defined in Chingu::Helpers::GFX. But the 0.8.1 version doesn't have the code for that method, which makes it crash.

I just downloaded the latest version of the helper file and added to my local gem. When the newest version of the gem is released this won't be a problem anymore, I guess.

make the dependency on crack and rest-client optional

I suspect most people won't be using the online high scores list, especially for smaller projects. Would it be possible to load OnlineHighScoreList or rest-client and crack on demand?

Trying to help my cousin learn Chingu and currently the dependency on rest-client is preventing Chingu loading at all. His Ubuntu installation seems to be missing net/https.rb and none of the advice online has actually yielded a result.

Making these dependencies optional since they're used only by a small part of the library would also be nice for people who just don't want to use them to reduce system clutter.

FPS drops on Gosu Tutorial

While going through the examples, I found that on Ubuntu 14.04 the Gosu Tutorial example FPS goes from 60 to 30's/20's. The problems seems to be the on screen display of the score, once that is removed it works fine and there is not a FPS drop.

Unable to get the library working on ubuntu

Hello,
I installed chingu trought gem install chingu, and used it without a problem. But then I decided to download the code and when I do the "require", I get the following errors:

/usr/lib/ruby/1.8/rubygems/custom_require.rb:31:in gem_original_require': /home/garoe/Aptana Studio 3 Workspace/chingu/lib/chingu/gosu_ext/sample.rb:41: odd number list for Hash (SyntaxError) volume: DEFAULT_VOLUME, ^ /home/garoe/Aptana Studio 3 Workspace/chingu/lib/chingu/gosu_ext/sample.rb:41: syntax error, unexpected ':', expecting '}' volume: DEFAULT_VOLUME, ^ /home/garoe/Aptana Studio 3 Workspace/chingu/lib/chingu/gosu_ext/sample.rb:41: dynamic constant assignment from /usr/lib/ruby/1.8/rubygems/custom_require.rb:31:inrequire'
from /home/garoe/Aptana Studio 3 Workspace/chingu/lib/chingu/require_all.rb:91:in require_all' from /home/garoe/Aptana Studio 3 Workspace/chingu/lib/chingu/require_all.rb:89:ineach'
from /home/garoe/Aptana Studio 3 Workspace/chingu/lib/chingu/require_all.rb:89:in `require_all'
from /home/garoe/Aptana Studio 3 Workspace/chingu/lib/chingu.rb:38

I'm working with ruby 1.8.7 on ubuntu 11.04 64 bits. Any help is apreciated :-)

Gem Install Chingu no longer works

I tried uninstalling and re-installing various old versions of Ruby to see if I could load up some of my old video games from eight years ago. The main Gosu Gem still works okay. But I have not been able to get Chingu to install in most cases. And in the one old version of Ruby where I was able to install Chingu, I was still not able to get the games to work. In all cases I encountered loading errors. ippa, are you out there? I have posted more details on the Gosu forum. Thanks! --EagleDog

If game map is used, yaml won't be included in Ocra

Yaml is only included when a map is loaded/saved, but assuming you stop Ocra from running as far as a window opening, it won't get included unless you manually include it. Best to always require it, even if it isn't needed. Doesn't really waste any time and removes this likelihood (and yaml is a standard library, so no worries there).

Animation undefined method next.

Hello, I'm an aspiring game developer and I've chosen Gosu + Chingu libraries as my stepping stone to greater glory. I've been playing around with it for quite some time now and I really have an annoying problem with animations.

I've looked up on the animation example and tried doing the same thing, problem is I'm always getting this NoMethodError on 'next'. What might be causing this?

FadeTo transitional game state stack weirdness

I've found that with a transitional game state set, pushing a new state then popping it back results in a new copy of the previous state being pushed onto the stack. Behold my hypothetical situation:

  1. TitleScreen

push_game_state OptionsMenu
  1. OptionsMenu
  2. TitleScreen

pop_game_state
  1. TitleScreen
  2. TitleScreen

I can't quite pinpoint it, but it seems to be a logic error in either GameStateManager#pop_game_state or #switch_game_state.

latest chiungu from git fails rake tests with segmentation fault

Hello,

I'm trying to install chingu from sources on osx Lion with ruby 1.9.2p2 (installed by macports) and rake fails with a segmentation fault, can someome help me? see the message below for a detailed trace:

Chingu::GameStateManager
initial configuration
$window should have a game_state_manager
should have 0 game states
push_game_state
should change current game state
should keep last game state
/Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:179: [BUG] Segmentation fault
ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-darwin11.1.0]

-- control frame ----------
c:0052 p:0019 s:0195 b:0195 l:000194 d:000194 METHOD /Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:179
c:0051 p:0028 s:0191 b:0191 l:000177 d:000190 BLOCK /Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:195
c:0050 p:---- s:0187 b:0187 l:000186 d:000186 FINISH
c:0049 p:---- s:0185 b:0185 l:000180 d:000184 IFUNC
c:0048 p:---- s:0183 b:0183 l:000182 d:000182 CFUNC :each
c:0047 p:---- s:0181 b:0181 l:000180 d:000180 CFUNC :find
c:0046 p:0013 s:0178 b:0178 l:000177 d:000177 METHOD /Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:194
c:0045 p:0013 s:0173 b:0173 l:000172 d:000172 METHOD /Users/francescopischedda/lavoro/chingu/lib/chingu/assets.rb:50
c:0044 p:0149 s:0166 b:0166 l:000165 d:000165 METHOD /Users/francescopischedda/lavoro/chingu/lib/chingu/assets.rb:81
c:0043 p:0088 s:0159 b:0159 l:000158 d:000158 METHOD /Users/francescopischedda/lavoro/chingu/lib/chingu/game_states/pause.rb:38
c:0042 p:---- s:0155 b:0155 l:000154 d:000154 FINISH
c:0041 p:---- s:0153 b:0153 l:000152 d:000152 CFUNC :new
c:0040 p:0035 s:0150 b:0150 l:000149 d:000149 METHOD /Users/francescopischedda/lavoro/chingu/lib/chingu/game_state_manager.rb:307
c:0039 p:0043 s:0145 b:0145 l:000144 d:000144 METHOD /Users/francescopischedda/lavoro/chingu/lib/chingu/game_state_manager.rb:148
c:0038 p:0025 s:0138 b:0138 l:000137 d:000137 METHOD /Users/francescopischedda/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/forwardable.rb:182
c:0037 p:0022 s:0133 b:0133 l:001068 d:000132 BLOCK /Users/francescopischedda/lavoro/chingu/spec/chingu/game_state_manager_spec.rb:24
c:0036 p:---- s:0131 b:0131 l:000130 d:000130 FINISH
c:0035 p:---- s:0129 b:0129 l:000128 d:000128 CFUNC :instance_eval
c:0034 p:0019 s:0126 b:0126 l:000125 d:000125 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:35
c:0033 p:0014 s:0122 b:0122 l:000113 d:000121 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:70
c:0032 p:---- s:0119 b:0119 l:000118 d:000118 FINISH
c:0031 p:---- s:0117 b:0117 l:000116 d:000116 CFUNC :each
c:0030 p:0025 s:0114 b:0114 l:000113 d:000113 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:70
c:0029 p:0030 s:0110 b:0110 l:000109 d:000109 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:116
c:0028 p:0024 s:0104 b:0104 l:000095 d:000103 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:221
c:0027 p:---- s:0101 b:0101 l:000100 d:000100 FINISH
c:0026 p:---- s:0099 b:0099 l:000098 d:000098 CFUNC :each
c:0025 p:0054 s:0096 b:0096 l:000095 d:000095 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:221
c:0024 p:0039 s:0092 b:0092 l:000091 d:000091 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:145
c:0023 p:0011 s:0089 b:0089 l:001560 d:000088 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:47
c:0022 p:0024 s:0086 b:0086 l:000085 d:000085 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:107
c:0021 p:0059 s:0082 b:0082 l:001560 d:001560 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:45
c:0020 p:0071 s:0076 b:0076 l:000065 d:000075 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:294
c:0019 p:---- s:0071 b:0071 l:000070 d:000070 FINISH
c:0018 p:---- s:0069 b:0069 l:000068 d:000068 CFUNC :map
c:0017 p:0017 s:0066 b:0066 l:000065 d:000065 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:290
c:0016 p:0096 s:0062 b:0062 l:000061 d:000061 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:262
c:0015 p:0014 s:0055 b:0055 l:000046 d:000054 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:263
c:0014 p:---- s:0052 b:0052 l:000051 d:000051 FINISH
c:0013 p:---- s:0050 b:0050 l:000049 d:000049 CFUNC :map
c:0012 p:0113 s:0047 b:0047 l:000046 d:000046 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:263
c:0011 p:0014 s:0040 b:0040 l:000024 d:000039 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:24
c:0010 p:---- s:0037 b:0037 l:000036 d:000036 FINISH
c:0009 p:---- s:0035 b:0035 l:000034 d:000034 CFUNC :map
c:0008 p:0035 s:0032 b:0032 l:000024 d:000031 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:24
c:0007 p:0022 s:0029 b:0029 l:000028 d:000028 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/reporter.rb:12
c:0006 p:0113 s:0025 b:0025 l:000024 d:000024 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:21
c:0005 p:0055 s:0020 b:0020 l:000019 d:000019 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:80
c:0004 p:0101 s:0014 b:0014 l:000013 d:000013 METHOD /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:69
c:0003 p:0021 s:0007 b:0006 l:001758 d:000005 BLOCK /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:11
c:0002 p:---- s:0004 b:0004 l:000003 d:000003 FINISH

c:0001 p:0000 s:0002 b:0002 l:002518 d:002518 TOP

-- Ruby level backtrace information ----------------------------------------
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:11:in block in autorun' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:69:inrun'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/runner.rb:80:in run_in_process' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:21:inrun'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/reporter.rb:12:in report' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:24:inblock in run'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:24:in map' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/command_line.rb:24:inblock (2 levels) in run'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:263:in run' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:263:inmap'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:263:in block in run' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:262:inrun'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:290:in run_examples' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:290:inmap'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:294:in block in run_examples' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:45:inrun'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:107:in with_around_hooks' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:47:inblock in run'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example.rb:145:in run_before_each' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:221:ineval_before_eachs'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:221:in each' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/example_group.rb:221:inblock in eval_before_eachs'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:116:in run_hook' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:70:inrun_all'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:70:in each' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:70:inblock in run_all'
/Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:35:in run_in' /Users/francescopischedda/.rvm/gems/ruby-1.9.2-p290/gems/rspec-core-2.6.4/lib/rspec/core/hooks.rb:35:ininstance_eval'
/Users/francescopischedda/lavoro/chingu/spec/chingu/game_state_manager_spec.rb:24:in block (3 levels) in <module:Chingu>' /Users/francescopischedda/.rvm/rubies/ruby-1.9.2-p290/lib/ruby/1.9.1/forwardable.rb:182:inpush_game_state'
/Users/francescopischedda/lavoro/chingu/lib/chingu/game_state_manager.rb:148:in push_game_state' /Users/francescopischedda/lavoro/chingu/lib/chingu/game_state_manager.rb:307:ingame_state_instance'
/Users/francescopischedda/lavoro/chingu/lib/chingu/game_state_manager.rb:307:in new' /Users/francescopischedda/lavoro/chingu/lib/chingu/game_states/pause.rb:38:ininitialize'
/Users/francescopischedda/lavoro/chingu/lib/chingu/assets.rb:81:in []' /Users/francescopischedda/lavoro/chingu/lib/chingu/assets.rb:50:inautoload'
/Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:194:in find_file' /Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:194:infind'
/Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:194:in each' /Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:195:inblock in find_file'
/Users/francescopischedda/lavoro/chingu/lib/chingu/named_resource.rb:179:in `exist?'

-- C level backtrace information -------------------------------------------

[NOTE]
You may have encountered a bug in the Ruby interpreter or extension libraries.
Bug reports are welcome.
For details: http://www.ruby-lang.org/bugreport.html

rake aborted!
ruby -S rspec ./spec/chingu/animation_spec.rb ./spec/chingu/assets_spec.rb ./spec/chingu/basic_game_object_spec.rb ./spec/chingu/console_spec.rb ./spec/chingu/fpscounter_spec.rb ./spec/chingu/game_object_list_spec.rb ./spec/chingu/game_object_map_spec.rb ./spec/chingu/game_object_spec.rb ./spec/chingu/game_state_manager_spec.rb ./spec/chingu/helpers/input_client_spec.rb ./spec/chingu/helpers/input_dispatcher_spec.rb ./spec/chingu/helpers/options_setter_spec.rb ./spec/chingu/inflector_spec.rb ./spec/chingu/input_spec.rb ./spec/chingu/network_spec.rb ./spec/chingu/parallax_spec.rb ./spec/chingu/text_spec.rb ./spec/chingu/window_spec.rb failed

Klass.empty?

Hi, I have a question about game objects. How can I know if exist objects of a particular class? That is, I need to do something like:
if Enemy.empty?
# logic if not objects of Enemy class.
end
Could create an Array with all the enemies but do not want to create variables if not necessary. I tried with "Array(Enemy).empty?" but nothing.

Another question is that when I load a font, the console throws me this:
ERROR: failed to open './resources/8_bit_madness.ttf'
ERROR: CreateFile failed

The code is this:
@ text_starge = Text.create (: text => "# {@ starge STARGE}",: size => 25,: font => "resources/8_bit_madness.ttf")

Any help?. Thanks!

hexed drops an error on exitting (pressing ESC)

sanderson@shiny-3:~/code/hexed$ ruby hexed.rb
/usr/local/lib/ruby1.9/gems/1.9.1/gems/chingu-0.5.1/lib/chingu/helpers.rb:81:in dispatch_action': undefined methodsuperclass' for "exit":String (NoMethodError)
from /usr/local/lib/ruby1.9/gems/1.9.1/gems/chingu-0.5.1/lib/chingu/helpers.rb:30:in block in dispatch_button_down' from /usr/local/lib/ruby1.9/gems/1.9.1/gems/chingu-0.5.1/lib/chingu/helpers.rb:28:ineach'
from /usr/local/lib/ruby1.9/gems/1.9.1/gems/chingu-0.5.1/lib/chingu/helpers.rb:28:in dispatch_button_down' from /usr/local/lib/ruby1.9/gems/1.9.1/gems/chingu-0.5.1/lib/chingu/window.rb:168:inbutton_down'
from hexed.rb:167:in show' from hexed.rb:167:in

'

Stopping timers stops all timers.

name always equals itself (timer trait)

 def stop_timer(name)
     @_timers.reject! { |name, start_time, end_time, block| name == name }
     @_repeating_timers.reject! { |name, start_time, end_time, block| name == name }
  end

Swig::DirectorTypeMismatchException

I'm getting this Exception whenever I exit a program written using Chingu or the program stops for any error.

Screenshot: https://img.skitch.com/20110617-nue4kssps1qfqepb7466ww1an9.jpg

Backtrace from the problem report:

Process: ruby [25821]
Path: /Users/martin/.rvm/rubies/ruby-1.9.2-p136/bin/ruby
Identifier: ruby
Version: ??? (???)
Code Type: X86 (Native)
Parent Process: zsh [4491]

Date/Time: 2011-06-17 21:04:01.281 +1000
OS Version: Mac OS X 10.6.7 (10J869)
Report Version: 6

Interval Since Last Report: 78880 sec
Crashes Since Last Report: 87
Per-App Crashes Since Last Report: 87
Anonymous UUID: 93EBC185-888E-47E1-9F88-CF462049CB36

Exception Type: EXC_CRASH (SIGABRT)
Exception Codes: 0x0000000000000000, 0x0000000000000000
Crashed Thread: 0 Dispatch queue: com.apple.main-thread

Application Specific Information:
abort() called

Thread 0 Crashed: Dispatch queue: com.apple.main-thread
0 libSystem.B.dylib 0x95dec156 __kill + 10
1 libSystem.B.dylib 0x95dec148 kill$UNIX2003 + 32
2 libSystem.B.dylib 0x95e7e899 raise + 26
3 libSystem.B.dylib 0x95e949b8 abort + 93
4 libstdc++.6.dylib 0x901c4fda __gnu_cxx::__verbose_terminate_handler() + 433
5 libstdc++.6.dylib 0x901c317a __cxxabiv1::__terminate(void ()()) + 10
6 libstdc++.6.dylib 0x901c31ba __cxxabiv1::__unexpected(void (
)()) + 0
7 libstdc++.6.dylib 0x901c32b8 __gxx_exception_cleanup(_Unwind_Reason_Code, Unwind_Exception) + 0
8 gosu.for_1_9.bundle 0x0060a2da SwigDirector_Window::needsRedraw() const + 378
9 gosu.for_1_9.bundle 0x00656ae3 Gosu::Window::Impl::doTick(Gosu::Window&) + 307
10 com.apple.Foundation 0x98abc8d4 __NSFireTimer + 141
11 com.apple.CoreFoundation 0x953d7adb __CFRunLoopRun + 8059
12 com.apple.CoreFoundation 0x953d5464 CFRunLoopRunSpecific + 452
13 com.apple.CoreFoundation 0x953d5291 CFRunLoopRunInMode + 97
14 com.apple.HIToolbox 0x949f6e04 RunCurrentEventLoopInMode + 392
15 com.apple.HIToolbox 0x949f6bb9 ReceiveNextEventCommon + 354
16 com.apple.HIToolbox 0x949f6a3e BlockUntilNextEventMatchingListInMode + 81
17 com.apple.AppKit 0x917f278d _DPSNextEvent + 847
18 com.apple.AppKit 0x917f1fce -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 156
19 com.apple.AppKit 0x917b4247 -[NSApplication run] + 821
20 gosu.for_1_9.bundle 0x0065651c Gosu::Window::show() + 284
21 gosu.for_1_9.bundle 0x00634574 wrap_Window_show(int, unsigned long, unsigned long) + 84
22 libruby.1.9.1.dylib 0x001758e5 call_cfunc + 581 (vm_insnhelper.c:315)

Does this look like a gosu wrapper problem or an issue with Chingu?

One strange this is I'm having the problem on one Macbook but not another that is nearly identical.

regards

Martin

Parallax and Viewpoint

There is a problem when using Parallax and Viewpoint together since Parallax is GameObject but does not have @image set and therefor the draw_relative method fails:

 chingu-0.7.5/lib/chingu/game_object.rb:155:in `draw_relative': undefined method      `draw_rot' for nil:NilClass (NoMethodError)

Minimal code reproducing the issue is:

class Flying < Chingu::GameState

   trait :viewport

  def initialize(options = {})
    super
     @parallax = Chingu::Parallax.create(:x => 0, :y => 0, :rotation_center => :top_left)
  end
end


class Game < Chingu::Window
  def initialize
    switch_game_state(Flying)
  end
end

Is there something wrong with my understanding or is it an issue? AFAIK it is not fixed in master branch but I am willing to consult it and commit a fix, please let me know.

thanks

Jakub

destroy method doesn't really destroy GameObjects

How do I remove a GameObject from memory? If I create a space game and shoot an alien, I want that alien completely destroyed. So I do an alien.destroy. But his update method is still being called 60 times/second.

Parallax and Viewpoint problem!

I'm trying to use a simple parallax in a viewport example21_sidescroller_with_edit.rb similar to, but when I walk too much parallax repeated stops, these two traits are incompatible? and tested in various ways and nothing.

At first he repetipe several times but when I move a lot of stops and the only thing left is the black background of the viewport. Any help?

Sorry for the bad English :)

Basically, this is what I'm doing:

class Nivel1 < GameState
traits :viewport

def initialize(options = {})
super
self.input = {:e => :edit}
self.viewport.game_area = [0, 0, 3000, HEIGHT]

@parallax = Chingu::Parallax.create(:x => 0, :y => 0, :rotation_center => :top_left)
@parallax.add_layer(
  :image => "space.png",
  :repeat_x => true,
  :repeat_y => false,
  :damping => 5
)

load_game_objects
@player = Player.create

end

def edit
push_game_state(GameStates::Edit.new(
:grid => [32,32], #tamaño de las rejillas en el modo editor.
:classes => [
Player,
Rocks,
Water
]))
end

def update
super
self.viewport.center_around(@player)
@parallax.camera_x, @parallax.camera_y = self.viewport.x, self.viewport.y
end
end

EnterName and HighScore GameStates not working as expected

I get a black screen. Am I using these GameStates correctly?

require 'rubygems' rescue nil
$LOAD_PATH.unshift File.join(File.expand_path(__FILE__), "..", "..", "lib")
require 'chingu'
include Gosu
include Chingu

class Game < Chingu::Window
  def initialize
    super
  end
  def setup
    switch_game_state(MainState)
  end
end

class MainState < Chingu::GameState
  def initialize
    super
    $name = "Player"
    $points = 500
    $high_score_list = Chingu::HighScoreList.load(:size => 10)
    $window.push_game_state(GameStates::EnterName.new(:callback => method(:got_name)))
  end

  def got_name(name)
    $name = name
    $newscore = $high_score_list.add({name: $name, score:   $points})
    puts "Got name: #{name}"
    pop_game_state
    $window.switch_game_state(HighScores)
  end
end

class HighScores < Chingu::GameState
  def initialize
    super
    create_text
  end

  def create_text
    $high_score_list.each_with_index do |high_score, index|
      y = index * 25 + 100
      Text.create(high_score[:name], :x => 200, :y => y, :size => 20)
      Text.create(high_score[:score], :x => 400, :y => y, :size => 20)
    end
  end
end

Game.new.show

How to disable enter name gamestate once pushed to remote

This is more of a question rather than a issue, but Im wondering how I can disable the enter_name gamestate once a user has already entered and successfully added their name to the remote highscores list? My idea initially was to re-assign the input that pushed the enter_name gamestate to something else, but that doesnt seem to work? Any ideas?

Also, is there a better place to ask general questions?

Thanks!
Jacob

Error with EnterName State

I try the game state following the example 24, and it works great. Then I decided to use it after a previous state but then I got the following error : prueba.rb:24:in 'initialize': undefined method 'push_game_state' for nil:NilClass (NoMethodError). So it seems that the this state can only be pushed by Chingu::Window and not by any other state. The code that shows the error is:

class Game < Chingu::Window
  def initialize
    super(800,400,false)              # leave it blank and it will be 800,600,non fullscreen
    self.input = { :escape => :exit } # exits example on Escape    
    self.caption = "Demonstration of GameStates::EnterName"
    push_game_state(Name_Select)
  end  
end

class Name_Select < Chingu::GameState
  def initialize(options = {})
    super  
    push_game_state(GameStates::EnterName.new(:callback => method(:got_name)))
  end

  def got_name(name)
    puts "Got name: #{name}"
    exit
  end    

end  

How to listen to semicolon and quote characters

I see that chingu maps gosu's keys to nice simple symbols. But there doesn't seem to be a symbol for the semicolon or quote characters (or others I'm sure). I don't know what they would map to for gosu or if gosu takes into account those characters either.

What can I do to listen to semicolon and quote keypresses?

Problem with accessing namespaces

Hi:

/Users/piotr/.rbenv/versions/1.9.3-p0/lib/ruby/gems/1.9.1/bundler/gems/chingu-962ef58b03bc/lib/chingu/game_states/enter_name.rb:66:in `initialize': uninitialized constant Chingu::GameStates::EnterName::Color (NameError)
from /Users/piotr/Work/GitHub/apocalypse/lib/apocalypse/game_window.rb:8:in `new'
from /Users/piotr/Work/GitHub/apocalypse/lib/apocalypse/game_window.rb:8:in `initialise'

And this is the code:

require 'chingu'

module Apocalypse
  class GameWindow < Chingu::Window
    def initialize
      super

      push_game_state GameStates::EnterName.new(:callback => method(:add))
    end

    def add(name)
      puts "User entered name #{name}"
    end
  end
end

I think it would be better if Chingu address the absolute namespaces in the code e.g.:

@texts[@index].color = ::Gosu::Color::RED

instead of

@texts[@index].color = Color::RED

Rect has inconsistent method names (0.7.6.6)

Rect has somewhat unexpected method names. I can use GameObject#center_x, but have to use Rect#centerx (I know they mean different things in the two contexts, but what I am pointing out is that they are written differently). I assume the reason for this is that Rect is taken from Rubygame, rather than being created for Chingu specifically. Please add method_aliases so I can use methods such as Rect#center_x (which is what I expect to work). I personally don't think that renaming/deprecating, rather than just aliasing the existing methods, is worth the effort.

Changing state directly via input does nothing with indirect inheritance from GameState (0.7.6.6)

The input system checks to see if a class given is directly inheriting from GameState, so if you have

self.input = { :space => StartGame }

where:

StartGame < MyGameState < Chingu::GameState

then StartGame won't get recognised as a GameState (Not a priority for me since you can just use a very simple #new to get around the issue; just something I noticed). InputDispatcher.rb line 96, anyway.

EDIT: Could also raise an exception if they pass the wrong value, rather than just ignoring it.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.