Threejs实现的2D射击小游戏
Threejs实现的2D射击小游戏,有血槽和射击冷却设定。
核心代码如下:
let artwork, canvas, rect, _x, _y, c, w, h, w2, h2, TWOPI, genetics, player, enemies, bullets, players, prevTime, nextTime, deltaTime, startTime, totalTime, isGameover, u, aPlayer, maxEnemies, generation = 1, isStarting = true;const init = function(){maxEnemies = 7;isGameover = false;const oldCanvas = document.querySelector('#game');if( oldCanvas )oldCanvas.remove();elseaddEventsListener();canvas = document.createElement('canvas');canvas.id = "game";canvas.width = w = 1366;canvas.height = h = 768;w2 = w/2;h2 = h/2;TWOPI = Math.PI * 2;prevTime = nextTime = deltaTime = startTime = Date.now();totalTime = 0;c = canvas.getContext('2d');c.font = "25px Arial";c.textAlign = "center";document.body.appendChild(canvas);rect = canvas.getBoundingClientRect();_x = w/rect.width;_y = h/rect.height;genetics = new Genetics();genetics.createPopulation();player = new Player();enemies = genetics.population.slice();bullets = Array();players = [player, ...enemies];if( isStarting ){startScreen();}else{update();}}const update = function(){nextTime = Date.now();deltaTime = nextTime - prevTime;totalTime += deltaTime;for(let i = bullets.length-1; i >= 0; i--){bullets[i].update();if( bullets[i].isGone )bullets.splice(i, 1)}for(let i = players.length-1; i >= 0 ; i--){if( !players[i].isDead )players[i].update(player);}draw();if( player.isDead ){gameover()return}let allDead = true;for(let i = 0; i < enemies.length; i++ ){if( !enemies[i].isDead ){allDead = false;break;}}if( allDead ){endRound()return}prevTime = nextTime;u = requestAnimationFrame( update );}const draw = function(){c.clearRect(0, 0, w, h);for(let i = 0; i < bullets.length; i++){bullets[i].show();}for(let i = 0; i < players.length; i++){if( !players[i].isDead )players[i].show();}c.textAlign = "start";c.fillStyle = "black";c.fillText("Generation: "+generation, 10, 30 )c.textAlign = "center";}const endRound = function(){totalTime = (Date.now() - startTime) / 1000;genetics.evolve();enemies = genetics.population.slice();players = [player, ...enemies];startTime = Date.now();generation += 1;player.health = Math.min(10, player.health + player.health * 0.15)update();}const startScreen = function(){c.clearRect(0,0,w,h);c.drawImage(artwork, 0, 0, artwork.width, artwork.height, 0, 0, w, h);c.fillColor = "black";c.fillText("Click to Start", w-w2/2, h2 )}const gameover = function(){if(u)cancelAnimationFrame(u)generation = 1;let i = 0;const drawGameover = function(){c.fillStyle = "rgba(0,0,0,"+(i += 0.01)+")";c.fillRect(0,0,w,h);c.fillStyle = "white";c.fillText("You have failed the human race.", w2, h2-25);c.fillText("You should move to mars or something.", w2, h2+25);if( i <= 1 ){requestAnimationFrame( drawGameover );}else{c.fillText("Click to try again.", w2, h2/2);isGameover = true;}}drawGameover();}const addEventsListener = function(){document.body.addEventListener('mousemove', e => {player.lookAt(e.clientX * _x, e.clientY * _y);});document.body.addEventListener('keydown', e => {e.preventDefault();switch(e.keyCode){case 37 :case 65 :player.isMoving.left = true;break;case 38 :case 87 :player.isMoving.up = true;break;case 39 :case 68 :player.isMoving.right = true;break;case 40 :case 83 :player.isMoving.down = true;break;}});document.body.addEventListener('keyup', e => {e.preventDefault();switch(e.keyCode){case 37 :case 65 :player.isMoving.left = false;break;case 38 :case 87 :player.isMoving.up = false;break;case 39 :case 68 :player.isMoving.right = false;break;case 40 :case 83 :player.isMoving.down = false;break;}});document.body.addEventListener('mouseup', e => {e.preventDefault();player.isShooting = false;});document.body.addEventListener('mousedown', e => {e.preventDefault();if( isGameover ){init();return;}if( isStarting ){isStarting = false;update();return;}player.isShooting = true;});window.onresize = _ => {if(u)cancelAnimationFrame(u)isStarting = true;init();}}aPlayer = document.createElement('audio');aPlayer.src = "sounds/shoot.mp3";artwork = new Image();artwork.src = "artwork.png";artwork.onload = _ => {init();if( /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent) ){const control = new GuiControls();}}
下载链接:【https://pan.baidu.com/s/1bjhCkznBMIng1lQFNiK75g】
下载码:【gnf3】
