-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit 6159396
Showing
36 changed files
with
387 additions
and
0 deletions.
There are no files selected for viewing
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
.DS_Store | ||
doc/* | ||
.rvmrc |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
#!/usr/bin/env ruby | ||
|
||
$:.push File.expand_path('../../lib', __FILE__) | ||
|
||
begin | ||
require 'java' | ||
rescue LoadError | ||
puts 'This game requires JRuby. Please load JRuby and try again.' | ||
return false | ||
end | ||
|
||
require 'lwjgl.jar' | ||
require 'slick.jar' | ||
require 'breakout' | ||
|
||
java_import org.newdawn.slick.AppGameContainer | ||
|
||
app = AppGameContainer.new(Breakout::Game.new) | ||
app.set_display_mode(640, 480, false) | ||
app.start |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,106 @@ | ||
require 'java' | ||
require 'lwjgl.jar' | ||
require 'slick.jar' | ||
|
||
java_import org.newdawn.slick.BasicGame | ||
java_import org.newdawn.slick.GameContainer | ||
java_import org.newdawn.slick.Graphics | ||
java_import org.newdawn.slick.Image | ||
java_import org.newdawn.slick.Input | ||
java_import org.newdawn.slick.SlickException | ||
|
||
require 'breakout/paddle' | ||
require 'breakout/ball' | ||
require 'breakout/block' | ||
|
||
class Breakout | ||
class Game < BasicGame | ||
def initialize | ||
super('RubyBreakout') | ||
end | ||
|
||
def init(container) | ||
@bg = Image.new('media/bg.png') | ||
@ball = Breakout::Ball.new | ||
@paddle = Breakout::Paddle.new | ||
@blocks = [] | ||
@score = 0 | ||
5.times do |row_count| | ||
y = (row_count+1) * 25 | ||
5.times do |cell_count| | ||
x = (cell_count * 100) | ||
x += 10 if cell_count == 0 | ||
|
||
block = Breakout::Block.new(x, y) | ||
@blocks.push(block) | ||
end | ||
end | ||
end | ||
|
||
def render(container, graphics) | ||
@bg.draw(0, 0) | ||
@ball.draw | ||
@paddle.draw | ||
@blocks.each do |b| | ||
b.draw | ||
end | ||
graphics.draw_string("SCORE: #{@score}", container.width - 100, 10) | ||
graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30) | ||
if game_won? | ||
graphics.draw_string("YOU WIN!", container.width / 2, container.height / 2) | ||
end | ||
end | ||
|
||
def update(container, delta) | ||
handle_input(container, delta) | ||
unless game_won? | ||
@ball.move(delta) | ||
collision_detection(container, delta) | ||
end | ||
end | ||
|
||
def handle_input(container, delta) | ||
input = container.get_input | ||
container.exit if input.is_key_down(Input::KEY_ESCAPE) | ||
|
||
if input.is_key_down(Input::KEY_LEFT) || input.is_key_down(Input::KEY_A) | ||
@paddle.move(-delta) if !@paddle.leaving_the(container, 'left') | ||
end | ||
|
||
if input.is_key_down(Input::KEY_RIGHT) || input.is_key_down(Input::KEY_D) | ||
@paddle.move(delta) if !@paddle.leaving_the(container, 'right') | ||
end | ||
end | ||
|
||
def collision_detection(container, delta) | ||
if @ball.leaving_the container | ||
@ball.bounce | ||
end | ||
|
||
if @ball.leaving_the container, 'bottom' | ||
reset | ||
end | ||
|
||
if @ball.is_colliding_with? @paddle | ||
@ball.bounce | ||
end | ||
|
||
@blocks.each do |block| | ||
if @ball.is_colliding_with? block | ||
@ball.bounce | ||
@blocks.delete(block) | ||
@score += 150 | ||
end | ||
end | ||
end | ||
|
||
def reset | ||
@ball.reset | ||
@paddle.reset | ||
end | ||
|
||
def game_won? | ||
@blocks.empty? | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
require 'java' | ||
require 'lwjgl.jar' | ||
require 'slick.jar' | ||
|
||
java_import org.newdawn.slick.Image | ||
|
||
require 'breakout/image_context' | ||
require 'breakout/collision' | ||
|
||
class Breakout | ||
class Ball | ||
include Breakout::ImageContext | ||
include Breakout::Collision | ||
attr_accessor :x, :y, :velocity, :angle | ||
|
||
def initialize | ||
@image = Image.new('media/ball.png') | ||
reset | ||
end | ||
|
||
def reset | ||
@x = 200 | ||
@y = 200 | ||
@angle = 45 | ||
@velocity = 0.3 | ||
end | ||
|
||
def move(delta) | ||
@x += @velocity * delta * Math.cos(@angle * Math::PI / 180) | ||
@y -= @velocity * delta * Math.sin(@angle * Math::PI / 180) | ||
end | ||
|
||
def bounce | ||
@angle = (@angle + 90) % 360 | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
require 'java' | ||
require 'lwjgl.jar' | ||
require 'slick.jar' | ||
|
||
java_import org.newdawn.slick.Image | ||
|
||
require 'breakout/image_context' | ||
require 'breakout/collision' | ||
|
||
class Breakout | ||
class Block | ||
include Breakout::ImageContext | ||
include Breakout::Collision | ||
attr_accessor :x, :y | ||
def initialize(x,y) | ||
@x = x | ||
@y = y | ||
@image = Image.new('media/block.png') | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
require 'core_ext' | ||
|
||
class Breakout | ||
# Used for collision detection of the ball to the container and the ball to the paddle. | ||
# This module assumes the existence of dimension attributes (x, y, width, height) | ||
module Collision | ||
# Detect block-style object collision | ||
# | ||
# @param [Object] Entity to detect collision with | ||
# @return [Boolean] Collision state | ||
def is_colliding_with? entity | ||
entity_x = (entity.x)..(entity.x + entity.width) | ||
entity_y = (entity.y)..(entity.y + entity.height) | ||
x_range = (x)..(x + width) | ||
y_range = (y)..(y + height) | ||
|
||
!(entity_x & x_range).nil? && !(entity_y & y_range).nil? | ||
end | ||
|
||
# Detect if the object is leaving the containment of `entity` | ||
# | ||
# @param [Object] The container entity | ||
# @param [String] The edge to detect containment on. Defaults to 'all' | ||
# @return [Boolean] Containment state | ||
def leaving_the entity, edge = 'all' | ||
case edge | ||
when 'all' | ||
%w{left right top bottom}.each do |direction| | ||
return true if leaving_the(entity, direction) | ||
end | ||
when 'left' | ||
return x < 0 | ||
when 'right' | ||
return x > entity.width - width | ||
when 'top' | ||
return y < 0 | ||
when 'bottom' | ||
return y > entity.height | ||
end | ||
return false | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
class Breakout | ||
# Images in Slick2D work differently than...well, any other game library I've worked with. Instead of | ||
# explicitly binding images to the window context, it implicitly binds them by only allowing a single | ||
# container to be instantiated. | ||
# | ||
# ImageContext handles delegation of coordinates and sizing of an object to the image context. In Pong, | ||
# we use this for the Pong and Paddle | ||
module ImageContext | ||
attr_accessor :image | ||
|
||
def width | ||
@image.width | ||
end | ||
|
||
def height | ||
@image.height | ||
end | ||
|
||
def draw | ||
@image.draw(@x, @y) | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
require 'java' | ||
require 'lwjgl.jar' | ||
require 'slick.jar' | ||
|
||
java_import org.newdawn.slick.Image | ||
|
||
require 'breakout/image_context' | ||
require 'breakout/collision' | ||
|
||
class Breakout | ||
class Paddle | ||
include Breakout::ImageContext | ||
include Breakout::Collision | ||
attr_accessor :x, :y, :velocity | ||
|
||
def initialize | ||
@image = Image.new('media/paddle.png') | ||
@y = 400 | ||
reset | ||
end | ||
|
||
def reset | ||
@x = 200 | ||
@velocity = 0.3 | ||
end | ||
|
||
def move(delta) | ||
@x += velocity * delta | ||
end | ||
end | ||
end |
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
class Range | ||
def intersection(other) | ||
raise ArgumentError, 'value must be a Range' unless other.kind_of?(Range) | ||
|
||
my_min, my_max = first, exclude_end? ? max : last | ||
other_min, other_max = other.first, other.exclude_end? ? other.max : other.last | ||
|
||
new_min = self === other_min ? other_min : other === my_min ? my_min : nil | ||
new_max = self === other_max ? other_max : other === my_max ? my_max : nil | ||
|
||
new_min && new_max ? new_min..new_max : nil | ||
end | ||
|
||
alias_method :&, :intersection | ||
end |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
This file contains 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
require 'java' | ||
require 'lwjgl.jar' | ||
require 'slick.jar' | ||
require 'pong/ball' | ||
require 'pong/paddle' | ||
|
||
java_import org.newdawn.slick.BasicGame | ||
java_import org.newdawn.slick.GameContainer | ||
java_import org.newdawn.slick.Graphics | ||
java_import org.newdawn.slick.Image | ||
java_import org.newdawn.slick.Input | ||
java_import org.newdawn.slick.SlickException | ||
|
||
module Pong | ||
# We subclass BasicGame so we can let Slick2D handle the rendering and main game loop | ||
# This means we need to define `render`, `init`, and `update`. | ||
class Game < BasicGame | ||
def initialize | ||
super('RubyPong') | ||
end | ||
|
||
# This method is called continuously. Rule of thumb: Always redraw the screen from blank. You do not | ||
# because you do not know if `update` will have been called. | ||
def render(container, graphics) | ||
@bg.draw(0, 0) | ||
@ball.draw | ||
@paddle.draw | ||
graphics.draw_string('RubyPong (ESC to exit)', 8, container.height - 30) | ||
end | ||
|
||
# Establishes the connection between container and game state. Creates our game objects. We have `init` | ||
# AND `initialize` because Java sucks at naming... | ||
# | ||
# @param [AppContainer] - The AppContainer state | ||
def init(container) | ||
@bg = Image.new('bg.png') | ||
@ball = Pong::Ball.new | ||
@paddle = Pong::Paddle.new | ||
end | ||
|
||
# This is your game logic method. This will be called continuously in the main game loop and should be | ||
# the entry point for input handling and game state change. Do NOT put rendering logic in the update method | ||
# due to the nature of update vs render running potentially simultaneously | ||
# | ||
# @param [AppContainer] - The AppContainer game state | ||
# @param [Float] - The time since last update call | ||
def update(container, delta) | ||
handle_input(container, delta) | ||
@ball.move(delta) | ||
collision_detection(container) | ||
end | ||
|
||
# Handles input to move the paddle left/right and game exit. | ||
# Controls: [LEFT/A] for left, [RIGHT/D] for right, [ESC] to exit | ||
# | ||
# Input handler. Every key is mapped to a constant in the Input class. This method is not an override, but | ||
# it's a good idea to isolate your input handler from your game logic as it will be the second most bloated | ||
# point for game logic | ||
# | ||
# @param [AppContainer] - The AppContainer game state | ||
# @param [Float] - Time since last update call | ||
def handle_input(container, delta) | ||
input = container.get_input | ||
container.exit if input.is_key_down(Input::KEY_ESCAPE) | ||
|
||
@paddle.move(-delta) if (input.is_key_down(Input::KEY_LEFT) || input.is_key_down(Input::KEY_A)) && !@paddle.container_collision(container, 'left') | ||
@paddle.move(delta) if (input.is_key_down(Input::KEY_RIGHT) || input.is_key_down(Input::KEY_D)) && !@paddle.container_collision(container, 'right') | ||
end | ||
|
||
# Collision detection for the ball staying within the window container | ||
# | ||
# @param [container] - the AppContainer object state | ||
def collision_detection(container) | ||
if @ball.colliding_with_container? container | ||
@ball.angle = (@ball.angle + 90) % 360 | ||
end | ||
|
||
if @ball.container_collision(container, 'bottom') | ||
@paddle.reset | ||
@ball.reset | ||
end | ||
|
||
if @ball.is_colliding_with? @paddle | ||
@ball.angle = (@ball.angle + 90) % 360 | ||
end | ||
end | ||
end | ||
end |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.