Skip to content

Instantly share code, notes, and snippets.

@FredrikAugust
Created May 9, 2016 14:18
Show Gist options
  • Save FredrikAugust/7c3a7b3bb2190b9ec8cdec29ab764335 to your computer and use it in GitHub Desktop.
Save FredrikAugust/7c3a7b3bb2190b9ec8cdec29ab764335 to your computer and use it in GitHub Desktop.
Next EA bestseller
#!/home/greg/.rvm/rubies/default/bin/ruby
require 'gosu'
# main class for the laser element in game
class Laser
attr_reader :created_at, :x, :y, :created_by
def initialize(window_size, angle, player)
@window_size = window_size
@image = Gosu::Image.new('./laser.png')
@angle = angle
# position = 0 (float)
@x = @y = 0.0
@created_at = Time.now
@created_by = player
end
def warp(x, y)
@x = x
@y = y
end
def move
@x += Gosu.offset_x(@angle, 10)
@y += Gosu.offset_y(@angle, 10)
end
def valid?
return false if @x >= @window_size[:x] || @y >= @window_size[:y]\
|| @x <= 0 || @y <= 0
true
end
def draw
@image.draw_rot(@x, @y, 1, @angle)
end
end
# main player class, this is the spaceship flying around
class Player
attr_reader :x, :y, :angle
def initialize(window_size)
@window_size = window_size
@image = Gosu::Image.new('./player.png')
# position, angle and velocity = 0 (float)
@x = @y = @vel_x = @vel_y = @angle = 0.0
end
def warp(x, y)
@x = x
@y = y
end
def turn_left
@angle -= 4.5
end
def turn_right
@angle += 4.5
end
def accelerate
@vel_x += Gosu.offset_x(@angle, 0.4)
@vel_y += Gosu.offset_y(@angle, 0.4)
end
def de_accelerate
@vel_x += Gosu.offset_x(@angle, -0.3)
@vel_y += Gosu.offset_y(@angle, -0.3)
end
def move
@x += @vel_x
@y += @vel_y
@x %= @window_size[:x]
@y %= @window_size[:y]
@vel_x *= 0.95
@vel_y *= 0.95
end
def draw
@image.draw_rot(@x, @y, 2, @angle)
end
# is the player ready to shoot another laser?
def ready?(laser_pool)
# the lasers that has been shot by this player
my_lasers = laser_pool.select { |l| l.created_by == self }
return true if my_lasers.empty?
# return true if the last laser was shot more than 0.2 seconds ago
true if my_lasers.last.created_at < Time.now - 0.2
end
# determine if the player was hit
def hit?(lasers)
return false if lasers.empty?
laser_distance = lasers.reject { |l| l.created_by == self }.map do |l|
Gosu.distance(x, y, l.x, l.y)
end
return false if laser_distance.min.nil?
return [true, [x, y]] if laser_distance.min < 30.0
false
end
end
# main game window, inherits from gosu main window
class MainWindow < Gosu::Window
def initialize
@window_size = { x: 1280, y: 720 }
# window size (x, y)
super @window_size[:x], @window_size[:y]
self.caption = 'Test Game'
@player = Player.new(@window_size)
# random start-pos
@player.warp(rand * @window_size[:x], rand * @window_size[:y])
@lasers = []
@player2 = Player.new(@window_size)
@player2.warp(*rand_pos)
# background stuff
@background_image = Gosu::Image.new('./battleground.jpg', tileable: true)
@scores = { @player => 0, @player2 => 0 }
@score_text = Gosu::Font.new(self, 'Arial', 40)
end
def rand_pos
[rand * @window_size[:x], rand * @window_size[:y]]
end
def update
# quit the game
close if Gosu.button_down?(Gosu::KbEscape)
@player.turn_left if button_down?(Gosu::KbA) || button_down?(Gosu::GpLeft)
@player.turn_right if button_down?(Gosu::KbD) || button_down?(Gosu::GpRight)
@player.accelerate if button_down?(Gosu::KbW) || button_down?(Gosu::GpUp)
@player.de_accelerate if button_down?(Gosu::KbS) ||
button_down?(Gosu::GpDown)
if button_down?(Gosu::KbSpace) || button_down?(Gosu::GpButton0)
# can only create one laser per 0.2 seconds
# check if last laser created was more than 0.2 seconds ago
if @player.ready?(@lasers)
@lasers << Laser.new(@window_size, @player.angle, @player)
@lasers.last.warp(@player.x, @player.y)
end
end
@player2.turn_left if button_down?(Gosu::KbLeft)
@player2.turn_right if button_down?(Gosu::KbRight)
@player2.accelerate if button_down?(Gosu::KbUp)
@player2.de_accelerate if button_down?(Gosu::KbDown)
if button_down?(Gosu::KbRightControl)
# can only create one laser per 0.2 seconds
# check if last laser created was more than 0.2 seconds ago
if @player2.ready?(@lasers)
@lasers << Laser.new(@window_size, @player2.angle, @player2)
@lasers.last.warp(@player2.x, @player2.y)
end
end
@player.move
@player2.move
@lasers.each(&:move)
[@player, @player2].each do |p|
hit_stat = p.hit?(@lasers)
next if hit_stat == false
@lasers.delete_if do |l|
Gosu.distance(p.x, p.y, l.x, l.y) <= 30
end
p.warp(*rand_pos)
@scores[p] += 1
end
end
def draw
@player.draw
@player2.draw
# remove laser if it hit someone
@lasers.each do |b|
if b.valid?
b.draw
else
@lasers.delete_if do |b_|
b_ == b
end
end
end
@background_image.draw(0, 0, 0)
@score_text.draw("Player 1: #{@scores[@player]} \
- Player 2: #{@scores[@player2]}", 10, 10, 10, 1, 1, 0xff_000000)
end
end
window = MainWindow.new
window.show
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment