chingu 0.6.4 → 0.6.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data.tar.gz.sig CHANGED
Binary file
@@ -18,6 +18,8 @@ examples/example11.rb
18
18
  examples/example12.rb
19
19
  examples/example13.rb
20
20
  examples/example14.rb
21
+ examples/example15.rb
22
+ examples/example16.rb
21
23
  examples/example2.rb
22
24
  examples/example3.rb
23
25
  examples/example4.rb
@@ -84,6 +86,7 @@ lib/chingu/high_score_list.rb
84
86
  lib/chingu/inflector.rb
85
87
  lib/chingu/input.rb
86
88
  lib/chingu/named_resource.rb
89
+ lib/chingu/online_high_score_list.rb
87
90
  lib/chingu/parallax.rb
88
91
  lib/chingu/particle.rb
89
92
  lib/chingu/rect.rb
@@ -2,17 +2,17 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = %q{chingu}
5
- s.version = "0.6.4"
5
+ s.version = "0.6.5"
6
6
 
7
7
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
8
8
  s.authors = ["ippa"]
9
- s.date = %q{2009-11-29}
9
+ s.date = %q{2009-12-08}
10
10
  s.description = %q{OpenGL accelerated 2D game framework for Ruby.
11
11
  Builds on the awesome Gosu (Ruby/C++) which provides all the core functionality.
12
12
  It adds simple yet powerful game states, prettier input handling, deployment safe asset-handling, a basic re-usable game object and automation of common task.}
13
13
  s.email = ["ippa@rubylicio.us"]
14
14
  s.extra_rdoc_files = ["History.txt", "Manifest.txt", "benchmarks/README.txt"]
15
- s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "benchmarks/README.txt", "benchmarks/benchmark.rb", "benchmarks/benchmark3.rb", "benchmarks/benchmark4.rb", "benchmarks/benchmark5.rb", "benchmarks/benchmark6.rb", "benchmarks/meta_benchmark.rb", "benchmarks/meta_benchmark2.rb", "chingu.gemspec", "examples/example1.rb", "examples/example10.rb", "examples/example11.rb", "examples/example12.rb", "examples/example13.rb", "examples/example14.rb", "examples/example2.rb", "examples/example3.rb", "examples/example4.rb", "examples/example5.rb", "examples/example6.rb", "examples/example7.rb", "examples/example8.rb", "examples/example9.rb", "examples/game1.rb", "examples/high_score_list.yml", "examples/media/Parallax-scroll-example-layer-0.png", "examples/media/Parallax-scroll-example-layer-1.png", "examples/media/Parallax-scroll-example-layer-2.png", "examples/media/Parallax-scroll-example-layer-3.png", "examples/media/background1.png", "examples/media/bullet.png", "examples/media/bullet_hit.wav", "examples/media/circle.png", "examples/media/city1.csv", "examples/media/city1.png", "examples/media/city2.png", "examples/media/droid.bmp", "examples/media/enemy_bullet.png", "examples/media/explosion.wav", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/laser.wav", "examples/media/particle.png", "examples/media/plane.csv", "examples/media/plane.png", "examples/media/rect.png", "examples/media/ruby.png", "examples/media/saucer.csv", "examples/media/saucer.gal", "examples/media/saucer.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "examples/media/wood.png", "lib/chingu.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_ext/array.rb", "lib/chingu/fpscounter.rb", "lib/chingu/game_object.rb", "lib/chingu/game_object_list.rb", "lib/chingu/game_state.rb", "lib/chingu/game_state_manager.rb", "lib/chingu/game_states/debug.rb", "lib/chingu/game_states/edit.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/gosu_ext/image.rb", "lib/chingu/helpers/class_inheritable_accessor.rb", "lib/chingu/helpers/game_object.rb", "lib/chingu/helpers/game_state.rb", "lib/chingu/helpers/gfx.rb", "lib/chingu/helpers/input_client.rb", "lib/chingu/helpers/input_dispatcher.rb", "lib/chingu/helpers/rotation_center.rb", "lib/chingu/high_score_list.rb", "lib/chingu/inflector.rb", "lib/chingu/input.rb", "lib/chingu/named_resource.rb", "lib/chingu/parallax.rb", "lib/chingu/particle.rb", "lib/chingu/rect.rb", "lib/chingu/require_all.rb", "lib/chingu/text.rb", "lib/chingu/traits/bounding_box.rb", "lib/chingu/traits/bounding_circle.rb", "lib/chingu/traits/collision_detection.rb", "lib/chingu/traits/effect.rb", "lib/chingu/traits/retrofy.rb", "lib/chingu/traits/timer.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/window.rb"]
15
+ s.files = ["History.txt", "LICENSE", "Manifest.txt", "README.rdoc", "Rakefile", "benchmarks/README.txt", "benchmarks/benchmark.rb", "benchmarks/benchmark3.rb", "benchmarks/benchmark4.rb", "benchmarks/benchmark5.rb", "benchmarks/benchmark6.rb", "benchmarks/meta_benchmark.rb", "benchmarks/meta_benchmark2.rb", "chingu.gemspec", "examples/example1.rb", "examples/example10.rb", "examples/example11.rb", "examples/example12.rb", "examples/example13.rb", "examples/example14.rb", "examples/example15.rb", "examples/example16.rb", "examples/example2.rb", "examples/example3.rb", "examples/example4.rb", "examples/example5.rb", "examples/example6.rb", "examples/example7.rb", "examples/example8.rb", "examples/example9.rb", "examples/game1.rb", "examples/high_score_list.yml", "examples/media/Parallax-scroll-example-layer-0.png", "examples/media/Parallax-scroll-example-layer-1.png", "examples/media/Parallax-scroll-example-layer-2.png", "examples/media/Parallax-scroll-example-layer-3.png", "examples/media/background1.png", "examples/media/bullet.png", "examples/media/bullet_hit.wav", "examples/media/circle.png", "examples/media/city1.csv", "examples/media/city1.png", "examples/media/city2.png", "examples/media/droid.bmp", "examples/media/enemy_bullet.png", "examples/media/explosion.wav", "examples/media/fire_bullet.png", "examples/media/fireball.png", "examples/media/laser.wav", "examples/media/particle.png", "examples/media/plane.csv", "examples/media/plane.png", "examples/media/rect.png", "examples/media/ruby.png", "examples/media/saucer.csv", "examples/media/saucer.gal", "examples/media/saucer.png", "examples/media/spaceship.png", "examples/media/stickfigure.bmp", "examples/media/stickfigure.png", "examples/media/video_games.png", "examples/media/wood.png", "lib/chingu.rb", "lib/chingu/animation.rb", "lib/chingu/assets.rb", "lib/chingu/basic_game_object.rb", "lib/chingu/core_ext/array.rb", "lib/chingu/fpscounter.rb", "lib/chingu/game_object.rb", "lib/chingu/game_object_list.rb", "lib/chingu/game_state.rb", "lib/chingu/game_state_manager.rb", "lib/chingu/game_states/debug.rb", "lib/chingu/game_states/edit.rb", "lib/chingu/game_states/fade_to.rb", "lib/chingu/game_states/pause.rb", "lib/chingu/gosu_ext/image.rb", "lib/chingu/helpers/class_inheritable_accessor.rb", "lib/chingu/helpers/game_object.rb", "lib/chingu/helpers/game_state.rb", "lib/chingu/helpers/gfx.rb", "lib/chingu/helpers/input_client.rb", "lib/chingu/helpers/input_dispatcher.rb", "lib/chingu/helpers/rotation_center.rb", "lib/chingu/high_score_list.rb", "lib/chingu/inflector.rb", "lib/chingu/input.rb", "lib/chingu/named_resource.rb", "lib/chingu/online_high_score_list.rb", "lib/chingu/parallax.rb", "lib/chingu/particle.rb", "lib/chingu/rect.rb", "lib/chingu/require_all.rb", "lib/chingu/text.rb", "lib/chingu/traits/bounding_box.rb", "lib/chingu/traits/bounding_circle.rb", "lib/chingu/traits/collision_detection.rb", "lib/chingu/traits/effect.rb", "lib/chingu/traits/retrofy.rb", "lib/chingu/traits/timer.rb", "lib/chingu/traits/velocity.rb", "lib/chingu/window.rb"]
16
16
  s.homepage = %q{http://github.com/ippa/chingu/tree/master}
17
17
  s.rdoc_options = ["--main", "README.rdoc"]
18
18
  s.require_paths = ["lib"]
@@ -10,8 +10,8 @@ include Chingu
10
10
  class Game < Chingu::Window
11
11
  def initialize
12
12
  super(640,400)
13
- self.input = {:esc => :exit, :space => :remote_high_score, :a => :add}
14
- self.caption = "Example of Chingus HighScore class. Press Space to go to fetch high scores remotely!"
13
+ self.input = {:esc => :exit, :a => :add }
14
+ self.caption = "Example of Chingus HighScore class"
15
15
 
16
16
  @title = PulsatingText.create("HIGH SCORES", :x => $window.width/2, :y => 50, :size => 70)
17
17
 
@@ -37,53 +37,27 @@ class Game < Chingu::Window
37
37
  end
38
38
 
39
39
  create_text
40
-
41
- # @high_score_list.save_to_file # Uncomment to save list to disk
42
- end
43
-
44
- def remote_high_score
45
- game_objects.destroy_all
46
-
47
- @title = PulsatingText.create("REMOTE WEBSERVICE HIGH SCORES", :x => $window.width/2, :y => 50, :size => 30)
48
-
49
- #
50
- # :game_id is the unique ID the game has on www.gamercv.com
51
- # :user is the login for that specific game (set by owner)
52
- # :password is the password for that specific game (set by owner)
53
- #
54
- # To read a high score list only :game_id is required
55
- # To write to a high score list :user and :password is required as well
56
- #
57
- @high_score_list = HighScoreList.load_remote(:game_id => 1, :user => "chingu", :password => "chingu", :size => 10)
58
- create_text
59
40
  end
60
41
 
61
42
  def add
62
- data = {:name => "NEW", :score => 1600}
43
+ data = {:name => "NEW", :score => @high_score_list.high_scores.first[:score] + 10, :text => "from example13.rb"}
63
44
  position = @high_score_list.add(data)
64
45
  puts "Got position: #{position.to_s}"
65
46
  create_text
66
47
  end
67
48
 
68
49
  def create_text
69
- @score_texts ||= []
70
- @score_texts.each { |text| text.destroy }
50
+ Text.destroy_if { |text| text.size == 20}
71
51
 
72
52
  #
73
53
  # Iterate through all high scores and create the visual represenation of it
74
54
  #
75
55
  @high_score_list.each_with_index do |high_score, index|
76
56
  y = index * 25 + 100
77
- @score_texts << Text.create(high_score[:name], :x => 200, :y => y, :size => 20)
78
- @score_texts << Text.create(high_score[:score], :x => 400, :y => y, :size => 20)
79
- end
80
-
81
- 5.times do
82
- score = rand(20000)
83
- puts "position for possible score #{score}: #{@high_score_list.position_by_score(score)}"
84
- end
57
+ Text.create(high_score[:name], :x => 200, :y => y, :size => 20)
58
+ Text.create(high_score[:score], :x => 400, :y => y, :size => 20)
59
+ end
85
60
  end
86
-
87
61
  end
88
62
 
89
63
  #
@@ -0,0 +1,42 @@
1
+ require 'rubygems'
2
+ require File.join(File.dirname($0), "..", "lib", "chingu")
3
+ include Gosu
4
+ include Chingu
5
+
6
+ class Game < Chingu::Window
7
+ def initialize
8
+ super(640,400)
9
+ self.input = {:esc => :exit}
10
+ switch_game_state(Stuff)
11
+ end
12
+ end
13
+
14
+ class Stuff < GameState
15
+ has_trait :timer
16
+
17
+ def initialize(options = {})
18
+ super
19
+
20
+ @thing = Thing.create(:x => $window.width/2, :y => $window.height / 2 )
21
+ #every(1000) { Thing.create(:x => 200)}
22
+ every(500){ @thing.visible? ? @thing.hide! : @thing.show!}
23
+ end
24
+
25
+ def update
26
+ super
27
+ game_objects.destroy_if { |object| object.outside_window? }
28
+ end
29
+ end
30
+
31
+ class Thing < GameObject
32
+ def initialize(options = {})
33
+ super
34
+ @image = Image["circle.png"]
35
+ end
36
+
37
+ def update
38
+ #@y += 1
39
+ end
40
+ end
41
+
42
+ Game.new.show
@@ -0,0 +1,90 @@
1
+ require 'rubygems'
2
+ require File.join(File.dirname($0), "..", "lib", "chingu")
3
+ include Gosu
4
+ include Chingu
5
+
6
+ #
7
+ # Demonstrating Chingus OnlineHighScoreList-class
8
+ #
9
+ # Syncs against http://www.gamercv.com/games/1-test
10
+ #
11
+ class Game < Chingu::Window
12
+ def initialize
13
+ super(640,400)
14
+ self.input = {:esc => :exit, :a => :add, :r => :add_random}
15
+ self.caption = "OnlineHighScoreList example. Press 'A' to add a top-score, 'R' to add a random."
16
+
17
+ @title = PulsatingText.create("class OnlineHighScoreList & www.gamvercv.com", :x => $window.width/2, :y => 50, :size => 30)
18
+
19
+ #
20
+ # Load a remote high score list
21
+ #
22
+ @high_score_list = OnlineHighScoreList.load(:game_id => 1, :login => "chingu", :password => "chingu", :limit => 10)
23
+
24
+ create_text
25
+ end
26
+
27
+ def add
28
+ data = {:name => "NEW", :score => (@high_score_list[0][:score].to_i + 10), :text => "Hello from Chingus example16.rb"}
29
+ position = @high_score_list.add(data)
30
+ puts "Got position: #{position.to_s}"
31
+ create_text
32
+ end
33
+
34
+ def add_random
35
+ data = {:name => "RND", :score => @high_score_list[0][:score]-rand(100), :text => "Random from Chingus example16.rb"}
36
+ position = @high_score_list.add(data)
37
+ puts "Got position: #{position.to_s}"
38
+ create_text
39
+ end
40
+
41
+ def create_text
42
+ Text.destroy_if { |text| text.size == 20 }
43
+
44
+ #
45
+ # Iterate through all high scores and create the visual represenation of it
46
+ #
47
+ @high_score_list.each_with_index do |high_score, index|
48
+ y = index * 25 + 100
49
+ Text.create(high_score[:name], :x => 200, :y => y, :size => 20)
50
+ Text.create(high_score[:score], :x => 400, :y => y, :size => 20)
51
+ end
52
+ end
53
+ end
54
+
55
+ #
56
+ # colorful pulsating text...
57
+ #
58
+ class PulsatingText < Text
59
+ has_traits :timer, :effect
60
+ @@red = Color.new(0xFFFF0000)
61
+ @@green = Color.new(0xFF00FF00)
62
+ @@blue = Color.new(0xFF0000FF)
63
+
64
+ def initialize(text, options = {})
65
+ super(text, options)
66
+
67
+ options = text if text.is_a? Hash
68
+ @pulse = options[:pulse] || false
69
+ self.rotation_center(:center_center)
70
+ every(20) { create_pulse } if @pulse == false
71
+ end
72
+
73
+ def create_pulse
74
+ pulse = PulsatingText.create(@text, :x => @x, :y => @y, :height => @height, :pulse => true, :image => @image, :zorder => @zorder+1)
75
+ colors = [@@red, @@green, @@blue]
76
+ pulse.color = colors[rand(colors.size)].dup
77
+ pulse.mode = :additive
78
+ pulse.alpha -= 150
79
+ pulse.scale_rate = 0.002
80
+ pulse.fade_rate = -3 + rand(2)
81
+ pulse.rotation_rate = rand(2)==0 ? 0.05 : -0.05
82
+ end
83
+
84
+ def update
85
+ destroy if self.alpha == 0
86
+ end
87
+
88
+ end
89
+
90
+ Game.new.show
@@ -37,6 +37,10 @@ class FireCube < Chingu::GameObject
37
37
  @color = @blue
38
38
  end
39
39
 
40
+ def bounding_box
41
+ @box
42
+ end
43
+
40
44
  def draw
41
45
  $window.fill_rect(@box, @color)
42
46
  end
@@ -80,7 +84,11 @@ class ParticleState < Chingu::GameState
80
84
  #
81
85
  # FireCube.each_bounding_circle_collision(FireCube) do |cube1, cube2| # 30 FPS on my computer
82
86
  #
83
- # Let's see if we can optimize each_collision, starts with 19 FPS
87
+ # Let's see if we can optimize each_collision, starts with 19 FPS with radius collision
88
+ # 30 FPS by checking for radius and automatically delegate to each_bounding_circle_collision
89
+ #
90
+ # For bounding_box collision we start out with 7 FPS
91
+ # Got 8 FPS, the bulk CPU consumtion is in the rect vs rect check, not in the loops.
84
92
  #
85
93
  FireCube.each_collision(FireCube) do |cube1, cube2|
86
94
  cube1.die!
@@ -1,23 +1,34 @@
1
1
  ---
2
2
  - :name: NEW
3
- :score: 9987
3
+ :score: 10197
4
+ :text: from example13.rb
4
5
  - :name: NEW
5
- :score: 9971
6
+ :score: 10187
7
+ :text: from example13.rb
6
8
  - :name: NEW
7
- :score: 9960
9
+ :score: 10177
10
+ :text: from example13.rb
8
11
  - :name: NEW
9
- :score: 9912
12
+ :score: 10167
13
+ :text: from example13.rb
10
14
  - :name: NEW
11
- :score: 9900
15
+ :score: 10157
16
+ :text: from example13.rb
12
17
  - :name: NEW
13
- :score: 9886
18
+ :score: 10147
19
+ :text: from example13.rb
14
20
  - :name: NEW
15
- :score: 9885
21
+ :score: 10137
22
+ :text: from example13.rb
16
23
  - :name: NEW
17
- :score: 9840
24
+ :score: 10127
25
+ :text: from example13.rb
18
26
  - :name: NEW
19
- :score: 9839
27
+ :score: 10117
28
+ :text: from example13.rb
20
29
  - :name: NEW
21
- :score: 9746
30
+ :score: 10112
31
+ :text: from example13.rb
22
32
  - :name: NEW
23
- :score: 9742
33
+ :score: 10107
34
+ :text: from example13.rb
@@ -33,7 +33,7 @@ require_all "#{CHINGU_ROOT}/chingu/traits"
33
33
  require_all "#{CHINGU_ROOT}/chingu"
34
34
 
35
35
  module Chingu
36
- VERSION = "0.6.4"
36
+ VERSION = "0.6.5"
37
37
 
38
38
  DEBUG_COLOR = Gosu::Color.new(0xFFFF0000)
39
39
  DEBUG_ZORDER = 9999
@@ -27,12 +27,8 @@ module Chingu
27
27
  # - Add, delete, clear highscores
28
28
  # - Iterate through highscores with simple HighScores#each
29
29
  #
30
- # Working with the high score list:
31
- # ...as a local file requires gem 'yaml'
32
- # ...as a remote gamercv.com resource requires gem 'crack' and 'rest_client'
33
- #
34
30
  class HighScoreList
35
- attr_reader :file
31
+ attr_reader :file, :high_scores
36
32
 
37
33
  #
38
34
  # Create a new high score list with 0 entries
@@ -41,13 +37,6 @@ module Chingu
41
37
  @file = options[:file] || "high_score_list.yml"
42
38
  @size = options[:size] || 100
43
39
  @sort_on = options[:sort_on] || :score
44
-
45
- @user = options[:user]
46
- @password = options[:password]
47
- @game_id = options[:game_id]
48
- @server = "http://api.gamercv.com"
49
- @resource = nil
50
-
51
40
  @high_scores = Array.new
52
41
  end
53
42
 
@@ -62,12 +51,6 @@ module Chingu
62
51
  return high_score_list
63
52
  end
64
53
 
65
- def self.load_remote(options = {})
66
- high_score_list = HighScoreList.new(options)
67
- high_score_list.load_remote
68
- return high_score_list
69
- end
70
-
71
54
  #
72
55
  # Adda a new high score to the local file
73
56
  # 'data' is a hash of key/value-pairs that needs to contain at least the keys :name and :score
@@ -76,35 +59,12 @@ module Chingu
76
59
  def add(data)
77
60
  raise "No :name value in high score!" if data[:name].nil?
78
61
  raise "No :score value in high score!" if data[:score].nil?
79
- @resource ? add_remote(data) : add_local(data)
62
+ add_to_list(force_symbol_hash(data))
63
+ save_to_file
80
64
  position_by_score(data[:score])
81
65
  end
82
66
  alias << add
83
67
 
84
- #
85
- # POSTs a new high score to the remote web service
86
- #
87
- def add_remote(data)
88
- begin
89
- @res = @resource.post({:high_score => data})
90
- data = Crack::XML.parse(@res)
91
- add_to_list(force_symbol_hash(data["high_score"]))
92
- rescue RestClient::RequestFailed
93
- puts "RequestFailed: couldn't add high score"
94
- rescue RestClient::Unauthorized
95
- puts "Unauthorized to add high score (check :user and :password arguments)"
96
- end
97
- end
98
-
99
- #
100
- # Adds a new high score to local file
101
- # Returns the position it got in the list, with 1 beeing the first positions
102
- #
103
- def add_local(data)
104
- add_to_list(force_symbol_hash(data))
105
- save_to_file
106
- end
107
-
108
68
  #
109
69
  # Returns the position of full data-hash data entry, used internally
110
70
  #
@@ -121,7 +81,7 @@ module Chingu
121
81
  def position_by_score(score)
122
82
  position = 1
123
83
  @high_scores.each do |high_score|
124
- return position if score > high_score[:score]
84
+ return position if score >= high_score[:score]
125
85
  position += 1
126
86
  end
127
87
  return nil
@@ -135,37 +95,6 @@ module Chingu
135
95
  @high_scores = @high_scores[0..@size]
136
96
  end
137
97
 
138
- #
139
- # Load data from remove web service.
140
- # Under the hood, this is accomplished through a simple REST-interface
141
- # The returned XML-data is converted into a simple Hash (@high_scores), which is also returned from this method.
142
- #
143
- def load_remote
144
- raise "You need to specify a Game_id to load a remote high score list" unless defined?(@game_id)
145
- raise "You need to specify a User to load a remote high score list" unless defined?(@user)
146
- raise "You need to specify a Password to load a remote high score list" unless defined?(@password)
147
-
148
- require 'rest_client'
149
- require 'crack/xml'
150
- @resource = RestClient::Resource.new "#{@server}/games/#{@game_id}/high_scores", :user => @user, :password => @password, :timeout => 20, :open_timeout => 5
151
-
152
- @high_scores.clear
153
- begin
154
- res = @resource.get
155
- data = Crack::XML.parse(res)
156
- if data["high_scores"]
157
- data["high_scores"].each do |high_score|
158
- @high_scores.push(force_symbol_hash(high_score))
159
- end
160
- end
161
- rescue RestClient::ResourceNotFound
162
- puts "Couldn't find Resource, did you specify a correct :game_id ?"
163
- end
164
-
165
- @high_scores = @high_scores[0..@size]
166
- return @high_scores
167
- end
168
-
169
98
  #
170
99
  # Direct access to invidual high scores
171
100
  #
@@ -0,0 +1,167 @@
1
+ #--
2
+ #
3
+ # Chingu -- OpenGL accelerated 2D game framework for Ruby
4
+ # Copyright (C) 2009 ippa / ippa@rubylicio.us
5
+ #
6
+ # This library is free software; you can redistribute it and/or
7
+ # modify it under the terms of the GNU Lesser General Public
8
+ # License as published by the Free Software Foundation; either
9
+ # version 2.1 of the License, or (at your option) any later version.
10
+ #
11
+ # This library is distributed in the hope that it will be useful,
12
+ # but WITHOUT ANY WARRANTY; without even the implied warranty of
13
+ # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14
+ # Lesser General Public License for more details.
15
+ #
16
+ # You should have received a copy of the GNU Lesser General Public
17
+ # License along with this library; if not, write to the Free Software
18
+ # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19
+ #
20
+ #++
21
+
22
+ module Chingu
23
+ #
24
+ # Online high score list, remotely synced to www.gamvercv.com's RESTful web api.
25
+ #
26
+ # - fetch high scores, add new ones
27
+ # - Iterate through highscores with each and each_with_index
28
+ #
29
+ # Requires gems 'crack' and 'rest_client', included on initialize.
30
+ #
31
+ class OnlineHighScoreList
32
+ attr_reader :resource, :high_scores
33
+
34
+ def initialize(options = {})
35
+ @limit = options[:limit] || 100
36
+ @sort_on = options[:sort_on] || :score
37
+ @login = options[:login] || options[:user]
38
+ @password = options[:password]
39
+ @game_id = options[:game_id]
40
+
41
+ require 'rest_client'
42
+ require 'crack/xml'
43
+ @resource = RestClient::Resource.new("http://api.gamercv.com/games/#{@game_id}/high_scores",
44
+ :user => @login, :password => @password, :timeout => 20, :open_timeout => 5)
45
+
46
+ @high_scores = Array.new # Keeping a local copy in a ruby array
47
+ end
48
+
49
+ #
50
+ # Create a new high score list and try to load content from :file-parameter
51
+ # If no :file is given, HighScoreList tries to load from file "high_score_list.yml"
52
+ #
53
+ def self.load(options = {})
54
+ high_score_list = OnlineHighScoreList.new(options)
55
+ high_score_list.load
56
+ return high_score_list
57
+ end
58
+
59
+ #
60
+ # POSTs a new high score to the remote web service
61
+ #
62
+ # 'data' is a hash of key/value-pairs that can contain
63
+ # :name - player-name, could be "AAA" or "Aaron Avocado"
64
+ # :score - the score
65
+ # :text - free text, up to 255 chars,
66
+ #
67
+ # Returns the position the new score got in the high score list.
68
+ # return 1 for number one spot. returns -1 if it didn't quallify as a high scores.
69
+ #
70
+ def add(data)
71
+ raise "No :name value in high score!" if data[:name].nil?
72
+ raise "No :score value in high score!" if data[:score].nil?
73
+ begin
74
+ @res = @resource.post({:high_score => data})
75
+ data = Crack::XML.parse(@res)
76
+ add_to_list(force_symbol_hash(data["high_score"]))
77
+ rescue RestClient::RequestFailed
78
+ puts "RequestFailed: couldn't add high score"
79
+ rescue RestClient::ResourceNotFound
80
+ return -1
81
+ rescue RestClient::Unauthorized
82
+ puts "Unauthorized to add high score (check :login and :password arguments)"
83
+ end
84
+ return data["high_score"]["position"]
85
+ end
86
+ alias << add
87
+
88
+ #
89
+ # Returns the position 'score' would get in among the high scores:
90
+ # @high_score_list.position_by_score(999999999) # most likely returns 1 for the number one spot
91
+ # @high_score_list.position_by_score(1) # most likely returns nil since no placement is found (didn't make it to the high scores)
92
+ #
93
+ def position_by_score(score)
94
+ position = 1
95
+ @high_scores.each do |high_score|
96
+ return position if score > high_score[:score]
97
+ position += 1
98
+ end
99
+ return nil
100
+ end
101
+
102
+ #
103
+ # Load data from remove web service.
104
+ # Under the hood, this is accomplished through a simple REST-interface
105
+ # The returned XML-data is converted into a simple Hash (@high_scores), which is also returned from this method.
106
+ #
107
+ def load
108
+ raise "You need to specify a Game_id to load a remote high score list" unless defined?(@game_id)
109
+ raise "You need to specify a Login to load a remote high score list" unless defined?(@login)
110
+ raise "You need to specify a Password to load a remote high score list" unless defined?(@password)
111
+
112
+ @high_scores.clear
113
+ begin
114
+ res = @resource.get
115
+ data = Crack::XML.parse(res)
116
+ if data["high_scores"]
117
+ data["high_scores"].each do |high_score|
118
+ @high_scores.push(force_symbol_hash(high_score))
119
+ end
120
+ end
121
+ rescue RestClient::ResourceNotFound
122
+ puts "Couldn't find Resource, did you specify a correct :game_id ?"
123
+ end
124
+
125
+ @high_scores = @high_scores[0..@limit-1] unless @high_scores.empty?
126
+ return @high_scores
127
+ end
128
+
129
+ #
130
+ # Direct access to @high_scores-array
131
+ #
132
+ def [](index)
133
+ @high_scores[index]
134
+ end
135
+
136
+ #
137
+ # Iterate through @high_scores-array with each
138
+ #
139
+ def each
140
+ @high_scores.each { |high_score| yield high_score }
141
+ end
142
+
143
+ #
144
+ # Iterate through @high_scores-array with each_with_index
145
+ #
146
+ def each_with_index
147
+ @high_scores.each_with_index { |high_score, index| yield high_score, index }
148
+ end
149
+
150
+ private
151
+
152
+ def add_to_list(data)
153
+ @high_scores.push(data)
154
+ @high_scores.sort! { |a, b| b[@sort_on] <=> a[@sort_on] }
155
+ @high_scores = @high_scores[0..@limit-1]
156
+ end
157
+
158
+ def force_symbol_hash(hash)
159
+ symbol_hash = {}
160
+ hash.each_pair do |key, value|
161
+ symbol_hash[key.to_sym] = value
162
+ end
163
+ return symbol_hash
164
+ end
165
+
166
+ end
167
+ end
@@ -179,8 +179,21 @@ module Chingu
179
179
  def each_collision(*klasses)
180
180
  # Make sure klasses is always an array.
181
181
  Array(klasses).each do |klass|
182
- object2_list = klass.all
183
182
 
183
+ if self.instance_methods.include?(:radius) && klass.instance_methods.include?(:radius)
184
+ self.each_bounding_circle_collision(klass) do |o1, o2|
185
+ yield o1, o2
186
+ end
187
+ next
188
+ end
189
+
190
+ if self.instance_methods.include?(:bounding_box) && klass.instance_methods.include?(:bounding_box)
191
+ self.each_bounding_box_collision(klass) do |o1, o2|
192
+ yield o1, o2
193
+ end
194
+ next
195
+ end
196
+
184
197
  #
185
198
  # Possible optimization, look into later.
186
199
  #
@@ -195,8 +208,7 @@ module Chingu
195
208
  # end
196
209
  # end
197
210
  #end
198
-
199
-
211
+ object2_list = klass.all
200
212
  self.all.each do |object1|
201
213
  object2_list.each do |object2|
202
214
  next if object1 == object2 # Don't collide objects with themselves
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: chingu
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.4
4
+ version: 0.6.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - ippa
@@ -30,7 +30,7 @@ cert_chain:
30
30
  hxtMlw==
31
31
  -----END CERTIFICATE-----
32
32
 
33
- date: 2009-11-29 00:00:00 +01:00
33
+ date: 2009-12-08 00:00:00 +01:00
34
34
  default_executable:
35
35
  dependencies:
36
36
  - !ruby/object:Gem::Dependency
@@ -78,6 +78,8 @@ files:
78
78
  - examples/example12.rb
79
79
  - examples/example13.rb
80
80
  - examples/example14.rb
81
+ - examples/example15.rb
82
+ - examples/example16.rb
81
83
  - examples/example2.rb
82
84
  - examples/example3.rb
83
85
  - examples/example4.rb
@@ -144,6 +146,7 @@ files:
144
146
  - lib/chingu/inflector.rb
145
147
  - lib/chingu/input.rb
146
148
  - lib/chingu/named_resource.rb
149
+ - lib/chingu/online_high_score_list.rb
147
150
  - lib/chingu/parallax.rb
148
151
  - lib/chingu/particle.rb
149
152
  - lib/chingu/rect.rb
metadata.gz.sig CHANGED
Binary file