-
Notifications
You must be signed in to change notification settings - Fork 47
Home
It is fairly easy to create a simple game with PX8.
You could create directly a P8 empty file with at least the section code (python or lua), with the 3 functions that will be called by the engine.
- _init : Called once on startup, mainly to initialize your variables
- _update: Called once per visible frame, mainly to get keyboard input for example
- _draw: Called once per visible frame, mainly to draw things on the screen :)
With Python:
px8 / python cartridge
version 1
__python__
def _init():
pass
def _update():
pass
def _draw():
cls()
px8_print("Hello World", 40, 64, 1)
With Lua:
function _init()
end
function _update()
end
function _draw()
cls()
print("Hello World", 40, 64, 1)
end
With Rust:
extern crate px8;
extern crate sdl2;
extern crate time;
extern crate rand;
#[macro_use]
extern crate log;
extern crate fern;
use std::sync::{Arc, Mutex};
use px8::px8::math;
use px8::frontend;
use px8::gfx;
use px8::cartridge;
use px8::px8::{RustPlugin};
use px8::config::Players;
pub struct HelloWorld {
pub sprite_filename: String,
pub t: i32,
}
impl HelloWorld {
pub fn new(sprite_filename: String) -> HelloWorld {
HelloWorld {
sprite_filename: sprite_filename,
t: 0,
}
}
}
impl RustPlugin for HelloWorld {
fn init(&mut self, screen: Arc<Mutex<gfx::Screen>>) -> f64 {
match cartridge::Cartridge::parse(self.sprite_filename.clone(), false) {
Ok(c) => screen.lock().unwrap().set_sprites(c.gfx.sprites),
Err(e) => panic!("Impossible to load the assets {:?}", e),
}
return 0.;
}
fn update(&mut self, _players: Arc<Mutex<Players>>) -> f64 {
debug!("HelloWorld update");
self.t += 1;
return 0.;
}
fn draw(&mut self, screen: Arc<Mutex<gfx::Screen>>) -> f64 {
debug!("HelloWorld draw");
screen.lock().unwrap().cls();
screen.lock().unwrap().print("Hello World".to_string(), 40, 64, 1);
return 0.;
}
}
fn main() {
let logger_config = fern::DispatchConfig {
format: Box::new(|msg: &str, level: &log::LogLevel, _location: &log::LogLocation| {
format!("[{}][{}] {}", time::now().strftime("%Y-%m-%d][%H:%M:%S").unwrap(), level, msg)
}),
output: vec![fern::OutputConfig::stdout(), fern::OutputConfig::file("output.log")],
level: log::LogLevelFilter::Trace,
};
if let Err(e) = fern::init_global_logger(logger_config, log::LogLevelFilter::Info) {
panic!("Failed to initialize global logger: {}", e);
}
let helloworld_example = HelloWorld::new("./examples/helloworld/helloworld.dpx8".to_string());
let mut frontend = match frontend::Frontend::init(px8::gfx::Scale::Scale4x, false, true) {
Err(error) => panic!("{:?}", error),
Ok(frontend) => frontend
};
frontend.px8.register(helloworld_example);
frontend.start("./sys/config/gamecontrollerdb.txt".to_string());
frontend.run_native_cartridge();
}
You can test it with:
./px8 -s 4 examples/helloworld/helloworld.p8
And normally you will be able to see:
In this piece of code we used the function print (to display a message) and cls (to clear the screen)
In order to draw a simple rectangle on the screen, we will use the rect function, by providing the top left and bottom right coordinates. Let's add that in the draw function:
def _draw():
px8_print("Hello World", 40, 64, 1)
rect(30, 50, 90, 80, 7)
The last parameter is the color value, by default from 0 to 15 (you could add more colors, let's see that later), from the following palettes. By default we are using the pico8 palette, so 7 is for 'white':
A sprite in PX8 is a 8x8 pixels data located in the sprite section. To draw a sprite you need to add the sprite section in your file. Let's add one:
__gfx__
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000077007700777777007700000077000000777777000000000770007700777777007777770077000000777700000000000000000000000000000000000
00000000077007700770000007700000077000000770077000000000770007700770077007700770077000000770077000000000000000000000000000000000
00000000077007700770000007700000077000000770077000000000770707700770077007700770077000000770077000000000000000000000000000000000
00000000077777700777700007700000077000000770077000000000777777700770077007777000077000000770077000000000000000000000000000000000
00000000077007700770000007700000077000000770077000000000777077700770077007700770077000000770077000000000000000000000000000000000
00000000077007700777777007777770077777700777777000000000770007700777777007700770077777700777777000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
You could directly modify each value in your file, or use the editor:
./px8 -s 4 -e ./examples/helloworld/helloworld.p8
So let's add simple sprites in the first entries:
and save it with F5.
You will notice that it is not super easy to save the data and the code in the same file, and slow down your workflow. So we could split our example in a PX8 file that will contains references to the code and data:
{
"code": "./demos/helloworld/helloworld.py",
"data": "./demos/helloworld/helloworld.dpx8"
}
where 'helloworld.py' will contain:
def _init():
pass
def _update():
pass
def _draw():
px8_print("Hello World", 40, 64, 1)
rect(30, 50, 90, 80, 7)
and 'helloworld.dpx8':
__gfx__
...
...
...
Let's display this sprite with spr at the location 20, 20:
spr(0, 20, 20)
You could display this sprite as much as you want, everywhere:
for i in range(0, 124, 8):
spr(0, i, 20)
And of course, you could flip horizontally or vertically the sprite by using the latest arguments:
for i in range(0, 124, 8):
spr(0, i, 29, flip_x=True)
for i in range(0, 124, 8):
spr(0, i, 38, flip_y=True)
for i in range(0, 124, 8):
spr(0, i, 47, flip_x=True, flip_y=True)
Let's took our first example and edit it a little bit to change some sprites.
You could find the original tutorial here.
I converted everything to the Python support and I added new chapters.
class Ship(object):
def __init__(self, x, y):
self.x = x
self.y = y
ship = None
def _init():
global ship
ship = Ship(x=60,y=60)
def _update():
pass
def _draw():
cls()
spr(1,ship.x,ship.y)
class Ship(object):
def __init__(self, x, y, sp):
self.x = x
self.y = y
self.sp = sp
T=0
ship = None
def _init():
global ship
ship = Ship(sp=1,x=60,y=60)
def _update():
global T, ship
T=T+1
if(T%6<3):
ship.sp=1
else:
ship.sp=2
def _draw():
global ship
cls()
spr(ship.sp,ship.x,ship.y)
class Ship(object):
def __init__(self, x, y, sp):
self.x = x
self.y = y
self.sp = sp
T=0
ship = None
def _init():
global ship
ship = Ship(sp=1,x=60,y=60)
def _update():
global T, ship
T=T+1
if(T%6<3):
ship.sp=1
else:
ship.sp=2
if btn(0):
ship.x-=1
if btn(1):
ship.x+=1
if btn(2):
ship.y-=1
if btn(3):
ship.y+=1
def _draw():
global ship
cls()
spr(ship.sp,ship.x,ship.y)
class Ship(object):
def __init__(self, x, y, sp):
self.x = x
self.y = y
self.sp = sp
class Bullet(object):
def __init__(self, sp, x, y, dx, dy):
self.sp = sp
self.x = x
self.y = y
self.dx = dx
self.dy = dy
def update(self):
self.x+=self.dx
self.y+=self.dy
def draw(self):
spr(self.sp, self.x, self.y)
class Bullets(object):
def __init__(self):
self.bullets = []
def add(self, sp, x, y, dx, dy):
self.bullets.append(Bullet(sp, x, y, dx, dy))
def update(self):
for b in self.bullets:
b.update()
def draw(self):
for b in self.bullets:
b.draw()
T=0
ship = None
B = Bullets()
def _init():
global ship
ship = Ship(sp=1,x=60,y=60)
def fire():
global ship, B
B.add(3, ship.x, ship.y, 0, -3)
def _update():
global T, ship, B
T=T+1
B.update()
if(T%6<3):
ship.sp=1
else:
ship.sp=2
if btn(0):
ship.x-=1
if btn(1):
ship.x+=1
if btn(2):
ship.y-=1
if btn(3):
ship.y+=1
if btnp(4):
fire()
def _draw():
global ship, B
cls()
spr(ship.sp,ship.x,ship.y)
B.draw()
class Ship(object):
def __init__(self, x, y, sp):
self.x = x
self.y = y
self.sp = sp
class Bullet(object):
def __init__(self, sp, x, y, dx, dy):
self.sp = sp
self.x = x
self.y = y
self.dx = dx
self.dy = dy
def update(self):
self.x+=self.dx
self.y+=self.dy
def draw(self):
spr(self.sp, self.x, self.y)
class Bullets(object):
def __init__(self):
self.bullets = []
def add(self, sp, x, y, dx, dy):
self.bullets.append(Bullet(sp, x, y, dx, dy))
def update(self):
to_del = []
for k, b in enumerate(self.bullets):
b.update()
if b.x < 0 or b.x > 128 or b.y < 0 or b.y > 128:
to_del.append(b)
# delete bullets outside the screen
for remove_element in to_del:
self.bullets.pop(self.bullets.index(remove_element))
def draw(self):
for b in self.bullets:
b.draw()
T=0
ship = None
B = Bullets()
def _init():
global ship
ship = Ship(sp=1,x=60,y=60)
def fire():
global ship, B
B.add(3, ship.x, ship.y, 0, -3)
def _update():
global T, ship, B
T=T+1
B.update()
if(T%6<3):
ship.sp=1
else:
ship.sp=2
if btn(0):
ship.x-=1
if btn(1):
ship.x+=1
if btn(2):
ship.y-=1
if btn(3):
ship.y+=1
if btnp(4):
fire()
def _draw():
global ship, B
cls()
px8_print(str(len(B.bullets)), 0, 0, 9)
spr(ship.sp,ship.x,ship.y)
B.draw()
class Ship(object):
def __init__(self, x, y, sp):
self.x = x
self.y = y
self.sp = sp
class Bullet(object):
def __init__(self, sp, x, y, dx, dy):
self.sp = sp
self.x = x
self.y = y
self.dx = dx
self.dy = dy
def update(self):
self.x+=self.dx
self.y+=self.dy
def draw(self):
spr(self.sp, self.x, self.y)
class Bullets(object):
def __init__(self):
self.bullets = []
def add(self, sp, x, y, dx, dy):
self.bullets.append(Bullet(sp, x, y, dx, dy))
def update(self):
to_del = []
for k, b in enumerate(self.bullets):
b.update()
if b.x < 0 or b.x > 128 or b.y < 0 or b.y > 128:
to_del.append(b)
# delete bullets outside the screen
for remove_element in to_del:
self.bullets.pop(self.bullets.index(remove_element))
def draw(self):
for b in self.bullets:
b.draw()
class Enemy(object):
def __init__(self, sp, x, y):
self.sp = sp
self.x = x
self.y = y
def draw(self):
spr(self.sp, self.x, self.y)
class Enemies(object):
def __init__(self, nb):
self.enemies = []
for i in range(0, nb):
self.enemies.append(Enemy(sp=17, x=i*16, y=60-i*8))
def draw(self):
for e in self.enemies:
e.draw()
T=0
ship = None
B = Bullets()
E = Enemies(10)
def _init():
global ship
ship = Ship(sp=1,x=60,y=60)
def fire():
global ship, B
B.add(3, ship.x, ship.y, 0, -3)
def _update():
global T, ship, B
T=T+1
B.update()
if(T%6<3):
ship.sp=1
else:
ship.sp=2
if btn(0):
ship.x-=1
if btn(1):
ship.x+=1
if btn(2):
ship.y-=1
if btn(3):
ship.y+=1
if btnp(4):
fire()
def _draw():
global ship, B, E
cls()
px8_print(str(len(B.bullets)), 0, 0, 9)
spr(ship.sp,ship.x,ship.y)
B.draw()
E.draw()
It is simple with Python support to use for example the Pymunk physical engine.
Please check the example in the demos directory.