Skip to content

Instantly share code, notes, and snippets.

@myokoym
Last active August 29, 2015 13:57
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 myokoym/9799856 to your computer and use it in GitHub Desktop.
Save myokoym/9799856 to your computer and use it in GitHub Desktop.
A baseball game for PC. (under construction...)
require "gosu"
module Persosta
module ZOrder
Background, Ball, Bat = *0..2
end
module Base
def draw_square(window, x1, y1, x2, y2, color, z_order=0)
window.draw_quad(x1, y1, color,
x2, y1, color,
x1, y2, color,
x2, y2, color,
z_order)
end
def draw_frame(window, x1, y1, x2, y2, color, z_order=0)
window.draw_line(x1, y1, color,
x2, y1, color,
z_order)
window.draw_line(x1, y1, color,
x1, y2, color,
z_order)
window.draw_line(x1, y2, color,
x2, y2, color,
z_order)
window.draw_line(x2, y1, color,
x2, y2, color,
z_order)
end
def hit?(x, y)
x >= @x1 && x <= @x2 &&
y >= @y1 && y <= @y2
end
end
class Bat
include Base
attr_reader :x, :y
attr_writer :swinging
def initialize(window, base_x, base_y, max_y, image_path=nil)
@window = window
@base_x = base_x
@base_y = base_y
@x = @base_x
@y = @base_y
@max_y = max_y
@central_x = @window.width * 0.8
@central_y = (@base_y + @max_y) / 2
@radius = @window.height * 0.02
@angle = 0
@speed = @window.height * 0.02
@moving = true
@swinging = false
if image_path
@image = Gosu::Image.new(@window, image_path, false)
end
end
def move
return unless @moving
if @swinging
return if @y <= @max_y
@y += Gosu.offset_y(@angle, @speed)
else
return if @y >= @base_y
@y -= Gosu.offset_y(@angle, @speed)
end
end
def draw
if @image
@image.draw(@x - @radius,
@y - @radius,
ZOrder::Bat,
2.0 * @radius / @image.width,
2.0 * @radius / @image.height)
else
color = Gosu::Color::BLACK
@window.draw_line(@x - @radius * 3, @y, color,
@central_x, @central_y, color,
ZOrder::Bat)
end
end
def meet?(ball)
return unless @swinging
return if @y <= @max_y
Gosu::distance(@x, @y, ball.x, ball.y) < (@window.height * 0.02)
end
def reflect_angle
(@central_y - @y) * (@window.height * 0.02)
end
end
class Ball
include Base
attr_reader :x, :y
attr_accessor :flying
def initialize(window, image_path=nil)
@window = window
@x = @y = 0.0
@ball_radius = @window.height * 0.02
@angle = 180
@speed = @window.height * 0.02
@moving = true
@flying = false
if image_path
@image = Gosu::Image.new(@window, image_path, false)
end
end
def draw
if @image
@image.draw(@x - @ball_radius,
@y - @ball_radius,
ZOrder::Ball,
2.0 * @ball_radius / @image.width,
2.0 * @ball_radius / @image.height)
else
draw_square(@window,
@x - @ball_radius, @y - @ball_radius,
@x + @ball_radius, @y + @ball_radius,
Gosu::Color::WHITE, ZOrder::Ball)
draw_frame(@window,
@x - @ball_radius, @y - @ball_radius,
@x + @ball_radius, @y + @ball_radius,
Gosu::Color::BLACK, ZOrder::Ball)
end
end
def warp(x, y)
@x, @y = x, y
end
def move
return unless @moving
@x += Gosu.offset_x(@angle, @speed)
@y += Gosu.offset_y(@angle, @speed)
end
def reflect(bat)
@angle += 180
@angle %= 360
@angle += bat.reflect_angle
@speed *= 2
end
end
class Window < Gosu::Window
include Base
def initialize
super(240, 240, false)
self.caption = "Persosta"
@ball = Ball.new(self)
@ball.warp(self.width * 0.5, self.height * 0.2)
@bat = Bat.new(self,
self.width * 0.5,
self.height * 0.9,
self.height * 0.7)
end
def update
@ball.move
if button_down?(Gosu::KbSpace) ||
button_down?(Gosu::MsLeft)
@bat.swinging = true
else
@bat.swinging = false
end
@bat.move
if (not @ball.flying) && @bat.meet?(@ball)
@ball.flying = true
@ball.reflect(@bat)
end
end
def draw
draw_field
@ball.draw
@bat.draw
end
def button_down(id)
case id
when Gosu::Kb1
@ball = Ball.new(self)
@ball.warp(self.width * 0.5, self.height * 0.2)
when Gosu::KbEscape
close
end
end
private
def draw_field
draw_square(self,
0, 0,
self.width, self.height,
Gosu::Color::WHITE, ZOrder::Background)
end
end
end
window = Persosta::Window.new
window.show
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment