Skip to content

Instantly share code, notes, and snippets.

@mahmed8003
Created February 8, 2016 09:16
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
  • Save mahmed8003/df4dc64b2201e4df7050 to your computer and use it in GitHub Desktop.
Save mahmed8003/df4dc64b2201e4df7050 to your computer and use it in GitHub Desktop.
Pixi.js and Box2D debug draw demo
// Credit goes to https://gist.github.com/cbranch/260224a7e4699552d2dc
// Gets a JSDraw instance which renders to a PIXI graphics object.
// graphics: an instance of PIXI.Graphics
// scale: the scaling factor to convert from Box2D coordinates to screen pixels
function getPIXIDebugDraw(graphics, scale) {
function getColorFromDebugDrawCallback(color) {
var col = Box2D.wrapPointer(color, Box2D.b2Color);
var red = (col.get_r() * 255 * 255 * 255)|0;
var green = (col.get_g() * 255 * 255)|0;
var blue = (col.get_b() * 255)|0;
return red + green + blue;
}
function drawSegment(graphics, vert1, vert2, color) {
var vert1V = Box2D.wrapPointer(vert1, Box2D.b2Vec2);
var vert2V = Box2D.wrapPointer(vert2, Box2D.b2Vec2);
graphics.lineStyle(1, color, 1);
graphics.moveTo(vert1V.get_x() * scale, vert1V.get_y() * scale);
graphics.lineTo(vert2V.get_x() * scale, vert2V.get_y() * scale);
}
function drawPolygon(graphics, vertices, vertexCount, fill, color) {
graphics.lineStyle(1, color, 1);
if (fill) {
graphics.beginFill(color, 0.5);
}
for(tmpI=0;tmpI<vertexCount;tmpI++) {
var vert = Box2D.wrapPointer(vertices+(tmpI*8), Box2D.b2Vec2);
if ( tmpI === 0 )
graphics.moveTo(vert.get_x() * scale, vert.get_y() * scale);
else
graphics.lineTo(vert.get_x() * scale, vert.get_y() * scale);
}
if (fill) {
graphics.endFill();
}
}
function drawCircle(graphics, center, radius, axis, fill, color) {
var centerV = Box2D.wrapPointer(center, Box2D.b2Vec2);
var axisV = Box2D.wrapPointer(axis, Box2D.b2Vec2);
graphics.lineStyle(1, color, 1);
if (fill) {
graphics.beginFill(color, 0.5);
}
graphics.arc(centerV.get_x() * scale, centerV.get_y() * scale, radius * scale, 0, 2 * Math.PI, false);
if (fill) {
graphics.endFill();
}
if (fill) {
//render axis marker
var vert2V = new Box2D.b2Vec2(centerV.get_x(), centerV.get_y());
vert2V.op_add(new Box2D.b2Vec2(axisV.get_x() * radius, axisV.get_y() * radius));
graphics.moveTo(centerV.get_x() * scale, centerV.get_y() * scale);
graphics.lineTo(vert2V.get_x() * scale, vert2V.get_y() * scale);
}
}
function drawAxes(graphics, x, y, angle) {
var sin = Math.sin(angle);
var cos = Math.cos(angle);
var newX = x * scale;
var newY = y * scale;
function transform(x, y) { return { x: x * cos + y * sin, y: -x * sin + y * cos }; }
var origin = transform(newX, newY);
var xAxis = transform(newX + 100, newY);
var yAxis = transform(newX, newY + 100);
graphics.lineStyle(2, 'rgb(192,0,0)', 1);
graphics.moveTo(origin.x, origin.y);
graphics.lineTo(xAxis.x, xAxis.y);
graphics.lineStyle(2, 'rgb(0,192,0)', 1);
graphics.moveTo(origin.x, origin.y);
graphics.lineTo(yAxis.x, yAxis.y);
}
function drawTransform(transform) {
var trans = Box2D.wrapPointer(transform, Box2D.b2Transform);
var pos = trans.get_p();
var rot = trans.get_q();
drawAxes(graphics, pos.get_x(), pos.get_y(), rot.GetAngle());
}
var debugDraw = new Box2D.JSDraw();
debugDraw.DrawSegment = function(vert1, vert2, color) {
drawSegment(graphics, vert1, vert2, getColorFromDebugDrawCallback(color));
};
debugDraw.DrawPolygon = function(vertices, vertexCount, color) {
drawPolygon(graphics, vertices, vertexCount, false, getColorFromDebugDrawCallback(color));
};
debugDraw.DrawSolidPolygon = function(vertices, vertexCount, color) {
drawPolygon(graphics, vertices, vertexCount, true, getColorFromDebugDrawCallback(color));
};
debugDraw.DrawCircle = function(center, radius, color) {
drawCircle(graphics, center, radius, Box2D.b2Vec2(0,0), false, getColorFromDebugDrawCallback(color));
};
debugDraw.DrawSolidCircle = function(center, radius, axis, color) {
drawCircle(graphics, center, radius, axis, true, getColorFromDebugDrawCallback(color));
};
debugDraw.DrawTransform = function(transform) {
drawTransform(graphics, transform);
};
return debugDraw;
}
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Pinata</title>
<meta http-equiv="X-UA-Compatible" content="chrome=1, IE=9">
<meta name="format-detection" content="telephone=no">
<meta name="HandheldFriendly" content="true" />
<meta name="robots" content="noindex,nofollow" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="black" />
<meta name="apple-mobile-web-app-title" content="Phaser App">
<meta name="viewport" content="initial-scale=1 maximum-scale=1 user-scalable=0 minimal-ui" />
<link rel="stylesheet" href="styles/main.css">
<script type="text/javascript" src="js/pixi.min.js"></script>
<script type="text/javascript" src="js/Box2D_v2.3.1_min.js"></script>
<script type="text/javascript" src="js/debugdraw.js"></script>
</head>
<body>
<script type="text/javascript">
var windowWidth = window.innerWidth;
var windowHeight = window.innerHeight;
var loader = PIXI.loader;
var Container = PIXI.Container;
var Sprite = PIXI.Sprite;
//--------------
var gravity = new Box2D.b2Vec2(0.0, 9.8);
var world = new Box2D.b2World(gravity, true);
// physics debug
var debugGraphics = new PIXI.Graphics();
var debugDraw = getPIXIDebugDraw(debugGraphics, 20);
var e_shapeBit = 0x0001;
var e_jointBit = 0x0002;
var e_aabbBit = 0x0004;
var e_pairBit = 0x0008;
var e_centerOfMassBit = 0x0010;
debugDraw.SetFlags(e_shapeBit);
debugDraw.enable = true;
world.SetDebugDraw(debugDraw);
console.log(debugDraw);
// create an new instance of a pixi stage
var stage = new Container();
stage.addChild(debugGraphics);
// create a renderer instance
var renderer = PIXI.autoDetectRenderer(800, 600, {antialias: false, transparent: false, resolution: 1});
renderer.view.style.border = "1px dashed black";
renderer.backgroundColor = 0x215421;
//renderer.view.style.position = "absolute";
renderer.view.style.display = "block";
//renderer.autoResize = true;
//renderer.resize(window.innerWidth, window.innerHeight);
// add render view to DOM
document.body.appendChild(renderer.view);
{
var ground = world.CreateBody(new Box2D.b2BodyDef());
var shape = new Box2D.b2EdgeShape();
shape.Set(new Box2D.b2Vec2(2, 30), new Box2D.b2Vec2(70.0, 30.0));
ground.CreateFixture(shape, 0.0);
}
{
var a = 0.5;
var shape = new Box2D.b2PolygonShape();
shape.SetAsBox(a, a);
var x = new Box2D.b2Vec2(10, 0.75);
var y = new Box2D.b2Vec2();
var deltaX = new Box2D.b2Vec2(0.5625, 1.25);
var deltaY = new Box2D.b2Vec2(1.125, 0.0);
var bd = new Box2D.b2BodyDef();
bd.set_type( Box2D.b2_dynamicBody );
for (var i = 0; i < 15; ++i) {
y = copyVec2(x);
for (var j = i; j < 15; ++j)
{
bd.set_position(y);
world.CreateBody(bd).CreateFixture(shape, 5.0);
y.op_add(deltaY);
}
x.op_add(deltaX);
}
}
//
loader.add([
'assets/textures/ball.png',
'assets/textures/box.jpg',
'assets/textures/bunny.jpg',
])
.on("progress", loadProgressHandler)
.load(setup);
function loadProgressHandler(loader, resource) {
console.log("loading" + loader.progress);
}
function setup() {
console.log("setup");
var ball = new Sprite(
loader.resources['assets/textures/ball.png'].texture
);
//stage.addChild(ball);
gameLoop();
}
//
function gameLoop() {
//Loop this function at 60 frames per second
requestAnimationFrame(gameLoop);
world.Step(1/60, 6, 2);
//draw debug
debugGraphics.clear();
world.DrawDebugData();
//Render the stage to see the animation
renderer.render(stage);
}
//to replace original C++ operator =
function copyVec2(vec) {
return new Box2D.b2Vec2(vec.get_x(), vec.get_y());
}
</script>
</body>
</html>
html {
width: 100%;
height: 100%;
margin: 0px;
padding: 0px;
}
body {
height: inherit;
width: inherit;
margin: 0px;
display: flex;
justify-content: center;
align-items: center;
background: #fafafa;
text-align: center;
}
canvas {
display: inline-block;
max-width: 100%;
max-height: 100%;
}
canvas:active {
cursor: pointer;
cursor: -webkit-grabbing;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment