box2d/pinball
/**
* @author Chris Campbell
* @author Richard Davey
* @copyright 2015 Photon Storm Ltd.
* @license {@link http://choosealicense.com/licenses/no-license/|No License}
*
* @description This example requires the Phaser Box2D Plugin to run.
* For more details please see http://phaser.io/shop/plugins/box2d
*/
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { create: create, update: update, render: render });
var outlineVertices = [1440,-3186.59,1376.96,-3195.95,1023.88,-2194.34,1345.45,-1961.25,1345.45,-663.375,
638.684,-480.341,160.054,-154.361,150.206,471.008,-318.575,470.023,-319.559,-153.376,
-800.158,-480.341,-1519.35,-619.21,-1518.23,-1988.98,-1147.38,-2175.73,-1429.31,-3152.17,
-1500.1,-3195.52,-1492.51,-3399.68,-1438.82,-3867.33,-1309.07,-4132.41,-1112.22,-4351.64,
-787.851,-4540.67,-389.666,-4670.41,139.843,-4778.28,655.92,-4846.15,872.006,-4837.87,
1067.14,-4792.27,1236.26,-4700.02,1374.63,-4584.71,1480.34,-4440.57,1557.21,-4271.45,
1601.65,-3992.59,1601.41,-3712.19,1604.11,-2197.86,1814.72,-2234.37,1848.77,-2057.55,
1600,-2003.04,1600,-171.408,1442.93,-169.434,1439.5,-663.941];
var launcherVertices = [1401.35,-224.963,1631.98,-224.963];
var guide1Vertices = [-825.819,-746.541,-771.419,-853.487,-1280,-1120,-1280,-1759.99,-1360,-1759.99,
-1360,-959.993];
var guide2Vertices = [663.001,-743.13,614.862,-855.893,1119.91,-1121.82,1123.3,-1760.68,1200.08,-1759.99,
1200.08,-959.993];
var guide3Vertices = [-1116.81,-1753.55,-1118.98,-1277.67,-878.975,-1117.67];
var guide4Vertices = [721.698,-1128.55,956.731,-1282.32,956.731,-1762.32];
var gutterVertices = [-480.857,413.599,293.837,413.599];
var bouncer1 = [-1042.47,-1763.21,-826.297,-1160.74];
var bouncer2 = [883.433,-1767.01,669.858,-1171.73];
var smallCircles = [1406,-3183.89,-1320,-1759.99,-1078.86,-1753.03,-861.88,-1152.05,918.723,-1760.8,1160.08,-1759.99,704.87,-1161.38];
var mediumCircles = [-1500.82,-3132.63,-866.447,-3163.29,-290.006,-3074.23,187.945,-3415.55,614.227,-3074.23,-451.581,-2232.34,396.293,-2242];
var largeCircles = [-446.686,-3704.69,309.841,-4133.62,995.658,-3595.05];
var leftFlipperVertices = [560,32,560,-32,0,-64,0,64];
var rightFlipperVertices = [0,64,0,-64,-560,-32,-560,32];
var ballStart = [17.5016, -21.318];
var ballBody;
var flipperJoints = [];
var PTM = 100; // conversion ratio for values in arrays above
var needReset = false;
function create() {
game.world.setBounds(-400, -520, 800, 600);
game.stage.backgroundColor = '#124184';
// Enable Box2D physics
game.physics.startSystem(Phaser.Physics.BOX2D);
game.physics.box2d.ptmRatio = 500;
game.physics.box2d.gravity.y = 5000; // large gravity to make scene feel smaller
game.physics.box2d.friction = 0.1;
// Make the ground body
var mainBody = new Phaser.Physics.Box2D.Body(this.game, null, 0, 0, 0);
// Add bounce-less fixtures
game.physics.box2d.restitution = 0.1;
mainBody.addLoop(outlineVertices);
mainBody.addLoop(guide1Vertices);
mainBody.addLoop(guide2Vertices);
mainBody.addChain(guide3Vertices);
mainBody.addChain(guide4Vertices);
// Add bouncy fixtures
game.physics.box2d.restitution = 1;
mainBody.addEdge(bouncer1[0], bouncer1[1], bouncer1[2], bouncer1[3]);
mainBody.addEdge(bouncer2[0], bouncer2[1], bouncer2[2], bouncer2[3]);
for (var i = 0; i < smallCircles.length / 2; i++)
{
mainBody.addCircle(0.35 * PTM, smallCircles[2 * i + 0], smallCircles[2 * i + 1]);
}
for (var i = 0; i < mediumCircles.length / 2; i++)
{
mainBody.addCircle(1 * PTM, mediumCircles[2 * i + 0], mediumCircles[2 * i + 1]);
}
for (var i = 0; i < largeCircles.length / 2; i++)
{
mainBody.addCircle(2.8 * PTM, largeCircles[2 * i + 0], largeCircles[2 * i + 1]);
}
// Add gutter fixture
gutterFixture = mainBody.addEdge(gutterVertices[0], gutterVertices[1], gutterVertices[2], gutterVertices[3]);
gutterFixture.SetSensor(true);
// Set restitution for launcher
game.physics.box2d.restitution = 2;
mainBody.addEdge(launcherVertices[0], launcherVertices[1], launcherVertices[2], launcherVertices[3]);
// ball
game.physics.box2d.restitution = 0.1;
ballBody = new Phaser.Physics.Box2D.Body(this.game, null, ballStart[0] * PTM, ballStart[1] * PTM);
ballBody.setCircle(0.64 * PTM);
ballBody.setFixtureContactCallback(gutterFixture, onHitGutter, this);
ballBody.bullet = true;
// Flippers
game.physics.box2d.restitution = 0.1;
var leftFlipperBody = new Phaser.Physics.Box2D.Body(this.game, null, -8 * PTM, -7.99956 * PTM, 2);
leftFlipperBody.addPolygon(leftFlipperVertices);
var rightFlipperBody = new Phaser.Physics.Box2D.Body(this.game, null, 6.4 * PTM, -7.99956 * PTM, 2);
rightFlipperBody.addPolygon(rightFlipperVertices);
// Flipper joints
var motorSpeed = 2;
var motorTorque = 100;
// bodyA, bodyB, ax, ay, bx, by, motorSpeed, motorTorque, motorEnabled, lowerLimit, upperLimit, limitEnabled
flipperJoints[0] = game.physics.box2d.revoluteJoint(mainBody, leftFlipperBody, -8*PTM,-7.99956*PTM, 0,0, motorSpeed, motorTorque, true, -25, 25, true );
flipperJoints[1] = game.physics.box2d.revoluteJoint(mainBody, rightFlipperBody, 6.4*PTM,-7.99956*PTM, 0,0, motorSpeed, motorTorque, true, -25, 25, true );
cursors = game.input.keyboard.createCursorKeys();
var caption = game.add.text(5, 5, 'Pinball. Left/right arrow keys to control flippers.', { fill: '#ffffff', font: '14pt Arial' });
caption.fixedToCamera = true;
}
function onHitGutter(body1, body2, fixture1, fixture2, begin) {
needReset = true; // this occurs inside the world Step, so don't do the actual reset here
}
function update() {
if (needReset)
{
ballBody.x = ballStart[0]*PTM;
ballBody.y = ballStart[1]*PTM;
ballBody.velocity.x = 0;
ballBody.velocity.y = 0;
ballBody.angularVelocity = 0;
needReset = false;
}
var flipperSpeed = 20; // rad/s
if (cursors.left.isDown)
{
flipperJoints[0].SetMotorSpeed(-flipperSpeed);
}
else
{
flipperJoints[0].SetMotorSpeed(flipperSpeed);
}
if (cursors.right.isDown)
{
flipperJoints[1].SetMotorSpeed(flipperSpeed);
}
else
{
flipperJoints[1].SetMotorSpeed(-flipperSpeed);
}
}
function render() {
game.debug.box2dWorld();
}