asteroids 0.0.1

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 (41) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +14 -0
  3. data/Gemfile +4 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +19 -0
  6. data/Rakefile +2 -0
  7. data/assets/fonts/victor-pixel.ttf +0 -0
  8. data/assets/images/asteroid.png +0 -0
  9. data/assets/images/asteroid_medium.png +0 -0
  10. data/assets/images/asteroid_small.png +0 -0
  11. data/assets/images/background.png +0 -0
  12. data/assets/images/explosion.png +0 -0
  13. data/assets/images/ship.png +0 -0
  14. data/assets/images/ship_small.png +0 -0
  15. data/assets/images/simple_missile.png +0 -0
  16. data/asteroids.gemspec +30 -0
  17. data/bin/asteroids +17 -0
  18. data/lib/asteroids.rb +28 -0
  19. data/lib/asteroids/asteroid/asteroid.rb +23 -0
  20. data/lib/asteroids/asteroid/asteroid_graphics.rb +26 -0
  21. data/lib/asteroids/asteroid/asteroid_physics.rb +51 -0
  22. data/lib/asteroids/componenets/component.rb +29 -0
  23. data/lib/asteroids/componenets/game_object.rb +37 -0
  24. data/lib/asteroids/componenets/game_pool.rb +34 -0
  25. data/lib/asteroids/explosion/explosion.rb +14 -0
  26. data/lib/asteroids/explosion/explosion_graphics.rb +48 -0
  27. data/lib/asteroids/menu/menu.rb +46 -0
  28. data/lib/asteroids/menu/menu_item.rb +55 -0
  29. data/lib/asteroids/missile/missile.rb +21 -0
  30. data/lib/asteroids/missile/missile_graphics.rb +15 -0
  31. data/lib/asteroids/missile/missile_physics.rb +42 -0
  32. data/lib/asteroids/ship/ship.rb +51 -0
  33. data/lib/asteroids/ship/ship_graphics.rb +20 -0
  34. data/lib/asteroids/ship/ship_physics.rb +58 -0
  35. data/lib/asteroids/states/game_state.rb +29 -0
  36. data/lib/asteroids/states/menu_state.rb +41 -0
  37. data/lib/asteroids/states/play_state.rb +61 -0
  38. data/lib/asteroids/utils/utils.rb +37 -0
  39. data/lib/asteroids/version.rb +3 -0
  40. data/saves/save.yaml +0 -0
  41. metadata +128 -0
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 653e006ed4b1952a181301ff0b0ebacdc6683cd5
4
+ data.tar.gz: e8426442c2d7eb1e8a94e2b158e59305258bff9e
5
+ SHA512:
6
+ metadata.gz: c34ba4d438fe0304320a429c7c82ea5fed1d6f7e56b54d40fed78b3352a6a071e71020ccfdbc007ea8008a4b3e4bb49b5b0405706728391c8a1b0111c2b546b1
7
+ data.tar.gz: 7ade9c273e94d6a5fcd51d0d6c06569e87ad86e96c27c9e31b90a14c55042aab065490fbd65537b9391563077aac0c9e94062b8104175c12cdbb1f09bbe30591
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in asteroids.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Svetoslav Kuzmanov
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,19 @@
1
+ # Asteroids
2
+
3
+ This is my take on the classic arcade space shooted Asteroids by Atari.
4
+ In the game the player controls a spaceship in an asteroid field which is periodically traversed by flying saucers.
5
+ The object of the game is to shoot and destroy asteroids and saucers while not colliding with either,
6
+ or being hit by the saucers counter-fire. The game becomes harder as the number of asteroids increases.
7
+
8
+ ## Installation
9
+
10
+ To install the game run:
11
+ $ gem install asteroids
12
+
13
+ ## Starting the game
14
+ $ asteroids
15
+
16
+ ## Controls
17
+ Use the arrow keys to control the ship
18
+ Space shoots
19
+ ESC goes to menu.
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
Binary file
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'asteroids/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "asteroids"
8
+ spec.version = Asteroids::VERSION
9
+ spec.authors = ["Svetoslav Kuzmanov"]
10
+ spec.email = ["svetoslav.kuzmanov@gmail.com"]
11
+ spec.summary = <<-EOS
12
+ This is my take on the classic arcade space shooter Asteroids by Atari
13
+ EOS
14
+ spec.description = <<-EOS
15
+ This game is build with Gosu library as a final project for the
16
+ "Programming with Ruby" course.
17
+ EOS
18
+ spec.homepage = ""
19
+ spec.license = "MIT"
20
+
21
+ spec.files = `git ls-files -z`.split("\x0")
22
+ spec.executables = 'asteroids'
23
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
24
+ spec.require_paths = ["lib"]
25
+
26
+ spec.add_development_dependency "bundler", "~> 1.7"
27
+ spec.add_development_dependency "rake", "~> 10.0"
28
+
29
+ spec.add_runtime_dependency 'gosu'
30
+ end
@@ -0,0 +1,17 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'gosu'
4
+ require 'yaml'
5
+
6
+ root_dir = File.expand_path(File.join(
7
+ File.dirname(File.dirname(__FILE__)), 'lib'))
8
+ require_pattern_components = File.join(root_dir, '*/componenets/*.rb')
9
+ require_pattern = File.join(root_dir, '**/*.rb')
10
+
11
+ Dir.glob(require_pattern_components).each { |file| require file }
12
+
13
+ Dir.glob(require_pattern).each { |file| require file }
14
+
15
+ $window = Asteroids::GameWindow.new
16
+ Asteroids::GameState.switch(Asteroids::MenuState.instance)
17
+ $window.show
@@ -0,0 +1,28 @@
1
+ module Asteroids
2
+ class GameWindow < Gosu::Window
3
+
4
+ attr_accessor :state
5
+
6
+ def initialize
7
+ super(800, 600, false)
8
+ self.caption = 'Asteroids'
9
+ end
10
+
11
+ def update
12
+ @state.update
13
+ end
14
+
15
+ def draw
16
+ @state.draw
17
+ end
18
+
19
+ def needs_redraw?
20
+ @state.needs_redraw?
21
+ end
22
+
23
+ def button_down(id)
24
+ @state.button_down(id)
25
+ end
26
+
27
+ end
28
+ end
@@ -0,0 +1,23 @@
1
+ module Asteroids
2
+ class Asteroid < GameObject
3
+
4
+ attr_accessor :x, :y, :vel_x, :vel_y, :angle, :radius
5
+
6
+ def initialize(object_pool, x, y, vel_x, vel_y, angle, radius = 45)
7
+ super(object_pool)
8
+ @x = x
9
+ @y = y
10
+ @angle = angle
11
+ @vel_x = vel_x
12
+ @vel_y = vel_y
13
+ @physics = AsteroidPhysics.new(self, object_pool)
14
+ @graphics = AsteroidGraphics.new(self)
15
+ @radius = radius
16
+ end
17
+
18
+ def explode
19
+ Explosion.new(object_pool, @x, @y)
20
+ end
21
+
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ module Asteroids
2
+ class AsteroidGraphics < Component
3
+
4
+ def initialize(game_object)
5
+ super(game_object)
6
+ @image = Gosu::Image.new($window,
7
+ Utils.get_image_path("asteroid.png"), true)
8
+ @image_medium = Gosu::Image.new($window,
9
+ Utils.get_image_path("asteroid_medium.png"), true)
10
+ @image_small = Gosu::Image.new($window,
11
+ Utils.get_image_path("asteroid_small.png"), true)
12
+ end
13
+
14
+ def draw
15
+ case object.radius
16
+ when 45
17
+ @image.draw_rot(object.x, object.y, 1, object.angle)
18
+ when 30
19
+ @image_medium.draw_rot(object.x, object.y, 1, object.angle)
20
+ when 17.5
21
+ @image_small.draw_rot(object.x, object.y, 1, object.angle)
22
+ end
23
+ end
24
+
25
+ end
26
+ end
@@ -0,0 +1,51 @@
1
+ module Asteroids
2
+ class AsteroidPhysics < Component
3
+
4
+ def initialize(game_object, object_pool)
5
+ super(game_object)
6
+ @object_pool = object_pool
7
+ end
8
+
9
+ def update
10
+ if detect_collision?
11
+ @explosion_time = Gosu.milliseconds
12
+ object.explode
13
+ end
14
+ if @explosion_time
15
+ if Gosu.milliseconds - @explosion_time > 100
16
+ object.mark_for_removal
17
+ if object.radius == 45
18
+ 2.times do |n|
19
+ Asteroid.new(@object_pool, object.x + rand(20),
20
+ object.y + rand(20), rand * (-1.5), rand() * 1.5, rand * 3,
21
+ (object.radius - 15))
22
+ end
23
+ end
24
+ if object.radius == 30
25
+ 2.times do |n|
26
+ Asteroid.new(@object_pool, object.x + rand(20),
27
+ object.y + rand(20), rand() * (-2.2), rand() * 2.2, rand * 3,
28
+ (object.radius - 12.5))
29
+ end
30
+ end
31
+ end
32
+ end
33
+ object.x += Gosu::offset_x(object.angle, 0.0001) + object.vel_x
34
+ object.y += Gosu::offset_y(object.angle, 0.0001) + object.vel_y
35
+ object.x %= 800
36
+ object.y %= 600
37
+ end
38
+
39
+ def detect_collision?
40
+ @object_pool.objects.each do |other_object|
41
+ if other_object.is_a? Asteroids::Missile or
42
+ other_object.is_a? Asteroids::Ship and
43
+ Utils.collide(object, other_object)
44
+ return true
45
+ end
46
+ end
47
+ return false
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,29 @@
1
+ module Asteroids
2
+ class Component
3
+
4
+ def initialize(game_object = nil)
5
+ self.object = game_object
6
+ end
7
+
8
+ def update
9
+ end
10
+
11
+ def draw
12
+ end
13
+
14
+ protected
15
+
16
+ def object=(obj)
17
+ if obj
18
+ @object = obj
19
+ obj.components << self
20
+ end
21
+ end
22
+
23
+ def object
24
+ @object
25
+ end
26
+
27
+ end
28
+
29
+ end
@@ -0,0 +1,37 @@
1
+ module Asteroids
2
+ class GameObject
3
+
4
+ def initialize(object_pool)
5
+ @components = []
6
+ @object_pool = object_pool
7
+ @object_pool.objects << self
8
+ end
9
+
10
+ def components
11
+ @components
12
+ end
13
+
14
+ def update
15
+ @components.map(&:update)
16
+ end
17
+
18
+ def draw
19
+ @components.map(&:draw)
20
+ end
21
+
22
+ def removable?
23
+ @removable
24
+ end
25
+
26
+ def mark_for_removal
27
+ @removable = true
28
+ end
29
+
30
+ protected
31
+
32
+ def object_pool
33
+ @object_pool
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ module Asteroids
2
+ class ObjectPool
3
+ attr_accessor :objects
4
+
5
+ def initialize
6
+ @objects = []
7
+ end
8
+
9
+ def update_all
10
+ @objects.map(&:update)
11
+ @objects.delete_if { |object| object.removable?}
12
+ end
13
+
14
+ def find_empty_space
15
+ x = Gosu::random(0, 800)
16
+ y = Gosu::random(0, 600)
17
+ while is_not_empty(x, y)
18
+ x = Gosu::random(0, 800)
19
+ y = Gosu::random(0, 600)
20
+ end
21
+ {x: x, y: y}
22
+ end
23
+
24
+ def is_not_empty(x, y)
25
+ @objects.each do |object|
26
+ if object.is_a? Asteroids::Asteroid and object.x == x and object.y == y
27
+ return true
28
+ end
29
+ end
30
+ false
31
+ end
32
+
33
+ end
34
+ end
@@ -0,0 +1,14 @@
1
+ module Asteroids
2
+ class Explosion < GameObject
3
+
4
+ attr_accessor :x, :y
5
+
6
+ def initialize(object_pool, x, y)
7
+ super(object_pool)
8
+ @x, @y = x, y
9
+ @current_frame = 0
10
+ ExplosionGraphics.new(self)
11
+ end
12
+
13
+ end
14
+ end
@@ -0,0 +1,48 @@
1
+ module Asteroids
2
+ class ExplosionGraphics < Component
3
+
4
+ FRAME_DELAY = 17
5
+
6
+ def initialize(game_object)
7
+ super
8
+ @current_frame = 0
9
+ end
10
+
11
+
12
+ def draw()
13
+ image = current_frame
14
+ image.draw(
15
+ object.x - image.width / 2.0,
16
+ object.y - image.height / 2.0,
17
+ 100)
18
+ end
19
+
20
+ def update
21
+ now = Gosu.milliseconds
22
+ delta = now - (@last_frame ||= now)
23
+ if delta > FRAME_DELAY
24
+ @last_frame = now
25
+ end
26
+ @current_frame += (delta / FRAME_DELAY).floor
27
+ object.mark_for_removal if done?
28
+ end
29
+
30
+ private
31
+
32
+ def current_frame
33
+ animation[@current_frame % animation.size]
34
+ end
35
+
36
+ def done?
37
+ @done ||= @current_frame >= animation.size
38
+ end
39
+
40
+ def animation
41
+ @@animation ||=
42
+ Gosu::Image.load_tiles(
43
+ $window, Utils.get_image_path("explosion.png"),
44
+ 128, 128, false)
45
+ end
46
+
47
+ end
48
+ end
@@ -0,0 +1,46 @@
1
+ module Asteroids
2
+ class Menu
3
+ def initialize ()
4
+ @items = []
5
+ end
6
+
7
+ def add_item (image, callback, selected)
8
+ item = MenuItem.new(image, callback, selected)
9
+ @items << item
10
+ item.x = position[:x]
11
+ item.y = position[:y]
12
+ end
13
+
14
+ def draw
15
+ @items.each do |i|
16
+ i.draw
17
+ end
18
+ end
19
+
20
+ def position
21
+ {x: $window.width / 2 - @items[@items.count - 1].width / 2,
22
+ y: $window.height / 3 - @items[@items.count - 1].height / 3 +
23
+ @items.count * 60 }
24
+ end
25
+
26
+ def select_item(which)
27
+ @items.each_with_index do |item, index|
28
+ if item.is_selected?
29
+ if @items[index.send(which, 1) % 3].select
30
+ item.deselect
31
+ return true
32
+ end
33
+ end
34
+ end
35
+ end
36
+
37
+ def confirm
38
+ @items.each do |item|
39
+ if item.is_selected?
40
+ item.execute
41
+ end
42
+ end
43
+ end
44
+
45
+ end
46
+ end
@@ -0,0 +1,55 @@
1
+ module Asteroids
2
+ class MenuItem
3
+ attr_writer :x, :y
4
+
5
+ def initialize (text, callback, selected)
6
+ @image = Gosu::Image.from_text($window, text,
7
+ Utils.get_font_path('victor-pixel.ttf'), 65)
8
+ @x = 0
9
+ @y = 0
10
+ @callback = callback
11
+ @selected = selected
12
+ end
13
+
14
+ def draw
15
+ if @selected
16
+ @image.draw(@x, @y, 10, 1, 1, 0xffffff00)
17
+ else
18
+ @image.draw(@x, @y, 10)
19
+ end
20
+ end
21
+
22
+ def is_selected?
23
+ @selected
24
+ end
25
+
26
+ def select
27
+ @selected = true
28
+ end
29
+
30
+ def deselect
31
+ @selected = false
32
+ end
33
+
34
+ def execute
35
+ if @selected
36
+ @callback.call
37
+ end
38
+ end
39
+
40
+ def width
41
+ @image.width
42
+ end
43
+
44
+ def height
45
+ @image.height
46
+ end
47
+
48
+ def execute
49
+ if @selected
50
+ @callback.call
51
+ end
52
+ end
53
+
54
+ end
55
+ end
@@ -0,0 +1,21 @@
1
+ module Asteroids
2
+ class Missile < GameObject
3
+
4
+ attr_accessor :ship, :x, :y, :vel_x, :vel_y, :angle, :lifespan, :radius
5
+
6
+ def initialize(ship, object_pool, x, y, vel_x, vel_y, angle)
7
+ super(object_pool)
8
+ @x = x
9
+ @y = y
10
+ @angle = angle
11
+ @vel_x = vel_x
12
+ @vel_y = vel_y
13
+ @lifespan = 3
14
+ @radius = 3
15
+ @ship = ship
16
+ @physics = MissilePhysics.new(self, object_pool)
17
+ @graphics = MissileGraphics.new(self)
18
+ end
19
+
20
+ end
21
+ end
@@ -0,0 +1,15 @@
1
+ module Asteroids
2
+ class MissileGraphics < Component
3
+
4
+ def initialize(game_object)
5
+ super(game_object)
6
+ @image = Gosu::Image.new($window,
7
+ Utils.get_image_path("simple_missile.png"), true)
8
+ end
9
+
10
+ def draw
11
+ @image.draw_rot(object.x, object.y, 0, object.angle)
12
+ end
13
+
14
+ end
15
+ end
@@ -0,0 +1,42 @@
1
+ module Asteroids
2
+ class MissilePhysics < Component
3
+
4
+ def initialize(game_object, object_pool)
5
+ super(game_object)
6
+ @object_pool = object_pool
7
+ end
8
+
9
+ def update
10
+ object.mark_for_removal if detect_collision?
11
+ object.x += Gosu::offset_x(object.angle, 10) + object.vel_x
12
+ object.y += Gosu::offset_y(object.angle, 10) + object.vel_y
13
+ object.x %= 800
14
+ object.y %= 600
15
+ object.lifespan -= 0.1
16
+ object.mark_for_removal if object.lifespan <= 0
17
+ end
18
+
19
+ def detect_collision?
20
+ @object_pool.objects.each do |other_object|
21
+ if other_object.is_a? Asteroids::Asteroid and
22
+ Utils.collide(object, other_object)
23
+ object.ship.add_score(calculate_points(other_object))
24
+ return true
25
+ end
26
+ end
27
+ return false
28
+ end
29
+
30
+ def calculate_points(asteroid)
31
+ case asteroid.radius
32
+ when 45
33
+ 20
34
+ when 30
35
+ 50
36
+ when 17.5
37
+ 100
38
+ end
39
+ end
40
+
41
+ end
42
+ end
@@ -0,0 +1,51 @@
1
+ module Asteroids
2
+ class Ship < GameObject
3
+
4
+ SHOOT_DELAY = 600
5
+
6
+ attr_accessor :x, :y, :vel_x, :vel_y, :angle, :thrust, :radius,
7
+ :score, :lives
8
+
9
+ def initialize(object_pool)
10
+ super(object_pool)
11
+ @physics = ShipPhysics.new(self, object_pool)
12
+ @graphics = ShipGraphics.new(self)
13
+ @vel_x = @vel_y = @angle = 0.0
14
+ @radius = 35
15
+ @lives = 3
16
+ @score = 0
17
+ @object_pool = object_pool
18
+ end
19
+
20
+ def shoot
21
+ if can_shoot?
22
+ @last_shot = Gosu.milliseconds
23
+ Missile.new(self, object_pool, @x, @y, @vel_x, @vel_y, @angle)
24
+ end
25
+ end
26
+
27
+ def can_shoot?
28
+ Gosu.milliseconds - (@last_shot || 0) > SHOOT_DELAY
29
+ end
30
+
31
+ def explode
32
+ Explosion.new(object_pool, @x, @y)
33
+ @lives -= 1
34
+ spawn
35
+ end
36
+
37
+ def is_alive?
38
+ return true if @lives != 0 or @lives > 0
39
+ end
40
+
41
+ def spawn
42
+ @x = object_pool.find_empty_space[:x]
43
+ @y = object_pool.find_empty_space[:y]
44
+ end
45
+
46
+ def add_score(points)
47
+ @score += points
48
+ end
49
+
50
+ end
51
+ end
@@ -0,0 +1,20 @@
1
+ module Asteroids
2
+ class ShipGraphics < Component
3
+
4
+ def initialize(game_object)
5
+ super(game_object)
6
+ @image = Gosu::Image.load_tiles($window,
7
+ Utils.get_image_path("ship.png"), 90, 90, true)
8
+ end
9
+
10
+ def draw
11
+ if object.thrust
12
+ @image[0].draw_rot(object.x, object.y, 1, object.angle)
13
+ else
14
+ @image[1].draw_rot(object.x, object.y, 1, object.angle)
15
+ end
16
+
17
+ end
18
+
19
+ end
20
+ end
@@ -0,0 +1,58 @@
1
+ module Asteroids
2
+ class ShipPhysics < Component
3
+
4
+ def initialize(game_object, object_pool)
5
+ super(game_object)
6
+ @object_pool = object_pool
7
+ object.spawn
8
+ end
9
+
10
+ def update
11
+ object.explode if detect_collision?
12
+ if $window.button_down? Gosu::KbUp
13
+ accelerate
14
+ object.thrust = true
15
+ else
16
+ object.thrust = false
17
+ end
18
+ if $window.button_down? Gosu::KbLeft
19
+ object.angle -= 4.5
20
+ end
21
+ if $window.button_down? Gosu::KbRight
22
+ object.angle += 4.5
23
+ end
24
+ if $window.button_down? Gosu::Button::KbSpace
25
+ object.shoot
26
+ end
27
+ @object.mark_for_removal unless object.is_alive?
28
+ move
29
+ end
30
+
31
+ private
32
+
33
+ def detect_collision?
34
+ @object_pool.objects.each do |other_object|
35
+ if other_object.is_a? Asteroids::Asteroid and
36
+ Utils.collide(object, other_object)
37
+ return true
38
+ end
39
+ end
40
+ return false
41
+ end
42
+
43
+ def accelerate
44
+ object.vel_x += Gosu::offset_x(object.angle, 0.5)
45
+ object.vel_y += Gosu::offset_y(object.angle, 0.5)
46
+ end
47
+
48
+ def move
49
+ object.x += object.vel_x
50
+ object.y += object.vel_y
51
+ object.x %= 800
52
+ object.y %= 600
53
+ object.vel_x *= 0.95
54
+ object.vel_y *= 0.95
55
+ end
56
+
57
+ end
58
+ end
@@ -0,0 +1,29 @@
1
+ module Asteroids
2
+ class GameState
3
+
4
+ def self.switch(new_state)
5
+ $window.state && $window.state.leave
6
+ $window.state = new_state
7
+ new_state.enter
8
+ end
9
+
10
+ def enter
11
+ end
12
+
13
+ def leave
14
+ end
15
+
16
+ def draw
17
+ end
18
+
19
+ def update
20
+ end
21
+
22
+ def needs_redraw?
23
+ true
24
+ end
25
+
26
+ def button_down(id)
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,41 @@
1
+ require 'singleton'
2
+
3
+ module Asteroids
4
+ class MenuState < GameState
5
+ include Singleton
6
+
7
+ def initialize
8
+ @title = Gosu::Image.from_text($window, "Asteroids",
9
+ Utils.get_font_path('victor-pixel.ttf'), 100)
10
+ @background = Gosu::Image.new($window,
11
+ Utils.get_image_path('background.png'), false)
12
+ @menu = Menu.new
13
+ @menu.add_item("New Game", lambda { GameState.switch(PlayState.new) },
14
+ true)
15
+ @menu.add_item("Load Game", lambda { puts 'load game' }, false)
16
+ @menu.add_item("Exit", lambda { $window.close }, false)
17
+ end
18
+
19
+ def draw
20
+ @background.draw(0, 0, 0)
21
+ @title.draw(
22
+ $window.width / 2 - @title.width / 2,
23
+ $window.height / 5 - @title.height / 5,
24
+ 10)
25
+ @menu.draw
26
+ end
27
+
28
+ def button_down(id)
29
+ if id == Gosu::KbDown
30
+ @menu.select_item(:+)
31
+ end
32
+ if id == Gosu::KbUp
33
+ @menu.select_item(:-)
34
+ end
35
+ if id == Gosu::KbReturn
36
+ @menu.confirm
37
+ end
38
+ end
39
+
40
+ end
41
+ end
@@ -0,0 +1,61 @@
1
+ module Asteroids
2
+ class PlayState < GameState
3
+
4
+ def initialize
5
+ @background = Gosu::Image.new($window,
6
+ Utils.get_image_path('background.png'), false)
7
+ @live_image = Gosu::Image.new($window,
8
+ Utils.get_image_path('ship_small.png'), false)
9
+ @object_pool = ObjectPool.new
10
+ @ship = Ship.new(@object_pool)
11
+ Utils.create_asteroids(@object_pool, 4)
12
+ @font = Gosu::Font.new($window,
13
+ Utils.get_font_path('victor-pixel.ttf'),
14
+ 34)
15
+ @level = 1
16
+ @level_compleate = false
17
+ end
18
+
19
+ def draw
20
+ @background.draw(0, 0, 0)
21
+ @object_pool.objects.map(&:draw)
22
+ if !@ship.is_alive?
23
+ @font.draw("Game Over", 210, 250, 50, 2.0, 2.0, 0xffffff00)
24
+ else
25
+ @font.draw("Score: ", 580, 10, 50, 1.0, 1.0, 0xffffff00)
26
+ @font.draw(@ship.score, 700, 10, 50, 1.0, 1.0, 0xffffff00)
27
+ @font.draw("Lives: ", 10, 10, 50, 1.0, 1.0, 0xffffff00)
28
+ @ship.lives.times do |n|
29
+ @live_image.draw(110 + n * 50, 10, 50)
30
+ end
31
+ end
32
+ end
33
+
34
+ def update
35
+ check_level_compleate
36
+ if @level_compleate == true
37
+ Utils.create_asteroids(@object_pool, 4 + @level)
38
+ @level += 1
39
+ @level_compleate = false
40
+ end
41
+ @object_pool.update_all
42
+ end
43
+
44
+ def check_level_compleate
45
+ @level_compleate = !@object_pool.objects.any? { |object| object.is_a? Asteroids::Asteroid }
46
+ end
47
+
48
+ def button_down(id)
49
+ if id == Gosu::KbEscape
50
+ Asteroids::GameState.switch(Asteroids::MenuState.instance)
51
+ end
52
+ if id == Gosu::KbS
53
+ serialized_object = ::YAML::dump(@object_pool)
54
+ File.open(Utils.saves_path + '/save.yaml', 'w+') do |file|
55
+ file.write(serialized_object)
56
+ end
57
+ end
58
+ end
59
+
60
+ end
61
+ end
@@ -0,0 +1,37 @@
1
+ module Asteroids
2
+ class Utils
3
+
4
+ def self.assets_path
5
+ File.expand_path("../../../../assets/", __FILE__)
6
+ end
7
+
8
+ def self.saves_path
9
+ File.expand_path("../../../../saves/", __FILE__)
10
+ end
11
+
12
+
13
+ def self.get_image_path(image_name)
14
+ "#{assets_path}/images/#{image_name}"
15
+ end
16
+
17
+ def self.get_font_path(font_name)
18
+ "#{assets_path}/fonts/#{font_name}"
19
+ end
20
+
21
+ def self.collide(object_a, object_b)
22
+ if Gosu::distance(object_a.x, object_a.y, object_b.x, object_b.y) <
23
+ object_a.radius + object_b.radius
24
+ return true
25
+ end
26
+ false
27
+ end
28
+
29
+ def self.create_asteroids(object_pool, amount)
30
+ amount.times do |n|
31
+ Asteroid.new(object_pool, rand(800), rand(600),
32
+ rand() * 0.6 - 0.3, rand() * 0.6 - 0.3, 0)
33
+ end
34
+ end
35
+
36
+ end
37
+ end
@@ -0,0 +1,3 @@
1
+ module Asteroids
2
+ VERSION = "0.0.1"
3
+ end
File without changes
metadata ADDED
@@ -0,0 +1,128 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: asteroids
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Svetoslav Kuzmanov
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-02-08 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.7'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.7'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: gosu
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ">="
46
+ - !ruby/object:Gem::Version
47
+ version: '0'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ version: '0'
55
+ description: |2
56
+ This game is build with Gosu library as a final project for the
57
+ "Programming with Ruby" course.
58
+ email:
59
+ - svetoslav.kuzmanov@gmail.com
60
+ executables:
61
+ - asteroids
62
+ extensions: []
63
+ extra_rdoc_files: []
64
+ files:
65
+ - ".gitignore"
66
+ - Gemfile
67
+ - LICENSE.txt
68
+ - README.md
69
+ - Rakefile
70
+ - assets/fonts/victor-pixel.ttf
71
+ - assets/images/asteroid.png
72
+ - assets/images/asteroid_medium.png
73
+ - assets/images/asteroid_small.png
74
+ - assets/images/background.png
75
+ - assets/images/explosion.png
76
+ - assets/images/ship.png
77
+ - assets/images/ship_small.png
78
+ - assets/images/simple_missile.png
79
+ - asteroids.gemspec
80
+ - bin/asteroids
81
+ - lib/asteroids.rb
82
+ - lib/asteroids/asteroid/asteroid.rb
83
+ - lib/asteroids/asteroid/asteroid_graphics.rb
84
+ - lib/asteroids/asteroid/asteroid_physics.rb
85
+ - lib/asteroids/componenets/component.rb
86
+ - lib/asteroids/componenets/game_object.rb
87
+ - lib/asteroids/componenets/game_pool.rb
88
+ - lib/asteroids/explosion/explosion.rb
89
+ - lib/asteroids/explosion/explosion_graphics.rb
90
+ - lib/asteroids/menu/menu.rb
91
+ - lib/asteroids/menu/menu_item.rb
92
+ - lib/asteroids/missile/missile.rb
93
+ - lib/asteroids/missile/missile_graphics.rb
94
+ - lib/asteroids/missile/missile_physics.rb
95
+ - lib/asteroids/ship/ship.rb
96
+ - lib/asteroids/ship/ship_graphics.rb
97
+ - lib/asteroids/ship/ship_physics.rb
98
+ - lib/asteroids/states/game_state.rb
99
+ - lib/asteroids/states/menu_state.rb
100
+ - lib/asteroids/states/play_state.rb
101
+ - lib/asteroids/utils/utils.rb
102
+ - lib/asteroids/version.rb
103
+ - saves/save.yaml
104
+ homepage: ''
105
+ licenses:
106
+ - MIT
107
+ metadata: {}
108
+ post_install_message:
109
+ rdoc_options: []
110
+ require_paths:
111
+ - lib
112
+ required_ruby_version: !ruby/object:Gem::Requirement
113
+ requirements:
114
+ - - ">="
115
+ - !ruby/object:Gem::Version
116
+ version: '0'
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ requirements:
119
+ - - ">="
120
+ - !ruby/object:Gem::Version
121
+ version: '0'
122
+ requirements: []
123
+ rubyforge_project:
124
+ rubygems_version: 2.2.2
125
+ signing_key:
126
+ specification_version: 4
127
+ summary: This is my take on the classic arcade space shooter Asteroids by Atari
128
+ test_files: []