Created
May 9, 2016 14:18
-
-
Save FredrikAugust/7c3a7b3bb2190b9ec8cdec29ab764335 to your computer and use it in GitHub Desktop.
Next EA bestseller
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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