Skip to content

Instantly share code, notes, and snippets.

@csaunders
Last active August 29, 2015 14:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save csaunders/11398808c6977e93b3d8 to your computer and use it in GitHub Desktop.
Save csaunders/11398808c6977e93b3d8 to your computer and use it in GitHub Desktop.
Gosu Demo

If you are on a Mac all you should need to do is:

gem install gosu

To run the game simply:

ruby pawng.rb

You will require 2 png assets:

  • paddle.png (10 x 100px)
  • ball.png (10 x 10px)

What is there?

  • Paddles can be moved by using the keyboard
    • Q & A move the left paddle
    • Up and Down arrows move the right paddle
  • Scoring has been implemented
  • After scoring the ball will be reset and given a random direction

What is missing?

  • Regardless of where the ball hits the paddle it will bounce away from the paddle
  • Top and Bottom edge of screen don't have walls so the ball will go off the screen
require 'gosu'
up = ->(position){ position[:y] -= 5; position }
down = ->(position){ position[:y] += 5; position }
player1 = {
player: :player1,
position: {x: 0, y: 384},
bindings: {
Gosu::KbQ => up,
Gosu::KbA => down
}
}
player2 = {
player: :player2,
position: {x: 1014, y: 384},
bindings: {
Gosu::KbUp => up,
Gosu::KbDown => down
}
}
class PawngWindow < Gosu::Window
@@ball = nil
attr_accessor :paddles, :ball, :score
def initialize(players)
super(1024, 768, false)
self.score = Score.new(self)
self.paddles = players.map { |player| Paddle.new(self, player) }
self.caption = "Pawng"
reset
load_assets
end
def reset
self.ball = Ball.new(self, {x: 512, y: 384})
end
def update
close if button_down?(Gosu::KbEscape)
ball.update(self)
paddles.each do |paddle|
paddle.update(self)
ball.collide(paddle.position)
end
if ball.offscreen?
farthest = ball.farthest(paddles)
score.point(farthest)
reset
end
end
def draw
paddles.each(&:draw)
ball.draw
score.draw(self)
end
def load_assets
@@ball = Gosu::Image.new(self, 'ball.png', false)
end
end
class Ball
LEFT = -1
RIGHT = 1
attr_accessor :position, :speed, :direction
def initialize(context, position)
@image = Gosu::Image.new(context, 'ball.png', false)
@position = position
@direction = rand(2) == 0 ? LEFT : RIGHT
@speed = 5
@offscreen = false
end
def update(context)
position[:x] += speed * direction
@offscreen = position[:x] > context.width || position[:x] < 0
end
def draw
@image.draw(position[:x], position[:y], 1)
end
def collide(other)
deltaX = (position[:x] - other[:x]).abs
deltaY = (position[:y] - other[:y])
hittingPaddle = deltaY > 0 && deltaY < 100
change_direction! if deltaX < 5 && hittingPaddle
end
def change_direction!
self.direction = self.direction * -1
end
def offscreen?
@offscreen
end
def farthest(paddles)
measurements = paddles.map do |paddle|
delta = (position[:x] - paddle.position[:x]).abs
{player: paddle.player, delta: delta}
end
measurements.sort{ |m1, m2| m1[:delta] <=> m2[:delta] }.last[:player]
end
end
class Paddle
attr_accessor :bindings, :position, :player
def initialize(context, options = {})
@player = options[:player]
@position = options[:position]
@bindings = options[:bindings]
@image = Gosu::Image.new(context, 'paddle.png', false)
end
def update(context)
bindings.each do |binding, handler|
self.position = handler.call(self.position) if context.button_down?(binding)
end
end
def draw
@image.draw(position[:x], position[:y], 1)
end
end
class Score
def initialize(context)
@font = Gosu::Font.new(context, Gosu::default_font_name, 40)
reset
end
def score(player)
@scores[player] || 0
end
def point(player)
@scores[player] += 1 if @scores[player]
end
def reset
@scores = {player1: 0, player2: 0}
end
def draw(context)
y = @font.height * 2
x = context.width / 2
p1Score = scoreFor(1, score(:player1))
p2Score = scoreFor(2, score(:player2))
{p1Score => -1, p2Score => 1}.each do |msg, offsetModifier|
width = @font.text_width(msg)
@font.draw(msg, x + offsetModifier*width, y, 0)
end
end
private
def scoreFor(num, score)
"P#{num} - #{score}"
end
end
window = PawngWindow.new([player1, player2])
window.show
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment