Permalink
Browse files

big trait-overhaul/refactor, may break your code. replace your has_tr…

…ait with has_traits. the first now works as has_trait :trait, {options}. rewrote traits :bounding_box and :radius, partly to use the new format (try has_trait :bounding_box, :scale => 0.80, :debug => true), see updated readme for more info. shawn24 contributed an elite draw_circle(x,y,radius,color). Examples updated, game1 still in flux.
  • Loading branch information...
ippa committed Nov 20, 2009
1 parent 3626ef7 commit 8740bdecdfbcd270fb21d9177ee57acf39187b6c
View
@@ -66,7 +66,7 @@ For example, inside game state Menu you call push_game_state(Level). When Level
Traits are extensions (or plugins if you so will) to BasicGameObjects.
The aim is so encapsulate common behaivor 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 "has_trait" to work inside GameObject-classes.
+It currently has to be namespaced to Chingu::Traits for "has_traits" to work inside GameObject-classes.
== OTHER CLASSES / HELPERS
@@ -454,7 +454,7 @@ Each of those 3 methods must call "super" to continue the trait-chain.
Example:
class Ogre < Chingu::GameObject
- has_trait :velocity, :timer
+ has_traits :velocity, :timer
def initialize(options)
super
@@ -481,7 +481,10 @@ Example:
The flow for a game object then becomes:
- -- creating the object
+ -- creating a GameObject class X ( with a "has_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)
+ -- creating an instance of X
1) GameObject#initialize(options)
2) GameObject#setup_trait(options)
-- each game iteration
@@ -503,6 +506,20 @@ Adds timer functionality to your game object
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 a Rect based on current image size,x,y,factor_x,factor_y,center_x,center_y
+You can also scale the calculated rect with has_trait-options:
+
+ # This would return a rect slightly smaller then the image.
+ # Make player think he's better @ dodging bullets then he really is ;)
+ has_trait :bounding_box, :scale => 0.80
+
+==== Trait "radius"
+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 has_trait-options:
+
+ # This would return a radius slightly bigger then what initialize was calculated
+ has_trait :radius, :scale => 1.10
==== Trait "effect"
Adds accessors rotation_rate, fade_rate and scale_rate to game object.
@@ -651,3 +668,10 @@ As far as possible, use correct rubyfied english game_objects, not gameobjects.
* gem 'texplay' for some bonus Image-pixel operations, not needed otherwise
+
+
+
+ "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
+
+
View
Binary file not shown.
View
@@ -15,12 +15,12 @@ def initialize
@factor = 6
self.input = { :escape => :exit }
self.caption = "Chingu::Animation / retrofy example. Move with arrows!"
- Droid.create(:x => $window.width/@factor/2, :y => $window.height/@factor/2)
+ Droid.create(:x => $window.width/2, :y => $window.height/2)
end
end
class Droid < Chingu::GameObject
- has_trait :retrofy # modifies draw(),
+ has_traits :timer
def initialize(options = {})
super
@@ -50,22 +50,22 @@ def initialize(options = {})
end
def left
- @x -= 1
+ @x -= 2
@animation = @animations[:left]
end
def right
- @x += 1
+ @x += 2
@animation = @animations[:right]
end
def up
- @y -= 1
+ @y -= 2
@animation = @animations[:up]
end
def down
- @y += 1
+ @y += 2
@animation = @animations[:down]
end
View
@@ -90,7 +90,7 @@ def create_text
# colorful pulsating text...
#
class PulsatingText < Text
- has_trait :timer, :effect
+ has_traits :timer, :effect
@@red = Color.new(0xFFFF0000)
@@green = Color.new(0xFF00FF00)
@@blue = Color.new(0xFF0000FF)
View
@@ -0,0 +1,124 @@
+require 'rubygems'
+require File.join(File.dirname($0), "..", "lib", "chingu")
+include Gosu
+include Chingu
+
+#
+# Demonstrating Chingus HighScoreList-class
+# I couldn't keep myself from spicying it up some though :P
+#
+class Game < Chingu::Window
+ def initialize
+ super(640,400)
+ self.input = {:esc => :exit, :space => :remote_high_score, :a => :add}
+ self.caption = "Example of Chingus HighScore class. Press Space to go to fetch high scores remotely!"
+
+ @title = PulsatingText.create("HIGH SCORES", :x => $window.width/2, :y => 50, :size => 70)
+
+ #
+ # Load a list from disk, defaults to "high_score_list.yml"
+ # Argument :size forces list to this size
+ #
+ @high_score_list = HighScoreList.load(:size => 10)
+
+ #
+ # Add some new high scores to the list. :name and :score are required but you can put whatever.
+ # They will mix with the old scores, automatic default sorting on :score
+ #
+ 10.times do
+ data = {:name => "NEW", :score => rand(10000)}
+
+ position = @high_score_list.add(data)
+ if position
+ puts "#{data[:name]} - #{data[:score]} got position #{position}"
+ else
+ puts "#{data[:name]} - #{data[:score]} didn't make it"
+ end
+ end
+
+ create_text
+
+ # @high_score_list.save_to_file # Uncomment to save list to disk
+ end
+
+ def remote_high_score
+ game_objects.destroy_all
+
+ @title = PulsatingText.create("REMOTE WEBSERVICE HIGH SCORES", :x => $window.width/2, :y => 50, :size => 30)
+
+ #
+ # :game_id is the unique ID the game has on www.gamercv.com
+ # :user is the login for that specific game (set by owner)
+ # :password is the password for that specific game (set by owner)
+ #
+ # To read a high score list only :game_id is required
+ # To write to a high score list :user and :password is required as well
+ #
+ @high_score_list = HighScoreList.load_remote(:game_id => 1, :user => "chingu", :password => "chingu", :size => 10)
+ create_text
+ end
+
+ def add
+ data = {:name => "NEW", :score => 1600}
+ position = @high_score_list.add(data)
+ puts "Got position: #{position.to_s}"
+ create_text
+ end
+
+ def create_text
+ @score_texts ||= []
+ @score_texts.each { |text| text.destroy }
+
+ #
+ # Iterate through all high scores and create the visual represenation of it
+ #
+ @high_score_list.each_with_index do |high_score, index|
+ y = index * 25 + 100
+ @score_texts << Text.create(high_score[:name], :x => 200, :y => y, :size => 20)
+ @score_texts << Text.create(high_score[:score], :x => 400, :y => y, :size => 20)
+ end
+
+ 5.times do
+ score = rand(20000)
+ puts "position for possible score #{score}: #{@high_score_list.position_by_score(score)}"
+ end
+ end
+
+end
+
+#
+# colorful pulsating text...
+#
+class PulsatingText < Text
+ has_traits :timer, :effect
+ @@red = Color.new(0xFFFF0000)
+ @@green = Color.new(0xFF00FF00)
+ @@blue = Color.new(0xFF0000FF)
+
+ def initialize(text, options = {})
+ super(text, options)
+
+ options = text if text.is_a? Hash
+ @pulse = options[:pulse] || false
+ self.rotation_center(:center_center)
+ every(20) { create_pulse } if @pulse == false
+ end
+
+ def create_pulse
+ pulse = PulsatingText.create(@text, :x => @x, :y => @y, :height => @height, :pulse => true, :image => @image, :zorder => @zorder+1)
+ colors = [@@red, @@green, @@blue]
+ pulse.color = colors[rand(colors.size)].dup
+ pulse.mode = :additive
+ pulse.alpha -= 150
+ pulse.scale_rate = 0.002
+ pulse.fade_rate = -3 + rand(2)
+ pulse.rotation_rate = rand(2)==0 ? 0.05 : -0.05
+ end
+
+ def update
+ destroy if self.alpha == 0
+ end
+
+end
+
+Game.new.show
View
@@ -18,14 +18,7 @@ def next_effect; pop_game_state; end
end
class FireCube < Chingu::GameObject
- has_trait :velocity
- has_trait :collision_detection
- #
- # TODO:
- # has_trait :collision_detection, :type => :bounding_box
- # has_trait :collision_detection, :type => :radius
- #
-
+ has_traits :velocity, :collision_detection
attr_accessor :color, :radius
def initialize(options)
@@ -36,7 +29,7 @@ def initialize(options)
@velocity_x = options[:velocity_x] || 1 + rand(2)
@velocity_y = options[:velocity_y] || 1 + rand(2)
- @bounding_box = Rect.new([@x, @y, 10, 10])
+ @box = Rect.new([@x, @y, 10, 10])
@radius = 6
@blue = Color.new(255,100,255,255)
@@ -45,17 +38,14 @@ def initialize(options)
end
def draw
- $window.fill_rect(@bounding_box, @color)
+ $window.fill_rect(@box, @color)
end
def update
+ @box.x, @box.y = @x, @y
@color = @blue
end
- def collides?(object2)
- radius_collision?(object2)
- end
-
def die!
@color = @red
end
Oops, something went wrong.

0 comments on commit 8740bde

Please sign in to comment.