var WIDTH = 480; var HEIGHT = 320; var canvas = document.getElementById("game"); canvas.width = WIDTH; canvas.height = HEIGHT; var scene = canvas.getContext("2d"); Number.prototype.clamp = function(min, max) { return Math.min(Math.max(this, min), max); }; var keydown = { states: {}, left: function() { return this.states[37] || false; }, right: function() { return this.states[39] || false; }, up: function() { return this.states[38] || false; }, down: function() { return this.states[40] || false; }, space: function() { return this.states[32] || false; } }; document.addEventListener("keydown", function (e) { keydown.states[e.keyCode] = true; }); document.addEventListener("keyup", function (e) { keydown.states[e.keyCode] = false; }); var Player = function(x, y) { this.x = x; this.y = y; this.width = 32; this.height = 32; this.color = "#0f0"; this.draw = () => { scene.fillStyle = this.color; scene.fillRect(this.x,this.y,this.width,this.height); }; this.shoot = () => { bullets.push(new Bullet(this.x+this.width/2, this.y)); }; } var Bullet = function(x, y) { this.x = x; this.y = y; this.radius = 1; this.vy = -5; this.draw = () => { scene.beginPath(); scene.arc(this.x, this.y, this.radius, 0, 2 * Math.PI, false); scene.fillStyle = "#000"; scene.fill(); } this.isInBounds = () => { return this.y == this.y.clamp(0, HEIGHT); }; } var Enemy = function() { this.x = WIDTH / 4 + Math.random() * WIDTH / 2; this.y = 0; this.vx = 0; this.vy = 1; this.width = 32; this.height = 32; this.age = Math.floor(Math.random() * 128); this.color = "#f00"; this.active = true; this.draw = () => { scene.fillStyle = this.color; scene.fillRect(this.x,this.y,this.width,this.height); }; this.step = () => { this.x += this.vx; this.y += this.vy; this.age++; this.vx = 3 * Math.sin(this.age * Math.PI / 64); }; this.isInBounds = () => { return this.x == this.x.clamp(0, WIDTH) || this.y == this.y.clamp(0, HEIGHT); }; } var player1 = new Player(); player1.x = WIDTH/2; player1.y = HEIGHT-player1.height; var bullets = []; var enemies = []; (function loop() { window.requestAnimationFrame(loop); step(); draw(); })(); function step() { if(keydown.left()) { player1.x -= 4; } else if(keydown.right()) { player1.x += 4; } player1.x = player1.x.clamp(0, WIDTH-player1.width); bullets.forEach(bullet => { bullet.y+=bullet.vy; enemies.forEach(enemy => { if(bullet.x > enemy.x && bullet.x < enemy.x + enemy.width && bullet.y < enemy.y + enemy.height && bullet.y > enemy.y) { enemy.active = false; } }) }); bullets = bullets.filter(b => b.isInBounds()); enemies.forEach(e => e.step()); enemies = enemies.filter(e => e.active && e.isInBounds()); if(keydown.space()) { player1.shoot(); } if(Math.random() < 0.05) { enemies.push(new Enemy()); } } function draw() { scene.clearRect(0,0,WIDTH,HEIGHT); player1.draw(); bullets.forEach(b => b.draw()); enemies.forEach(e => e.draw()); }
<canvas id="game"></canvas>