Skip to content

Commit

Permalink
Merge pull request #1 from petros/refactor-scenes
Browse files Browse the repository at this point in the history
Scene refactoring
  • Loading branch information
petros authored Nov 11, 2019
2 parents 28f532e + 5f5636f commit e2c0a64
Show file tree
Hide file tree
Showing 14 changed files with 389 additions and 265 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
.DS_Store
_build

50 changes: 50 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
Sector Five II
==============

Extended edition of the game, based on a Tutorial from Learn Game Programming
with Ruby by Mark Sobkowicz.

You can read the [credits](credits.txt) seperately.

Installation
============

The are two ways to run the game. One is setting up Ruby in your environment,
along all the necessary libraries. Download the source code and run the game.

The other is to go to this repository's releases page, and download a bundled
version. For now, I only provide a macOS bundle, but I can soon provide a
Windows one as well.

Running or developing on macOS
==============================

1. Install the latest Ruby version
2. brew install sdl2 libogg libvorbis​
3. gem install gosu
4. gem install chipmunk

Running or developing on Windows
================================

[...Help Needed...]
Need someone with Windows to contribute this bit. They need to be able to run
this game on their system.

Credits
=======
The starter base code comes from a tutorial from Learn Game Programming
with Ruby by [Mark Sobkowicz](https://twitter.com/MarkSobkowicz).

You can read the rest of the [credits](credits.txt) seperately. It includes the
attributions for the sounds and images used in this game.

Contributing
============

Please follow the [CONTRIBUTING](CONTRIBUTING) guide.

Contributors
============

- [petros](https://twitter.com/amiridis) ([petros.blog/games](https://petros.blog/games))
15 changes: 8 additions & 7 deletions bullet.rb
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
class Bullet
require_relative 'sprite'

class Bullet < Sprite
SPEED = 5
attr_reader :x, :y, :radius


def initialize(window, x, y, angle)
@x = x
@y = y
Expand All @@ -10,16 +11,16 @@ def initialize(window, x, y, angle)
@radius = 3
@window = window
end

def move
@x += Gosu.offset_x(@direction, SPEED)
@y += Gosu.offset_y(@direction, SPEED)
end

def draw
@image.draw(@x - @radius, @y - @radius, 1)
@image.draw(@x - @radius, @y - @radius, 1)
end

def onscreen?
right = @window.width + @radius
left = -@radius
Expand Down
8 changes: 4 additions & 4 deletions credit.rb
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
class Credit
SPEED = 1
attr_reader :y

def initialize(window, text, x, y)
@x = x
@y = @initial_y = y
@text = text
@font = Gosu::Font.new(24)
end

def move
@y -= SPEED
end

def draw
@font.draw_text(@text, @x, @y, 1)
end

def reset
@y = @initial_y
end
Expand Down
78 changes: 78 additions & 0 deletions end_scenes.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
require 'gosu'
require_relative 'scene'
require_relative 'credit'

class EndScene < Scene
def initialize(enemies_destroyed)
@enemies_destroyed = enemies_destroyed
@bottom_message = "Press P to play again, or Q to quit."
@message_font = Gosu::Font.new(28)
@credits = []
y = 700
File.open('credits.txt').each do |line|
@credits.push(Credit.new(self, line.chomp, 100, y))
y += 30
end
@scene = :end
@end_music = Gosu::Song.new('sounds/from_here.ogg')
@end_music.play(true)
end

def button_down(id)
if id == Gosu::KbP
Game.current_scene = FirstWaveScene.new
elsif id == Gosu::KbQ
Game.window.close
end
end

def update
@credits.each do |credit|
credit.move
end
if @credits.last.y < 150
@credits.each do |credit|
credit.reset
end
end
end

def draw
Gosu.clip_to(50, 140, 700, 360) do
@credits.each do |credit|
credit.draw
end
end
Gosu.draw_line(0, 140, Gosu::Color::RED, Game::WINDOW_WIDTH, 140, Gosu::Color::RED)
@message_font.draw_text(@message, 40, 40, 1, 1, 1, Gosu::Color::FUCHSIA)
@message_font.draw_text(@message2, 40, 75, 1, 1, 1, Gosu::Color::FUCHSIA)
Gosu.draw_line(0, 500, Gosu::Color::RED, Game::WINDOW_WIDTH, 500, Gosu::Color::RED)
@message_font.draw_text(@bottom_message, 180, 540, 1, 1, 1, Gosu::Color::AQUA)
end
end

class EndCountReachedScene < EndScene
def initialize(enemies_destroyed)
super(enemies_destroyed)
@message = "You made it! You destroyed #{enemies_destroyed} ships"
@message2 = "and #{Game::MAX_ENEMIES - enemies_destroyed} reached the base."
end
end

class EndHitByEnemyScene < EndScene
def initialize(enemies_destroyed)
super(enemies_destroyed)
@message = "You were struck by an enemy ship."
@message2 = "Before your ship was destroyed, "
@message2 += "you took out #{enemies_destroyed} enemy ships."
end
end

class EndOffTopScene < EndScene
def initialize(enemies_destroyed)
super(enemies_destroyed)
@message = "You got too close to the enemy mother ship."
@message2 = "Before your ship was destroyed, "
@message2 += "you took out #{enemies_destroyed} enemy ships."
end
end
10 changes: 5 additions & 5 deletions enemy.rb
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
class Enemy
attr_reader :x, :y, :radius
require_relative 'sprite'

class Enemy < Sprite
def initialize(window)
@radius = 20
@x = rand(window.width - 2 * @radius) + @radius
@y = 0
@image = Gosu::Image.new('images/enemy.png')
@speed = rand(1..6)
end

def move
@y += @speed
end

def draw
@image.draw(@x - @radius, @y - @radius, 1)
end
Expand Down
10 changes: 6 additions & 4 deletions explosion.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
class Explosion
attr_reader :x, :y, :radius, :finished

require_relative 'sprite'

class Explosion < Sprite
attr_reader :finished

def initialize(window, x, y)
@x = x
@y = y
Expand All @@ -9,7 +11,7 @@ def initialize(window, x, y)
@image_index = 0
@finished = false
end

def draw
if @image_index < @images.count
@images[@image_index].draw(@x - @radius, @y - @radius, 2)
Expand Down
145 changes: 145 additions & 0 deletions first_wave_scene.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
require 'gosu'
require_relative 'game'
require_relative 'scene'
require_relative 'player'
require_relative 'enemy'
require_relative 'bullet'
require_relative 'explosion'
require_relative 'end_scenes'

class FirstWaveScene < Scene
def initialize
@scene = :first_wave
@player = Player.new(Game.window)
@enemies = []
@bullets = []
@explosions = []
@enemies_appeared = 0
@enemies_appeared_font = Gosu::Font.new(18, bold: true)
@enemies_destroyed = 0
@enemies_destroyed_font = Gosu::Font.new(18, bold: true)
@enemies_escaped_font = Gosu::Font.new(18, bold: true)
@game_music = Gosu::Song.new('sounds/cephalopod.ogg')
@game_music.play(true)
@explosion_sound = Gosu::Sample.new('sounds/explosion.ogg')
@shooting_sound = Gosu::Sample.new('sounds/shoot.ogg')
@teleport_sound = Gosu::Sample.new('sounds/teleport.wav')
end

def button_down(id)
if id == Gosu::KbSpace
@bullets.push Bullet.new(Game.window, @player.x, @player.y, @player.angle)
@shooting_sound.play(0.3)
end
end

def update
@player.turn_left if Gosu.button_down?(Gosu::KbLeft)
@player.turn_right if Gosu.button_down?(Gosu::KbRight)
@player.accelerate if Gosu.button_down?(Gosu::KbUp)
@player.move
if rand < Game::ENEMY_FREQUENCY
@enemies.push Enemy.new(Game.window)
@enemies_appeared += 1
end
@enemies.each do |enemy|
enemy.move
end
@bullets.each do |bullet|
bullet.move
end
# Detect if a bullet hits an enemy, and push an explosion.
@enemies.dup.each do |enemy|
@bullets.dup.each do |bullet|
if bullet.collides_with?(enemy)
@enemies.delete enemy
@enemies_destroyed += 1
@bullets.delete bullet
@explosions.push Explosion.new(Game.window, enemy.x, enemy.y)
@explosion_sound.play
end
end
end
# Chain explosions. If an enemy is near an ongoing explosion, it explodes
# too.
@enemies.dup.each do |enemy|
@explosions.dup.each do |explosion|
if enemy.collides_with?(explosion)
@enemies.delete enemy
@enemies_destroyed += 1
@explosions.push Explosion.new(Game.window, enemy.x, enemy.y)
@explosion_sound.play
end
end
end
# Remove explosions that have finished animating.
@explosions.dup.each do |explosion|
@explosions.delete explosion if explosion.finished
end
# Remove enemies that have moved beyond the bottom of the screen.
@enemies.dup.each do |enemy|
if enemy.y > Game::WINDOW_HEIGHT + enemy.radius
@enemies.delete enemy
@teleport_sound.play(0.3)
end
end
# Remove bullets that have moved out of the screen boundaries.
@bullets.dup.each do |bullet|
@bullets.delete bullet unless bullet.onscreen?
end
if @enemies_appeared > Game::MAX_ENEMIES
Game.current_scene = EndCountReachedScene.new(@enemies_destroyed)
end
@enemies.each do |enemy|
#distance = Gosu.distance(enemy.x, enemy.y, @player.x, @player.y)
#if distance < @player.radius + enemy.radius
if enemy.collides_with?(@player)
Game.current_scene = EndHitByEnemyScene.new(@enemies_destroyed)
end
end
if @player.y < @player.radius
Game.current_scene = EndOffTopScene.new(@enemies_destroyed)
end
end

def draw
@player.draw
@enemies.each do |enemy|
enemy.draw
end
@bullets.each do |bullet|
bullet.draw
end
@explosions.each do |explosion|
explosion.draw
end
@enemies_appeared_font.draw_text(
"Fleet: #{Game::MAX_ENEMIES - @enemies_appeared}",
460,
10,
1,
1,
1,
Gosu::Color::WHITE
)
@enemies_destroyed_font.draw_text(
"Destroyed: #{@enemies_destroyed}",
540,
10,
1,
1,
1,
Gosu::Color::GREEN
)
@enemies_escaped_font.draw_text(
"Escaped: #{Game::MAX_ENEMIES - @enemies_destroyed}",
660,
10,
1,
1,
1,
Gosu::Color::RED
)
end

end
Loading

0 comments on commit e2c0a64

Please sign in to comment.