Skip to content

Instantly share code, notes, and snippets.

@Kuzcoo
Created December 4, 2016 21:29
Show Gist options
  • Save Kuzcoo/dfa838ea8c5aca367bbe8743ea0851f1 to your computer and use it in GitHub Desktop.
Save Kuzcoo/dfa838ea8c5aca367bbe8743ea0851f1 to your computer and use it in GitHub Desktop.
let setSize = function (w,h=w) {
this.width = w;
this.height = h;
};
let createCanvas = (w,h) => {
let canvas = document.createElement('canvas');
if (w) {
setSize.call(canvas,w,h);
}
return canvas;
};
let createContext = function (c) {
return c.getContext('2d');
};
let appendCanvas = function (c) {
document.body.appendChild(c);
};
let clearCanvas = function (ctx) {
ctx.clearRect(0,0,this.width,this.height);
};
/////////////////////////////////////////////////////////////////////
let random = n => {
return Math.floor(Math.random()*n);
};
let randomAmong = function () {
return arguments[random(arguments.length-1)];
};
/////////////////////////////////////////////////////////////////////
let Keyboarder = function () {
let keys = {},
KEYS = {
LEFT: 37,
UP: 38,
RIGHT: 39,
DOWN: 40,
SPACE: 32
},
lastKey = 'RIGHT';
window.addEventListener('keydown', e => {
keys[e.keyCode] = true;
});
window.addEventListener('keyup', e => {
keys[e.keyCode] = false;
});
return {
isPressed(key) {
return keys[KEYS[key]];
}
};
}();
/////////////////////////////////////////////////////////////////////
class Hero {
constructor(ctx,bullets) {
this.bullets = bullets;
this.ctx = ctx;
this.lives = 4;
this.pos = new Vector(200,200);
this.size = 10;
}
drawLife() {
for (let i = 0; i < this.lives; i++) {
this.ctx.fillRect(15*i,0,10,10);
};
}
checkEdges() {
if (this.pos.x <= 0) {this.pos.x=0}
if (this.pos.x >= 390) {this.pos.x=390}
if (this.pos.y <= 0) {this.pos.y=0}
if (this.pos.y >= 390) {this.pos.y=390}
}
shoot(direction) {
console.log('ammo:',this.bullets.ammo);
this.bullets.add(this.pos,direction);
};
drawWeapon() {
switch (Keyboarder.lastKey) {
case 'LEFT':
ctx.fillRect(this.pos.x-15,this.pos.y+3.5,5,5);
break;
case 'UP':
ctx.fillRect(this.pos.x+2.5,this.pos.y-15,5,5);
break;
case 'RIGHT':
ctx.fillRect(this.pos.x+15,this.pos.y+3.5,5,5);
break;
case 'DOWN':
ctx.fillRect(this.pos.x+2.5,this.pos.y+15,5,5);
break;
}
}
update() {
let kb = Keyboarder;
if (kb.isPressed('LEFT')) {this.pos.x-=4;kb.lastKey='LEFT';}
if (kb.isPressed('UP')) {this.pos.y-=4;kb.lastKey='UP';}
if (kb.isPressed('RIGHT')) {this.pos.x+=4;kb.lastKey='RIGHT';}
if (kb.isPressed('DOWN')) {this.pos.y+=4;kb.lastKey='DOWN';}
//
if (kb.isPressed('SPACE')) {this.shoot(kb.lastKey);}
this.checkEdges();
}
draw() {
this.ctx.fillStyle = '#000';
this.drawLife();
this.ctx.fillRect(this.pos.x,this.pos.y,this.size,this.size);
this.drawWeapon();
}
};
/////////////////////////////////////////////////////////////////////
class Zombie {
constructor(ctx) {
this.isAlive = true;
this.speed = random(2)+1;
this.ctx = ctx;
this.hit = false;
this.pos = new Vector(random(400),-10);
this.acc = new Vector(0,0);
this.size = 15;
}
collideWith(p) {
return (this.pos.x < p.pos.x + p.size &&
this.pos.x + this.size > p.pos.x &&
this.pos.y < p.pos.y + p.size &&
this.size + this.pos.y > p.pos.y);
}
die() {
//console.log('zombie dies');
this.isAlive = false;
}
wound(hero) {
if (!this.hit) {
this.hit = true;
hero.lives-=!hero.lives?0:1;
setTimeout(() => this.hit = false,500);
}
}
goTo(heroPos) {
this.acc = Vector.sub(heroPos,this.pos);
this.acc.norm();
this.acc.mul(this.speed);
}
update(hero) {
this.goTo(hero.pos);
this.pos.add(this.acc);
this.acc.mul(0);
}
draw() {
this.ctx.fillStyle = '#ff0000';
this.ctx.fillRect(this.pos.x,this.pos.y,this.size,this.size);
}
}
class ZombieGenerator {
constructor(ctx, n) {
this.zombies = [];
this.enableSpawn = true;
this.spawnTime = 5000;
this.spawnZombies(n);
}
spawnZombies(n) {
if (this.enableSpawn) {
this.enableSpawn = false;
for (let i = 0; i < n; i++) {
this.zombies.push(new Zombie(ctx));
}
setTimeout( () => {
this.enableSpawn = true;
},this.spawnTime);
}
}
update(hero) {
this.zombies = this.zombies.filter(z => z.isAlive);
this.zombies.forEach(z => {
z.update(hero);
if (z.collideWith(hero)) {
z.wound(hero);
}
});
}
draw() {
this.zombies.forEach(z => {
z.draw();
});
}
}
/////////////////////////////////////////////////////////////////////
class Bullet {
constructor(v,dir) {
this.alive = true;
this.size = 4;
this.pos = v.get();
this.dir = this.setDirection(dir);
this.dir.mul(10);
}
setDirection(dir) {
switch (dir) {
case 'LEFT': return new Vector(-1,0) ;break;
case 'UP': return new Vector(0,-1) ;break;
case 'RIGHT': return new Vector(1,0) ;break;
case 'DOWN': return new Vector(0,1) ;break;
}
}
die() {
this.alive = false;
}
update() {
this.pos.add(this.dir);
}
draw() {
ctx.fillStyle = '#00f';
ctx.fillRect(this.pos.x,this.pos.y,4,4);
}
}
class Bullets {
constructor() {
this.bullets = [];
this.ammo = 50;
}
add(pos,dir) {
if (this.ammo > 0) {
this.ammo--;
this.bullets.push(new Bullet(pos,dir));
}
}
update(zombies) {
this.bullets = this.bullets.filter(b => b.alive);
this.bullets.forEach(b => {
zombies.forEach(z => {
if (z.collideWith(b)) {
score++;
this.ammo+=5;
b.die();
z.die();
}
});
b.update();
});
}
draw() {
this.bullets.forEach(b => {
b.draw();
});
}
}
/////////////////////////////////////////////////////////////////////
let c = null,
ctx = null,
p = null,
zombies = null,
bullets = null,
score = 0, run = true;
/////////////////////////////////////////////////////////////////////
let setup = () => {
c = createCanvas(400);
ctx = createContext(c);
appendCanvas(c);
//
bullets = new Bullets();
p = new Hero(ctx,bullets);
zombies = new ZombieGenerator(ctx,10);
};
let update = () => {
zombies.spawnZombies(5);
p.update();
zombies.update(p);
bullets.update(zombies.zombies);
};
let draw = () => {
if (!p.lives) {return;}
clearCanvas.call(c,ctx);
update();
p.draw();
zombies.draw();
bullets.draw();
requestAnimationFrame(draw);
};
/////////////////////////////////////////////////////////////////////
setup();
draw();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment