Added the trunk/branches/tags directories at repository root, and moved previous root into trunk/
git-svn-id: https://sfml.svn.sourceforge.net/svnroot/sfml/trunk@1002 4e206d99-4929-0410-ac5d-dfc041789085
1
ruby/test/SideScroller.bat
Normal file
|
@ -0,0 +1 @@
|
|||
..\bin\ruby.exe SideScroller.rb
|
240
ruby/test/SideScroller.rb
Normal file
|
@ -0,0 +1,240 @@
|
|||
require 'RubySFML'
|
||||
include SFML
|
||||
|
||||
module Tiles
|
||||
Grass = 0
|
||||
Earth = 1
|
||||
end
|
||||
|
||||
# Collectible item.
|
||||
class Gem2 < Sprite
|
||||
def initialize(image, x, y)
|
||||
super(image)
|
||||
self.x = x
|
||||
self.y = y
|
||||
end
|
||||
|
||||
def update
|
||||
self.rotation = 25 * Math.sin($clock.to_f*6)
|
||||
end
|
||||
end
|
||||
|
||||
class Player < VSprite
|
||||
attr_reader :score
|
||||
|
||||
def initialize(image, w, h)
|
||||
super(image, w, h)
|
||||
@sb = SoundBuffer.new("media/Beep.wav")
|
||||
@sound = Sound.new(@sb)
|
||||
@score = 0
|
||||
end
|
||||
|
||||
def update(window, map)
|
||||
time = window.frameTime
|
||||
input = window.input
|
||||
|
||||
# If there's no ground beneath my feet, increase speed downward
|
||||
if !map.solid?(self.x, self.bottom)
|
||||
@vy += 1
|
||||
# If there is ground beneath my feet, and the user presses up,
|
||||
# boost speed upwards to jump
|
||||
elsif input.isKeyDown(Key::Up)
|
||||
@vy = -20
|
||||
end
|
||||
|
||||
super(1) # Update position based on velocity
|
||||
|
||||
# If we just moved down, see it we landed
|
||||
if @vy > 0
|
||||
if map.solid?(self.x, self.bottom)
|
||||
@vy = 0
|
||||
self.top -= self.top % 50
|
||||
end
|
||||
# If we just moved up, see if we hit our head
|
||||
elsif @vy < 0
|
||||
if map.solid?(self.x, self.top)
|
||||
@vy = 0
|
||||
self.top += 50 - self.top % 50
|
||||
end
|
||||
end
|
||||
|
||||
moved = false
|
||||
if input.isKeyDown(Key::Left)
|
||||
moved = true
|
||||
self.x -= 10
|
||||
# If we just moved left, see if we hit a wall
|
||||
if map.solid?(self.left, self.y)
|
||||
self.left += 50 - self.left % 50
|
||||
end
|
||||
end
|
||||
|
||||
if input.isKeyDown(Key::Right)
|
||||
moved = true
|
||||
self.x += 10
|
||||
# If we just moved right, see if we hit a wall
|
||||
if map.solid?(self.right, self.y)
|
||||
self.left -= self.left % 50
|
||||
end
|
||||
end
|
||||
|
||||
if @vy < 0
|
||||
@tx = 3
|
||||
elsif moved
|
||||
@tx = (@tx + 1) % 3
|
||||
else
|
||||
@tx = 0
|
||||
end
|
||||
|
||||
# Same as in the tutorial game.
|
||||
map.gems.reject! do |c|
|
||||
if (c.x - self.x).abs < 50 and (c.y - self.y).abs < 50
|
||||
@sound.play
|
||||
@score += 10
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Map class holds and draws tiles and gems.
|
||||
class Map < Drawable
|
||||
attr_reader :width, :height, :gems
|
||||
|
||||
def initialize(filename, player)
|
||||
@start = Time.now
|
||||
@tileset_image = Image.new("media/Tileset.png")
|
||||
@tileset = TSprite.new(@tileset_image, 50, 50)
|
||||
@gem_image = Image.new("media/Gem.png")
|
||||
@gems = []
|
||||
@exit_image = Image.new("media/Star.png")
|
||||
@exit = TSprite.new(@exit_image, 25, 25)
|
||||
|
||||
lines = File.readlines(filename).map { |line| line.chop }
|
||||
@height = lines.size
|
||||
@width = lines[0].size
|
||||
@tiles = Array.new(@width) do |x|
|
||||
Array.new(@height) do |y|
|
||||
case lines[y][x, 1]
|
||||
when '"' then Tiles::Grass
|
||||
when '#' then Tiles::Earth
|
||||
when 'S' then player.x, player.y = x*50, y*50; nil
|
||||
when 'E' then @exit.left, @exit.top = x*50+25, y*50+25; nil
|
||||
when 'x' then @gems << Gem2.new(@gem_image, x * 50 + 25, y * 50 + 25); nil
|
||||
else nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def done?(player)
|
||||
player.x.to_i/50 == @exit.x.to_i/50 and player.y.to_i/50 == @exit.y.to_i/50
|
||||
end
|
||||
|
||||
def render(window)
|
||||
# Very primitive drawing function:
|
||||
# Draws all the tiles, some off-screen, some on-screen.
|
||||
@height.times do |y|
|
||||
@width.times do |x|
|
||||
tile = @tiles[x][y]
|
||||
if tile
|
||||
@tileset.tx = tile
|
||||
@tileset.left = x * 50
|
||||
@tileset.top = y * 50
|
||||
window.draw(@tileset) if
|
||||
@tileset.right > window.view.left and
|
||||
@tileset.left < window.view.right and
|
||||
@tileset.bottom > window.view.top and
|
||||
@tileset.top < window.view.bottom
|
||||
end
|
||||
end
|
||||
end
|
||||
@gems.each { |c|
|
||||
c.update
|
||||
window.draw(c) if
|
||||
c.right > window.view.left and
|
||||
c.left < window.view.right and
|
||||
c.bottom > window.view.top and
|
||||
c.top < window.view.bottom
|
||||
}
|
||||
window.draw(@exit)
|
||||
end
|
||||
|
||||
# Solid at a given pixel position?
|
||||
def solid?(x, y)
|
||||
x < 0 or y < 0 or x >= @width*50 or y >= @height*50 or @tiles[x / 50][y / 50]
|
||||
end
|
||||
end
|
||||
|
||||
$clock = Clock.new
|
||||
mode = VideoMode.new(640, 480, 32)
|
||||
win = RenderWindow.new(mode, "RubySFML Test", 0)
|
||||
view = View.new(FloatRect.new(0, 0, 640, 480))
|
||||
win.showMouseCursor(false)
|
||||
win.useVerticalSync(true)
|
||||
sky_image = Image.new("media/Space.png")
|
||||
sky = Sprite.new(sky_image)
|
||||
player_image = Image.new("media/CptnRuby.png")
|
||||
player = Player.new(player_image, 50, 50)
|
||||
levels = Dir["media/Level*.txt"].sort
|
||||
level = 1
|
||||
level_start = Time.now
|
||||
map = Map.new(levels.shift, player)
|
||||
|
||||
# Simple game loop
|
||||
done = false
|
||||
game_over = false
|
||||
while !done
|
||||
if map.done?(player)
|
||||
if levels.empty?
|
||||
game_over = true
|
||||
else
|
||||
level += 1
|
||||
level_start = Time.now
|
||||
map = Map.new(levels.shift, player)
|
||||
end
|
||||
end
|
||||
|
||||
while e = win.getEvent()
|
||||
done = true if e.type == Event::Closed or
|
||||
(e.type == Event::KeyReleased and e.code == Key::Escape)
|
||||
end
|
||||
|
||||
player.update(win, map)
|
||||
|
||||
left = player.x - 640/2
|
||||
left = 0 if left < 0
|
||||
left = map.width*50-640 if left > map.width*50-640
|
||||
top = player.y - 480/2
|
||||
top = 0 if top < 0
|
||||
top = map.height*50-480 if top > map.height*50-480
|
||||
view.rect = FloatRect.new(left, top, left+640, top+480)
|
||||
win.setView(view)
|
||||
|
||||
sky.left = view.rect.left
|
||||
sky.top = view.rect.top
|
||||
win.draw(sky)
|
||||
win.draw(map)
|
||||
win.draw(player)
|
||||
score = Text.new("Score: #{player.score}", "", 20)
|
||||
score.left, score.top = sky.left, sky.top
|
||||
win.draw(score)
|
||||
|
||||
if game_over
|
||||
text = Text.new("Game Over!", "", 60)
|
||||
text.left, text.top = sky.left+200, sky.top+200
|
||||
win.draw(text)
|
||||
elsif Time.now - level_start < 3
|
||||
text = Text.new("Level #{level}!", "", 60)
|
||||
text.left, text.top = sky.left+200, sky.top+200
|
||||
win.draw(text)
|
||||
text = Text.new("(Collect the gems and find the exit)", "", 25)
|
||||
text.left, text.top = sky.left+125, sky.top+260
|
||||
win.draw(text)
|
||||
end
|
||||
|
||||
win.display()
|
||||
sleep(0.01)
|
||||
end
|
||||
|
1
ruby/test/Tetris.bat
Normal file
|
@ -0,0 +1 @@
|
|||
..\bin\ruby.exe tetris.rb
|
1
ruby/test/Tutorial.bat
Normal file
|
@ -0,0 +1 @@
|
|||
..\bin\ruby.exe Tutorial.rb
|
102
ruby/test/Tutorial.rb
Normal file
|
@ -0,0 +1,102 @@
|
|||
require 'RubySFML'
|
||||
include SFML
|
||||
|
||||
TURN = 180
|
||||
THRUST = 200
|
||||
|
||||
class Player < VSprite
|
||||
attr_reader :score
|
||||
|
||||
def initialize(image)
|
||||
super(image, image.w, image.h)
|
||||
@sb = SoundBuffer.new("media/Beep.wav")
|
||||
@beep = Sound.new(@sb)
|
||||
@score = 0
|
||||
end
|
||||
|
||||
def warp(x, y)
|
||||
self.x = x
|
||||
self.y = y
|
||||
end
|
||||
|
||||
def turn_left(time) super(TURN*time); end
|
||||
def turn_right(time) super(TURN*time); end
|
||||
def accelerate(time) super(upVector, THRUST*time); end
|
||||
def update(time)
|
||||
super(time)
|
||||
self.x %= 640
|
||||
self.y %= 480
|
||||
scale_speed(1.0 - 0.5*time)
|
||||
end
|
||||
|
||||
def collect(stars)
|
||||
stars.reject! { |star|
|
||||
if distance(star) < 35 then
|
||||
@score += 10
|
||||
@beep.play
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
class Star < TSprite
|
||||
def initialize(image)
|
||||
super(image, image.h, image.h)
|
||||
self.color = Color.new(rand(255 - 40) + 40, rand(255 - 40) + 40, rand(255 - 40) + 40, 255)
|
||||
self.x = rand * 640
|
||||
self.y = rand * 480
|
||||
self.subRect = IntRect.new(0, 0, image.h, image.h)
|
||||
@last_change = $clock.to_f
|
||||
end
|
||||
|
||||
def update(time)
|
||||
if $clock.to_f - @last_change >= 0.1 # Change every 10th of a second
|
||||
@tx = (@tx+1) % 10
|
||||
@last_change = $clock.to_f
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
$clock = Clock.new
|
||||
mode = VideoMode.new(640, 480, 32)
|
||||
win = RenderWindow.new(mode, "RubySFML Test", Window::Fullscreen)
|
||||
win.showMouseCursor(false)
|
||||
win.useVerticalSync(true)
|
||||
background_image = Image.new("media/Space.png")
|
||||
player_image = Image.new("media/Starfighter.png")
|
||||
star_image = Image.new("media/Star.png")
|
||||
|
||||
background = Sprite.new(background_image)
|
||||
player_image.createMaskFromColor(Color.new(255, 0, 255, 255))
|
||||
player = Player.new(player_image)
|
||||
player.warp(320, 240)
|
||||
stars = []
|
||||
10.times { stars << Star.new(star_image) }
|
||||
|
||||
# Simple game loop
|
||||
done = false
|
||||
while !done
|
||||
while e = win.getEvent()
|
||||
done = true if e.type == Event::Closed or
|
||||
(e.type == Event::KeyReleased and e.code == Key::Escape)
|
||||
end
|
||||
time = win.frameTime
|
||||
input = win.input
|
||||
player.turn_left(time) if input.isKeyDown(Key::Left)
|
||||
player.turn_right(time) if input.isKeyDown(Key::Right)
|
||||
player.accelerate(time) if input.isKeyDown(Key::Up)
|
||||
player.update(time)
|
||||
player.collect(stars)
|
||||
stars << Star.new(star_image) if rand(100) < 1 and stars.size < 10
|
||||
stars.each {|star| star.update(time) }
|
||||
|
||||
win.draw(background)
|
||||
stars.each {|star| win.draw(star) }
|
||||
win.draw(player)
|
||||
win.draw(Text.new("Score: #{player.score}", "", 20))
|
||||
win.display()
|
||||
end
|
||||
|
1
ruby/test/fps.bat
Normal file
|
@ -0,0 +1 @@
|
|||
..\bin\ruby.exe fps.rb
|
313
ruby/test/fps.rb
Normal file
|
@ -0,0 +1,313 @@
|
|||
require 'RubySFML'
|
||||
include SFML
|
||||
require 'gl'
|
||||
include Gl
|
||||
require 'glu'
|
||||
include Glu
|
||||
|
||||
class Array
|
||||
def magnitude
|
||||
return Math::sqrt(self[0]**2 + self[1]**2 + self[2]**2)
|
||||
end
|
||||
def normalize
|
||||
mag = self.magnitude
|
||||
return [self[0]/mag, self[1]/mag, self[2]/mag]
|
||||
end
|
||||
def normalize!
|
||||
mag = self.magnitude
|
||||
self[0] /= mag
|
||||
self[1] /= mag
|
||||
self[2] /= mag
|
||||
end
|
||||
def vec(pos)
|
||||
return [pos[0]-self[0], pos[1]-self[1], pos[2]-self[2]]
|
||||
end
|
||||
def dot(vec)
|
||||
return self[0]*vec[0] + self[1]*vec[1] + self[2]*vec[2]
|
||||
end
|
||||
def cross(vec)
|
||||
return [
|
||||
self[1]*vec[2] - self[2]*vec[1],
|
||||
self[2]*vec[0] - self[0]*vec[2],
|
||||
self[0]*vec[1] - self[1]*vec[0]
|
||||
]
|
||||
end
|
||||
end
|
||||
|
||||
class Player
|
||||
attr_accessor :pos, :view, :score
|
||||
def initialize(x, y)
|
||||
@score = 0
|
||||
@pos = [x+0.5, 10, y+0.5]
|
||||
@view = [0, 0, -1]
|
||||
end
|
||||
|
||||
def turn_left(time)
|
||||
angle = -2.0 * time
|
||||
@view[0], @view[2] = @view[0]*Math::cos(angle) - @view[2]*Math::sin(angle), @view[0]*Math::sin(angle) + @view[2]*Math::cos(angle)
|
||||
@view.normalize!
|
||||
end
|
||||
|
||||
def turn_right(time)
|
||||
angle = 2.0 * time
|
||||
@view[0], @view[2] = @view[0]*Math::cos(angle) - @view[2]*Math::sin(angle), @view[0]*Math::sin(angle) + @view[2]*Math::cos(angle)
|
||||
@view.normalize!
|
||||
end
|
||||
|
||||
def move_right(time)
|
||||
angle = 0.5*Math::PI
|
||||
right = [@view[0]*Math::cos(angle) - @view[2]*Math::sin(angle), 0, @view[0]*Math::sin(angle) + @view[2]*Math::cos(angle)]
|
||||
d = 5*time
|
||||
@pos = [@pos[0]+right[0]*d, @pos[1], @pos[2]+right[2]*d]
|
||||
end
|
||||
|
||||
def move_left(time)
|
||||
angle = 0.5*Math::PI
|
||||
right = [@view[0]*Math::cos(angle) - @view[2]*Math::sin(angle), 0, @view[0]*Math::sin(angle) + @view[2]*Math::cos(angle)]
|
||||
d = 5*time
|
||||
@pos = [@pos[0]-right[0]*d, @pos[1], @pos[2]-right[2]*d]
|
||||
end
|
||||
|
||||
def move_forward(time)
|
||||
d = 5*time
|
||||
@pos = [@pos[0]+@view[0]*d, @pos[1], @pos[2]+@view[2]*d]
|
||||
end
|
||||
|
||||
def move_backward(time)
|
||||
d = 5*time
|
||||
@pos = [@pos[0]-@view[0]*d, @pos[1], @pos[2]-@view[2]*d]
|
||||
end
|
||||
|
||||
def init_view
|
||||
glLoadIdentity()
|
||||
gluLookAt(@pos[0], @pos[1], @pos[2], @pos[0]+@view[0], @pos[1]+@view[1], @pos[2]+@view[2], 0, 1, 0)
|
||||
end
|
||||
|
||||
def update(win, map)
|
||||
pos = @pos
|
||||
input, time = win.input, win.frameTime
|
||||
turn_left(time) if input.isKeyDown(Key::Left)
|
||||
turn_right(time) if input.isKeyDown(Key::Right)
|
||||
move_forward(time) if input.isKeyDown(Key::W)
|
||||
move_backward(time) if input.isKeyDown(Key::S)
|
||||
move_left(time) if input.isKeyDown(Key::A)
|
||||
move_right(time) if input.isKeyDown(Key::D)
|
||||
@pos = pos if map.solid?(@pos[0], @pos[2])
|
||||
end
|
||||
end
|
||||
|
||||
class Block
|
||||
attr_accessor :pos
|
||||
def initialize(x, y)
|
||||
@pos = [x.to_i+0.5, 0, y.to_i+0.5]
|
||||
end
|
||||
|
||||
def draw()
|
||||
glPushMatrix()
|
||||
glTranslatef(@pos[0], @pos[1], @pos[2])
|
||||
glColor4f(1, 0, 0, 1)
|
||||
glBegin(GL_QUADS)
|
||||
# Facing +z
|
||||
glNormal3d(0, 0, 1)
|
||||
glVertex3f(0.5, 0.5, 0.5)
|
||||
glVertex3f(-0.5, 0.5, 0.5)
|
||||
glVertex3f(-0.5, -0.5, 0.5)
|
||||
glVertex3f(0.5, -0.5, 0.5)
|
||||
# Facing -z
|
||||
glNormal3d(0, 0, -1)
|
||||
glVertex3f(-0.5, 0.5, -0.5)
|
||||
glVertex3f(0.5, 0.5, -0.5)
|
||||
glVertex3f(0.5, -0.5, -0.5)
|
||||
glVertex3f(-0.5, -0.5, -0.5)
|
||||
# Facing +x
|
||||
glNormal3d(1, 0, 0)
|
||||
glVertex3f(0.5, 0.5, 0.5)
|
||||
glVertex3f(0.5, -0.5, 0.5)
|
||||
glVertex3f(0.5, -0.5, -0.5)
|
||||
glVertex3f(0.5, 0.5, -0.5)
|
||||
# Facing -x
|
||||
glNormal3d(-1, 0, 0)
|
||||
glVertex3f(-0.5, 0.5, 0.5)
|
||||
glVertex3f(-0.5, 0.5, -0.5)
|
||||
glVertex3f(-0.5, -0.5, -0.5)
|
||||
glVertex3f(-0.5, -0.5, 0.5)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
end
|
||||
end
|
||||
|
||||
class Billboard
|
||||
attr_accessor :pos
|
||||
def initialize(x, y, size=0.25)
|
||||
@size = size
|
||||
@pos = [x.to_i+0.5, 0, y.to_i+0.5]
|
||||
end
|
||||
|
||||
def draw(camera)
|
||||
normal = @pos.vec(camera.pos).normalize
|
||||
up = [0, 1, 0]
|
||||
right = up.cross(normal).normalize
|
||||
|
||||
glPushMatrix()
|
||||
glTranslatef(@pos[0], @pos[1], @pos[2])
|
||||
glColor4f(1, 1, 1, 1)
|
||||
glBegin(GL_QUADS)
|
||||
# Facing camera
|
||||
glNormal3d(normal[0], normal[1], normal[2])
|
||||
glTexCoord2f(1, 0)
|
||||
glVertex3f((right[0]+up[0])*@size, (right[1]+up[1])*@size, (right[2]+up[2])*@size)
|
||||
glTexCoord2f(0, 0)
|
||||
glVertex3f((-right[0]+up[0])*@size, (-right[1]+up[1])*@size, (-right[2]+up[2])*@size)
|
||||
glTexCoord2f(0, 1)
|
||||
glVertex3f(-(right[0]+up[0])*@size, -(right[1]+up[1])*@size, -(right[2]+up[2])*@size)
|
||||
glTexCoord2f(1, 1)
|
||||
glVertex3f((right[0]-up[0])*@size, (right[1]-up[1])*@size, (right[2]-up[2])*@size)
|
||||
glEnd()
|
||||
glPopMatrix()
|
||||
end
|
||||
end
|
||||
|
||||
# Map class holds and draws tiles and gems.
|
||||
class Map
|
||||
attr_reader :width, :height, :blocks, :gems
|
||||
|
||||
def initialize(filename, player)
|
||||
@start = Time.now
|
||||
@sb = SoundBuffer.new("media/Beep.wav")
|
||||
@sound = Sound.new(@sb)
|
||||
@gem_image = Image.new("media/Gem.png")
|
||||
@exit_image = Image.new("media/Star.png")
|
||||
@exit_image.resize(25, 25, Color.Black)
|
||||
@exit = nil
|
||||
@blocks = []
|
||||
@gems = []
|
||||
|
||||
lines = File.readlines(filename).map { |line| line.chop }
|
||||
@height = lines.size
|
||||
@width = lines[0].size
|
||||
@tiles = Array.new(@width) do |x|
|
||||
Array.new(@height) do |y|
|
||||
case lines[y][x, 1]
|
||||
when '"', '#' then @blocks << Block.new(x, y); @blocks[-1]
|
||||
when 'S' then player.pos = [x+0.5, 0, y+0.5]; nil
|
||||
when 'E' then @exit = Billboard.new(x, y); nil
|
||||
when 'x' then @gems << Billboard.new(x, y); nil
|
||||
else nil
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def draw(player)
|
||||
@blocks.each {|b| b.draw()}
|
||||
glEnable(GL_TEXTURE_2D)
|
||||
@gem_image.bind
|
||||
@gems.each {|g| g.draw(player)}
|
||||
@exit_image.bind
|
||||
@exit.draw(player)
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
end
|
||||
|
||||
def exit?(player)
|
||||
player.pos[0].to_i == @exit.pos[0].to_i and player.pos[2].to_i == @exit.pos[2].to_i
|
||||
end
|
||||
|
||||
# Solid at a given pixel position?
|
||||
def solid?(x, y)
|
||||
y < 0 or x < 0 or x >= @width or y >= @width or @tiles[x.to_i][y.to_i]
|
||||
end
|
||||
|
||||
def collect_gems(player)
|
||||
@gems.reject! {|g|
|
||||
if player.pos.vec(g.pos).magnitude <= 0.5
|
||||
@sound.play
|
||||
player.score += 10
|
||||
true
|
||||
else
|
||||
false
|
||||
end
|
||||
}
|
||||
end
|
||||
end
|
||||
|
||||
$clock = Clock.new
|
||||
mode = VideoMode.new(640, 480, 32)
|
||||
win = RenderWindow.new(mode, "RubySFML Test", 0)
|
||||
win.showMouseCursor(false)
|
||||
win.useVerticalSync(true)
|
||||
sky_image = Image.new("media/Space.png")
|
||||
player = Player.new(0, 5)
|
||||
levels = Dir["media/Level*.txt"].sort
|
||||
level = 1
|
||||
level_start = Time.now
|
||||
map = Map.new(levels.shift, player)
|
||||
|
||||
# Simple game loop
|
||||
done = false
|
||||
while !done
|
||||
if map.exit?(player)
|
||||
if levels.empty?
|
||||
game_over = true
|
||||
else
|
||||
level += 1
|
||||
level_start = Time.now
|
||||
map = Map.new(levels.shift, player)
|
||||
end
|
||||
end
|
||||
|
||||
while e = win.getEvent()
|
||||
done = true if e.type == Event::Closed or
|
||||
(e.type == Event::KeyReleased and e.code == Key::Escape)
|
||||
end
|
||||
time = win.frameTime
|
||||
player.update(win, map)
|
||||
|
||||
#win.beginOpenGL()
|
||||
glEnable(GL_DEPTH_TEST)
|
||||
glEnable(GL_CULL_FACE)
|
||||
glEnable(GL_BLEND)
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glPushMatrix()
|
||||
glLoadIdentity()
|
||||
gluPerspective(45.0, 640.0/480.0, 0.1, 100.0)
|
||||
glMatrixMode(GL_MODELVIEW)
|
||||
glPushMatrix()
|
||||
player.init_view()
|
||||
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT)
|
||||
glEnable(GL_COLOR_MATERIAL)
|
||||
glEnable(GL_LIGHTING)
|
||||
glEnable(GL_LIGHT0)
|
||||
glEnable(GL_NORMALIZE)
|
||||
glDisable(GL_TEXTURE_2D)
|
||||
glLightfv(GL_LIGHT0, GL_POSITION, player.pos + [1])
|
||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, [1, 1, 1, 1])
|
||||
glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.25)
|
||||
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, [0, 0, 0, 1])
|
||||
map.collect_gems(player)
|
||||
map.draw(player)
|
||||
glPopMatrix()
|
||||
glMatrixMode(GL_PROJECTION)
|
||||
glPopMatrix()
|
||||
#win.endOpenGL()
|
||||
|
||||
text = Text.new("Score: #{player.score}", "", 20)
|
||||
win.draw(text)
|
||||
|
||||
if game_over
|
||||
text = Text.new("Game Over!", "", 60)
|
||||
text.left, text.top = 200, 200
|
||||
win.draw(text)
|
||||
elsif Time.now - level_start < 3
|
||||
text = Text.new("Level #{level}!", "", 60)
|
||||
text.left, text.top = 200, 200
|
||||
win.draw(text)
|
||||
text = Text.new("(Collect the gems and find the exit)", "", 25)
|
||||
text.left, text.top = 125, 260
|
||||
win.draw(text)
|
||||
end
|
||||
|
||||
win.display()
|
||||
sleep(0.01)
|
||||
end
|
||||
|
BIN
ruby/test/media/Beep.wav
Normal file
BIN
ruby/test/media/CptnRuby.png
Normal file
After Width: | Height: | Size: 14 KiB |
BIN
ruby/test/media/Gem.png
Normal file
After Width: | Height: | Size: 7.5 KiB |
29
ruby/test/media/LICENSE
Normal file
|
@ -0,0 +1,29 @@
|
|||
NOTE: The Tutorial.rb and SideScroller.rb demos were ported from the gosu
|
||||
Ruby extension. As the Ruby code does not use the gosu extension, I doubt
|
||||
the code will be considered a derivative work. However, some of the
|
||||
media files are theirs, so we've included their copyright notice and license.
|
||||
|
||||
|
||||
Copyright (C) 2004-2007 Julian Raschke, Jan Lücker and all contributors.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a
|
||||
copy of this software and associated documentation files (the "Software"),
|
||||
to deal in the Software without restriction, including without limitation
|
||||
the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||
and/or sell copies of the Software, and to permit persons to whom the
|
||||
Software is furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
DEALINGS IN THE SOFTWARE.
|
||||
|
||||
Julian Raschke julian@raschke.de
|
||||
Jan Lücker jan.luecker@gmx.de
|
||||
http://code.google.com/p/gosu/
|
10
ruby/test/media/Level 1.txt
Normal file
|
@ -0,0 +1,10 @@
|
|||
##############
|
||||
#............#
|
||||
#...........##
|
||||
#...#....S...#
|
||||
#.....""""...#
|
||||
#.....#......E
|
||||
#"""""#.....##
|
||||
#.xxxx......##
|
||||
#.xxxx...#####
|
||||
######"""#####
|
26
ruby/test/media/Level 2.txt
Normal file
|
@ -0,0 +1,26 @@
|
|||
######################################################
|
||||
S....x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x...#
|
||||
#....................................................#
|
||||
#""""""""""""""""""""""""""""""""""""""""""""""""""..#
|
||||
#....................................................#
|
||||
#....................................................#
|
||||
#..""""""""""""""""""""""""""""""""""""""""""""""""""#
|
||||
#..##x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x####
|
||||
#....................................................#
|
||||
#.........###...........###...........###............#
|
||||
#.......#.....#.......#.....#.......#.....#..........#
|
||||
#.....#.........#...#.........#...#.........#...#....#
|
||||
#...#x.x.x.x.x.x.x#x.x.x.x.x.x.x#x.x.x.x.x.x.x#x.x...#
|
||||
#....................................................#
|
||||
#..""""""""""""""""""""""""""""""""""""""""""""""""""#
|
||||
#..###################################################
|
||||
#....x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x#x...#
|
||||
#....x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x...#
|
||||
#""""""""""""""""""""""""""""""""""""""""""""""""""..#
|
||||
###################################################..#
|
||||
#....x..x..x..x..x..x..x..x..x..x..x..x..x..x..x..x..#
|
||||
#....................................................#
|
||||
#....................................................#
|
||||
#..###################################################
|
||||
#....x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x.x...#
|
||||
####################################################E#
|
25
ruby/test/media/Level 3.txt
Normal file
|
@ -0,0 +1,25 @@
|
|||
######################################################
|
||||
#........S...........................................#
|
||||
#.............xx......x.x............................#
|
||||
#............x..x....................................#
|
||||
#x....x...x..x.......#####..xxx....................x.#
|
||||
#.x.........................xxx.........##.........x.#
|
||||
#...............""..........###...##..........##.....#
|
||||
#..##..###..##..##...................................#
|
||||
#........................................xx........###
|
||||
#.............................###....................#
|
||||
##....##.............................................#
|
||||
#....................##....##......##....##....##....#
|
||||
#.................................................x..#
|
||||
#...x....##....##.......x...x.....................x..#
|
||||
#.....x...............x...x...x...................x..#
|
||||
#......x...##.....##.................................#
|
||||
#.......x.........................................#..#
|
||||
#...........##........#...#...#..#.......x...........#
|
||||
#...#................................................#
|
||||
#....."""".................x.......#..#####...###....#
|
||||
#x....#......................##......................#
|
||||
#"""""#.....#.....x..................#...............#
|
||||
##xxxx......#........................................#
|
||||
##xxxx...#####............."...""""".................E
|
||||
######"""#############################################
|
BIN
ruby/test/media/Space.png
Normal file
After Width: | Height: | Size: 13 KiB |
BIN
ruby/test/media/Star.png
Normal file
After Width: | Height: | Size: 4.3 KiB |
BIN
ruby/test/media/Starfighter.png
Normal file
After Width: | Height: | Size: 2.4 KiB |
BIN
ruby/test/media/Tileset.png
Normal file
After Width: | Height: | Size: 8.5 KiB |
BIN
ruby/test/media/cannon.wav
Normal file
BIN
ruby/test/media/cursor.png
Normal file
After Width: | Height: | Size: 214 B |
1
ruby/test/test.bat
Normal file
|
@ -0,0 +1 @@
|
|||
..\bin\ruby.exe test.rb
|
99
ruby/test/test.rb
Normal file
|
@ -0,0 +1,99 @@
|
|||
require "RubySFML"
|
||||
include SFML
|
||||
|
||||
require "gl"
|
||||
include Gl
|
||||
|
||||
class TextTest < Text
|
||||
# Test overriding a virtual C++ method
|
||||
def render(win)
|
||||
self.color = Color.new(color.r+1, color.g+2, color.b+3, 255)
|
||||
super # Call base class's version of render (in C++)
|
||||
|
||||
# Custom OpenGL calls
|
||||
rect = getRect()
|
||||
#win.beginOpenGL()
|
||||
glColor4f(1, 1, 1, 1)
|
||||
glLineWidth(5)
|
||||
glBegin(GL_LINES)
|
||||
glVertex2f(0, 0)
|
||||
glVertex2f(rect.width, rect.height)
|
||||
glVertex2f(rect.width, 0)
|
||||
glVertex2f(0, rect.height)
|
||||
glEnd()
|
||||
#win.endOpenGL()
|
||||
end
|
||||
end
|
||||
|
||||
# Test Clock class
|
||||
clock = Clock.new
|
||||
10.times { sleep 0.01; puts "Clock - #{clock}" }
|
||||
puts
|
||||
|
||||
# Test VideoMode class
|
||||
puts "Current desktop mode - #{VideoMode::desktop}"
|
||||
puts "32-bit video modes:"
|
||||
VideoMode::each {|mode| puts mode.to_s if mode.bpp == 32 }
|
||||
puts
|
||||
|
||||
# Test RenderWindow class
|
||||
mode = VideoMode.new(800, 600, 32)
|
||||
win = RenderWindow.new(mode, "RubySFML Test")
|
||||
win.useVerticalSync(false)
|
||||
win.showMouseCursor(false)
|
||||
win.setBackgroundColor(Color.Red)
|
||||
puts "Window - #{win}"
|
||||
puts "View Rect - #{win.view}"
|
||||
puts
|
||||
|
||||
# Test Color, Image, and Sprite classes
|
||||
puts format("Red = 0x%X", Color.Red.toRGBA)
|
||||
puts format("Green = 0x%X", Color.Green.toRGBA)
|
||||
puts format("Blue = 0x%X", Color.Blue.toRGBA)
|
||||
puts format("Black = 0x%X", Color.Black.toRGBA)
|
||||
image = Image.new("media/cursor.png")
|
||||
sprite = Sprite.new(image)
|
||||
image.width.times {|x| puts "image[#{x},#{x}] = #{image[x,x]}" }
|
||||
image.createMaskFromColor(Color.Black) # Set black to transparent
|
||||
sprite.x = mode.w/2 - sprite.w/2
|
||||
sprite.y = mode.h/2 - sprite.h/2
|
||||
puts "Image - #{image}"
|
||||
puts "Sprite - #{sprite}"
|
||||
puts
|
||||
|
||||
# Test Text (sfString) class
|
||||
text = TextTest.new("This is a test!")
|
||||
|
||||
# Test Sound and SoundBuffer classes
|
||||
sb = SoundBuffer.new("media/cannon.wav")
|
||||
sound = Sound.new(sb)
|
||||
sound.volume = 100
|
||||
puts "SoundBuffer - #{sound.buffer}"
|
||||
puts "Sound - #{sound}"
|
||||
|
||||
# Simple game loop
|
||||
done = false
|
||||
while !done
|
||||
while e = win.getEvent()
|
||||
puts "Event - #{e.to_s}" # Dump events to stdout
|
||||
|
||||
done = true if
|
||||
e.type == Event::Closed or
|
||||
(e.type == Event::KeyReleased and e.code == Key::Escape)
|
||||
|
||||
sound.play if
|
||||
(e.type == Event::KeyPressed and e.code == Key::Space) or
|
||||
(e.type == Event::MouseButtonPressed and e.buttons == Mouse::Left)
|
||||
|
||||
sprite.x, sprite.y = e.x-sprite.w/2, e.y-sprite.h/2 if
|
||||
e.type == Event::MouseMoved
|
||||
end
|
||||
|
||||
text.left = 0 if (text.left += 1) >= 800
|
||||
text.top = 0 if (text.top += 1) >= 600
|
||||
win.draw(text)
|
||||
win.draw(sprite)
|
||||
|
||||
win.display()
|
||||
end
|
||||
|
196
ruby/test/tetris.rb
Normal file
|
@ -0,0 +1,196 @@
|
|||
require 'RubySFML'
|
||||
include SFML
|
||||
|
||||
# A simple class to handle a single puzzle piece
|
||||
class Piece
|
||||
# Each shape is made up of 4 blocks:
|
||||
# * * * * ** ** **
|
||||
# * ** ** ** * * **
|
||||
# * * * * * *
|
||||
# *
|
||||
SHAPES = [ # Negative y is down
|
||||
[[0, 0], [0, 1], [0, -1], [0, -2]],
|
||||
[[0, 0], [0, 1], [1, 0], [0, -1]],
|
||||
[[0, 0], [0, 1], [1, 0], [1, -1]],
|
||||
[[1, 0], [1, 1], [0, 0], [0, -1]],
|
||||
[[0, 0], [0, 1], [1, 1], [0, -1]],
|
||||
[[1, 0], [1, 1], [0, 1], [1, -1]],
|
||||
[[0, 0], [0, 1], [1, 1], [1, 0]],
|
||||
]
|
||||
# Each shape has its own color
|
||||
COLORS = [Color.Red, Color.Yellow, Color.Cyan, Color.Magenta, Color.Green, Color.Blue, Color.new(255, 128, 64)]
|
||||
|
||||
attr_accessor :x, :y, :r
|
||||
def initialize(n, x, y)
|
||||
@n, @x, @y = n, x, y
|
||||
@r = 0
|
||||
end
|
||||
|
||||
def shape(); SHAPES[@n]; end
|
||||
def color(); COLORS[@n]; end
|
||||
def rleft(); @r = (@r+1) % 4; end
|
||||
def rright(); @r = (@r-1) % 4; end
|
||||
def each() # Iterate each block coordinate (corrected for rotation)
|
||||
case @r
|
||||
when 0 then shape.each {|c| yield([c[0], c[1]])}
|
||||
when 1 then shape.each {|c| yield([-c[1], c[0]])}
|
||||
when 2 then shape.each {|c| yield([-c[0], -c[1]])}
|
||||
when 3 then shape.each {|c| yield([c[1], -c[0]])}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
class Grid
|
||||
HEIGHT = 20
|
||||
WIDTH = 10
|
||||
BLOCK = 18
|
||||
BORDER = 1
|
||||
BSIZE = BLOCK + BORDER
|
||||
|
||||
def initialize()
|
||||
@rows = []
|
||||
HEIGHT.times { @rows.push Array.new(WIDTH) }
|
||||
@background_image = Image.new(WIDTH*(BSIZE)+BORDER, HEIGHT*BSIZE+BORDER, Color.White)
|
||||
@background = Sprite.new(@background_image, (640-WIDTH*BSIZE)/2-BORDER, (480-HEIGHT*BSIZE)/2-BORDER)
|
||||
@block_image = Image.new(BLOCK, BLOCK, Color.White)
|
||||
@block = Sprite.new(@block_image)
|
||||
|
||||
@score = 0
|
||||
@last_down = $clock.to_f
|
||||
@piece = Piece.new(rand(7), WIDTH/2-1, HEIGHT-1)
|
||||
@next_piece = Piece.new(rand(7), WIDTH/2-1, HEIGHT-1)
|
||||
end
|
||||
|
||||
def [](y)
|
||||
return @rows[y]
|
||||
end
|
||||
|
||||
def draw_block(win, x, y, color)
|
||||
@block.left = x*BSIZE + @background.left+BORDER
|
||||
@block.top = ((HEIGHT-1)-y)*BSIZE + @background.top+BORDER
|
||||
@block.color = color
|
||||
win.draw(@block)
|
||||
end
|
||||
|
||||
def solid?(x, y)
|
||||
return true if x < 0 or y < 0 or x >= WIDTH or y >= HEIGHT
|
||||
return @rows[y][x]
|
||||
end
|
||||
|
||||
def left
|
||||
x = @piece.x
|
||||
@piece.x -= 1
|
||||
@piece.each {|c| @piece.x = x if solid?(@piece.x+c[0], @piece.y+c[1])}
|
||||
end
|
||||
|
||||
def right
|
||||
x = @piece.x
|
||||
@piece.x += 1
|
||||
@piece.each {|c| @piece.x = x if solid?(@piece.x+c[0], @piece.y+c[1])}
|
||||
end
|
||||
|
||||
def up
|
||||
r = @piece.r
|
||||
@piece.rright
|
||||
@piece.each {|c| @piece.r = r if solid?(@piece.x+c[0], @piece.y+c[1])}
|
||||
end
|
||||
|
||||
def down
|
||||
@last_down = $clock.to_f
|
||||
y = @piece.y
|
||||
@piece.y -= 1
|
||||
done = false
|
||||
@piece.each {|c| done = true if solid?(@piece.x+c[0], @piece.y+c[1])}
|
||||
if done
|
||||
@piece.y = y
|
||||
@piece.each {|c| @rows[@piece.y+c[1]][@piece.x+c[0]] = @piece.color}
|
||||
@piece = @next_piece
|
||||
@next_piece = Piece.new(rand(7), WIDTH/2-1, HEIGHT-1)
|
||||
end
|
||||
end
|
||||
|
||||
def update(win)
|
||||
speed = 0.5 - 0.1 * (@score/1000)
|
||||
down if $clock.to_f - @last_down >= speed
|
||||
|
||||
collapsed = 0
|
||||
while y = find_full_row()
|
||||
collapse_row(y)
|
||||
collapsed += 1
|
||||
end
|
||||
@score += 5 * 2**collapsed if collapsed > 0
|
||||
end
|
||||
|
||||
def render(win)
|
||||
win.draw(@background)
|
||||
|
||||
HEIGHT.times {|y|
|
||||
WIDTH.times {|x|
|
||||
c = @rows[y][x] || Color.Black
|
||||
draw_block(win, x, y, c)
|
||||
}
|
||||
}
|
||||
|
||||
@piece.each {|c|
|
||||
x, y, c = @piece.x+c[0], @piece.y+c[1], @piece.color
|
||||
next if y < 0 or y > HEIGHT-1
|
||||
draw_block(win, x, y, c)
|
||||
}
|
||||
|
||||
score = Text.new("Score: #{@score}", "", 20)
|
||||
#score.left, score.top = 10, 10
|
||||
win.draw(score)
|
||||
|
||||
text = Text.new("Coming Next:", "", 20)
|
||||
text.left, text.top = 450, 50
|
||||
win.draw(text)
|
||||
@next_piece.each {|c|
|
||||
x, y, c = 14+c[0], 16+c[1], @next_piece.color
|
||||
next if y < 0 or y > HEIGHT-1
|
||||
draw_block(win, x, y, c)
|
||||
}
|
||||
end
|
||||
|
||||
def collapse_row(i)
|
||||
while i < HEIGHT-1
|
||||
@rows[i] = @rows[i+1]
|
||||
i += 1
|
||||
end
|
||||
@rows[HEIGHT-1] = Array.new(WIDTH, nil)
|
||||
end
|
||||
|
||||
def find_full_row()
|
||||
HEIGHT.times {|y| return y unless @rows[y].index(nil) }
|
||||
return nil
|
||||
end
|
||||
end
|
||||
|
||||
$clock = Clock.new
|
||||
mode = VideoMode.new(640, 480, 32)
|
||||
win = RenderWindow.new(mode, "RubySFML Test", 0)
|
||||
win.showMouseCursor(false)
|
||||
win.useVerticalSync(true)
|
||||
grid = Grid.new()
|
||||
|
||||
# Simple game loop
|
||||
done = false
|
||||
while !done
|
||||
while e = win.getEvent()
|
||||
case e.type
|
||||
when Event::Closed then done = true
|
||||
when Event::KeyReleased then done = true if e.code == Key::Escape
|
||||
when Event::KeyPressed
|
||||
case e.code
|
||||
when Key::Up then grid.up
|
||||
when Key::Left then grid.left
|
||||
when Key::Right then grid.right
|
||||
when Key::Down then grid.down
|
||||
end
|
||||
end
|
||||
end
|
||||
grid.update(win)
|
||||
grid.render(win)
|
||||
win.display()
|
||||
sleep(0.01)
|
||||
end
|
||||
|