diff --git a/game.html b/game.html index 63ab13a..b0b812c 100644 --- a/game.html +++ b/game.html @@ -10,7 +10,7 @@
- Score:
0

+ Score: 0

diff --git a/game.js b/game.js index a3adddf..0fb7bfe 100644 --- a/game.js +++ b/game.js @@ -6,9 +6,9 @@ varying float intensity; varying vec3 vColor; vec3 hsv2rgb(vec3 c) { - vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); - vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); - return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } void main() @@ -17,7 +17,7 @@ void main() vec3 vNormel = normalize( normalMatrix * viewVector ); intensity = pow( c - dot(vNormal, vNormel), p ); - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); vColor = hsv2rgb(vec3(fract(gl_Position[2] / 270.0), 0.7, 0.7)); //vColor = vec3((sin(position[2] / 360.0) + 1.0) * 0.5, (sin(position[2] / 1000.0) + 1.0) * 0.5, (sin(position[2] / 70.0) + 1.0) * 0.5); //vColor = vec3(0.5, 0, 0.5); @@ -30,461 +30,397 @@ varying float intensity; void main() { vec3 glow = vColor * intensity; - gl_FragColor = vec4( glow, 1.0 ); + gl_FragColor = vec4( glow, 1.0 ); } `; - - const fragmentShader = ` - #include - - uniform vec3 iResolution; - uniform float iTime; - uniform sampler2D iChannel0; - - // By Daedelus: https://www.shadertoy.com/user/Daedelus - // license: Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. - #define TIMESCALE 0.25 - #define TILES 8 - #define COLOR 0.7, 1.6, 2.8 - - varying vec2 vUv; - varying float z; - - void mainImage( out vec4 fragColor, in vec2 fragCoord ) - { - vec2 uv = fragCoord.xy / iResolution.xy; - uv.x *= iResolution.x / iResolution.y; - - vec4 noise = texture2D(iChannel0, floor(uv * float(TILES)) / float(TILES)); - float p = 1.0 - mod(noise.r + noise.g + noise.b + (iTime + z) * float(TIMESCALE), 1.0); - p = min(max(p * 3.0 - 1.8, 0.1), 2.0); - - vec2 r = mod(uv * float(TILES), 1.0); - r = vec2(pow(r.x - 0.5, 2.0), pow(r.y - 0.5, 2.0)); - p *= 1.0 - pow(min(1.0, 12.0 * dot(r, r)), 2.0); - - fragColor = vec4(COLOR, 1.0) * p; + +const fragmentShader = ` +#include + +uniform vec3 iResolution; +uniform float iTime; +uniform sampler2D iChannel0; + +// By Daedelus: https://www.shadertoy.com/user/Daedelus +// license: Creative Commons Attribution-NonCommercial-ShareAlike 3.0 Unported License. +#define TIMESCALE 0.25 +#define TILES 8 +#define COLOR 0.7, 1.6, 2.8 + +varying vec2 vUv; +varying float z; + +void mainImage( out vec4 fragColor, in vec2 fragCoord ) +{ + vec2 uv = fragCoord.xy / iResolution.xy; + uv.x *= iResolution.x / iResolution.y; + + vec4 noise = texture2D(iChannel0, floor(uv * float(TILES)) / float(TILES)); + float p = 1.0 - mod(noise.r + noise.g + noise.b + (iTime + z) * float(TIMESCALE), 1.0); + p = min(max(p * 3.0 - 1.8, 0.1), 2.0); + + vec2 r = mod(uv * float(TILES), 1.0); + r = vec2(pow(r.x - 0.5, 2.0), pow(r.y - 0.5, 2.0)); + p *= 1.0 - pow(min(1.0, 12.0 * dot(r, r)), 2.0); + + fragColor = vec4(COLOR, 1.0) * p; +} + +void main() { + mainImage(gl_FragColor, vUv * iResolution.xy); +} +`; +const vertexShader = ` + varying vec2 vUv; + varying float z; + void main() { + vUv = uv; + z = -position[1]; + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + } +`; + +const diameterOfTunnel = 100; + +var gn; +var headSet = false; +var betaReference = 0.0; +var leftRightMove = 0.0; +var upDownMove = 0.0; + +var speed = 5.0; +let score = 0; +let removed = 0; +let running = false; +let frameCount = 0; + +function logger(text) { + console.log(text); +} + +function init_gn() { + var args = { + logger: logger + }; + + gn = new GyroNorm(); + + gn.init(args).then(function() { + var isAvailable = gn.isAvailable(); + if (!isAvailable.deviceOrientationAvailable) { + console.log({ + message: 'Device orientation is not available.' + }); + } + + if (!isAvailable.accelerationAvailable) { + console.log({ + message: 'Device acceleration is not available.' + }); + } + + if (!isAvailable.accelerationIncludingGravityAvailable) { + console.log({ + message: 'Device acceleration incl. gravity is not available.' + }); + } + + if (!isAvailable.rotationRateAvailable) { + console.log({ + message: 'Device rotation rate is not available.' + }); + } + + start_gn(); + }).catch(function(e) { + console.error(e); + }); + + document.addEventListener('keydown', e => { + if (e.key === "ArrowLeft") { + leftRightMove = -10.0; + } else if (e.key === "ArrowRight") { + leftRightMove = 10.0; + } else if (e.key === "ArrowDown") { + upDownMove = -10.0; + } else if (e.key === "ArrowUp") { + upDownMove = 10.0; + } + }); + document.addEventListener('keyup', e => { + if (e.key === "ArrowLeft") { + leftRightMove = 0; + } else if (e.key === "ArrowRight") { + leftRightMove = 0; + } else if (e.key === "ArrowDown") { + upDownMove = 0; + } else if (e.key === "ArrowUp") { + upDownMove = 0; + } + }); +} + +function stop_gn() { + gn.stop(); +} + +function start_gn() { + gn.start(gnCallBack); +} + +function gnCallBack(data) { + if (!headSet) { + betaReference = data.do.beta; + } else { + let leftRight = data.do.alpha > 180.0 ? "right" : "left"; + leftRightMove = data.do.alpha > 180.0 ? 360.0 - data.do.alpha : -data.do.alpha; + let upDown = data.do.beta > betaReference ? "up" : "down"; + upDownMove = data.do.beta - betaReference; + } +} + +function set_head_gn() { + gn.setHeadDirection(); + headSet = true; +} + +document.getElementById("set_head").addEventListener("click", () => { + document.getElementById("log").innerHTML += "clicked button
"; + set_head_gn(); +}); + +init_gn(); + +import * as THREE from './three.module.js'; +let scene, renderer; +const camera = new THREE.PerspectiveCamera(70, window.innerWidth / window.innerHeight, 0.1, 1000); + +const geometrySphere = new THREE.SphereGeometry(11, 32, 32); +const materialCube = new THREE.MeshBasicMaterial(); +const customMaterial = new THREE.ShaderMaterial({ + uniforms: { + "c": { + type: "f", + value: 0.8 + }, + "p": { + type: "f", + value: 2.4 + }, + viewVector: { + type: "v3", + value: camera.position + } + }, + vertexShader: vertexShaderGlow, + //vertexColors: true, + fragmentShader: fragmentShaderGlow, + side: THREE.FrontSide, + blending: THREE.AdditiveBlending, + transparent: true +}); + + +const loader = new THREE.TextureLoader(); +const texture = loader.load('/bayer.png'); +texture.minFilter = THREE.NearestFilter; +texture.magFilter = THREE.NearestFilter; +texture.wrapS = THREE.RepeatWrapping; +texture.wrapT = THREE.RepeatWrapping; +const uniforms = { + iTime: { + value: 0 + }, + iResolution: { + value: new THREE.Vector3(1, 1, 1) + }, + iChannel0: { + value: texture + }, +}; +const material = new THREE.ShaderMaterial({ + vertexShader, + fragmentShader, + uniforms, +}); +const borderGeometry = new THREE.PlaneGeometry(1, 1); + +const cubes = []; +const borders = []; + +init(); +animate(); + +document.getElementById("start").onclick = () => { + document.getElementById("start").style.zIndex = -10; + document.getElementById("start").style.visibility = "hidden"; + speed = 5.0; + score = 0; + for (let i = 0; i < cubes.length; i++) { + scene.remove(cubes[i]); + } + cubes.length = 0; + removed = 0; + running = true; +} + +function gameOver() { + running = false; + document.getElementById("score").innerText = document.getElementById("score").innerText + " - Game Over!"; + document.getElementById("start").style.zIndex = 0; + document.getElementById("start").style.visibility = "visible"; + document.getElementById("start").innerText = "Restart"; +} + +function init() { + + // + + scene = new THREE.Scene(); + + camera.position.set(0, 10, 25); + camera.lookAt(scene.position); + + const ambientLight = new THREE.AmbientLight(0xffffff, 0.7); + scene.add(ambientLight); + + const pointLight = new THREE.PointLight(0xffffff, 0.8); + camera.add(pointLight); + scene.add(camera); + + + renderer = new THREE.WebGLRenderer(); + renderer.setPixelRatio(window.devicePixelRatio); + renderer.setSize(window.innerWidth, window.innerHeight); + document.body.appendChild(renderer.domElement); + + + window.addEventListener('resize', onWindowResize); + +} + +function onWindowResize() { + + camera.aspect = window.innerWidth / window.innerHeight; + camera.updateProjectionMatrix(); + + renderer.setSize(window.innerWidth, window.innerHeight); + +} + +function animate() { + + requestAnimationFrame(animate); + + uniforms.iTime.value = frameCount / 60.0; + frameCount++; + + if (running) { + + for (let i = 0; i < cubes.length; i++) { + if (cubes[i].geometry.parameters.radius !== geometrySphere.parameters.radius) { + continue; } - - void main() { - mainImage(gl_FragColor, vUv * iResolution.xy); + let x1 = cubes[i].position.x; + let y1 = cubes[i].position.y; + let z1 = cubes[i].position.z; + let x2 = camera.position.x; + let y2 = camera.position.y; + let z2 = camera.position.z; + if (z2 > z1) { + // account for very fast speeds + // (prevents clipping through obstacles) + z2 = Math.max(z1, z2 - speed); } - `; - const vertexShader = ` - varying vec2 vUv; - varying float z; - void main() { - vUv = uv; - z = -position[1]; - gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); - } - `; - - const diameterOfTunnel = 100; - - var gn; - var headSet = false; - var betaReference = 0.0; - var leftRightMove = 0.0; - var upDownMove = 0.0; - - var speed = 5.0; - let score = 0; - let removed = 0; - let running = false; - let frameCount = 0; - - function logger(text) { - - } - - function init_gn() { - var args = { - logger: logger - }; - - gn = new GyroNorm(); - - gn.init(args).then(function() { - var isAvailable = gn.isAvailable(); - if(!isAvailable.deviceOrientationAvailable) { - console.log({message:'Device orientation is not available.'}); - } - - if(!isAvailable.accelerationAvailable) { - console.log({message:'Device acceleration is not available.'}); - } - - if(!isAvailable.accelerationIncludingGravityAvailable) { - console.log({message:'Device acceleration incl. gravity is not available.'}); - } - - if(!isAvailable.rotationRateAvailable) { - console.log({message:'Device rotation rate is not available.'}); - } - - start_gn(); - }).catch(function(e){ - console.error(e); - }); - - document.addEventListener('keydown', e => { - if (e.key === "ArrowLeft") { - leftRightMove = -10.0; - } else if (e.key === "ArrowRight") { - leftRightMove = 10.0; - } else if (e.key === "ArrowDown") { - upDownMove = -10.0; - } else if (e.key === "ArrowUp") { - upDownMove = 10.0; - } - }); - document.addEventListener('keyup', e => { - if (e.key === "ArrowLeft") { - leftRightMove = 0; - } else if (e.key === "ArrowRight") { - leftRightMove = 0; - } else if (e.key === "ArrowDown") { - upDownMove = 0; - } else if (e.key === "ArrowUp") { - upDownMove = 0; - } - }); - } - - function stop_gn() { - gn.stop(); - } - - function start_gn() { - gn.start(gnCallBack); - } - - function gnCallBack(data) { - if (!headSet) { - betaReference = data.do.beta; - } else { - let leftRight = data.do.alpha > 180.0 ? "right" : "left"; - leftRightMove = data.do.alpha > 180.0 ? 360.0 - data.do.alpha : -data.do.alpha; - let upDown = data.do.beta > betaReference ? "up" : "down"; - upDownMove = data.do.beta - betaReference; - } - } - - function set_head_gn() { - gn.setHeadDirection(); - headSet = true; - } - - document.getElementById("set_head").addEventListener("click", () => { - document.getElementById("log").innerHTML += "clicked button
"; - set_head_gn(); - }); - - init_gn(); - - import * as THREE from './three.module.js'; - - // import { GUI } from './jsm/libs/dat.gui.module.js'; - - //import { OrbitControls } from './three/examples/jsm/controls/OrbitControls.js'; - - //import { EffectComposer } from './three/examples/jsm/postprocessing/EffectComposer.js'; - //import { RenderPass } from './three/examples/jsm/postprocessing/RenderPass.js'; - //import { ShaderPass } from '/three/examples/jsm/postprocessing/ShaderPass.js'; - //import { LuminosityShader } from '/three/examples/jsm/shaders/LuminosityShader.js'; - //import { SobelOperatorShader } from '/three/examples/jsm/shaders/SobelOperatorShader.js'; - - let scene, renderer, composer; - const camera = new THREE.PerspectiveCamera( 70, window.innerWidth / window.innerHeight, 0.1, 1000 ); - - let effectSobel; - - const params = { - enable: true - }; - const geometryCube = new THREE.BoxGeometry( 20, 20, 20 ); - const geometrySphere = new THREE.SphereGeometry(11, 32, 32); - const geometrySphere2 = new THREE.SphereGeometry(13, 32, 32); - const materialCube = new THREE.MeshBasicMaterial(); - const outlineMaterial = new THREE.MeshBasicMaterial( { color: 0x00ffff, side: THREE.BackSide } ); - const customMaterial = new THREE.ShaderMaterial({ - uniforms: - { - "c": { type: "f", value: 0.8 }, - "p": { type: "f", value: 2.4 }, - viewVector: { type: "v3", value: camera.position } - }, - vertexShader: vertexShaderGlow, - //vertexColors: true, - fragmentShader: fragmentShaderGlow, - side: THREE.FrontSide, - blending: THREE.AdditiveBlending, - transparent: true - }); - - - const loader = new THREE.TextureLoader(); - const texture = loader.load('/bayer.png'); - texture.minFilter = THREE.NearestFilter; - texture.magFilter = THREE.NearestFilter; - texture.wrapS = THREE.RepeatWrapping; - texture.wrapT = THREE.RepeatWrapping; - const uniforms = { - iTime: { value: 0 }, - iResolution: { value: new THREE.Vector3(1, 1, 1) }, - iChannel0: { value: texture }, - }; - const material = new THREE.ShaderMaterial({ - vertexShader, - fragmentShader, - uniforms, - }); - const borderGeometry = new THREE.PlaneGeometry( 1, 1 ); - - const positions = []; - const colors = []; - const sizes = []; - const color = new THREE.Color(); - - const cubes = []; - const borders = []; - - init(); - animate(); - - document.getElementById("start").onclick = () => { - document.getElementById("start").style.zIndex = -10; - speed = 5.0; - score = 0; - for (let i = 0; i < cubes.length; i++) { - scene.remove(cubes[i]); - } - cubes.length = 0; - removed = 0; - running = true; - } - - function init() { - - // - - scene = new THREE.Scene(); - - camera.position.set( 0, 10, 25 ); - camera.lookAt( scene.position ); - - //const geometry = geometrySphere2; - //geometry.setAttribute( 'positioned', new THREE.Float32BufferAttribute( positions, 3 ) ); - //geometry.setAttribute( 'glowColor', new THREE.Float32BufferAttribute( colors, 3 ) ); - ////geometry.setAttribute( 'size', new THREE.Float32BufferAttribute( sizes, 1 ).setUsage( THREE.DynamicDrawUsage ) ); - //const particleSystem = new THREE.Mesh( geometry, customMaterial ); - //scene.add(particleSystem); - - // - - // - - //const meshCube = new THREE.Mesh( geometryCube, materialCube ); - //meshCube.position.z = -30; - //meshCube.position.x = 40; - //scene.add(meshCube); - //cubes.push(meshCube); - - // - - const ambientLight = new THREE.AmbientLight( 0xffffff, 0.7 ); - scene.add( ambientLight ); - - const pointLight = new THREE.PointLight( 0xffffff, 0.8 ); - camera.add( pointLight ); - scene.add( camera ); - - // - - renderer = new THREE.WebGLRenderer(); - renderer.setPixelRatio( window.devicePixelRatio ); - renderer.setSize( window.innerWidth, window.innerHeight ); - document.body.appendChild( renderer.domElement ); - - // postprocessing - - //composer = new EffectComposer( renderer ); - //const renderPass = new RenderPass( scene, camera ); - //composer.addPass( renderPass ); - - // color to grayscale conversion - - //const effectGrayScale = new ShaderPass( LuminosityShader ); - //composer.addPass( effectGrayScale ); - - // you might want to use a gaussian blur filter before - // the next pass to improve the result of the Sobel operator - - // Sobel operator - - //effectSobel = new ShaderPass( SobelOperatorShader ); - //effectSobel.uniforms[ 'resolution' ].value.x = window.innerWidth * window.devicePixelRatio; - //effectSobel.uniforms[ 'resolution' ].value.y = window.innerHeight * window.devicePixelRatio; - //composer.addPass( effectSobel ); - - //const controls = new OrbitControls( camera, renderer.domElement ); - //controls.minDistance = 10; - //controls.maxDistance = 100; - - // - - //const gui = new GUI(); - - //gui.add( params, 'enable' ); - //gui.open(); - - // - - window.addEventListener( 'resize', onWindowResize ); - - } - - function onWindowResize() { - - camera.aspect = window.innerWidth / window.innerHeight; - camera.updateProjectionMatrix(); - - renderer.setSize( window.innerWidth, window.innerHeight ); - //composer.setSize( window.innerWidth, window.innerHeight ); - - //effectSobel.uniforms[ 'resolution' ].value.x = window.innerWidth * window.devicePixelRatio; - //effectSobel.uniforms[ 'resolution' ].value.y = window.innerHeight * window.devicePixelRatio; - - } - - function animate() { - - requestAnimationFrame( animate ); - - uniforms.iTime.value = frameCount / 60.0; - frameCount++; - - if (running) { - - for (let i = 0; i < cubes.length; i++) { - if (cubes[i].geometry.parameters.radius !== geometrySphere.parameters.radius) { - continue; - } - let x1 = cubes[i].position.x; - let y1 = cubes[i].position.y; - let z1 = cubes[i].position.z; - let x2 = camera.position.x; - let y2 = camera.position.y; - let z2 = camera.position.z; - if (z2 > z1) { - // account for very fast speeds - // (prevents clipping through obstacles) - z2 = Math.max(z1, z2 - speed); - } - let dist_squared = (x1 - x2)**2 + (y1 - y2)**2 + (z1-z2)**2; - if (dist_squared <= cubes[i].geometry.parameters.radius**2) { - running = false; - document.getElementById("score").innerText = document.getElementById("score").innerText + " - Game Over!"; - document.getElementById("start").style.zIndex = 0; - document.getElementById("start").innerText = "Restart"; - break; - } - } - - camera.position.z -= 0.5 * speed; - speed += 0.01; - camera.position.x += 0.1 * leftRightMove; - camera.position.y += 0.1 * upDownMove; - - if (Math.random() < 0.09) { - const meshCube = new THREE.Mesh( geometrySphere, materialCube ); - meshCube.position.z = camera.position.z - 930; - meshCube.position.x = (2 * Math.random() - 1.0) * diameterOfTunnel; - meshCube.position.y = (2 * Math.random() - 1.0) * 0.9 * diameterOfTunnel; - - const outlineMesh = new THREE.Mesh( geometrySphere, customMaterial ); - outlineMesh.scale.multiplyScalar( 1.17 ); - outlineMesh.position.z = meshCube.position.z; - outlineMesh.position.x = meshCube.position.x; - outlineMesh.position.y = meshCube.position.y; - meshCube.add( outlineMesh ); - scene.add(outlineMesh); - cubes.push(outlineMesh); - //positions.push( meshCube.position.x ); - //positions.push( meshCube.position.y ); - //positions.push( meshCube.position.z ); - // - //color.setHSL( Math.random(), 1.0, 0.5 ); - //colors.push( color.r, color.g, color.b ); - - //sizes.push( 20 ); - - scene.add(meshCube); - cubes.push(meshCube); - } - - } - renderer.render( scene, camera ); - - - for (let i = 0; i < cubes.length; i++) { - if (cubes[i].position.z > camera.position.z + cubes[i].geometry.parameters.radius) { - scene.remove(cubes[i]); - cubes.splice(i, 1); - i--; - removed++; - } - } - if (removed >= 2 || score == 0) { - score += removed / 2; - removed = removed % 2; - document.getElementById("score").innerText = score; - } - if (borders.length == 0 || borders[borders.length - 1].position.z - camera.position.z > -600) { - const newZ = borders.length == 0 ? -200 : borders[borders.length - 1].position.z - diameterOfTunnel * 2; - - let border = new THREE.Mesh( borderGeometry, material ); - //border.position.x = -70; - border.position.y = -diameterOfTunnel; - border.rotation.x = -Math.PI / 2; - border.position.z = newZ; - border.scale.multiplyScalar(diameterOfTunnel * 2); - scene.add(border); - borders.push(border); - - border = new THREE.Mesh( borderGeometry, material ); - border.position.y = diameterOfTunnel; - border.rotation.x = Math.PI / 2; - border.position.z = newZ; - border.scale.multiplyScalar(diameterOfTunnel * 2); - scene.add(border); - borders.push(border); - - border = new THREE.Mesh( borderGeometry, material ); - border.position.x = -diameterOfTunnel; - border.rotation.y = Math.PI / 2; - border.position.z = newZ; - border.scale.multiplyScalar(diameterOfTunnel * 2); - scene.add(border); - borders.push(border); - - border = new THREE.Mesh( borderGeometry, material ); - border.position.x = diameterOfTunnel; - border.rotation.y = -Math.PI / 2; - border.position.z = newZ; - border.scale.multiplyScalar(diameterOfTunnel * 2); - scene.add(border); - borders.push(border); - } - //console.log(borders[borders.length - 1].position.z - camera.position.z); - //console.log(borders[borders.length - 1] - camera.position.z); - for (let i = 0; i < borders.length; i++) { - if (borders[i].position.z > camera.position.z + diameterOfTunnel + 50) { - scene.remove(borders[i]); - borders.splice(i, 1); - i--; - } - } - } - \ No newline at end of file + let dist_squared = (x1 - x2) ** 2 + (y1 - y2) ** 2 + (z1 - z2) ** 2; + if (dist_squared <= cubes[i].geometry.parameters.radius ** 2) { + gameOver(); + break; + } + } + + camera.position.z -= 0.5 * speed; + speed += 0.01; + camera.position.x += 0.1 * leftRightMove; + camera.position.y += 0.1 * upDownMove; + + if (Math.random() < 0.09) { + const meshCube = new THREE.Mesh(geometrySphere, materialCube); + meshCube.position.z = camera.position.z - 930; + meshCube.position.x = (2 * Math.random() - 1.0) * diameterOfTunnel; + meshCube.position.y = (2 * Math.random() - 1.0) * 0.9 * diameterOfTunnel; + + const outlineMesh = new THREE.Mesh(geometrySphere, customMaterial); + outlineMesh.scale.multiplyScalar(1.17); + outlineMesh.position.z = meshCube.position.z; + outlineMesh.position.x = meshCube.position.x; + outlineMesh.position.y = meshCube.position.y; + meshCube.add(outlineMesh); + scene.add(outlineMesh); + cubes.push(outlineMesh); + + scene.add(meshCube); + cubes.push(meshCube); + } + + } + renderer.render(scene, camera); + + + for (let i = 0; i < cubes.length; i++) { + if (cubes[i].position.z > camera.position.z + cubes[i].geometry.parameters.radius) { + scene.remove(cubes[i]); + cubes.splice(i, 1); + i--; + removed++; + } + } + if (removed >= 2 || score == 0) { + score += removed / 2; + removed = removed % 2; + document.getElementById("score").innerText = score; + } + if (borders.length == 0 || borders[borders.length - 1].position.z - camera.position.z > -600) { + const newZ = borders.length == 0 ? -200 : borders[borders.length - 1].position.z - diameterOfTunnel * 2; + + let border = new THREE.Mesh(borderGeometry, material); + //border.position.x = -70; + border.position.y = -diameterOfTunnel; + border.rotation.x = -Math.PI / 2; + border.position.z = newZ; + border.scale.multiplyScalar(diameterOfTunnel * 2); + scene.add(border); + borders.push(border); + + border = new THREE.Mesh(borderGeometry, material); + border.position.y = diameterOfTunnel; + border.rotation.x = Math.PI / 2; + border.position.z = newZ; + border.scale.multiplyScalar(diameterOfTunnel * 2); + scene.add(border); + borders.push(border); + + border = new THREE.Mesh(borderGeometry, material); + border.position.x = -diameterOfTunnel; + border.rotation.y = Math.PI / 2; + border.position.z = newZ; + border.scale.multiplyScalar(diameterOfTunnel * 2); + scene.add(border); + borders.push(border); + + border = new THREE.Mesh(borderGeometry, material); + border.position.x = diameterOfTunnel; + border.rotation.y = -Math.PI / 2; + border.position.z = newZ; + border.scale.multiplyScalar(diameterOfTunnel * 2); + scene.add(border); + borders.push(border); + } + for (let i = 0; i < borders.length; i++) { + if (borders[i].position.z > camera.position.z + diameterOfTunnel + 50) { + scene.remove(borders[i]); + borders.splice(i, 1); + i--; + } + } +} \ No newline at end of file diff --git a/main.css b/main.css index d600cf5..5f127a4 100644 --- a/main.css +++ b/main.css @@ -1,11 +1,16 @@ body { margin: 0; background-color: #000; - color: #fff; font-family: Monospace; - font-size: 13px; - line-height: 24px; overscroll-behavior: none; + + font-size: xxx-large; + color: #fff; + text-shadow: + 0.07em 0 black, + 0 0.07em black, + -0.07em 0 black, + 0 -0.07em black; } #start { width: 50vw;