Commit 901b61bc authored by Raphaël Bastide's avatar Raphaël Bastide

External object types are in a units.json + simpler world builder + code is cleaner (I guess)

parent 3ba0bafa
......@@ -10,9 +10,7 @@
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="robots" content="noindex">
<link rel="stylesheet" href="css/main.css">
<title>Ball On URL</title>
<title>Url Rider</title>
</head>
<body>
<!-- <button class="play">play</button> -->
......@@ -31,7 +29,9 @@
<script src="lib/tone.js"></script>
<script src="js/sound.js"></script>
<!-- Car -->
<script src="js/car.js"></script>
<script src="js/launcher.js"></script>
<!-- <script src="js/car.js"></script>
<script src="js/launcher.js"></script> -->
<script src="js/launch.js"></script>
<script src="js/world.js"></script>
</body>
</html>
var urlRider = urlRider || {};
history.pushState(null, null, '#ddbftbgfffftuuffffdfff');
urlRider.car = function() {
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Composite = Matter.Composite,
Composites = Matter.Composites,
Constraint = Matter.Constraint,
MouseConstraint = Matter.MouseConstraint,
Mouse = Matter.Mouse,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body,
Events = Matter.Events;
var terrain = window.location.hash.substr(1);
var urlshapes = false
if (terrain.includes('%E')) {
urlshapes = true
terrain = terrain.split('%E')
}else {
terrain = terrain.split('')
}
// create engine
var engine = Engine.create(),
world = engine.world;
// create renderer
var render = Render.create({
element: document.body,
engine: engine,
options: {
wireframes:false,
width: 1900,
height: 1000,
showAngleIndicator: false,
showCollisions: false,
background: '#222',
}
});
var startX = 100
var startY = 200
var nextPos = 0
var lastDir = 0
var w = 400
var h = 10
var tr = "77"
var platformColor = "#CCCCCC"+tr
var ballColor = "#e91763"
var zoom = false
Render.run(render);
// create runner
var runner = Runner.create();
runner.isFixed = true
Runner.run(runner, engine);
engine.world.gravity.y = 1;
var car = Composites.car(150, 100, 150, 30, 40)
var ball = Bodies.circle(100, 100, 100, { friction:1, frictionAir:.003, restitution: 0.2})
var bonus = Bodies.circle(1800, 0, 10, {name:"bonus",isStatic:true, isSensor:true})
bonus.render.fillStyle ="red"
ball.render.sprite.texture = 'img/ball.svg'
// ball.render.fillStyle = ballColor
var tailBall = Bodies.circle(-10, -10, 10, 60);
var tail = Constraint.create({
bodyA: ball,
pointA: { x: 0, y: 0 },
bodyB: tailBall,
pointB: { x: 0, y: 0 },
stiffness: 0.001,
// damping: 0.2
});
World.add(world, [
// tail,
// tailBall,
bonus,
ball
]);
// World.add(world, car);
for (var i = 0; i < terrain.length; i++) {
if (urlshapes) {
var t = "%E" + String(terrain[i])
}else {
t = terrain[i]
}
if (!nextPos){nextPos = {x:startX,y:startY}}
buildUnit(t, nextPos)
}
function buildUnit(char, nextPos){
var posY = nextPos.y
if (char == 'f') {
var unit = Bodies.rectangle(nextPos.x, posY, w, h, { isStatic: true })
unit.name = 'flat'
unit.render.fillStyle = platformColor
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
}else if (char == 'u') {
var unit = Bodies.rectangle(nextPos.x, posY - 150, w, h, { isStatic: true, angle: Math.PI * -0.2 })
unit.name = 'up'
unit.render.fillStyle = platformColor
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y -= unit.distances.h
}else if (char == 'd') {
var unit = Bodies.rectangle(nextPos.x, posY + 150, w, h, { isStatic: true, angle: Math.PI * 0.2})
unit.name = 'down'
unit.render.fillStyle = platformColor
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
}else if (char == 'b') {
var unit = Bodies.rectangle(nextPos.x, posY, w, h, {isStatic: true})
unit.name = 'boost'
unit.render.fillStyle = '#60a74b'+tr
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
}else if (char == 'w') {
var unit = Bodies.rectangle(nextPos.x - 150, posY - 150, w, h, {isStatic: true, angle: Math.PI * 0.5})
unit.name = 'wall'
unit.render.fillStyle = platformColor
getDistances(unit)
nextPos.x += 100
nextPos.y += 0
}else if (char == 'z') {
var unit = Bodies.rectangle(nextPos.x, posY , w, h, {isStatic: true})
unit.name = 'bulletTime'
unit.render.fillStyle = "#ba36a0"+tr
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
} else if (char == 'g') {
var unit = Bodies.rectangle(nextPos.x, posY, w, h, { isStatic: true})
unit.name = 'gap'
unit.render.fillStyle = '#ffffff00'
unit.isSensor = true
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
}else if (char == 'j') {
var unit = Bodies.rectangle(nextPos.x, posY, w, h, { isStatic: true})
unit.name = 'jump'
unit.render.fillStyle = '#f227dd'+tr
unit.isSensor = true
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
}else if (char == 'i') {
var unit = Bodies.rectangle(nextPos.x, posY, w, h, { isStatic: true})
unit.name = 'invertedGravity'
unit.render.fillStyle = '#f2b927'+tr
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
}else if (char == 't') {
var unit = Bodies.rectangle(nextPos.x, posY, w, h, { isStatic: true})
unit.name = 'time'
unit.render.fillStyle = '#2797f2'+tr
getDistances(unit)
nextPos.x += unit.distances.w
nextPos.y += unit.distances.h
}else if (char == "1") { // up
nextPos.x += 0
nextPos.y += -500
}else if (char == "0") { // down
nextPos.x += 0
nextPos.y += 500
}
if (unit != null) {
World.add(world,unit);
}
}
function getDistances(unit){
var realW = unit.bounds.max.x - unit.bounds.min.x
var realH = unit.bounds.max.y - unit.bounds.min.y
return unit.distances = {w:realW, h:realH}
}
// add mouse control
var mouse = Mouse.create(render.canvas),
mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
});
// World.add(world, mouseConstraint);
render.mouse = mouse;
var timeScaleTarget = 1
var zoom = 500
var zoomTarget = 500
var counter = 0
var bulletTime, bonusTime, isBackInTime, checkPoint, lastCollided = false
// Render after each Tick
Events.on( engine, 'afterTick', (e)=> {
if (bulletTime) {
engine.timing.timeScale
zoom += (zoomTarget - zoom) * 0.05;
if (counter >= 60 * 3.5) {
zoomTarget = 500
timeScaleTarget = 1
}else{
zoomTarget = 200
timeScaleTarget = 0.05
}
if (counter >= 60 * 3.6) {
ball.render.sprite.texture = 'img/ball.svg'
}
if (counter >= 60 * 4.5) {
engine.timing.timeScale = 1
timeScaleTarget = 1
zoomTarget = 500
zoom = 500
counter = 0
bulletTime = false
}
counter +=1
}
if (bonusTime) {
if (counter >=50) {
console.log(counter);
ball.render.sprite.texture = 'img/ball.svg'
bonusTime = false
}
counter +=1
}
Render.lookAt(render, ball, {x: zoom, y: zoom },true );
})
Events.on(engine, 'collisionStart', function(event) {
var pairs = event.pairs;
for (var i = 0, j = pairs.length; i != j; ++i) {
var pair = pairs[i];
var col = pair.bodyB.render.fillStyle
if (col !== "#ffffff00") { // If not transparent, highlight the color when collision
col = col.substring(0, col.length - 2);
pair.bodyB.render.fillStyle = col+"FF"
}
if (pair.bodyB.name === 'boost') {
pair.bodyA.render.fillStyle = '#00FF00';
Body.setVelocity(ball, { x: 50, y: 0 });
}else if(pair.bodyB.name === 'bulletTime') {
ball.render.sprite.texture = 'img/ball-bullettime.svg'
bulletTime = true
}else if(pair.bodyB.name === 'bonus') {
bonusTime = true
bonus.render.fillStyle = "#ffffff00"
ball.render.sprite.texture ="img/bonus.svg"
}else if(pair.bodyB.name === 'jump') {
Body.setVelocity(ball, { x: ball.speed, y: -50 });
}else if(pair.bodyB.name === 'invertedGravity') {
if (engine.world.gravity.y == -1) {
engine.world.gravity.y = 1;
}else {
engine.world.gravity.y = -1;
}
}else if(pair.bodyB.name === 'time') {
var currentCollided = pair.bodyB.id; // avoid repeated collision
if ( lastCollided != currentCollided) {
if (isBackInTime) {
// console.log('back',checkPoint);
console.log(ball.position.x, ball.position.y);
Body.setPosition(ball,{x:checkPoint.x, y:checkPoint.y})
isBackInTime = false
}else {
checkPoint = {x:ball.position.x, y:ball.position.y}
isBackInTime = true
}
lastCollided = currentCollided
}
}
}
});
return {
engine: engine,
runner: runner,
render: render,
canvas: render.canvas,
stop: function() {
Matter.Render.stop(render);
Matter.Runner.stop(runner);
}
};
};
var data
var request = new XMLHttpRequest();
request.open('GET', 'js/units.json', true);
request.onload = function() {
if (request.status >= 200 && request.status < 400) {
data = JSON.parse(request.responseText);
console.log('request success');
launch(data)
} else {
console.log('json not found');
}
};
request.onerror = function() {
console.log('json request error');
};
request.send();
......@@ -40,5 +40,5 @@
]
});
document.body.appendChild(urlcar.dom.root);
MatterTools.Demo.start(urlcar);
// MatterTools.Demo.start(urlcar);
})();
{
"units": [
{
"name": "flat",
"char": "f",
"verticalShift":"0",
"isLocked": false,
"color":"#D7D7CD",
"angle":"0",
"isStatic":true
},
{
"name": "down",
"char": "d",
"verticalShift":"-1",
"isLocked": false,
"color":"#eeeeee",
"angle":"0.2",
"isStatic":true
},
{
"name": "up",
"char": "u",
"verticalShift": "1",
"isLocked": false,
"color":"#eeeeee",
"angle":"-0.2",
"isStatic":true
},
{
"name": "gap",
"char": "g",
"verticalShift": "0",
"isLocked": false,
"color":"#ffffff00",
"angle":"0",
"isStatic":true,
"isSensor":true
},
{
"name": "boost",
"char": "b",
"verticalShift": "0",
"isLocked": false,
"color":"#e26262",
"angle":"0",
"isStatic":true
},
{
"name": "time",
"char": "t",
"verticalShift": "0",
"isLocked": false,
"color":"#532890",
"angle":"0",
"isStatic":true
},
{
"name": "invertedGravity",
"char": "i",
"verticalShift": "0",
"isLocked": false,
"color":"#69e262",
"angle":"0",
"isStatic":true
},
{
"name": "jump",
"char": "j",
"verticalShift": "0",
"isLocked": false,
"color":"#62e2c3",
"angle":"0",
"isStatic":true
},
{
"name": "bulletTime",
"char": "z",
"verticalShift": "0",
"isLocked": false,
"color":"#dfe262",
"angle":"0",
"isStatic":true
},
{
"name": "buildUp",
"char": "1",
"verticalShift": "500"
},
{
"name": "buildDown",
"char": "0",
"verticalShift": "-500"
}
]
}
function launch(units){
var Engine = Matter.Engine,
Render = Matter.Render,
Runner = Matter.Runner,
Composite = Matter.Composite,
Composites = Matter.Composites,
Constraint = Matter.Constraint,
MouseConstraint = Matter.MouseConstraint,
Mouse = Matter.Mouse,
World = Matter.World,
Bodies = Matter.Bodies,
Body = Matter.Body,
Events = Matter.Events;
var startX = 100,
startY = 200,
nextPos = 0,
lastDir = 0,
w = 400,
h = 10,
alpha = "77",
ballColor = "#e26262",
zoom = false,
timeScaleTarget = 1,
zoom = 500,
zoomTarget = 500,
counter = 0,
bulletTime, bonusTime, isBackInTime, checkPoint, lastCollided = false,
terrain = window.location.hash.substr(1),
urlshapes = false
// create engine
var engine = Engine.create(),
world = engine.world;
engine.world.gravity.y = 1;
// create renderer
var render = Render.create({
element: document.body,
engine:engine,
options: {
wireframes:false,
width: 1500,
height: 800,
showAngleIndicator: false,
showCollisions: false,
background: '#171717',
}
});
// Building common objects
var car = Composites.car(150, 100, 150, 30, 40)
var ball = Bodies.circle(100, 100, 100, { friction:1, frictionAir:.003, restitution: 0.2})
var bonus = Bodies.circle(1800, 0, 10, {name:"bonus",isStatic:true, isSensor:true})
bonus.render.fillStyle ="red"
ball.render.sprite.texture = 'img/ball.svg'
// Adding common objects to the world
World.add(world, [
bonus,
ball
]);
// Extracting URL characters to build the terrain
if (terrain.includes('%E')) {
urlshapes = true
terrain = terrain.split('%E')
}else {
terrain = terrain.split('')
}
for (var i = 0; i < terrain.length; i++) {
c = terrain[i]
if (!nextPos){nextPos = {x:startX,y:startY}}
buildUnit(c, nextPos)
}
var posY = nextPos.y
// Building terrain from the character array
function buildUnit(char, nextPos){
var unit = findObjectByKey(data.units, 'char', char);
if (unit.name == "buildUp") {
nextPos.x += 0
nextPos.y += -500
}else if (unit.name == "buildDown") {
nextPos.x += 0
nextPos.y += 500
}else {
if (unit.verticalShift == 1) {
var posX = nextPos.x
var posY = nextPos.y + (unit.angle * 550) - 6
}else if (unit.verticalShift == 0) {
var posX = nextPos.x + 35
var posY = nextPos.y + (unit.angle * 550)
}else if (unit.verticalShift == -1) {
var posX = nextPos.x
var posY = nextPos.y + (unit.angle * 550) + 6
}
w = w + w * Math.round(Math.abs(unit.angle))
var toBuild = Bodies.rectangle(posX, posY, w, h, {isStatic:unit.isStatic,angle: Math.PI * unit.angle})
toBuild.isLocked = unit.isLocked
toBuild.name = unit.name
toBuild.isSensor = unit.isSensor
toBuild.render.fillStyle = unit.color + alpha
getDistances(toBuild)
if (toBuild != null) {
World.add(world,toBuild);
}
if (unit.verticalShift == 1) {
nextPos.x += Math.round(toBuild.distances.w)
nextPos.y -= Math.round(toBuild.distances.h) - h
}else if (unit.verticalShift == 0) {
nextPos.x += Math.round(toBuild.distances.w)
nextPos.y += Math.round(toBuild.distances.h) - h
}else {
nextPos.x += Math.round(toBuild.distances.w)
nextPos.y += Math.round(toBuild.distances.h) - h
}
}
}
function getDistances(unit){
var realW = unit.bounds.max.x - unit.bounds.min.x
var realH = unit.bounds.max.y - unit.bounds.min.y
return unit.distances = {w:realW, h:realH}
}
function checkLock(unit){
if (unit.isLocked == true) {
notifAlert(unit.name)
}
}
function unlock(unit){
unit.isLocked = false
}
function findObjectByKey(array, key, value) {
for (var i = 0; i < array.length; i++) {
if (array[i][key] === value) {
return array[i];
}
}
return null;
}
// add mouse control
var mouse = Mouse.create(render.canvas),
mouseConstraint = MouseConstraint.create(engine, {
mouse: mouse,
constraint: {
stiffness: 0.2,
render: {
visible: false
}
}
});
// World.add(world, mouseConstraint);
render.mouse = mouse;
// Render after each Tick
Events.on( engine, 'afterTick', (e)=> {
if (bulletTime) {
engine.timing.timeScale
zoom += (zoomTarget - zoom) * 0.05;
if (counter >= 60 * 3.5) {
zoomTarget = 500
timeScaleTarget = 1
}else{
zoomTarget = 200
timeScaleTarget = 0.05
}
if (counter >= 60 * 3.6) {
ball.render.sprite.texture = 'img/ball.svg'
}
if (counter >= 60 * 4.5) {
engine.timing.timeScale = 1
timeScaleTarget = 1
zoomTarget = 500
zoom = 500
counter = 0
bulletTime = false
}
counter +=1
}
if (bonusTime) {
if (counter >=50) {
console.log(counter);
ball.render.sprite.texture = 'img/ball.svg'
bonusTime = false
}
counter +=1
}
Render.lookAt(render, ball, {x: zoom, y: zoom },true );
})
// Handling collisions
Events.on(engine, 'collisionStart', function(event) {
var pairs = event.pairs;
for (var i = 0, j = pairs.length; i != j; ++i) {
var pair = pairs[i];
console.log(pair);
var col = pair.bodyB.render.fillStyle
if (col !== "#ffffff00") { // If not transparent, highlight the color when collision
col = col.substring(0, col.length - 2);
pair.bodyB.render.fillStyle = col+"FF"
}
if (pair.bodyB.name === 'boost') {
pair.bodyA.render.fillStyle = '#00FF00';
Body.setVelocity(ball, { x: 50, y: 0 });
}else if(pair.bodyB.name === 'bulletTime') {
ball.render.sprite.texture = 'img/ball-bullettime.svg'
bulletTime = true
}else if(pair.bodyB.name === 'bonus') {
bonusTime = true
bonus.render.fillStyle = "#ffffff00"
ball.render.sprite.texture ="img/bonus.svg"
}else if(pair.bodyB.name === 'jump') {
Body.setVelocity(ball, { x: ball.speed, y: -50 });
}else if(pair.bodyB.name === 'invertedGravity') {
if (engine.world.gravity.y == -1) {
engine.world.gravity.y = 1;
}else {
engine.world.gravity.y = -1;
}
}else if(pair.bodyB.name === 'time') {
var currentCollided = pair.bodyB.id; // avoid repeated collision
if ( lastCollided != currentCollided) {
if (isBackInTime) {
// console.log('back',checkPoint);
console.log(ball.position.x, ball.position.y);
Body.setPosition(ball,{x:checkPoint.x, y:checkPoint.y})
isBackInTime = false
}else {
checkPoint = {x:ball.position.x, y:ball.position.y}
isBackInTime = true
}
lastCollided = currentCollided
}
}
}
});
Engine.run(engine);
Render.run(render);
} // end launch()
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment