|
@@ -0,0 +1,129 @@
|
|
|
+class Vector2D {
|
|
|
+ constructor(x, y) {
|
|
|
+ this.x = x;
|
|
|
+ this.y = y;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+class Entity {
|
|
|
+ constructor(pos, vel, size, color) {
|
|
|
+ this.pos = pos;
|
|
|
+ this.vel = vel;
|
|
|
+ this.size = size;
|
|
|
+ this.color = color;
|
|
|
+ }
|
|
|
+
|
|
|
+ collides(e) {
|
|
|
+ return !(this.pos.x > e.pos.x + e.size.x || this.pos.x + this.size.x < e.pos.x)
|
|
|
+ && !(this.pos.y > e.pos.y + e.size.y || this.pos.y + this.size.y < e.pos.y);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+var player = new Entity(
|
|
|
+ new Vector2D(50, 0),
|
|
|
+ new Vector2D(0, 0),
|
|
|
+ new Vector2D(100, 100),
|
|
|
+ "#FF0000"
|
|
|
+);
|
|
|
+
|
|
|
+var enemies = [];
|
|
|
+
|
|
|
+var spawnCooldown = 0;
|
|
|
+
|
|
|
+var c = document.getElementById("myCanvas");
|
|
|
+var ctx = c.getContext("2d");
|
|
|
+
|
|
|
+// resize the canvas to fill browser window dynamically
|
|
|
+window.addEventListener('resize', resizeCanvas, false);
|
|
|
+
|
|
|
+document.onkeypress = function(evt) {
|
|
|
+ evt = evt || window.event;
|
|
|
+ var charCode = evt.keyCode || evt.which;
|
|
|
+ var charStr = String.fromCharCode(charCode);
|
|
|
+ evt.preventDefault();
|
|
|
+ onKeyPress(charStr);
|
|
|
+};
|
|
|
+
|
|
|
+function resizeCanvas() {
|
|
|
+ c.width = window.innerWidth;
|
|
|
+ c.height = window.innerHeight;
|
|
|
+
|
|
|
+ draw();
|
|
|
+}
|
|
|
+
|
|
|
+resizeCanvas();
|
|
|
+
|
|
|
+function randInt(min, max) {
|
|
|
+ return min + Math.random() * (max - min);
|
|
|
+}
|
|
|
+
|
|
|
+function drawEntity(e) {
|
|
|
+ ctx.fillStyle = e.color;
|
|
|
+ ctx.fillRect(e.pos.x, e.pos.y, e.size.x, e.size.y);
|
|
|
+}
|
|
|
+
|
|
|
+function draw() {
|
|
|
+ ctx.clearRect(0, 0, c.width, c.height);
|
|
|
+ drawEntity(player);
|
|
|
+
|
|
|
+ enemies.forEach(drawEntity);
|
|
|
+}
|
|
|
+
|
|
|
+function update() {
|
|
|
+ // Spawn enemies
|
|
|
+ if (enemies.length < 5 && spawnCooldown <= 0) {
|
|
|
+ enemies.push(new Entity(new Vector2D(c.width + randInt(50, 100), 0), new Vector2D(randInt(-15, -5), 0), new Vector2D(randInt(50, 200), randInt(50, 200)), "#00FF00"));
|
|
|
+ spawnCooldown = randInt(1 * 60, 3 * 60); // 1-3 seconds
|
|
|
+ }
|
|
|
+ spawnCooldown--;
|
|
|
+
|
|
|
+ // Apply physics to all entities
|
|
|
+ (enemies.concat([player])).forEach(function (e) {
|
|
|
+ e.pos.x += e.vel.x;
|
|
|
+ e.pos.y += e.vel.y;
|
|
|
+
|
|
|
+ e.vel.y += 1;
|
|
|
+ if (e.pos.y + e.size.y > c.height) {
|
|
|
+ e.vel.y = 0;
|
|
|
+ e.pos.y = c.height - e.size.y;
|
|
|
+ }
|
|
|
+
|
|
|
+ });
|
|
|
+
|
|
|
+ // Recolor enemies
|
|
|
+ enemies.forEach(function (e) {
|
|
|
+ if (e.pos.x < player.pos.x) {
|
|
|
+ e.color = "#0000FF";
|
|
|
+ }
|
|
|
+ });
|
|
|
+
|
|
|
+ // Kill enemies
|
|
|
+ enemies = enemies.filter(function (e) {
|
|
|
+ return e.pos.x > -e.size.x;
|
|
|
+ });
|
|
|
+
|
|
|
+ // Kill player
|
|
|
+ enemies.forEach(function (e) {
|
|
|
+ if (e.collides(player)) {
|
|
|
+ console.log("Game over!");
|
|
|
+ clearInterval(interval);
|
|
|
+ }
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+function onKeyPress(key) {
|
|
|
+ switch (key) {
|
|
|
+ case "w":
|
|
|
+ if (player.pos.y + player.size.y == c.height) {
|
|
|
+ player.vel.y = -40;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+function mainloop() {
|
|
|
+ update();
|
|
|
+ draw();
|
|
|
+}
|
|
|
+
|
|
|
+var interval = setInterval(mainloop, 1000 / 60); // 60 fps
|