chingu 0.6.4 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
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