Created
July 29, 2018 01:59
-
-
Save ichub/d8afbf991244ad1eddf73b1459a4be66 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<canvas width="800" height="600"></canvas> | |
<div id="score">0</div> | |
space to shoot <br> | |
arrow keys to move <br> | |
reload to restart | |
<script> | |
const canvas = document.querySelector("canvas"); | |
const scoreElement = document.getElementById("score"); | |
const ctx = canvas.getContext("2d"); | |
const keyMap = {}; | |
const player = { | |
x: 100, | |
y: 100, | |
vx: 0, | |
vy: 0, | |
size: 10, | |
angle: 0 | |
}; | |
let bullets = []; | |
let asteroids = []; | |
const maxAsteroidSpeed = 3; | |
const rotSpeed = 0.1; | |
const moveSpeed = 0.3; | |
const width = 800; | |
const height = 600; | |
let finished = false; | |
let score = 0; | |
makeRandomAsteroids(); | |
function getDirection(angle) { | |
return { | |
x: Math.cos(angle), | |
y: Math.sin(angle) | |
} | |
} | |
function scaleVec(vec, scale) { | |
return { | |
x: vec.x * scale, | |
y: vec.y * scale | |
} | |
} | |
function update() { | |
player.x += player.vx; | |
player.y += player.vy; | |
player.vy *= 0.90; | |
player.vx *= 0.90; | |
if (keyMap["ArrowLeft"]) { | |
player.angle -= rotSpeed; | |
} | |
if (keyMap["ArrowRight"]) { | |
player.angle += rotSpeed; | |
} | |
if (keyMap["ArrowUp"]) { | |
let acceleration = scaleVec(getDirection(player.angle), moveSpeed); | |
player.vx += acceleration.x; | |
player.vy += acceleration.y; | |
} | |
if (player.x > width) { | |
player.x = -player.size; | |
} | |
if (player.x < -player.size) { | |
player.x = width; | |
} | |
if (player.y < -player.size) { | |
player.y = height; | |
} | |
if (player.y > height) { | |
player.y = -player.size; | |
} | |
for (let bullet of bullets) { | |
bullet.x += bullet.vx; | |
bullet.y += bullet.vy; | |
if (bullet.x >= width || bullet.y >= height || bullet.x < 0 || bullet.y < 0) { | |
bullet.dead = true; | |
} | |
for (let asteroid of asteroids) { | |
if (!asteroid.dead) { | |
if (bullet.x >= asteroid.x && bullet.x <= asteroid.x + asteroid.size | |
&& bullet.y >= asteroid.y && bullet.y <= asteroid.y + asteroid.size) { | |
asteroid.dead = true; | |
bullet.dead = true; | |
incrementScore(); | |
asteroids = asteroids.concat(explodeAsteroid(asteroid)); | |
} | |
} | |
} | |
} | |
for (let asteroid of asteroids) { | |
asteroid.x += asteroid.vx; | |
asteroid.y += asteroid.vy; | |
if (asteroid.x > width) { | |
asteroid.x = -asteroid.size; | |
} | |
if (asteroid.x < -asteroid.size) { | |
asteroid.x = width; | |
} | |
if (asteroid.y < -asteroid.size) { | |
asteroid.y = height; | |
} | |
if (asteroid.y > height) { | |
asteroid.y = -asteroid.size; | |
} | |
if (player.x >= asteroid.x && player.x <= asteroid.x + asteroid.size | |
&& player.y >= asteroid.y && player.y <= asteroid.y + asteroid.size) { | |
finished = true; | |
alert("you lose"); | |
} | |
} | |
const nextAsteroids = []; | |
const nextBullets = []; | |
for (let asteroid of asteroids) { | |
if (!asteroid.dead) { | |
nextAsteroids.push(asteroid); | |
} | |
} | |
for (let bullet of bullets) { | |
if (!bullet.dead) { | |
nextBullets.push(bullet); | |
} | |
} | |
bullets = nextBullets; | |
asteroids = nextAsteroids; | |
if (asteroids.length === 0) { | |
alert("you win!"); | |
finished = true; | |
} | |
} | |
function incrementScore() { | |
score++; | |
scoreElement.innerText = score; | |
} | |
function explodeAsteroid(asteroid) { | |
let children = []; | |
if (asteroid.size >= 25) { | |
for (let i = 0; i < 2; i++) { | |
children.push({ | |
x: asteroid.x, | |
y: asteroid.y, | |
vx: Math.random() * maxAsteroidSpeed - maxAsteroidSpeed / 2, | |
vy: Math.random() * maxAsteroidSpeed - maxAsteroidSpeed / 2, | |
size: asteroid.size / 2, | |
dead: false | |
}) | |
} | |
} | |
return children; | |
} | |
function makeRandomAsteroids() { | |
for (let i = 0; i < 20; i++) { | |
asteroids.push({ | |
x: Math.random() * width, | |
y: Math.random() * height, | |
vx: Math.random() * 2 - 1, | |
vy: Math.random() * 2 - 1, | |
size: Math.random() * 25 + 50, | |
dead: false | |
}) | |
} | |
} | |
function draw() { | |
ctx.fillStyle = "black"; | |
ctx.strokeStyle = "white"; | |
ctx.fillRect(0, 0, 800, 600); | |
ctx.fillStyle = "white"; | |
ctx.fillRect(player.x - 2, player.y - 2, 4, 4); | |
ctx.beginPath(); | |
ctx.moveTo(player.x, player.y); | |
ctx.lineTo(Math.cos(player.angle) * 15 + player.x, Math.sin(player.angle) * 15 + player.y); | |
ctx.stroke(); | |
for (let bullet of bullets) { | |
ctx.fillRect(bullet.x, bullet.y, 5, 5); | |
} | |
for (let asteroid of asteroids) { | |
ctx.strokeRect(asteroid.x, asteroid.y, asteroid.size, asteroid.size); | |
} | |
} | |
function shoot() { | |
const vel = scaleVec(getDirection(player.angle), 5); | |
bullets.push({ | |
x: player.x, | |
y: player.y, | |
vx: vel.x, | |
vy: vel.y, | |
dead: false | |
}) | |
} | |
function frame() { | |
if (!finished) { | |
update(); | |
if (!finished) { | |
draw(); | |
} | |
} | |
} | |
document.addEventListener("keydown", function (e) { | |
keyMap[e.key] = true; | |
console.log(e.key); | |
}); | |
document.addEventListener("keyup", function (e) { | |
keyMap[e.key] = false; | |
}); | |
document.addEventListener("keydown", function (e) { | |
if (e.key === " ") { | |
shoot(); | |
} | |
}); | |
setInterval(frame, 1000 / 60); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment