Skip to content

Instantly share code, notes, and snippets.

@runnerpack
Created January 10, 2014 00:05
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 runnerpack/8344513 to your computer and use it in GitHub Desktop.
Save runnerpack/8344513 to your computer and use it in GitHub Desktop.
My basic implementation of "platformer" physics, based on information from http://freespace.virgin.net/hugo.elias/models/m_main.htm You'll need to supply your own "dude.png" to act as a character.
# Fix require path issues in 1.9.*
$: << "."
begin; require 'rubygems'; rescue; end
require 'gosu'
include Gosu
#require 'texplay'
# Screen size
W = 1024
H = 576
# Full-screen mode
FS = false
# Update interval (Hz)
FPS = 60
# Acceleration due to gravity (not sure what the units are; it doesn't have to be based on the update interval)
GRAVITY = FPS.div(20)
class Point
attr_accessor :x, :y
def initialize(x = 0, y = 0)
@x = x
@y = y
end
end # Point class
class Jumpman
attr_accessor :pos, :speed, :f_ground, :f_air, :tv, :jumps, :maxjumps, :color, :face
attr_reader :grav
def initialize (win, x, y, speed = 2, grav = 1.0, f_ground = 0.85, f_air = 0.85, tv = 64)
@win = win
@pos = Point.new(x, y)
@vel = Point.new(0, 0)
@acc = Point.new(0, 0)
# @acc = Point.new(0, @grav * GRAVITY)
@speed = speed
self.grav = grav
@f_ground = f_ground
@f_air = f_air
@tv = tv
@color = 0xFFFFFFFF
@jumps = 0
@maxjumps = 1
@face = 1.0
# TODO: Replace with load_from_tiles for animation
@player = Gosu::Image.new(@win, "dude.png", true)
@vel = Point.new(@player.width * -0.5, -@player.height + 5)
end # Jumpman.new
def grav=(g)
@grav = g
@acc.y = @grav * GRAVITY if @acc
end
def draw
@win.translate(@pos.x, @pos.y) {
@player.draw_rot(0, 0, 0, 0.0, 0.5, 1.0, @face, @grav < 0 ? -1.0 : 1.0, @color)
}
end # Jumpman#draw
def update
@pos.x += @vel.x
@pos.y += @vel.y
@vel.x += @acc.x
@vel.y += @acc.y
# I haven't implemented Hugo's "wind resistance" formula, yet, hence this cludge.
if @jumps > 0
@vel.x *= @f_air
else
@vel.x *= @f_ground
end
if @vel.y.abs > @tv
@vel.y = @tv * @grav
end
# Simple collision to keep player from falling off the screen
if (@pos.y > H * 0.95)
@pos.y = H * 0.95
@vel.y = 0
@jumps = 0
elsif (@pos.y < H * 0.05)
@pos.y = H * 0.05
@vel.y = 0
@jumps = 0
end
end # Jumpman#update
def button_down(id)
case id
when GpLeft, KbLeft
@face = -1.0
@acc.x = -@speed
when GpRight, KbRight
@face = 1.0
@acc.x = @speed
when GpButton2, KbLeftControl
# Jump
if @jumps < @maxjumps
@jumps += 1
@vel.y = -@grav * GRAVITY * 12.0
end
end
end # Jumpman#button_down
def button_up(id)
case id
when GpLeft, GpRight, KbLeft, KbRight
@acc.x = 0.0
when GpButton2
# Reserved for fireballs, etc. ;)
when GpButton0, KbSpace
# Gravity flip!
self.grav = -@grav
@jumps = @maxjumps
end
end # Jumpman#button_up
end # class Jumpman
class GfxWindow < Gosu::Window
def initialize
# Call the base class' initialize
super W, H, FS, 1.0 / FPS * 1000
self.caption = "Jumping Physics!"
# Sprites
@actors = []
# Player
@actors << Jumpman.new(self, W * 0.5, H * 0.25)
# Collectables
@statics = []
# @statics << Item.new(self, W * 0.85, H * 0.75)
# @background = Image.new(self, 'blank_room.jpg', false)
@info = Gosu::Font.new(self, Gosu::default_font_name, 14)
@last_time = Gosu::milliseconds()
end
def button_down(id)
@actors.each do |a|
a.button_down(id)
end
if id == Gosu::Button::KbEscape then
close
end
end
def button_up(id)
@actors.each do |a|
a.button_up(id)
end
end
def draw
# @background.draw(0, 0, -1000, W.to_f / @background.width, H.to_f / @background.height)
@actors.each do |a|
a.draw
end
# @statics.each do |s|
# s.draw
# end
# @info.draw("x: #{@actors[0].x.floor} y: #{@actors[0].y.floor} ms: #{Gosu::milliseconds() - @last_time}", 10, 10, 0)
@last_time = Gosu::milliseconds()
end
def update
@actors.each do |a|
a.update
end
# @statics.each do |s|
# s.update
# end
end
def needs_cursor?()
true
end
end # class GfxWindow
begin
$window = GfxWindow.new
$window.show
rescue Exception => e
puts e.message, e.backtrace
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment