space_invaders 0.0.2

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