space_invaders 0.0.2

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.
Files changed (58) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +38 -0
  6. data/Rakefile +1 -0
  7. data/assets/fonts/unifont.ttf +0 -0
  8. data/assets/images/Bullet.png +0 -0
  9. data/assets/images/FullBlock.png +0 -0
  10. data/assets/images/InvaderA1.png +0 -0
  11. data/assets/images/InvaderA2.png +0 -0
  12. data/assets/images/InvaderB1.png +0 -0
  13. data/assets/images/InvaderB2.png +0 -0
  14. data/assets/images/InvaderC1.png +0 -0
  15. data/assets/images/InvaderC2.png +0 -0
  16. data/assets/images/OkBlock.png +0 -0
  17. data/assets/images/RedInvader.png +0 -0
  18. data/assets/images/Ship.png +0 -0
  19. data/assets/images/ShipCrushedLeft.png +0 -0
  20. data/assets/images/ShipCrushedRight.png +0 -0
  21. data/assets/images/WeakBlock.png +0 -0
  22. data/assets/sounds/InvaderBullet.wav +0 -0
  23. data/assets/sounds/InvaderHit.wav +0 -0
  24. data/assets/sounds/ShipBullet.wav +0 -0
  25. data/assets/sounds/ShipHit.wav +0 -0
  26. data/bin/space-invaders +9 -0
  27. data/go.rb +5 -0
  28. data/lib/space_invaders.rb +4 -0
  29. data/lib/space_invaders/app.rb +99 -0
  30. data/lib/space_invaders/base.rb +14 -0
  31. data/lib/space_invaders/behaviors/centerable.rb +13 -0
  32. data/lib/space_invaders/behaviors/collideable.rb +18 -0
  33. data/lib/space_invaders/behaviors/fireable.rb +35 -0
  34. data/lib/space_invaders/behaviors/mesurable.rb +17 -0
  35. data/lib/space_invaders/blocks/block.rb +62 -0
  36. data/lib/space_invaders/blocks/u_block.rb +37 -0
  37. data/lib/space_invaders/blocks/u_block_container.rb +46 -0
  38. data/lib/space_invaders/bullets/bullet.rb +46 -0
  39. data/lib/space_invaders/bullets/bullet_collection.rb +23 -0
  40. data/lib/space_invaders/invaders/invader.rb +38 -0
  41. data/lib/space_invaders/invaders/invader_abc.rb +27 -0
  42. data/lib/space_invaders/invaders/invader_row.rb +52 -0
  43. data/lib/space_invaders/invaders/invaders_container.rb +146 -0
  44. data/lib/space_invaders/invaders/red_invader.rb +66 -0
  45. data/lib/space_invaders/screens/game_over_screen.rb +42 -0
  46. data/lib/space_invaders/screens/next_level_screen.rb +39 -0
  47. data/lib/space_invaders/screens/welcome_screen.rb +46 -0
  48. data/lib/space_invaders/ship/drowned_ship_animator.rb +46 -0
  49. data/lib/space_invaders/ship/ship.rb +99 -0
  50. data/lib/space_invaders/statics/button_controller.rb +33 -0
  51. data/lib/space_invaders/statics/game_status.rb +52 -0
  52. data/lib/space_invaders/statics/images.rb +39 -0
  53. data/lib/space_invaders/statics/sounds.rb +37 -0
  54. data/lib/space_invaders/trackers/lives_tracker.rb +27 -0
  55. data/lib/space_invaders/trackers/score_tracker.rb +27 -0
  56. data/lib/space_invaders/utils.rb +19 -0
  57. data/space_invaders.gemspec +23 -0
  58. metadata +143 -0
@@ -0,0 +1,42 @@
1
+ require 'space_invaders/base'
2
+ require 'space_invaders/behaviors/centerable'
3
+
4
+ module SpaceInvaders
5
+ class GameOverScreen < Base
6
+ include Centerable
7
+
8
+ attr_reader :game_over_message, :result, :control_index, :press_play
9
+
10
+ def initialize app
11
+ super
12
+ @game_over_message = Gosu::Image.from_text app, "G A M E O V E R", App::DEFAULT_FONT, 50
13
+ @press_play = Gosu::Image.from_text app, "PRESS SPACE TO PLAY AGAIN", App::DEFAULT_FONT, 30
14
+ @press_play_counter = 0
15
+ end
16
+
17
+ def draw
18
+ set_result
19
+ horizontal_center_draw game_over_message, 100
20
+ horizontal_center_draw result, 200
21
+
22
+ horizontal_center_draw press_play, 300 if press_play_counter.between?(30,60)
23
+ update_press_play_counter
24
+ end
25
+
26
+ private
27
+
28
+ attr_reader :press_play_counter
29
+
30
+ def update_press_play_counter
31
+ if press_play_counter == 60
32
+ @press_play_counter = 0
33
+ else
34
+ @press_play_counter += 1
35
+ end
36
+ end
37
+
38
+ def set_result
39
+ @result ||= Gosu::Image.from_text app, "SCORE: #{app.score_tracker.score}", App::DEFAULT_FONT, 40
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,39 @@
1
+ require 'space_invaders/base'
2
+ require 'space_invaders/behaviors/centerable'
3
+
4
+ module SpaceInvaders
5
+ class NextLevelScreen < Base
6
+ include Centerable
7
+
8
+ attr_reader :next_level_message
9
+
10
+ def initialize app
11
+ super
12
+ @next_level_message = Gosu::Image.from_text app, "NEXT LEVEL", App::DEFAULT_FONT, 50
13
+ end
14
+
15
+ def draw
16
+ if time_passed?
17
+ timer_stop!
18
+ game_status.continue!
19
+ else
20
+ horizontal_center_draw next_level_message, 300
21
+ end
22
+ end
23
+
24
+ def timer_start!
25
+ @timeout = Time.now
26
+ end
27
+
28
+ def timer_stop!
29
+ app.invaders_container.reinitialize!
30
+ @timeout = nil
31
+ end
32
+
33
+ private
34
+
35
+ def time_passed?
36
+ Time.now - @timeout > 3
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,46 @@
1
+ require 'space_invaders/base'
2
+ require 'space_invaders/behaviors/centerable'
3
+
4
+ module SpaceInvaders
5
+ class WelcomeScreen < Base
6
+ include Centerable
7
+
8
+ attr_reader :welcome_message, :control_index, :press_play
9
+
10
+ def initialize app
11
+ super
12
+ @welcome_message = Gosu::Image.from_text app, "SpaceInvaders.rb", App::DEFAULT_FONT, 50
13
+ @control_index = Gosu::Image.from_text app, control_index_string, App::DEFAULT_FONT, 20
14
+ @press_play = Gosu::Image.from_text app, "PRESS SPACE TO PLAY", App::DEFAULT_FONT, 30
15
+ @press_play_counter = 0
16
+ end
17
+
18
+ def draw
19
+ horizontal_center_draw welcome_message, 100
20
+ horizontal_center_draw control_index, 200
21
+
22
+
23
+ horizontal_center_draw press_play, 350 if press_play_counter.between?(30,60)
24
+ update_press_play_counter
25
+ end
26
+
27
+ private
28
+
29
+ attr_reader :press_play_counter
30
+
31
+ def control_index_string
32
+ " :space => :fire \n" +
33
+ " :left_arrow => :move_left \n" +
34
+ ":right_arrow => :move_right\n"
35
+ end
36
+
37
+ def update_press_play_counter
38
+ if press_play_counter == 60
39
+ @press_play_counter = 0
40
+ else
41
+ @press_play_counter += 1
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,46 @@
1
+ module SpaceInvaders
2
+ class DrownedShipAnimator < Base
3
+
4
+ ANIMATION_LENGTH_IN_SECONDS = 2
5
+
6
+ attr_accessor :ship
7
+
8
+ def initialize(app, ship)
9
+ super(app)
10
+ @ship = ship
11
+ end
12
+
13
+ def start!
14
+ @start_time = Time.now
15
+ end
16
+
17
+ def animation_time_is_over?
18
+ passed_time > ANIMATION_LENGTH_IN_SECONDS
19
+ end
20
+
21
+ def reset!
22
+ @start_time = nil
23
+ end
24
+
25
+ def update
26
+ ship.image = if animation_time_is_over?
27
+ app.game_status.continue!
28
+ app.images.ship
29
+ elsif left_image_time?
30
+ app.images.ship_crushed_left
31
+ else
32
+ app.images.ship_crushed_right
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ def passed_time
39
+ Time.now - @start_time
40
+ end
41
+
42
+ def left_image_time?
43
+ (passed_time * 10 % 10).round.even?
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,99 @@
1
+ require 'space_invaders/ship/drowned_ship_animator'
2
+ require 'space_invaders/behaviors/mesurable'
3
+ require 'space_invaders/behaviors/collideable'
4
+ require 'space_invaders/behaviors/fireable'
5
+ module SpaceInvaders
6
+ class Ship < Base
7
+ include Mesurable
8
+ include Fireable
9
+ include Collideable
10
+
11
+ attr_accessor :lives, :image, :drowned_ship_animator
12
+
13
+ def initialize app
14
+ super
15
+ @image = app.images.ship
16
+ @x_position = app.width/2 - 40
17
+ @y_position = app.height - 50
18
+ @lives = 3
19
+ @drowned_ship_animator = DrownedShipAnimator.new app, self
20
+ end
21
+
22
+ def update
23
+ if game_status.drowned_ship?
24
+ drowned_ship_animator.update
25
+ else
26
+ if collides_with? rival_bullets
27
+ handle_collision
28
+ else
29
+ move_ship
30
+ bullet_collection.update
31
+ end
32
+ end
33
+ end
34
+
35
+ def no_more_lives?
36
+ lives == 0
37
+ end
38
+
39
+ def shooter
40
+ self
41
+ end
42
+
43
+ def sound
44
+ app.sounds.ship_bullet_sound
45
+ end
46
+
47
+ def bullets_going_down?
48
+ false
49
+ end
50
+
51
+ def bullet_offset_speed
52
+ 10
53
+ end
54
+
55
+ def draw
56
+ @image.draw @x_position, @y_position, 1
57
+ bullet_collection.draw
58
+ end
59
+
60
+ private
61
+
62
+ def rival_bullets
63
+ app.invaders_container.bullets
64
+ end
65
+
66
+ def decrease_lives!
67
+ @lives -= 1
68
+ app.lives_tracker.decrease_lives!
69
+ end
70
+
71
+ def animate_drowned_ship!
72
+ if @image == app.images.ship_crushed_left
73
+ @image = app.images.ship_crushed_right
74
+ else
75
+ @image = app.images.ship_crushed_left
76
+ end
77
+ end
78
+
79
+ def handle_collision
80
+ app.sounds.play_ship_hit!
81
+ decrease_lives!
82
+ if no_more_lives?
83
+ game_status.finished!
84
+ else
85
+ drowned_ship_animator.start!
86
+ game_status.drowned_ship!
87
+ end
88
+ end
89
+
90
+ def move_ship
91
+ if app.button_down? Gosu::KbLeft and x_position > 20
92
+ @x_position += -5
93
+ elsif app.button_down? Gosu::KbRight and x_position < app.width - 90
94
+ @x_position += 5
95
+ end
96
+ end
97
+
98
+ end
99
+ end
@@ -0,0 +1,33 @@
1
+ require 'space_invaders/base'
2
+
3
+ module SpaceInvaders
4
+ class ButtonController < Base
5
+
6
+ def button_down id
7
+ case id
8
+ when Gosu::KbEscape
9
+ escape
10
+ when Gosu::KbSpace
11
+ space
12
+ end
13
+ end
14
+
15
+ private
16
+
17
+ def escape
18
+ app.close
19
+ end
20
+
21
+ def space
22
+ if game_status.hasnt_started?
23
+ game_status.start!
24
+ elsif game_status.being_played?
25
+ app.ship.fire!
26
+ elsif game_status.finished?
27
+ app.initialize_dynamics_and_trackers
28
+ game_status.start!
29
+ end
30
+ end
31
+
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ module SpaceInvaders
2
+ class GameStatus < Base
3
+
4
+ attr_accessor :started, :finished, :drowned_ship, :next_level
5
+
6
+ alias_method :started?, :started
7
+ alias_method :finished?, :finished
8
+ alias_method :drowned_ship?, :drowned_ship
9
+ alias_method :next_level?, :next_level
10
+
11
+ def initialze app
12
+ super
13
+ @started = false
14
+ @finished = false
15
+ @drowned_ship = false
16
+ @next_level = false
17
+ end
18
+
19
+ def being_played?
20
+ started? && !drowned_ship && !next_level? && !finished?
21
+ end
22
+
23
+ def hasnt_started?
24
+ not started?
25
+ end
26
+
27
+ def next_level!
28
+ @next_level = true
29
+ end
30
+
31
+ def start!
32
+ @started = true
33
+ @finished = false
34
+ end
35
+
36
+ def finished!
37
+ @finished = true
38
+ end
39
+
40
+ def drowned_ship!
41
+ @drowned_ship = true
42
+ end
43
+
44
+ def continue!
45
+ @drowned_ship = false
46
+ @next_level = false
47
+ end
48
+
49
+ def status
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,39 @@
1
+ require 'space_invaders/base'
2
+ require 'space_invaders/utils'
3
+
4
+ module SpaceInvaders
5
+ class Images < Base
6
+
7
+ IMAGES = [ :invader_a1,
8
+ :invader_a2,
9
+ :invader_b1,
10
+ :invader_b2,
11
+ :invader_c1,
12
+ :invader_c2,
13
+ :red_invader,
14
+ :ship,
15
+ :ship_crushed_left,
16
+ :ship_crushed_right,
17
+ :bullet,
18
+ :full_block,
19
+ :ok_block,
20
+ :weak_block
21
+ ]
22
+
23
+ IMAGES.each do |image|
24
+ define_method image do
25
+ if instance_variable_get("@#{image}").nil?
26
+ instance_variable_set("@#{image}", Gosu::Image.new(app, asset_path(image)))
27
+ end
28
+ instance_variable_get("@#{image}")
29
+ end
30
+ end
31
+
32
+ private
33
+
34
+ def asset_path(image_name)
35
+ camel_case_name = Utils.camelcase(image_name)
36
+ File.join("assets", "images", "#{camel_case_name}.png")
37
+ end
38
+ end
39
+ end
@@ -0,0 +1,37 @@
1
+ require 'space_invaders/base'
2
+ module SpaceInvaders
3
+ class Sounds < Base
4
+
5
+ def ship_hit_sound
6
+ @ship_hit_sound ||= Gosu::Sample.new(app, "assets/sounds/ShipHit.wav")
7
+ end
8
+
9
+ def ship_bullet_sound
10
+ @ship_bullet_sound ||= Gosu::Sample.new(app, "assets/sounds/ShipBullet.wav")
11
+ end
12
+
13
+ def invader_hit_sound
14
+ @invader_hit_sound ||= Gosu::Sample.new(app, "assets/sounds/InvaderHit.wav")
15
+ end
16
+
17
+ def invader_bullet_sound
18
+ @invader_bullet_sound ||= Gosu::Sample.new(app, "assets/sounds/InvaderBullet.wav")
19
+ end
20
+
21
+ def play_ship_hit!
22
+ ship_hit_sound.play volume=0.5
23
+ end
24
+
25
+ def play_ship_fire!
26
+ ship_bullet_sound.play volume=0.05
27
+ end
28
+
29
+ def play_invader_hit!
30
+ invader_hit_sound.play volume=0.5
31
+ end
32
+
33
+ def play_invader_fire!
34
+ invader_bullet_sound.play volume=0.05
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,27 @@
1
+ module SpaceInvaders
2
+ class LivesTracker < Base
3
+
4
+ attr_reader :lives
5
+
6
+ def initialize app
7
+ @app = app
8
+ @lives = app.ship.lives
9
+ @lives_headline = Gosu::Image.from_text @app, "Lives:", App::DEFAULT_FONT, 30
10
+ set_lives_number
11
+ end
12
+
13
+ def decrease_lives!
14
+ @lives -= 1
15
+ set_lives_number
16
+ end
17
+
18
+ def set_lives_number
19
+ @lives_number = Gosu::Image.from_text @app, @lives, App::DEFAULT_FONT, 30
20
+ end
21
+
22
+ def draw
23
+ @lives_headline.draw app.width - 150, 10, 1
24
+ @lives_number.draw app.width - 50, 10, 1, 1, 1, Gosu::Color::GREEN
25
+ end
26
+ end
27
+ end