xxxxxxxxxx
258
// A basic example
var tmap;
var x = 0,
y = 0,
pg, moveState, jumpState, body, of, score=0, ding, start=true;
const
MS_STOP = 1,
MS_LEFT = 2,
MS_RIGHT = 4,
MS_JUMP = 8;
var spriteSheet, doAni, coins, doCoins, defs, ex=[];
var animation = [4, //4 frames
[4,0,30,50],[35,0,30,50],
[66,0,30,50],[97,0,34,50],
];
var coinAnimation = [4, //4 frames
[0,0,40,44],[0,45,40,44],
[0,90,40,44],[0,134,40,44],
];
var coinSpots=[5,6,7,13,18,19,65,66,87,88,89,90,91,92,104,148,149,150,171,172,173,180,181,182,186,187,194,
232,234,235,236,237,243,244,245];
var gameOverCoin = 19, gameOver = false;
function preload() {
tmap = loadTiledMap("test", "data");
spriteSheet = loadImage("data/0mario.png");
coins = loadImage("data/coins.png");
ding = loadSound("data/0ding.mp3");
}
function setup() {
createCanvas(640, 480);
b2newWorld(30, b2V(0, 9.8));
new b2Body("chain", false, b2V(width / 2, height), [
b2V(-width / 2, -height),
b2V(-width / 2, 0),
b2V(width / 2, 0),
b2V(width / 2, -height),
b2V(-width / 2, -height),
]);
body = new b2Body("box", true, b2V(20, height-100), b2V(30, 30),
{display:userDraw});
body.filterCategoryBits = 3;
var s = tmap.getMapSize();
tmap.camwidth = width;
tmap.camheight = height;
pg = createGraphics(width, height);
addChains(102);
addChains(140);
addChains(240);
moveState = MS_STOP; jumpState = MS_STOP;
doAni = {image: spriteSheet, frames: animation, scale: [1,1]};
doCoins = {image: coins, frames: coinAnimation, scale: [0.5,0.5]};
createRotor(140, 330, 'red');
var tm = TileMaps["test"];
var h = tm.height,
w = tm.width,
th = tm.tileheight,
tw = tm.tilewidth;
for (var i=0; i<coinSpots.length; i++) {
var j = coinSpots[i];
var b = new b2Body('circle', false, b2V((j%w)*tw+tw/2,
floor(j/w)*th+th/2),
b2V(20,20), {display: userDraw2, collision: bump});
b.sensor = true;
if (j == gameOverCoin) b.gameOver = true;
}
var t =
'{ ' +
' "parts": [ ' +
' { ' +
' "name": "explosion", ' +
' "color": ' +
' [[255,0,0],[255,255,0]], ' +
' "shape": "ellipse", ' +
' "gravity": 0, ' +
' "sizePercent": 0.9, ' +
' "angle": [0,360], ' +
' "speed": 1.8, ' +
' "limit": 60, ' +
' "lifetime": 10, ' +
' "size": [2,6] } ' +
']}';
defs = JSON.parse(t);
}
var dirtyImage = true;
function draw() {
background(tmap.getBackgroundColor().levels);
if (start) {
textSize(16);
text("This app shows how to load a Tiled scene and how to convert it so that it can be used with Planck's Box2D physics library.\n\nThe character is moved by applying force so the behavior won't match a non-physics app.\n\nUse left arrow for left, and right arrow for right, up arrow to jump, down arrow to stop.\n\nTry to collect all the coins. The game is over when the top-right coin is collected.\n\nTap the space bar to start.", width/6, height/5, width*2/3);
return;
}
if (dirtyImage) {
pg.clear();
tmap.draw(x, y, pg);
dirtyImage = false;
}
image(pg, 0, 0);
b2Update();
b2Draw();
ellipse(mouseX, mouseY, 4, 4);
//text(mouseX + " " + mouseY, mouseX, mouseY);
var d = round(degrees(body.angle));
if (d != 0) body.angle = 0;
var vel = body.linearVelocity;
switch (moveState) {
case MS_LEFT:
vel.x = max(vel.x - 0.18, -4.0);
break;
case MS_STOP:
vel.mul(0.98);
break;
case MS_RIGHT:
vel.x = min(vel.x + 0.18, 4.0);
break;
}
if (abs(vel.x) < 0.01) vel.x = 0;
if (abs(vel.y) < 0.01) vel.y = 0;
if (jumpState == MS_JUMP) {vel.y -= 5; jumpState = MS_STOP;}
body.linearVelocity = vel;
push();
for (var i = 0; i < ex.length; i++) {
ex[i].Step();
ex[i].Create();
ex[i].Draw();
if (ex[i].done) ex.splice(i, 1);
}
pop();
textSize(20);
text('SCORE = '+score+'/'+(coinSpots.length*10),10,20);
if (gameOver) {
textSize(60);
fill('blue');
text('G A M E O V E R', width/6, height/2);
}
}
function userDraw(body) {
var v = body.linearVelocity;
if (v.x < -0.2 && doAni.scale[0] > 0) doAni.scale[0] = -doAni.scale[0];
if (v.x > 0.2) doAni.scale[0] = abs(doAni.scale[0]);
v = abs(v.x) > 0.2 ? 0.1 : 0.000002;
doAnimation(doAni,0,-8, v);
}
function userDraw2(body) {
doAnimation(doCoins, 0, 0, 0.1);
}
function bump(fixture1, fixture2) {
if (fixture2.getType() === 'circle') fixture1 = fixture2;
if (fixture1.getType() === 'circle') {
var b = b2getBodyFromFixture(fixture1);
if (b.active) {
var xy = b.position;
b.destroy();
var x = new Fountain(defs, 'explosion', xy.x, xy.y);
ex.push(x);
score +=10;
if (!ding.isPlaying()) {ding.stop(); ding.play();}
if (b.gameOver) {gameOver = true; b2Destroy(); }
}
}
}
function keyPressed() {
if (key == ' ' && start) {
start = false; fullscreen(true);
}
switch (keyCode) {
case LEFT_ARROW: //move left
moveState = MS_LEFT;
break;
case DOWN_ARROW: //stop
moveState = MS_STOP; jumpState = MS_STOP;
break;
case RIGHT_ARROW: //move right
moveState = MS_RIGHT;
break;
case UP_ARROW: //jump
jumpState = MS_JUMP;
break;
}
}
function createRotor(x, y, col) {
var b = new b2Body(
"box",
true,
b2V(x, y),
b2V(110, 10),
{ filterCategoryBits: 2, filterMaskBits: 2 }
);
b.color = col;
b.display = rotorDrawer;
var c = new b2Body(
"circle",
false,
b2V(x, y),
b2V(10, 10),
{ filterCategoryBits: 2, filterMaskBits: 2 }
);
c.createJoint('revolute', b,
{ motorSpeed: PI/2,
maxMotorTorque: 10000,
enableMotor: true });
}
function rotorDrawer(body) {
fill(body.color);
body.draw();
}
//follows edges counterclockwise
function addChains(start) {
var tmap = TileMaps["test"];
var h = tmap.height,
w = tmap.width,
th = tmap.tileheight,
tw = tmap.tilewidth;
tiles = tmap.layers[0].data;
if (tiles[start] == 0) return;
var origin = b2V((start % w)*tw, floor(start / w) * th);
var vecs = [];
if ((start%w) != 0) vecs.push(b2V(0, th));
vecs.push(b2V(0, 0));
const right = 1,
down = 2,
up = 3;
var dir = right;
var next = b2V(tw, 0);
start -= w;
for (var i=0; i<34; i++) {
if (tiles[start+1] == 0 && tiles[start+1+w] != 0) {
if (dir != right) vecs.push(next.clone());
if (next.x >= tw*w) {
if (dir == right) vecs.push(next.clone());
break;
}
next.x += tw;
start++; dir = right;
} else if (tiles[start+1] == 0 && tiles[start+1+w] == 0 && tiles[start+w] != 0) {
if (dir != down) vecs.push(next.clone());
next.y += th;
start += w; dir = down;
} else if (tiles[start-w] == 0 && tiles[start+1] != 0) {
if (dir != up) vecs.push(next.clone());
next.y -= th;
start -= w; dir = up;
} else {vecs.push(next); break;}
//print(start+' '+next.x+' '+next.y+' '+dir);
} //for i
//print(origin); print(dir); print(vecs);
new b2Body("chain", false, origin, vecs);
}