feat: sound, generator, etc.
This commit is contained in:
parent
e983346ffc
commit
d6eaa09346
BIN
assets/audio/fire.wav
Normal file
BIN
assets/audio/fire.wav
Normal file
Binary file not shown.
BIN
assets/audio/impact-0.wav
Normal file
BIN
assets/audio/impact-0.wav
Normal file
Binary file not shown.
BIN
assets/audio/impact-1.wav
Normal file
BIN
assets/audio/impact-1.wav
Normal file
Binary file not shown.
BIN
assets/audio/impact-2.wav
Normal file
BIN
assets/audio/impact-2.wav
Normal file
Binary file not shown.
BIN
assets/audio/music.mp3
Normal file
BIN
assets/audio/music.mp3
Normal file
Binary file not shown.
BIN
assets/audio/rumble.wav
Normal file
BIN
assets/audio/rumble.wav
Normal file
Binary file not shown.
@ -31,7 +31,9 @@
|
|||||||
<script src='lib/physics-module.js'></script>
|
<script src='lib/physics-module.js'></script>
|
||||||
<script src='lib/ammo.js'></script>
|
<script src='lib/ammo.js'></script>
|
||||||
<script src='lib/mousetrap.js'></script>
|
<script src='lib/mousetrap.js'></script>
|
||||||
|
<script src='lib/howler.min.js'></script>
|
||||||
<script src='lib/moment.min.js'></script>
|
<script src='lib/moment.min.js'></script>
|
||||||
|
<script src='lib/color-scheme.min.js'></script>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<div id='gui'>
|
<div id='gui'>
|
||||||
@ -44,10 +46,14 @@
|
|||||||
<p>
|
<p>
|
||||||
Score: <span id='score'>000</span>
|
Score: <span id='score'>000</span>
|
||||||
</p>
|
</p>
|
||||||
|
<p>
|
||||||
|
Hits: <span id='hits'>00</span>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src='src/utils.js'></script>
|
<script src='src/utils.js'></script>
|
||||||
<script src='src/config.js'></script>
|
<script src='src/config.js'></script>
|
||||||
|
<script src='src/audio.js'></script>
|
||||||
<script src='src/gui.js'></script>
|
<script src='src/gui.js'></script>
|
||||||
<script src='src/objects.js'></script>
|
<script src='src/objects.js'></script>
|
||||||
<script src='src/world.js'></script>
|
<script src='src/world.js'></script>
|
||||||
|
1
lib/color-scheme.min.js
vendored
Normal file
1
lib/color-scheme.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
4
lib/howler.min.js
vendored
Normal file
4
lib/howler.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
30
src/audio.js
Normal file
30
src/audio.js
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
const audio = {
|
||||||
|
fire: new Howl({
|
||||||
|
src: ['assets/audio/fire.wav'],
|
||||||
|
autoplay: true,
|
||||||
|
loop: true,
|
||||||
|
volume: 0.3
|
||||||
|
}),
|
||||||
|
|
||||||
|
music: new Howl({
|
||||||
|
src: ['assets/audio/music.mp3'],
|
||||||
|
autoplay: true,
|
||||||
|
loop: true,
|
||||||
|
volume: 0.1,
|
||||||
|
}),
|
||||||
|
|
||||||
|
rumble: new Howl({
|
||||||
|
src: ['assets/audio/rumble.wav'],
|
||||||
|
autoplay: false,
|
||||||
|
loop: true,
|
||||||
|
volume: 0.2,
|
||||||
|
}),
|
||||||
|
|
||||||
|
impacts: [0, 1, 2].map(i => new Howl({
|
||||||
|
src: [`assets/audio/impact-${i}.wav`],
|
||||||
|
volume: 0.5
|
||||||
|
})),
|
||||||
|
}
|
||||||
|
|
||||||
|
audio.fire.play();
|
||||||
|
audio.music.play();
|
101
src/ball.js
101
src/ball.js
@ -1,10 +1,5 @@
|
|||||||
const RADIUS = 10;
|
const RADIUS = 10;
|
||||||
const SEGMENTS = 40;
|
const SEGMENTS = 40;
|
||||||
const material = new THREE.MeshLambertMaterial({
|
|
||||||
color: 0xFFFFFF,
|
|
||||||
emissive: 0xFF0000,
|
|
||||||
emissiveIntensity: 0.4,
|
|
||||||
});
|
|
||||||
const ballPhysics = new PHYSICS.SphereModule({
|
const ballPhysics = new PHYSICS.SphereModule({
|
||||||
mass: 2,
|
mass: 2,
|
||||||
friction: 0.5,
|
friction: 0.5,
|
||||||
@ -20,7 +15,11 @@ const ball = new WHS.Sphere({
|
|||||||
z: -30,
|
z: -30,
|
||||||
y: 10
|
y: 10
|
||||||
},
|
},
|
||||||
material,
|
material: new THREE.MeshLambertMaterial({
|
||||||
|
color: 0xFFFFFF,
|
||||||
|
emissive: 0xFF0000,
|
||||||
|
emissiveIntensity: 0.4,
|
||||||
|
}),
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
new WHS.TextureModule({
|
new WHS.TextureModule({
|
||||||
@ -30,21 +29,16 @@ const ball = new WHS.Sphere({
|
|||||||
],
|
],
|
||||||
});
|
});
|
||||||
|
|
||||||
const fireLight = new WHS.PointLight({
|
|
||||||
color: 0xff0000,
|
|
||||||
intensity: 5,
|
|
||||||
});
|
|
||||||
|
|
||||||
ball.physics = ballPhysics;
|
ball.physics = ballPhysics;
|
||||||
ball.fireLight = fireLight;
|
|
||||||
|
|
||||||
ball.addTo(app);
|
ball.addTo(app);
|
||||||
ball.add(fireLight);
|
|
||||||
|
|
||||||
camera.native.target = ball.native;
|
camera.native.target = ball.native;
|
||||||
|
|
||||||
ball.checkLife = () => {
|
ball.checkLife = () => {
|
||||||
if (ball.position.x > ground.geometry.parameters.width / 2 || ball.position.x < -ground.geometry.parameters.width / 2) {
|
if (ball.position.x > ground.geometry.parameters.width / 2
|
||||||
|
|| ball.position.x < -ground.geometry.parameters.width / 2
|
||||||
|
|| ball.position.z > -ground.SIZE) {
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -79,66 +73,37 @@ ball.checkLife = () => {
|
|||||||
color: 0xffffff,
|
color: 0xffffff,
|
||||||
});
|
});
|
||||||
|
|
||||||
new THREE.Geometry();
|
|
||||||
var smokeCount = 2000,
|
|
||||||
smokes = new THREE.Geometry(),
|
|
||||||
smokeMaterial = new THREE.PointsMaterial({
|
|
||||||
size: 1.5,
|
|
||||||
transparent: true,
|
|
||||||
color: 0x666666,
|
|
||||||
opacity: 0.5,
|
|
||||||
});
|
|
||||||
|
|
||||||
const radius = ball.params.geometry.radius;
|
const radius = ball.params.geometry.radius;
|
||||||
const start = ball.position;
|
const start = ball.position;
|
||||||
for (var p = 0; p < particleCount; p++) {
|
for (var p = 0; p < particleCount; p++) {
|
||||||
|
|
||||||
// create a particle with random
|
|
||||||
// position values, -250 -> 250
|
|
||||||
var pX = start.x + THREE.Math.randFloatSpread(radius),
|
var pX = start.x + THREE.Math.randFloatSpread(radius),
|
||||||
pY = start.y + THREE.Math.randFloatSpread(radius),
|
pY = start.y + THREE.Math.randFloatSpread(radius),
|
||||||
pZ = start.z + THREE.Math.randFloatSpread(radius),
|
pZ = start.z + THREE.Math.randFloatSpread(radius),
|
||||||
particle = new THREE.Vector3(pX, pY, pZ)
|
particle = new THREE.Vector3(pX, pY, pZ)
|
||||||
|
|
||||||
particle.lifetime = ball.params.geometry.radius + THREE.Math.randFloat(1, 1 + FIRE_HEIGHT_RANDOMNESS) * FIRE_HEIGHT;
|
particle.lifetime = Math.random() < 0.5 ? 0 : ball.params.geometry.radius + THREE.Math.randFloat(0.5, 1 + FIRE_HEIGHT_RANDOMNESS) * FIRE_HEIGHT;
|
||||||
//particle.color.offsetHSL(Math.random(), 0, Math.random());
|
|
||||||
|
|
||||||
// add it to the geometry
|
|
||||||
particles.vertices.push(particle);
|
particles.vertices.push(particle);
|
||||||
particles.colors.push(new THREE.Color(1, 0, 0));
|
particles.colors.push(new THREE.Color(1, 0, 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
particles.colorsNeedUpdate = true;
|
|
||||||
|
|
||||||
for (var i = 0; i < spriteCount; i++) {
|
for (var i = 0; i < spriteCount; i++) {
|
||||||
var pX = start.x + THREE.Math.randFloatSpread(radius),
|
var pX = start.x + THREE.Math.randFloatSpread(radius),
|
||||||
pY = start.y + THREE.Math.randFloatSpread(radius),
|
pY = start.y + THREE.Math.randFloatSpread(radius),
|
||||||
pZ = start.z + THREE.Math.randFloatSpread(radius),
|
pZ = start.z + THREE.Math.randFloatSpread(radius),
|
||||||
particle = new THREE.Vector3(pX, pY, pZ)
|
particle = new THREE.Vector3(pX, pY, pZ)
|
||||||
|
|
||||||
particle.lifetime = ball.params.geometry.radius + THREE.Math.randFloat(1, 1 + FIRE_HEIGHT_RANDOMNESS) * FIRE_HEIGHT;
|
particle.lifetime = Math.random() < 0.5 ? 0 : ball.params.geometry.radius + THREE.Math.randFloat(0.5, 1 + FIRE_HEIGHT_RANDOMNESS) * FIRE_HEIGHT;
|
||||||
|
|
||||||
sprites.vertices.push(particle);
|
sprites.vertices.push(particle);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < smokeCount; i++) {
|
|
||||||
var pX = start.x + THREE.Math.randFloatSpread(radius),
|
|
||||||
pY = start.y + THREE.Math.randFloat(radius),
|
|
||||||
pZ = start.z + THREE.Math.randFloatSpread(radius),
|
|
||||||
particle = new THREE.Vector3(pX, pY, pZ);
|
|
||||||
|
|
||||||
particle.lifetime = ball.params.geometry.radius + THREE.Math.randFloat(1, 1 + FIRE_HEIGHT_RANDOMNESS) * FIRE_HEIGHT * 1.5;
|
|
||||||
|
|
||||||
smokes.vertices.push(particle);
|
|
||||||
}
|
|
||||||
|
|
||||||
// create the particle system
|
// create the particle system
|
||||||
var points = WHS.MeshComponent.from(new THREE.Points(particles, pMaterial));
|
var points = WHS.MeshComponent.from(new THREE.Points(particles, pMaterial));
|
||||||
var spritesPoints = WHS.MeshComponent.from(new THREE.Points(sprites, spriteMaterial));
|
var spritesPoints = WHS.MeshComponent.from(new THREE.Points(sprites, spriteMaterial));
|
||||||
var smokePoints = WHS.MeshComponent.from(new THREE.Points(smokes, smokeMaterial));
|
|
||||||
smokePoints.isSmoke = true;
|
|
||||||
|
|
||||||
ball.fire = [points, spritesPoints, smokePoints];
|
ball.fire = [points, spritesPoints];
|
||||||
ball.fire.forEach(fire => {
|
ball.fire.forEach(fire => {
|
||||||
fire.addTo(app);
|
fire.addTo(app);
|
||||||
})
|
})
|
||||||
@ -154,25 +119,32 @@ ball.checkLife = () => {
|
|||||||
);
|
);
|
||||||
|
|
||||||
fire.geometry.vertices.forEach((v, i) => {
|
fire.geometry.vertices.forEach((v, i) => {
|
||||||
v.y += THREE.Math.randFloat(0, SPREAD_SPEED / 4);
|
let x = v.x + THREE.Math.randFloatSpread(SPREAD_SPEED) + velocity.x * -0.02;
|
||||||
v.x += THREE.Math.randFloatSpread(SPREAD_SPEED) + velocity.x * -0.02;
|
let y = v.y + THREE.Math.randFloat(0, SPREAD_SPEED / 4);
|
||||||
v.z += THREE.Math.randFloatSpread(SPREAD_SPEED) + velocity.z * -0.01;
|
let z = v.z + THREE.Math.randFloatSpread(SPREAD_SPEED) + velocity.z * -0.01;
|
||||||
|
|
||||||
if (fire.material.vertexColors === THREE.VertexColors) {
|
v.set(x, y, z);
|
||||||
|
|
||||||
|
if (!v.isSmoke && fire.material.vertexColors === THREE.VertexColors) {
|
||||||
fire.geometry.colors[i].offsetHSL(7e-4, 0, 0);
|
fire.geometry.colors[i].offsetHSL(7e-4, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (v.y >= v.lifetime) {
|
if (v.y >= v.lifetime) {
|
||||||
if (fire.isSmoke) {
|
if (!v.isSmoke && fire.material.vertexColors === THREE.VertexColors) {
|
||||||
v.y = FIRE_HEIGHT/3 + THREE.Math.randFloat(0, FIRE_HEIGHT_RANDOMNESS);
|
v.isSmoke = true;
|
||||||
|
fire.geometry.colors[i].setHex(0x444444)
|
||||||
|
v.lifetime += FIRE_HEIGHT * 0.5;
|
||||||
} else {
|
} else {
|
||||||
v.y = Math.min(radius, radius * velocity.z / -50);
|
y = Math.min(radius, radius * velocity.z / -50);
|
||||||
}
|
|
||||||
|
|
||||||
v.x = 0;
|
x = 0;
|
||||||
v.z = -ball.params.geometry.radius * 3;
|
z = -ball.params.geometry.radius * 3;
|
||||||
|
|
||||||
v.lifetime = ball.params.geometry.radius + THREE.Math.randFloat(1, 1 + FIRE_HEIGHT_RANDOMNESS) * FIRE_HEIGHT * (fire.isSmoke ? 1.5 : 1);
|
v.lifetime = ball.params.geometry.radius + THREE.Math.randFloat(1, 1 + FIRE_HEIGHT_RANDOMNESS) * FIRE_HEIGHT;
|
||||||
|
|
||||||
|
v.set(x, y, z);
|
||||||
|
|
||||||
|
v.isSmoke = false;
|
||||||
|
|
||||||
if (fire.material.vertexColors === THREE.VertexColors) {
|
if (fire.material.vertexColors === THREE.VertexColors) {
|
||||||
const r = THREE.Math.randFloat(0.8, 1);
|
const r = THREE.Math.randFloat(0.8, 1);
|
||||||
@ -181,6 +153,7 @@ ball.checkLife = () => {
|
|||||||
fire.geometry.colors[i].setRGB(r, g, b);
|
fire.geometry.colors[i].setRGB(r, g, b);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (fire.material.vertexColors === THREE.VertexColors) {
|
if (fire.material.vertexColors === THREE.VertexColors) {
|
||||||
@ -189,5 +162,19 @@ ball.checkLife = () => {
|
|||||||
fire.geometry.verticesNeedUpdate = true;
|
fire.geometry.verticesNeedUpdate = true;
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const fireLight = new WHS.PointLight({
|
||||||
|
color: 0xff0000,
|
||||||
|
intensity: 5,
|
||||||
|
});
|
||||||
|
ball.fireLight = fireLight;
|
||||||
|
ball.add(fireLight);
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
let hits = 0;
|
||||||
|
ball.on('collision', (o, v, r, cn) => {
|
||||||
|
if (o.uuid === ground.native.uuid) return;
|
||||||
|
rand(audio.impacts).play();
|
||||||
|
hits++;
|
||||||
|
GUI.setHits(hits);
|
||||||
|
});
|
||||||
|
34
src/controls.js
vendored
34
src/controls.js
vendored
@ -1,14 +1,18 @@
|
|||||||
const DFORCE = 3e3;
|
const DFORCE = 6e3;
|
||||||
const AFORCE = 500;
|
const AFORCE = 500;
|
||||||
const VFORCE = 1e4;
|
const VFORCE = 1e4;
|
||||||
|
|
||||||
Mousetrap.bind('left', () => {
|
Mousetrap.bind('left', () => {
|
||||||
if (!ball.started) return;
|
if (!ball.started) return;
|
||||||
|
const v = ball.physics.getLinearVelocity();
|
||||||
|
ball.physics.setLinearVelocity({ x: Math.min(0, v.x), y: v.y, z: v.z });
|
||||||
ball.physics.applyCentralForce({ x: -DFORCE, y: 0, z: 0 });
|
ball.physics.applyCentralForce({ x: -DFORCE, y: 0, z: 0 });
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind('right', () => {
|
Mousetrap.bind('right', () => {
|
||||||
if (!ball.started) return;
|
if (!ball.started) return;
|
||||||
|
const v = ball.physics.getLinearVelocity();
|
||||||
|
ball.physics.setLinearVelocity({ x: Math.max(0, v.x), y: v.y, z: v.z });
|
||||||
ball.physics.applyCentralForce({ x: DFORCE, y: 0, z: 0 });
|
ball.physics.applyCentralForce({ x: DFORCE, y: 0, z: 0 });
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -19,20 +23,20 @@ Mousetrap.bind('up', () => {
|
|||||||
//ball.methods.updateVelocity();
|
//ball.methods.updateVelocity();
|
||||||
});
|
});
|
||||||
|
|
||||||
Mousetrap.bind('space', () => {
|
//Mousetrap.bind('space', () => {
|
||||||
if (!ball.started) return;
|
//if (!ball.started) return;
|
||||||
if (ball.physics.data.touches.length) {
|
//if (ball.physics.data.touches.length) {
|
||||||
ball.physics.applyCentralForce({ x: 0, y: VFORCE, z: 0 });
|
//ball.physics.applyCentralForce({ x: 0, y: VFORCE, z: 0 });
|
||||||
}
|
//}
|
||||||
//ball.speed = Math.min(config.MAX_SPEED, Math.max(config.FINAL_SPEED, ball.speed + config.SPEED_INCREASE));
|
////ball.speed = Math.min(config.MAX_SPEED, Math.max(config.FINAL_SPEED, ball.speed + config.SPEED_INCREASE));
|
||||||
//ball.methods.updateVelocity();
|
////ball.methods.updateVelocity();
|
||||||
});
|
//});
|
||||||
|
|
||||||
Mousetrap.bind('down', () => {
|
//Mousetrap.bind('down', () => {
|
||||||
if (!ball.started) return;
|
//if (!ball.started) return;
|
||||||
ball.physics.applyCentralForce({ x: 0, y: 0, z: AFORCE * 3 });
|
//ball.physics.applyCentralForce({ x: 0, y: 0, z: AFORCE * 3 });
|
||||||
//ball.speed = Math.min(config.MAX_SPEED, Math.max(config.FINAL_SPEED, ball.speed - config.SPEED_INCREASE));
|
////ball.speed = Math.min(config.MAX_SPEED, Math.max(config.FINAL_SPEED, ball.speed - config.SPEED_INCREASE));
|
||||||
//ball.methods.updateVelocity();
|
////ball.methods.updateVelocity();
|
||||||
});
|
//});
|
||||||
|
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ const GUI = {
|
|||||||
score: document.getElementById('score'),
|
score: document.getElementById('score'),
|
||||||
speed: document.getElementById('speed'),
|
speed: document.getElementById('speed'),
|
||||||
time: document.getElementById('time'),
|
time: document.getElementById('time'),
|
||||||
|
hits: document.getElementById('hits'),
|
||||||
},
|
},
|
||||||
setScore(s) {
|
setScore(s) {
|
||||||
GUI.elements.score.textContent = Math.floor(s).toString().padStart(3, '0');
|
GUI.elements.score.textContent = Math.floor(s).toString().padStart(3, '0');
|
||||||
@ -13,6 +14,9 @@ const GUI = {
|
|||||||
setStartingTime() {
|
setStartingTime() {
|
||||||
GUI.startingTime = moment();
|
GUI.startingTime = moment();
|
||||||
},
|
},
|
||||||
|
setHits(s) {
|
||||||
|
GUI.elements.hits.textContent = Math.floor(s).toString().padStart(2, '0');
|
||||||
|
},
|
||||||
tickTime() {
|
tickTime() {
|
||||||
const now = moment();
|
const now = moment();
|
||||||
const diff = moment.duration(now.diff(GUI.startingTime));
|
const diff = moment.duration(now.diff(GUI.startingTime));
|
||||||
|
@ -1,36 +1,127 @@
|
|||||||
function level0() {
|
function level0() {
|
||||||
function jumpBoard(x, z) {
|
const step = rad(10);
|
||||||
const cylinder = new WHS.Cylinder({
|
const tan = Math.tan(step);
|
||||||
|
const BOX_SIZE = 100;
|
||||||
|
|
||||||
|
function add({ x, y, z } = {}, { width, depth, height } = {}, rotation = {}) {
|
||||||
|
y = y || (tan * z) + BOX_SIZE/2;
|
||||||
|
width = width || BOX_SIZE;
|
||||||
|
height = height || BOX_SIZE;
|
||||||
|
depth = depth || BOX_SIZE;
|
||||||
|
|
||||||
|
rotation.x = rotation.x || -step;
|
||||||
|
const box = new WHS.Box({
|
||||||
geometry: {
|
geometry: {
|
||||||
radiusTop: 50,
|
width,
|
||||||
radiusBottom: 1,
|
depth,
|
||||||
radiusSegments: 3,
|
height,
|
||||||
heightSegments: 1,
|
|
||||||
height: 2,
|
|
||||||
},
|
},
|
||||||
|
|
||||||
material: new THREE.MeshPhongMaterial({
|
material: new THREE.MeshPhongMaterial({
|
||||||
color: 0xffff00,
|
color: 0xffffff,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
position: [x, 0, z],
|
position: [x, y, z],
|
||||||
rotation: [Math.PI, rad(-35), 0],
|
|
||||||
|
rotation,
|
||||||
|
|
||||||
modules: [
|
modules: [
|
||||||
new PHYSICS.CylinderModule({
|
new PHYSICS.BoxModule({
|
||||||
mass: 0,
|
mass: 0,
|
||||||
|
friction: 1,
|
||||||
|
restitution: 0,
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
});
|
});
|
||||||
|
|
||||||
//cylinder.addTo(app);
|
box.addTo(app);
|
||||||
ground.add(cylinder);
|
return box;
|
||||||
}
|
}
|
||||||
|
|
||||||
//jumpBoard(5, -50);
|
const SPACE_UNIT = 250;
|
||||||
//jumpBoard(5, -100);
|
|
||||||
//
|
const patterns = [{
|
||||||
//ring({ x: 0, y: 10, z: -150 });
|
items: [3,4,5],
|
||||||
|
randoms: {
|
||||||
|
startX() {
|
||||||
|
return Math.random() > 0.5 ? 200 : -200;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
x(i, props) {
|
||||||
|
return props.startX + i * 50 * (props.startX === 200 ? -1 : 1);
|
||||||
|
},
|
||||||
|
z(i) {
|
||||||
|
return i * -BOX_SIZE;
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
items: [3,4,6],
|
||||||
|
props: {
|
||||||
|
side: 150,
|
||||||
|
},
|
||||||
|
rot: {
|
||||||
|
y(i, props) {
|
||||||
|
if (i % 3 == 0) {
|
||||||
|
return THREE.Math.randFloatSpread(Math.PI);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
size(i, props) {
|
||||||
|
return THREE.Math.randInt(BOX_SIZE * 0.8, BOX_SIZE * 1.2);
|
||||||
|
},
|
||||||
|
x(i, props) {
|
||||||
|
if (i % 3 == 0) {
|
||||||
|
return 0;
|
||||||
|
} else {
|
||||||
|
return i % 3 == 1 ? props.side : -props.side;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
z(i) {
|
||||||
|
if (i % 3 == 0) {
|
||||||
|
return i * -SPACE_UNIT;
|
||||||
|
} else {
|
||||||
|
return i % 3 == 1 ? i * -SPACE_UNIT : (i - 1) * -SPACE_UNIT;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}];
|
||||||
|
|
||||||
|
|
||||||
|
const applyPattern = (sz, { items, x, z, rot, props, randoms, space, size } = {}) => {
|
||||||
|
props = props || {};
|
||||||
|
randoms = randoms || {};
|
||||||
|
space = space || SPACE_UNIT;
|
||||||
|
rot = rot || {};
|
||||||
|
const count = rand(items);
|
||||||
|
|
||||||
|
const rs = {};
|
||||||
|
Object.entries(randoms).forEach(([key, value]) => {
|
||||||
|
rs[key] = value();
|
||||||
|
});
|
||||||
|
|
||||||
|
Object.assign(props, rs);
|
||||||
|
|
||||||
|
let zz;
|
||||||
|
|
||||||
|
for (let i = 0; i < count; i++) {
|
||||||
|
zz = sz + z(i, props);
|
||||||
|
const rotation = {};
|
||||||
|
Object.entries(rot).forEach(([key, value]) => {
|
||||||
|
rotation[key] = value(i, props);
|
||||||
|
});
|
||||||
|
let boxSize = BOX_SIZE;
|
||||||
|
if (size) {
|
||||||
|
boxSize = size(i, props);
|
||||||
|
}
|
||||||
|
add({ x: x(i, props), z: zz }, { width: boxSize, height: boxSize, depth: boxSize }, rotation);
|
||||||
|
}
|
||||||
|
|
||||||
|
return zz - space;
|
||||||
|
}
|
||||||
|
|
||||||
|
let sz = -300;
|
||||||
|
while (-sz < ground.SIZE) {
|
||||||
|
const pattern = rand(patterns);
|
||||||
|
sz = applyPattern(sz, pattern);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
level0();
|
|
||||||
|
@ -40,9 +40,13 @@ const entrance = () => {
|
|||||||
GUI.setStartingTime();
|
GUI.setStartingTime();
|
||||||
const diff = camera.position.y - ball.position.y;
|
const diff = camera.position.y - ball.position.y;
|
||||||
ball.started = true;
|
ball.started = true;
|
||||||
|
level0();
|
||||||
|
|
||||||
|
audio.rumble.play();
|
||||||
|
|
||||||
app.physics.addEventListener('update', function() {
|
app.physics.addEventListener('update', function() {
|
||||||
camera.position.set(camera.position.x, ball.position.y + diff, ball.position.z + 130);
|
//camera.position.set(camera.position.x, ball.position.y + diff, ball.position.z + 130);
|
||||||
|
camera.position.set(ball.position.x, ball.position.y + diff, ball.position.z + 130);
|
||||||
camera.native.lookAt(ball.position);
|
camera.native.lookAt(ball.position);
|
||||||
directionalLight.position.set(directionalLight.position.x, directionalLight.position.y, ball.position.z - 300);
|
directionalLight.position.set(directionalLight.position.x, directionalLight.position.y, ball.position.z - 300);
|
||||||
GUI.setScore(-ball.position.z / 100);
|
GUI.setScore(-ball.position.z / 100);
|
||||||
|
@ -1,2 +1,4 @@
|
|||||||
const rad = (deg) => deg * Math.PI / 180;
|
const rad = (deg) => deg * Math.PI / 180;
|
||||||
|
|
||||||
|
const rand = (items) => items[Math.floor(Math.random() * items.length)];
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ let ground;
|
|||||||
(function groundinit() {
|
(function groundinit() {
|
||||||
const WIDTH = 500;
|
const WIDTH = 500;
|
||||||
const SIZE = 1e5;
|
const SIZE = 1e5;
|
||||||
const mesh = new WHS.Plane({
|
ground = new WHS.Plane({
|
||||||
geometry: {
|
geometry: {
|
||||||
width: WIDTH,
|
width: WIDTH,
|
||||||
height: SIZE,
|
height: SIZE,
|
||||||
@ -51,12 +51,14 @@ let ground;
|
|||||||
}),
|
}),
|
||||||
new PHYSICS.PlaneModule({
|
new PHYSICS.PlaneModule({
|
||||||
mass: 0,
|
mass: 0,
|
||||||
|
restitution: 0,
|
||||||
}),
|
}),
|
||||||
],
|
],
|
||||||
material: new THREE.MeshPhongMaterial({ color: 0xffffff })
|
material: new THREE.MeshPhongMaterial({ color: 0xffffff })
|
||||||
});
|
});
|
||||||
|
|
||||||
ground = mesh;
|
ground.SIZE = SIZE;
|
||||||
|
|
||||||
ground.addTo(app);
|
ground.addTo(app);
|
||||||
}());
|
}());
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user