Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- (function(window, document) {
- var mis = [];
- var explosions = [];
- var buildings = [];
- var canv,ctx;
- var rng;
- var loopInterval;
- var missileInterval;
- var keyList = [];
- var running = false;
- var code = [38, 38, 40, 40, 37, 39, 37, 39, 65, 66];
- var missileRate = 0.3;
- var targetFPS = 30;
- var incSpeed = 2;
- var outSpeed = 6;
- var explodeDuration = 40;
- var explodeRadius = 70;
- function start() {
- setupContext();
- setupGame();
- running = true;
- }
- function setupContext() {
- canv = document.createElement('canvas');
- ctx = canv.getContext('2d');
- canv.setAttribute('style', 'position: fixed; width: 100%; height: 100%; top: 0; bottom: 0; left: 0; right: 0; cursor: crosshair; opacity: 0.75; z-index: 1000;');
- document.body.appendChild(canv);
- window.addEventListener('resize', handleResize);
- handleResize();
- }
- function seed(s) {
- return function () {
- var x = Math.sin(s++) * 10000;
- return x - Math.floor(x);
- };
- }
- function handleResize() {
- canv.width = window.innerWidth;
- canv.height = window.innerHeight;
- }
- function handleKey(evt) {
- switch(evt.keyCode) {
- case 27:
- close();
- }
- if (!running) {
- keyList.push(evt.keyCode);
- if (keyList.length > 10) {
- keyList.shift();
- }
- if (codeMatch()) {
- start();
- }
- }
- }
- function codeMatch() {
- for (var i = 0; i < 10; i++) {
- if (code[i] != keyList[i]) {
- return false;
- }
- }
- return true;
- }
- function setupGame() {
- rng = seed(Math.floor(Math.random() * 10000));
- mis = [];
- explosions = [];
- buildings = [];
- missileInterval = setInterval(() => {
- mis.push(makeMissile(rng() * canv.width, 0, rng() * canv.width, canv.height, incSpeed, false));
- }, 1000 / missileRate);
- loopInterval = setInterval(loop, 1000 / targetFPS);
- canv.addEventListener('click', evt => {
- mis.push(makeMissile(canv.width / 2, canv.height, evt.x, evt.y, outSpeed, true));
- });
- for (var i = 0; i < 6; i++) {
- buildings.push(makeBuilding(i/6));
- }
- }
- function close() {
- if (!running) return;
- clearInterval(missileInterval);
- clearInterval(loopInterval);
- document.body.removeChild(canv);
- window.removeEventListener('resize', handleResize);
- running = false;
- }
- function loop() {
- ctx.fillStyle = 'black';
- ctx.fillRect(0, 0, canv.width, canv.height);
- renderMissiles();
- renderBuildings();
- renderExplosions();
- }
- function renderMissiles() {
- for (var i = 0; i < mis.length; i++) {
- var m = mis[i];
- m.t++;
- var cx = m.sx + m.vx * m.t * m.s;
- var cy = m.sy + m.vy * m.t * m.s;
- drawLine(m.sx, m.sy, cx, cy, m.color);
- if (m.friendly) {
- ctx.fillStyle = 'red';
- ctx.fillRect(m.tx - 2, m.ty - 2, 4, 4);
- }
- if (collideCheck(m)) {
- explosions.push(makeExplosion(cx, cy, m.friendly));
- mis.splice(i--, 1);
- }
- }
- }
- function renderBuildings() {
- for (var i = 0; i < buildings.length; i++) {
- var b = buildings[i];
- ctx.fillStyle = 'blue';
- ctx.fillRect(b.x, canv.height - b.height, b.width, b.height * b.health);
- if (buildingCollide(b)) {
- buildings.splice(i--, 1);
- }
- }
- }
- function renderExplosions() {
- for (var i = 0; i < explosions.length; i++) {
- var exp = explosions[i];
- exp.t++;
- var r = getExplosionRadius(exp);
- if (r < 0) {
- explosions.splice(i--, 1);
- continue;
- }
- drawCircle(exp.x, exp.y, r, exp.color);
- }
- }
- function collideCheck(m) {
- var cx = m.sx + m.vx * m.t * m.s;
- var cy = m.sy + m.vy * m.t * m.s;
- var d = Math.sqrt(Math.pow(cx - m.tx, 2) + Math.pow(cy - m.ty, 2));
- if (cx < 0 || cx > canv.width || cy < 0 || cy > canv.height || d < 10) {
- return true;
- }
- if (!m.friendly) {
- for (var i = 0; i < explosions.length; i++) {
- var exp = explosions[i];
- d = Math.sqrt(Math.pow(cx - exp.x, 2) + Math.pow(cy - exp.y, 2));
- var r = getExplosionRadius(exp);
- if (d <= r) {
- return true;
- }
- }
- for (var i = 0; i < buildings.length; i++) {
- var b = buildings[i];
- if (pointInBuilding(b, cx, cy)) {
- return true;
- }
- }
- }
- return false;
- }
- function buildingCollide(b) {
- var l1x1 = b.x, l1y1 = canv.height - b.height;
- var l1x2 = b.x + b.width, l1y2 = canv.height - b.height;
- var l2x1 = b.x, l2y1 = canv.height - b.height;
- var l2x2 = b.x, l2y2 = canv.height;
- var l3x1 = b.x + b.width, l3y1 = canv.height - b.height;
- var l3x2 = b.x + b.width, l3y2 = canv.height;
- for (var i = 0; i < explosions.length; i++) {
- var exp = explosions[i];
- var r = getExplosionRadius(exp);
- if (
- lineInCircle(l1x1, l1y1, l1x2, l1y2, exp.x, exp.y, r) ||
- lineInCircle(l2x1, l2y1, l2x2, l2y2, exp.x, exp.y, r) ||
- lineInCircle(l3x1, l3y1, l3x2, l3y2, exp.x, exp.y, r)
- ) {
- return true
- }
- }
- return false;
- }
- function makeMissile(sx, sy, tx, ty, s, friendly) {
- var mag = Math.sqrt(Math.pow(sx - tx, 2) + Math.pow(sy - ty, 2));
- var vx = (tx - sx) / mag;
- var vy = (ty - sy) / mag;
- var color = friendly ? 'white' : 'yellow';
- return {
- sx: sx,
- sy: sy,
- tx: tx,
- ty: ty,
- vx: vx,
- vy: vy,
- friendly: friendly,
- color: color,
- children: [],
- s: s,
- t: 0
- };
- }
- function makeExplosion(x, y, friendly) {
- var color = friendly ? 'white' : 'yellow';
- return {
- x: x,
- y: y,
- t: 0,
- friendly: friendly,
- color: color
- };
- }
- function makeBuilding(pos) {
- var x = pos * canv.width;
- x += (rng() - 0.5) * (rng() * (canv.width / 6 - 20));
- if (x > canv.width) x -= (canv.width / 12);
- if (x < 0) x = 0;
- if (x > canv.width / 2 - 50 && x < canv.width / 2) x -= 50;
- if (x < canv.width / 2 + 50 && x >= canv.width / 2) x += 50;
- return {
- x: x,
- health: 1,
- width: rng() * canv.width / 40 + canv.width / 80,
- height: rng() * canv.height / 10 + canv.height / 40
- }
- }
- function getExplosionRadius(exp) {
- return (-Math.pow(exp.t/explodeDuration - 1, 4) + 1) * explodeRadius;
- }
- function pointInBuilding(b, x, y) {
- return x >= b.x && x <= b.x + b.width && y >= canv.height - b.height && y <= canv.height;
- }
- function lineInCircle(x1, y1, x2, y2, cx, cy, r) {
- x1 -= cx;
- x2 -= cx;
- y1 -= cy;
- y2 -= cy;
- var dx = x2 - x1;
- var dy = y2 - y1;
- var dr = Math.sqrt(dx*dx + dy*dy);
- var D = x1 * y2 - x2 * y1;
- var c = r * r * dr * dr - D * D;
- if (c >= 0) {
- var intr = Math.sqrt(r*r*dr*dr - D*D);
- var denom = dr*dr;
- cx1 = (D * dy + sgn(dy)*dx * intr) / denom;
- cx2 = (D * dy - sgn(dy)*dx * intr) / denom;
- cy1 = (-D * dx + Math.abs(dy) * intr) / denom;
- cy2 = (-D * dx - Math.abs(dy) * intr) / denom;
- return (cx1 >= x1 && cx1 <= x2 && cy1 >= y1 && cy1 <= y2) || (cx2 >= x1 && cx2 <= x2 && cy2 >= y1 && cy2 <= y2);
- }
- return false;
- }
- function sgn(x) {
- return x < 0 ? -1 : 1;
- }
- function drawLine(sx, sy, tx, ty, color) {
- ctx.beginPath();
- ctx.moveTo(sx, sy);
- ctx.lineTo(tx, ty);
- ctx.strokeStyle = color;
- ctx.stroke();
- }
- function drawCircle(x, y, r, color) {
- ctx.beginPath();
- ctx.arc(x, y, r, 0, Math.PI * 2);
- ctx.fillStyle = color;
- ctx.fill();
- }
- window.addEventListener('keydown', handleKey);
- })(window, document);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement