<commit_before>import stepper from './stepper';

// TODO: refactor common logic with updateCurrValue and updateCurrVelocity
export function interpolateValue(alpha, nextStyle, prevStyle) {
  // assume nextStyle and prevStyle have same shape
  let ret = {};
  for (let key in nextStyle) {
    if (!nextStyle.hasOwnProperty(key)) {
      continue;
    }

    if (!nextStyle[key].config) {
      ret[key] = nextStyle[key];
      // not a spring config, not something we want to interpolate
      continue;
    }
    const prevValue = prevStyle[key].config ? prevStyle[key].val : prevStyle[key];
    ret[key] = {
      val: nextStyle[key].val * alpha + prevValue * (1 - alpha),
      config: nextStyle[key].config,
    };
  }
  return ret;
}

// TODO: refactor common logic with updateCurrentVelocity
export function updateCurrentStyle(frameRate, currentStyle, currentVelocity, style) {
  let ret = {};
  for (let key in style) {
    if (!style.hasOwnProperty(key)) {
      continue;
    }
    if (!style[key].config) {
      ret[key] = style[key];
      // not a spring config, not something we want to interpolate
      continue;
    }
    const [k, b] = style[key].config;
    const val = stepper(
      frameRate,
      // might have been a non-springed prop that just became one
      currentStyle[key].val == null ? currentStyle[key] : currentStyle[key].val,
      currentVelocity[key],
      style[key].val,
      k,
      b,
    )[0];
    ret[key] = {
      val: val,
      config: style[key].config,
    };
  }
  return ret;
}

export function updateCurrentVelocity(frameRate, currentStyle, currentVelocity, style) {
  let ret = {};
  for (let key in style) {
    if (!style.hasOwnProperty(key)) {
      continue;
    }
    if (!style[key].config) {
      // not a spring config, not something we want to interpolate
      ret[key] = 0;
      continue;
    }
    const [k, b] = style[key].config;
    const val = stepper(
      frameRate,
      // might have been a non-springed prop that just became one
      currentStyle[key].val == null ? currentStyle[key] : currentStyle[key].val,
      currentVelocity[key],
      style[key].val,
      k,
      b,
    )[1];
    ret[key] = val;
  }
  return ret;
}
<commit_msg>Fix new interpolateValue bug<commit_after>import stepper from './stepper';

// TODO: refactor common logic with updateCurrValue and updateCurrVelocity
export function interpolateValue(alpha, nextStyle, prevStyle) {
  // might be used by a TransitionMotion, where prevStyle might not exist anymore
  if (!prevStyle) {
    return nextStyle;
  }

  let ret = {};
  for (let key in nextStyle) {
    if (!nextStyle.hasOwnProperty(key)) {
      continue;
    }

    if (!nextStyle[key].config) {
      ret[key] = nextStyle[key];
      // not a spring config, not something we want to interpolate
      continue;
    }
    const prevValue = prevStyle[key].config ? prevStyle[key].val : prevStyle[key];
    ret[key] = {
      val: nextStyle[key].val * alpha + prevValue * (1 - alpha),
      config: nextStyle[key].config,
    };
  }

  return ret;
}

// TODO: refactor common logic with updateCurrentVelocity
export function updateCurrentStyle(frameRate, currentStyle, currentVelocity, style) {
  let ret = {};
  for (let key in style) {
    if (!style.hasOwnProperty(key)) {
      continue;
    }
    if (!style[key].config) {
      ret[key] = style[key];
      // not a spring config, not something we want to interpolate
      continue;
    }
    const [k, b] = style[key].config;
    const val = stepper(
      frameRate,
      // might have been a non-springed prop that just became one
      currentStyle[key].val == null ? currentStyle[key] : currentStyle[key].val,
      currentVelocity[key],
      style[key].val,
      k,
      b,
    )[0];
    ret[key] = {
      val: val,
      config: style[key].config,
    };
  }
  return ret;
}

export function updateCurrentVelocity(frameRate, currentStyle, currentVelocity, style) {
  let ret = {};
  for (let key in style) {
    if (!style.hasOwnProperty(key)) {
      continue;
    }
    if (!style[key].config) {
      // not a spring config, not something we want to interpolate
      ret[key] = 0;
      continue;
    }
    const [k, b] = style[key].config;
    const val = stepper(
      frameRate,
      // might have been a non-springed prop that just became one
      currentStyle[key].val == null ? currentStyle[key] : currentStyle[key].val,
      currentVelocity[key],
      style[key].val,
      k,
      b,
    )[1];
    ret[key] = val;
  }
  return ret;
}
<|endoftext|>


<commit_before>// const shrinkRay = require('shrink-ray-current');
const polka = require('polka');
const next = require('next');
const { parse } = require('url');
const { join } = require('path');

const { PORT = 4242, NODE_ENV } = process.env;

const dev = NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

const rootStaticFiles = [
  '/favicon.ico',
  '/keybase.txt',
  '/robots.txt',
  '/sitemap.xml',
];

app.prepare().then(() => {
  polka()
    // Have Polka handle all requests
    .get('*', (req, res) => {
      const parsedUrl = parse(req.url, true);
      const { path, query } = parsedUrl;
      // IF: request is for one of the root static files,
      // then serve from /static/ as if root /
      // ELSE: handle and render request with Next.js
      // or by actual request path
      if (rootStaticFiles.includes(path)) {
        app.serveStatic(req, res, join(__dirname, 'static', path));
      } else {
        handle(req, res);
      }
    })
    .listen(PORT)
    .then(() => console.log(`> Ready on http://localhost:${PORT}`));
});

// const configuration = {
//   port: 4242,
//   config: {
//     cleanUrls: true,
//     headers: [
//       {
//         source: '**',
//         headers: [
//           {
//             key: 'Access-Control-Allow-Origin',
//             value: 'https://anthony.codes',
//           },
//           {
//             key: 'Cache-Control',
//             value: 'max-age=31536000',
//           },
//           {
//             key: 'Content-Security-Policy',
//             value:
//               "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net/ https://*.googleapis.com/; " +
//               "script-src 'self' 'unsafe-inline' https://*.google-analytics.com/ https://*.googletagmanager.com/ https://cdn.jsdelivr.net/; " +
//               "font-src 'self' https://*.gstatic.com/ https://*.googleapis.com/; " +
//               "base-uri 'self';",
//           },
//           {
//             key: 'Strict-Transport-Security',
//             value: 'max-age=63072000; includeSubDomains; preload',
//           },
//           {
//             key: 'X-Content-Type-Options',
//             value: 'nosniff',
//           },
//           {
//             key: 'X-Frame-Options',
//             value: 'DENY',
//           },
//           {
//             key: 'X-UA-Compatible',
//             value: 'IE=edge; chrome=1',
//           },
//           {
//             key: 'X-XSS-Protection',
//             value: '1; mode=block',
//           },
//         ],
//       },
//     ],
//     public: './build/web',
//     rewrites: [
//       {
//         source: '**',
//         destination: '/index.html',
//       },
//     ],
//   },
//   cwd: __dirname,
//   compression: shrinkRay(),
//   debug: false,
// };
<commit_msg>Add back shrink-ray-current and add https/fs to index.js for compression and local dev SSL<commit_after>const shrinkRay = require('shrink-ray-current');
const polka = require('polka');
const next = require('next');
const { parse } = require('url');
const { join } = require('path');
const { createServer } = require('https');
const { readFileSync } = require('fs');

const { PORT = 4242, NODE_ENV } = process.env;

const dev = NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();

const options = {
  key: readFileSync('./localhost+2-key.pem'),
  cert: readFileSync('./localhost+2.pem'),
};

const rootStaticFiles = [
  '/favicon.ico',
  '/keybase.txt',
  '/resume-anthony-maki.pdf',
  '/robots.txt',
  '/sitemap.xml',
];

app.prepare().then(() => {
  const { handler } = polka()
    // Have Polka handle all requests
    .use(shrinkRay())
    .get('*', (req, res) => {
      const parsedUrl = parse(req.url, true);
      const { path, query } = parsedUrl;
      // IF: request is for one of the root static files,
      // then serve from /static/ as if root /
      // ELSE: handle and render request with Next.js
      // or by actual request path
      if (rootStaticFiles.includes(path)) {
        app.serveStatic(req, res, join(__dirname, 'static', path));
      } else {
        handle(req, res);
      }
    });

  createServer(options, handler).listen(PORT, _ =>
    console.log(`> Ready on https://localhost:${PORT}`),
  );
});

// const configuration = {
//   port: 4242,
//   config: {
//     cleanUrls: true,
//     headers: [
//       {
//         source: '**',
//         headers: [
//           {
//             key: 'Access-Control-Allow-Origin',
//             value: 'https://anthony.codes',
//           },
//           {
//             key: 'Cache-Control',
//             value: 'max-age=31536000',
//           },
//           {
//             key: 'Content-Security-Policy',
//             value:
//               "style-src 'self' 'unsafe-inline' https://cdn.jsdelivr.net/ https://*.googleapis.com/; " +
//               "script-src 'self' 'unsafe-inline' https://*.google-analytics.com/ https://*.googletagmanager.com/ https://cdn.jsdelivr.net/; " +
//               "font-src 'self' https://*.gstatic.com/ https://*.googleapis.com/; " +
//               "base-uri 'self';",
//           },
//           {
//             key: 'Strict-Transport-Security',
//             value: 'max-age=63072000; includeSubDomains; preload',
//           },
//           {
//             key: 'X-Content-Type-Options',
//             value: 'nosniff',
//           },
//           {
//             key: 'X-Frame-Options',
//             value: 'DENY',
//           },
//           {
//             key: 'X-UA-Compatible',
//             value: 'IE=edge; chrome=1',
//           },
//           {
//             key: 'X-XSS-Protection',
//             value: '1; mode=block',
//           },
//         ],
//       },
//     ],
//     public: './build/web',
//     rewrites: [
//       {
//         source: '**',
//         destination: '/index.html',
//       },
//     ],
//   },
//   cwd: __dirname,
//   compression: shrinkRay(),
//   debug: false,
// };
<|endoftext|>


<commit_before>game.PlayerEntity = me.Entity.extend({
	init: function(x, y, settings) { /*constructor function*/
		this._super(me.Entity, 'init', [x, y, {
			image: "player", /*describes what the player entity is, its size shape ect*/
			width: 64,
			height: 64,
			spritewidth: "64",
			spriteheight: "64",
			getShape: function(){
				return(new me.Rect(0, 0, 64, 64)).toPolygon(); /*essentialy sets its hitbox*/
			}
		}]);

		this.body.setVelocity(5, 20); /*20 for the y value is essentially gravity so that the player falls*/
		this.facing = "right"; /*keeps track of direction of character*/
		this.now = new Date().getTime();
		this.lastHit = this.now;
		this.lastAttack = new Date().getTime();

		me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH); /*makes the camerafollow the player*/

		this.renderable.addAnimation("idle", [78]); /*adds the animation for idle*/
		this.renderable.addAnimation("walk", [117, 118, 119, 120, 121, 122, 123, 124, 125], 80);/*and for walk*/
		this.renderable.addAnimation("attack", [65, 66, 67, 68, 69, 70, 71, 72], 80); /*as wellas for attack*/

		this.renderable.setCurrentAnimation("idle"); /*by default set the animation for idle*/

	},

	update: function(delta){
		this.now = new Date().getTime();
		if(me.input.isKeyPressed("right")) { /*if the right arrow is being pushed then.....*/
			/* this adds the position of my x by adding the velocity and multiplying it by me.timer.tick*/
			/*me.timer.tick makes the movement look smooth*/
			this.body.vel.x += this.body.accel.x * me.timer.tick;
			this.facing = "right";
			this.flipX(true);
		}
		else if(me.input.isKeyPressed("left")) { /*if the right arrow is being pushed then.....*/
			/* this adds the position of my x by adding the velocity and multiplying it by me.timer.tick*/
			/*me.timer.tick makes the movement look smooth*/
			this.body.vel.x -= this.body.accel.x * me.timer.tick;
			this.facing ="left";
			this.flipX(false);
		}
		else{ /*if its not being pushed then its not moving*/
			this.body.vel.x = 0;
		}

		if(me.input.isKeyPressed("jump") && !this.body.jumping && !this.body.falling && !this.renderable.isCurrentAnimation("attack")) { /*if jump is pressed, and player isnt jumping or falling*/
			this.body.jumping = true; /*set jumping equal to true*/
			this.body.vel.y -= this.body.accel.y * me.timer.tick; /*formula saying y-velocity= y-accel * time*/
		}

		/*I made it so you cant attack while in the air*/
		if(me.input.isKeyPressed("attack") && !this.body.jumping && !this.body.falling){ /*if attack key (space) is being pressed then*/
			if(!this.renderable.isCurrentAnimation("attack")) { /*check if attack is not being pressed*/
				this.renderable.setCurrentAnimation("attack", "idle") /*if so then set animation to attack and then set it to idle*/
				this.renderable.setAnimationFrame();
				/*makes it so that when the animation plays again it starts from the very beggining*/
			}

		}
		else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")) { /*if the velocity doesnt equal 0*/
			if(!this.renderable.isCurrentAnimation("walk")) { /*and if the animation is currently not "walk"*/
				this.renderable.setCurrentAnimation("walk"); /* then set it to walk*/
			}
		}
		else if(!this.renderable.isCurrentAnimation("attack")) {
			this.renderable.setCurrentAnimation("idle"); /*otherwise set animation to idle*/
		}

		if(this.renderable.isCurrentAnimation("attack"))  { /*I made it so that you cant move while attacking*/
			this.body.vel.x = 0; /*if you're attacking your x velocity is 0*/
		}

		me.collision.check(this, true, this.collideHandler.bind(this), true); /*passing parameter tha is checking for thecollision and whatever its running in to*/
		this.body.update(delta); /*delta is the change in time*/

		this._super(me.Entity, "update", [delta]);
		return true;
	},

	collideHandler: function(response) {
		if(response.b.type ==='EnemyBaseEntity'){
			var ydif = this.pos.y - response.b.pos.y; /*sets variable equal to y-pos - responce.b.y-pos*/
			var xdif = this.pos.x - response.b.pos.x; /*sets variable equal to x-pos - responce.b.x-pos*/

			if(ydif< -40 && xdif< 70 && xdif >-35 && ydif>-50) { /*if you're in the location of the upper hitbox*/
				this.body.falling = false; /*you're no longer falling*/
				this.body.vel.y = -1; /*and your y velocity is -1*/
			}

			if(xdif > -35 && this.facing === 'right' && (xdif<0)) { /*if you're facing right and xdif>-35*/
				this.body.vel.x = 0; /*set velocity = 0*/
				this.pos.x = this.pos.x - 1; /*set position to itself minus 1*/
			}
			else if(xdif<70 && this.facing === 'left' && (xdif>0)) { /*same thing except inversely for left*/
				this.body.vel.x = 0;
				this.pos.x = this.pos.x + 1;
			}

			if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= 1000) { /*if attacking*/
				this.lastHit = this.now; /*makes it so it will only lose health once per one attack*/
				response.b.loseHealth(); /*tower will lose health*/
			}
		}
	}
});
/*Player base*/
game.PlayerBaseEntity = me.Entity.extend({
	init :  function(x, y, settings) {
		this._super(me.Entity, 'init', [x, y, { /*specifics for what the playerbase entity is and how big it is and its shape*/
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				return (new me.Rect(0, 0, 100, 72)).toPolygon();
			}
		}]);
		this.broken = false; /*by default it isnt borken*/
		this.health = 10; /*it has 10 health*/
		this.alwaysUpdate = true; /*always update*/
		this.body.onCollision = this.onCollision.bind(this);

		this.type = "PlayerBase";

		this.renderable.addAnimation("idle", [0]); /*adds animations for normal and broken towers*/
		this.renderable.addAnimation("broken", [1]);
		this.renderable.setCurrentAnimation("idle"); /*sets the normal animation to idle*/
	},

	update:function(delta) { /*keep checking if*/
		if(this.health<=0) { /*the health<=0 then the tower is broken*/
			this.broken = true; /*if so, then set it to broken*/
			this.renderable.setCurrentAnimation("broken");  /*and use the broken animation*/
		}
		this.body.update(delta); /*time since last update*/

		this._super(me.Entity, "update", [delta]);
		return true;
	},

	loseHealth: function(damage) {
		this.health = this.health - damage;
	},

	onCollision: function() {

	}

});

/*Enemy base*/
game.EnemyBaseEntity = me.Entity.extend({
	init :  function(x, y, settings) {
		this._super(me.Entity, 'init', [x, y, {
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				return (new me.Rect(0, 0, 100,72)).toPolygon();
			}
		}]);
		this.broken = false;
		this.health = 10;
		this.alwaysUpdate = true;
		this.body.onCollision = this.onCollision.bind(this);

		this.type = "EnemyBaseEntity";

		this.renderable.addAnimation("idle", [0]);
		this.renderable.addAnimation("broken", [1]);
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta) { /*keep checking if*/
		if(this.health<=0) { /*the health<=0 then the tower is broken*/
			this.broken = true; /*if so, then set it to broken*/
			this.renderable.setCurrentAnimation("broken");  /*and use the broken animation*/
		}
		this.body.update(delta); /*time since last update*/

		this._super(me.Entity, "update", [delta]);
		return true;
	},

	onCollision: function() {

	},

	loseHealth: function() {
		this.health--; /*subracts one from health*/
	}
});

game.EnemyCreep = me.Entity.extend({
	init: function(x, y, settings) { /*initializing what enemy creep is*/
		this._super(me.Entity, 'init', [x, y, {
			image: "creep1", /*uses this img*/
			width: 32, /*32 wide*/
			height: 64, /*64 tall*/
			spritewidth: "32",
			spriteheight: "64",
			getShape: function() {
				return (new me.Rect(0, 0, 32, 64)).toPolygon(); /*is a rectangle with these specs*/
			}
		}]);
		this.health = 10; /*has 10 health*/
		this.alwaysUpdate = true; /*always updates even if its not on screen*/
		this.attacking = false; /*makes the enemy not attacking*/
		this.lastAttacking = new Date().getTime(); /*keeps track of when our creeep last attacked anything*/
		this.lastHit = new Date().getTime(); /*and when our creep last hit anything*/
		this.now = new Date().getTime();
		this.body.setVelocity(3, 20);

		this.type = "EnemyCreep";

		this.renderable.addAnimation("walk", [3,4,5], 80); /*adds animation for walking*/
		this.renderable.setCurrentAnimation("walk"); /*sets animation to walk*/
	},

	update: function(delta) {
		this.now = new Date().getTime();
		this.body.vel.x -= this.body.accel.x * me.timer.tick; /*makes creep walk to the left*/

		me.collision.check(this, true, this.collideHandler.bind(this), true);

		this.body.update(delta); /*time since last update*/

		this._super(me.Entity, "update", [delta]);

		return true;
	},

	collideHandler: function(response) {
		if(response.b.type==='PlayerBase') { /*if colliding with player base*/
			this.attacking=true; /*set attacking to true*/
			//this.lastAttacking=this.now;
			this.body.vel.x = 0; /*make it sit still*/
			this.pos.x = this.pos.x + 1; /*push it slightly to the right to maintain its position*/
			if((this.now-this.lastHit >= 1000)) {/*and if the last attack was more than a second ago*/
				this.lastHit = this.now; /*and reset it to now as the current timer*/
				response.b.loseHealth(1); /*make player base lose 1 health*/
			}
		}
	}

});
game.GameManager = Object.extend({
	init: function(x, y, settings) {
		this.now = new Date().getTime();
		this.lastCreep = new Date().getTime();

		this.alwaysUpdate = true;
	},

	update: function() {
		this.now = new Date().getTime();

		if(Math.round(this.now/1000)%10 === 0 && (this.now - this.lastCreep >= 1000)) { /*on a timer every 1 second*/
			this.lastCreep = this.now;
			var creepe = me.pool.pull("EnemyCreep", 1000, 0, {}); /*define what creep is*/
			me.game.world.addChild(creepe, 5); /*and spawn one*/
		}
		return true;
	}
});<commit_msg>Awesomenauts completed video 22: completed, coded, and commented<commit_after>game.PlayerEntity = me.Entity.extend({
	init: function(x, y, settings) { /*constructor function*/
		this._super(me.Entity, 'init', [x, y, {
			image: "player", /*describes what the player entity is, its size shape ect*/
			width: 64,
			height: 64,
			spritewidth: "64",
			spriteheight: "64",
			getShape: function(){
				return(new me.Rect(0, 0, 64, 64)).toPolygon(); /*essentialy sets its hitbox*/
			}
		}]);
		this.type = "PlayerEntity"; /*you are a player entity*/
		this.health = 20; /*and your health is 20*/
		this.body.setVelocity(5, 20); /*20 for the y value is essentially gravity so that the player falls*/
		this.facing = "right"; /*keeps track of direction of character*/
		this.now = new Date().getTime();
		this.lastHit = this.now;
		this.lastAttack = new Date().getTime();

		me.game.viewport.follow(this.pos, me.game.viewport.AXIS.BOTH); /*makes the camerafollow the player*/

		this.renderable.addAnimation("idle", [78]); /*adds the animation for idle*/
		this.renderable.addAnimation("walk", [117, 118, 119, 120, 121, 122, 123, 124, 125], 80);/*and for walk*/
		this.renderable.addAnimation("attack", [65, 66, 67, 68, 69, 70, 71, 72], 80); /*as wellas for attack*/

		this.renderable.setCurrentAnimation("idle"); /*by default set the animation for idle*/

	},

	update: function(delta){
		this.now = new Date().getTime();
		if(me.input.isKeyPressed("right")) { /*if the right arrow is being pushed then.....*/
			/* this adds the position of my x by adding the velocity and multiplying it by me.timer.tick*/
			/*me.timer.tick makes the movement look smooth*/
			this.body.vel.x += this.body.accel.x * me.timer.tick;
			this.facing = "right";
			this.flipX(true);
		}
		else if(me.input.isKeyPressed("left")) { /*if the right arrow is being pushed then.....*/
			/* this adds the position of my x by adding the velocity and multiplying it by me.timer.tick*/
			/*me.timer.tick makes the movement look smooth*/
			this.body.vel.x -= this.body.accel.x * me.timer.tick;
			this.facing ="left";
			this.flipX(false);
		}
		else{ /*if its not being pushed then its not moving*/
			this.body.vel.x = 0;
		}

		if(me.input.isKeyPressed("jump") && !this.body.jumping && !this.body.falling && !this.renderable.isCurrentAnimation("attack")) { /*if jump is pressed, and player isnt jumping or falling*/
			this.body.jumping = true; /*set jumping equal to true*/
			this.body.vel.y -= this.body.accel.y * me.timer.tick; /*formula saying y-velocity= y-accel * time*/
		}

		/*I made it so you cant attack while in the air*/
		if(me.input.isKeyPressed("attack") && !this.body.jumping && !this.body.falling){ /*if attack key (space) is being pressed then*/
			if(!this.renderable.isCurrentAnimation("attack")) { /*check if attack is not being pressed*/
				this.renderable.setCurrentAnimation("attack", "idle") /*if so then set animation to attack and then set it to idle*/
				this.renderable.setAnimationFrame();
				/*makes it so that when the animation plays again it starts from the very beggining*/
			}

		}
		else if(this.body.vel.x !== 0 && !this.renderable.isCurrentAnimation("attack")) { /*if the velocity doesnt equal 0*/
			if(!this.renderable.isCurrentAnimation("walk")) { /*and if the animation is currently not "walk"*/
				this.renderable.setCurrentAnimation("walk"); /* then set it to walk*/
			}
		}
		else if(!this.renderable.isCurrentAnimation("attack")) {
			this.renderable.setCurrentAnimation("idle"); /*otherwise set animation to idle*/
		}

		if(this.renderable.isCurrentAnimation("attack"))  { /*I made it so that you cant move while attacking*/
			this.body.vel.x = 0; /*if you're attacking your x velocity is 0*/
		}

		me.collision.check(this, true, this.collideHandler.bind(this), true); /*passing parameter tha is checking for thecollision and whatever its running in to*/
		this.body.update(delta); /*delta is the change in time*/

		this._super(me.Entity, "update", [delta]);
		return true;
	},

	loseHealth: function(damage) {
		this.health = this.health - damage; /*current health is health minus howver much damage you took*/
	},

	collideHandler: function(response) {
		if(response.b.type ==='EnemyBaseEntity'){
			var ydif = this.pos.y - response.b.pos.y; /*sets variable equal to y-pos - responce.b.y-pos*/
			var xdif = this.pos.x - response.b.pos.x; /*sets variable equal to x-pos - responce.b.x-pos*/

			if(ydif< -40 && xdif< 70 && xdif >-35 && ydif>-50) { /*if you're in the location of the upper hitbox*/
				this.body.falling = false; /*you're no longer falling*/
				this.body.vel.y = -1; /*and your y velocity is -1*/
			}

			if(xdif > -35 && this.facing === 'right' && (xdif<0)) { /*if you're facing right and xdif>-35*/
				this.body.vel.x = 0; /*set velocity = 0*/
				this.pos.x = this.pos.x - 1; /*set position to itself minus 1*/
			}
			else if(xdif<70 && this.facing === 'left' && (xdif>0)) { /*same thing except inversely for left*/
				this.body.vel.x = 0;
				this.pos.x = this.pos.x + 1;
			}

			if(this.renderable.isCurrentAnimation("attack") && this.now-this.lastHit >= 1000) { /*if attacking*/
				this.lastHit = this.now; /*makes it so it will only lose health once per one attack*/
				response.b.loseHealth(); /*tower will lose health*/
			}
		}
	}
});
/*Player base*/
game.PlayerBaseEntity = me.Entity.extend({
	init :  function(x, y, settings) {
		this._super(me.Entity, 'init', [x, y, { /*specifics for what the playerbase entity is and how big it is and its shape*/
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				return (new me.Rect(0, 0, 100, 72)).toPolygon();
			}
		}]);
		this.broken = false; /*by default it isnt borken*/
		this.health = 10; /*it has 10 health*/
		this.alwaysUpdate = true; /*always update*/
		this.body.onCollision = this.onCollision.bind(this);

		this.type = "PlayerBase";

		this.renderable.addAnimation("idle", [0]); /*adds animations for normal and broken towers*/
		this.renderable.addAnimation("broken", [1]);
		this.renderable.setCurrentAnimation("idle"); /*sets the normal animation to idle*/
	},

	update:function(delta) { /*keep checking if*/
		if(this.health<=0) { /*the health<=0 then the tower is broken*/
			this.broken = true; /*if so, then set it to broken*/
			this.renderable.setCurrentAnimation("broken");  /*and use the broken animation*/
		}
		this.body.update(delta); /*time since last update*/

		this._super(me.Entity, "update", [delta]);
		return true;
	},

	loseHealth: function(damage) {
		this.health = this.health - damage;
	},

	onCollision: function() {

	}

});

/*Enemy base*/
game.EnemyBaseEntity = me.Entity.extend({
	init :  function(x, y, settings) {
		this._super(me.Entity, 'init', [x, y, {
			image: "tower",
			width: 100,
			height: 100,
			spritewidth: "100",
			spriteheight: "100",
			getShape: function() {
				return (new me.Rect(0, 0, 100,72)).toPolygon();
			}
		}]);
		this.broken = false;
		this.health = 10;
		this.alwaysUpdate = true;
		this.body.onCollision = this.onCollision.bind(this);

		this.type = "EnemyBaseEntity";

		this.renderable.addAnimation("idle", [0]);
		this.renderable.addAnimation("broken", [1]);
		this.renderable.setCurrentAnimation("idle");
	},

	update:function(delta) { /*keep checking if*/
		if(this.health<=0) { /*the health<=0 then the tower is broken*/
			this.broken = true; /*if so, then set it to broken*/
			this.renderable.setCurrentAnimation("broken");  /*and use the broken animation*/
		}
		this.body.update(delta); /*time since last update*/

		this._super(me.Entity, "update", [delta]);
		return true;
	},

	onCollision: function() {

	},

	loseHealth: function() {
		this.health--; /*subracts one from health*/
	}
});

game.EnemyCreep = me.Entity.extend({
	init: function(x, y, settings) { /*initializing what enemy creep is*/
		this._super(me.Entity, 'init', [x, y, {
			image: "creep1", /*uses this img*/
			width: 32, /*32 wide*/
			height: 64, /*64 tall*/
			spritewidth: "32",
			spriteheight: "64",
			getShape: function() {
				return (new me.Rect(0, 0, 32, 64)).toPolygon(); /*is a rectangle with these specs*/
			}
		}]);
		this.health = 10; /*has 10 health*/
		this.alwaysUpdate = true; /*always updates even if its not on screen*/
		this.attacking = false; /*makes the enemy not attacking*/
		this.lastAttacking = new Date().getTime(); /*keeps track of when our creeep last attacked anything*/
		this.lastHit = new Date().getTime(); /*and when our creep last hit anything*/
		this.now = new Date().getTime();
		this.body.setVelocity(3, 20);

		this.type = "EnemyCreep";

		this.renderable.addAnimation("walk", [3,4,5], 80); /*adds animation for walking*/
		this.renderable.setCurrentAnimation("walk"); /*sets animation to walk*/
	},

	update: function(delta) {
		this.now = new Date().getTime();
		this.body.vel.x -= this.body.accel.x * me.timer.tick; /*makes creep walk to the left*/

		me.collision.check(this, true, this.collideHandler.bind(this), true);

		this.body.update(delta); /*time since last update*/

		this._super(me.Entity, "update", [delta]);

		return true;
	},

	collideHandler: function(response) {
		if(response.b.type==='PlayerBase') { /*if colliding with player base*/
			this.attacking=true; /*set attacking to true*/
			//this.lastAttacking=this.now;
			this.body.vel.x = 0; /*make it sit still*/
			this.pos.x = this.pos.x + 1; /*push it slightly to the right to maintain its position*/
			if((this.now-this.lastHit >= 1000)) {/*and if the last attack was more than a second ago*/
				this.lastHit = this.now; /*and reset it to now as the current timer*/
				response.b.loseHealth(1); /*make player base lose 1 health*/
			}
		}

		else if(response.b.type==='PlayerEntity') { /*if colliding with player*/
			var xdif = this.pos.x - response.b.pos.x; /*xdif is used for position*/

			this.attacking=true; /*set attacking to true*/
			//this.lastAttacking=this.now;
			if(xdif>0) {
				this.pos.x = this.pos.x + 1; /*push it slightly to the right to maintain its position*/
				this.body.vel.x = 0; /*make it sit still*/
			}
			if((this.now-this.lastHit >= 1000) && xdif>0) {/*and if the last attack was more than a second ago*/
				this.lastHit = this.now; /*and reset it to now as the current timer*/
				response.b.loseHealth(1); /*make player lose 1 health*/
			}
		}
	}

});
game.GameManager = Object.extend({
	init: function(x, y, settings) {
		this.now = new Date().getTime();
		this.lastCreep = new Date().getTime();

		this.alwaysUpdate = true;
	},

	update: function() {
		this.now = new Date().getTime();

		if(Math.round(this.now/1000)%10 === 0 && (this.now - this.lastCreep >= 1000)) { /*on a timer every 1 second*/
			this.lastCreep = this.now;
			var creepe = me.pool.pull("EnemyCreep", 1000, 0, {}); /*define what creep is*/
			me.game.world.addChild(creepe, 5); /*and spawn one*/
		}
		return true;
	}
});<|endoftext|>


<commit_before>var socket = io.connect(),
  $ = document.querySelector.bind(document),
  name, arena;

canvas = $('#c')
canvas.width = 800
canvas.height = 600
ctx = canvas.getContext('2d')

image = new Image()
image.src = 'player.png'
image.onload = initialize

ctx.webkitImageSmoothingEnabled = false
ctx.mozImageSmoothingEnabled = false
ctx.translate(canvas.width / 2, canvas.height / 2)
ctx.scale(4, 4)
//ctx.scale(2,2)

socket.on('taken', taken)
// on id, set id for user tracking purposes
socket.on('name', function (n) {
  name = n
  hideInstructions()
})
// on death, draw instructios
socket.on('dead', drawInstructions)
// on game data, display on canvas
socket.on('setState', setState)
socket.on('diffState', mergeDiff)
// on item diff data, update item list

var alerts = []
socket.on('highScores', function (scores) {
  var $s = $('#scores')
  $s.innerHTML = '
Top 10
'

  // This is sage because names are guarenteed to only be letters
  for (var i = 0; i < scores.length; i++) {
    var len = (scores[i].name + scores[i].score).length
    $s.innerHTML += '
' + scores[i].name + repeat(' ', 22 - len) + scores[i].score + '
'
  }
});

function repeat(s, n) {
  return new Array(n + 1).join(s)
}
socket.on('alert', function alert(msg) {
  // split alert string into many msgs
  while (msg) {
    var m = msg.substr(0, 27)
    msg = msg.substring(27)
    alerts.push({
      msg: m,
      time: 200
    })
  }
})

socket.on('chat', function (msg) {
  var c = $('#chatBox')
  c.innerHTML = c.innerHTML.replace(/
/g, '\n')
  c.textContent += msg + '\n'
  c.innerHTML = c.innerHTML.replace(/\n/g, '
')
  c.scrollTop = 10e5
})
var instructionsVisible = true
// on keypress, send command to server
// left, up, right, down, space, z
var keys = [37, 38, 39, 40, 32, 90]
window.onkeydown = function (e) {
  keys.indexOf(e.which) != -1 && socket.emit('keydown', e.which)
}
window.onkeyup = function (e) {
  keys.slice(0, 4).indexOf(e.which) != -1 && socket.emit('keyup', e.which)
}

// start by drawing instructions (+ name inputs over canvas?)
function drawInstructions() {
  if (!instructionsVisible) {
    $('#overlay').style.display = 'block'
    instructionsVisible = true
  }
}

function hideInstructions() {
  if (instructionsVisible) {
    $('#overlay').style.display = 'none'
    $('#red').style.visibility = 'hidden'
    $('#name').style.borderColor = '#ECF0F1'
    instructionsVisible = false
  }
}

function initialize() {
  $('#join').onsubmit = join
  $('#chatInput').onsubmit = chat
  //debug
  $('#name').value = 'Zolmeister'
  join({
    preventDefault: function () {}
  })
}

function chat(e) {
  e.preventDefault()
  var msg = $('#msg').value
  $('#msg').value = ''
  socket.emit('chat', msg)
}

function join(e) {
  e.preventDefault()
  var name = $('#name').value
  if (/^[a-zA-Z]+$/.test(name)) {
    console.log('joining as', name)
    socket.emit('join', name)
    return
  }
  badName(name)
}

function taken(res) {
  $('#red').style.visibility = 'visible'
  $('#name').style.borderColor = '#C0392B'
  $('#taken').innerText = res.name + ' is ' + (res.dead ? 'dead' : 'taken')
}

function badName(name) {
  $('#red').style.visibility = 'visible'
  $('#taken').innerText = 'Only letters allowed'
}
// as soon as user id appears in player list, remove instructions

//game

function draw() {
  //ctx.restore()
  ctx.clearRect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height)
  var players = arena && arena.players

  var me;
  ctx.fillStyle = '#fff'
  for (var i = 0; i < players.length; i++) {
    var player = players[i]
    if (player.n == name) me = player
  }

  me = me || players[0]
  if (!me) return

  //draw terrain
  drawTerrain(me.x, me.y)

  // draw items
  drawItems(me.x, me.y)

  //draw bullets
  drawBullets(me.x, me.y)

  //ctx.save()
  //ctx.translate(canvas.width/2, canvas.height/2)
  for (var i = 0; i < players.length; i++) {
    var player = players[i]
    // draw player
    drawPlayer(player.x - me.x - 11, player.y - me.y - 5, player.n, player.h, player.d, player.f, player.w, player.s)
    //ctx.fillRect((player.x - me.x), (player.y - me.y), 10, 10)
  }

  drawAlerts()
}

function drawAlerts() {
  for (var i = alerts.length - 1; i >= 0; i--) {
    var alert = alerts[i]
    alert.time--
    if (alert.time <= 0) {
      alerts.splice(i, 1)
      continue
    }
    ctx.font = '5px sans'
    ctx.fillStyle = '#faa'
    ctx.fillText(alert.msg, (400 - 300) / 4, (-300 + 30 + 5 * 4 * i) / 4)
  }
}

var random = (function rng() {
  var x = 123456789,
    y = 362436069,
    z = 521288629,
    w = 88675123,
    t;
  return function rand() {
    t = x ^ (x << 11)
    x = y;
    y = z;
    z = w;
    w = w ^ (w >> 19) ^ (t ^ (t >> 8));
    return (w * 2.3283064365386963e-10) * 2;
  }
})()

var map = (function generateMap() {
  var m = []
  for (var y = -canvas.height / 2; y < canvas.height / 2; y += 14) {
    var temp = []
    for (var x = -canvas.width / 2; x < canvas.width / 2; x += 14) {
      var rand = random()
      if (rand > 0.99) {
        temp.push(3)
      } else if (rand > 0.95) {
        temp.push(2)
      } else if (rand > 0.8) {
        temp.push(1)
      } else {
        temp.push(0)
      }
    }
    m.push(temp)
  }
  return m
})();

function drawTerrain(offsetX, offsetY) {
  var row = 0
  var col = 2

  for (var y = -canvas.height / 2; y < canvas.height / 2; y += 14) {
    for (var x = -canvas.width / 2; x < canvas.width / 2; x += 14) {
      if (x - offsetX + 14 < -canvas.width / 4 / 2 || y - offsetY + 14 < -canvas.height / 4 / 2 || x - offsetX > canvas.width / 4 / 2 || y - offsetY > canvas.height / 4 / 2) continue
      ctx.drawImage(image, image.width - col * 14, map[(y + canvas.height / 2) / 14][(x + canvas.width / 2) / 14] * 14, 14, 14, x - offsetX, y - offsetY, 14, 14)
    }
  }
}

function drawItems(offsetX, offsetY) {
  var items = arena.items
  var row = 0
  var col = 1
  for (var i = 0; i < items.length; i++) {
    var item = items[i]
    if (item.x - offsetX + 14 < -canvas.width / 4 / 2 || item.y - offsetY + 14 < -canvas.height / 4 / 2 || item.x - offsetX > canvas.width / 4 / 2 || item.y - offsetY > canvas.height / 4 / 2) continue
    ctx.drawImage(image, image.width - col * 14, item.n * 14, 14, 14, item.x - offsetX, item.y - offsetY, 14, 14)
  }
}

function drawBullets(offsetX, offsetY) {
  var bullets = arena.bullets

  var row = 3
  var col = 1
  for (var i = 0; i < bullets.length; i++) {
    var bullet = bullets[i]
    if (bullet.x - offsetX + 14 < -canvas.width / 4 / 2 || bullet.y - offsetY + 14 < -canvas.height / 4 / 2 || bullet.x - offsetX > canvas.width / 4 / 2 || bullet.y - offsetY > canvas.height / 4 / 2) continue
    if (bullet.t == 0) {
      ctx.save()
      ctx.translate(bullet.x - offsetX + 7, bullet.y - offsetY + 7)
      // left, up/left, up, up/right, right, down/right, down, down/left
      // 0,    1,       2,  3,        4,     5,          6,    7
      var rotate = [1, -.75, -.5, -.25, 0, .25, .5, .75]
      ctx.rotate(rotate[bullet.d] * Math.PI)
      ctx.drawImage(image, image.width - col * 14, row * 14, 14, 14, -7, -7, 14, 14)
      ctx.restore()
    } else {
      ctx.save()
      ctx.translate(bullet.x - offsetX + 7 - (bullet.d == 2 ? -5 : 0), bullet.y - offsetY + 7)

      var rotate = [1, -.75, -.5, -.25, 0, .25, .5, .75]
      ctx.rotate(rotate[bullet.d] * Math.PI)
      ctx.fillStyle = '#666'
      ctx.fillRect(0, 0, 5, 2)
      //ctx.fillRect(bullet.x - offsetX + (bullet.d == 1 ? 10 : 5), bullet.y - offsetY + 7, bullet.d % 2 == 0 ? 5 : 2, bullet.d % 2 == 0 ? 2 : 5)
      ctx.restore()
    }
  }
}

function drawPlayer(x, y, name, health, dir, frame, weapon, kills) {

  // 22 x 20, with +10 x-offset
  var rowDir = [1, 0, 0, 0, 1, 2, 2, 2]
  var row = rowDir[dir]
  var col = frame == 3 ? 1 : frame
  col += (weapon + 1) * 7
  x += 10

  // draw name
  ctx.fillStyle = '#fff'
  ctx.font = '3px sans'
  ctx.fillText(name + ' (' + kills + ')', (x - name.length + 12), y - 2)

  // draw health bar
  ctx.fillStyle = '#3a3'
  ctx.fillRect(x + 1, y - 1, health / 5, 1)
  ctx.fillStyle = '#a33'
  ctx.fillRect(x + 1 + health / 5, y - 1, 100 / 5 - health / 5, 1)

  ctx.save()
  if (dir == 0 || dir == 1 || dir == 7) {
    ctx.translate(44, 0)
    ctx.scale(-1, 1)
    x = 22 - x
  }
  ctx.fillStyle = '#fff'
  //ctx.fillRect(x,y,22,20)
  var tanAngle = Math.tan(Math.PI / 4)
  var pMap = {
    1: {
      x: 304,
      y: 310 + 24
    },
    3: {
      x: 402,
      y: 292
    },
    5: {
      x: 400,
      y: 310
    },
    7: {
      x: 304,
      y: 310 - 42
    }
  }

  if (pMap[dir]) {
    ctx.setTransform(3.8, (dir == 1 || dir == 5 ? -1 : 1) * tanAngle, 0, 4, pMap[dir].x, pMap[dir].y)
  }

  //draw character
  ctx.drawImage(image, col * 22, row * 20, 22, 20, x, y, 22, 20)
  ctx.restore()

}

function setState(state) {
  arena = state
  draw()
}

// This diff will be sent and applied by the client to sync their arena
// diff[0-2] = players
// diff[0] = new players (append to end)
// diff[1] = del players indicies (splice, starting in reverse order)
// diff[2] = player updates (i:index, updated attrs)
// diff[3-5] = bullets
// diff[6-8] = items
function mergeDiff(diff) {

  // players
  for (var i = 0; i < diff[0].length; i++) {
    arena.players.push(diff[0][i])
  }
  for (var i = 0; i < diff[1].length; i++) {
    if (arena.players[diff[1][i]].n == name) drawInstructions()
    arena.players.splice(diff[1][i], 1)
  }
  for (var i = 0; i < diff[2].length; i++) {
    var update = diff[2][i]
    var index = update.i
    delete update.i
    for (var key in update) {
      arena.players[index][key] = update[key]
    }
  }

  // bullets
  for (var i = 0; i < diff[3].length; i++) {
    arena.bullets.push(diff[3][i])
  }
  for (var i = 0; i < diff[4].length; i++) {
    arena.bullets.splice(diff[4][i], 1)
  }
  for (var i = 0; i < diff[5].length; i++) {
    var update = diff[5][i]
    var index = update.i
    delete update.i
    for (var key in update) {
      arena.bullets[index][key] = update[key]
    }
  }

  // items
  for (var i = 0; i < diff[6].length; i++) {
    arena.items.push(diff[6][i])
  }
  for (var i = 0; i < diff[7].length; i++) {
    arena.items.splice(diff[7][i])
  }
  for (var i = 0; i < diff[8].length; i++) {
    var update = diff[8][i]
    var index = update.i
    delete update.i
    for (var key in update) {
      arena.items[index][key] = update[key]
    }
  }

  draw()
}<commit_msg>ventered text and healthbar<commit_after>var socket = io.connect(),
  $ = document.querySelector.bind(document),
  name, arena;

canvas = $('#c')
canvas.width = 800
canvas.height = 600
ctx = canvas.getContext('2d')

image = new Image()
image.src = 'player.png'
image.onload = initialize

ctx.webkitImageSmoothingEnabled = false
ctx.mozImageSmoothingEnabled = false
ctx.translate(canvas.width / 2, canvas.height / 2)
ctx.scale(4, 4)
//ctx.scale(2,2)
ctx.font = '3px sans'
ctx.textAlign='center'

socket.on('taken', taken)
// on id, set id for user tracking purposes
socket.on('name', function (n) {
  name = n
  hideInstructions()
})
// on death, draw instructios
socket.on('dead', drawInstructions)
// on game data, display on canvas
socket.on('setState', setState)
socket.on('diffState', mergeDiff)
// on item diff data, update item list

var alerts = []
socket.on('highScores', function (scores) {
  var $s = $('#scores')
  $s.innerHTML = '
Top 10
'

  // This is sage because names are guarenteed to only be letters
  for (var i = 0; i < scores.length; i++) {
    var len = (scores[i].name + scores[i].score).length
    $s.innerHTML += '
' + scores[i].name + repeat(' ', 22 - len) + scores[i].score + '
'
  }
});

function repeat(s, n) {
  return new Array(n + 1).join(s)
}
socket.on('alert', function alert(msg) {
  // split alert string into many msgs
  while (msg) {
    var m = msg.substr(0, 27)
    msg = msg.substring(27)
    alerts.push({
      msg: m,
      time: 200
    })
  }
})

socket.on('chat', function (msg) {
  var c = $('#chatBox')
  c.innerHTML = c.innerHTML.replace(/
/g, '\n')
  c.textContent += msg + '\n'
  c.innerHTML = c.innerHTML.replace(/\n/g, '
')
  c.scrollTop = 10e5
})
var instructionsVisible = true
// on keypress, send command to server
// left, up, right, down, space, z
var keys = [37, 38, 39, 40, 32, 90]
window.onkeydown = function (e) {
  keys.indexOf(e.which) != -1 && socket.emit('keydown', e.which)
}
window.onkeyup = function (e) {
  keys.slice(0, 4).indexOf(e.which) != -1 && socket.emit('keyup', e.which)
}

// start by drawing instructions (+ name inputs over canvas?)
function drawInstructions() {
  if (!instructionsVisible) {
    $('#overlay').style.display = 'block'
    instructionsVisible = true
  }
}

function hideInstructions() {
  if (instructionsVisible) {
    $('#overlay').style.display = 'none'
    $('#red').style.visibility = 'hidden'
    $('#name').style.borderColor = '#ECF0F1'
    instructionsVisible = false
  }
}

function initialize() {
  $('#join').onsubmit = join
  $('#chatInput').onsubmit = chat
  //debug
  $('#name').value = 'a'
  join({
    preventDefault: function () {}
  })
}

function chat(e) {
  e.preventDefault()
  var msg = $('#msg').value
  $('#msg').value = ''
  socket.emit('chat', msg)
}

function join(e) {
  e.preventDefault()
  var name = $('#name').value
  if (/^[a-zA-Z]+$/.test(name)) {
    console.log('joining as', name)
    socket.emit('join', name)
    return
  }
  badName(name)
}

function taken(res) {
  $('#red').style.visibility = 'visible'
  $('#name').style.borderColor = '#C0392B'
  $('#taken').innerText = res.name + ' is ' + (res.dead ? 'dead' : 'taken')
}

function badName(name) {
  $('#red').style.visibility = 'visible'
  $('#taken').innerText = 'Only letters allowed'
}
// as soon as user id appears in player list, remove instructions

//game

function draw() {
  //ctx.restore()
  ctx.clearRect(-canvas.width / 2, -canvas.height / 2, canvas.width, canvas.height)
  var players = arena && arena.players

  var me;
  ctx.fillStyle = '#fff'
  for (var i = 0; i < players.length; i++) {
    var player = players[i]
    if (player.n == name) me = player
  }

  me = me || players[0]
  if (!me) return

  //draw terrain
  drawTerrain(me.x, me.y)

  // draw items
  drawItems(me.x, me.y)

  //draw bullets
  drawBullets(me.x, me.y)

  //ctx.save()
  //ctx.translate(canvas.width/2, canvas.height/2)
  for (var i = 0; i < players.length; i++) {
    var player = players[i]
    // draw player
    drawPlayer(player.x - me.x - 11, player.y - me.y - 5, player.n, player.h, player.d, player.f, player.w, player.s)
    //ctx.fillRect((player.x - me.x), (player.y - me.y), 10, 10)
  }

  drawAlerts()
}

function drawAlerts() {
  for (var i = alerts.length - 1; i >= 0; i--) {
    var alert = alerts[i]
    alert.time--
    if (alert.time <= 0) {
      alerts.splice(i, 1)
      continue
    }
    ctx.font = '5px sans'
    ctx.fillStyle = '#faa'
    ctx.fillText(alert.msg, (400 - 300) / 4, (-300 + 30 + 5 * 4 * i) / 4)
  }
}

var random = (function rng() {
  var x = 123456789,
    y = 362436069,
    z = 521288629,
    w = 88675123,
    t;
  return function rand() {
    t = x ^ (x << 11)
    x = y;
    y = z;
    z = w;
    w = w ^ (w >> 19) ^ (t ^ (t >> 8));
    return (w * 2.3283064365386963e-10) * 2;
  }
})()

var map = (function generateMap() {
  var m = []
  for (var y = -canvas.height / 2; y < canvas.height / 2; y += 14) {
    var temp = []
    for (var x = -canvas.width / 2; x < canvas.width / 2; x += 14) {
      var rand = random()
      if (rand > 0.99) {
        temp.push(3)
      } else if (rand > 0.95) {
        temp.push(2)
      } else if (rand > 0.8) {
        temp.push(1)
      } else {
        temp.push(0)
      }
    }
    m.push(temp)
  }
  return m
})();

function drawTerrain(offsetX, offsetY) {
  var row = 0
  var col = 2

  for (var y = -canvas.height / 2; y < canvas.height / 2; y += 14) {
    for (var x = -canvas.width / 2; x < canvas.width / 2; x += 14) {
      if (x - offsetX + 14 < -canvas.width / 4 / 2 || y - offsetY + 14 < -canvas.height / 4 / 2 || x - offsetX > canvas.width / 4 / 2 || y - offsetY > canvas.height / 4 / 2) continue
      ctx.drawImage(image, image.width - col * 14, map[(y + canvas.height / 2) / 14][(x + canvas.width / 2) / 14] * 14, 14, 14, x - offsetX, y - offsetY, 14, 14)
    }
  }
}

function drawItems(offsetX, offsetY) {
  var items = arena.items
  var row = 0
  var col = 1
  for (var i = 0; i < items.length; i++) {
    var item = items[i]
    if (item.x - offsetX + 14 < -canvas.width / 4 / 2 || item.y - offsetY + 14 < -canvas.height / 4 / 2 || item.x - offsetX > canvas.width / 4 / 2 || item.y - offsetY > canvas.height / 4 / 2) continue
    ctx.drawImage(image, image.width - col * 14, item.n * 14, 14, 14, item.x - offsetX, item.y - offsetY, 14, 14)
  }
}

function drawBullets(offsetX, offsetY) {
  var bullets = arena.bullets

  var row = 3
  var col = 1
  for (var i = 0; i < bullets.length; i++) {
    var bullet = bullets[i]
    if (bullet.x - offsetX + 14 < -canvas.width / 4 / 2 || bullet.y - offsetY + 14 < -canvas.height / 4 / 2 || bullet.x - offsetX > canvas.width / 4 / 2 || bullet.y - offsetY > canvas.height / 4 / 2) continue
    if (bullet.t == 0) {
      ctx.save()
      ctx.translate(bullet.x - offsetX + 7, bullet.y - offsetY + 7)
      // left, up/left, up, up/right, right, down/right, down, down/left
      // 0,    1,       2,  3,        4,     5,          6,    7
      var rotate = [1, -.75, -.5, -.25, 0, .25, .5, .75]
      ctx.rotate(rotate[bullet.d] * Math.PI)
      ctx.drawImage(image, image.width - col * 14, row * 14, 14, 14, -7, -7, 14, 14)
      ctx.restore()
    } else {
      ctx.save()
      ctx.translate(bullet.x - offsetX + 7 - (bullet.d == 2 ? -5 : 0), bullet.y - offsetY + 7)

      var rotate = [1, -.75, -.5, -.25, 0, .25, .5, .75]
      ctx.rotate(rotate[bullet.d] * Math.PI)
      ctx.fillStyle = '#666'
      ctx.fillRect(0, 0, 5, 2)
      //ctx.fillRect(bullet.x - offsetX + (bullet.d == 1 ? 10 : 5), bullet.y - offsetY + 7, bullet.d % 2 == 0 ? 5 : 2, bullet.d % 2 == 0 ? 2 : 5)
      ctx.restore()
    }
  }
}

function drawPlayer(x, y, name, health, dir, frame, weapon, kills) {

  // 22 x 20, with +10 x-offset
  var rowDir = [1, 0, 0, 0, 1, 2, 2, 2]
  var row = rowDir[dir]
  var col = frame == 3 ? 1 : frame
  col += (weapon + 1) * 7
  x += 10

  // draw health bar
  var hp = health/6
  ctx.fillStyle = '#3a3'
  ctx.fillRect(x + 2, y - 1, hp, 1)
  ctx.fillStyle = '#a33'
  ctx.fillRect(x + hp, y - 1, 100 / 6 - hp, 1)

  // draw name
  ctx.fillStyle = '#fff'
  ctx.fillText(name + ' (' + kills + ')', x + 11, y - 2)

  ctx.save()
  if (dir == 0 || dir == 1 || dir == 7) {
    ctx.translate(44, 0)
    ctx.scale(-1, 1)
    x = 22 - x
  }

  //ctx.fillStyle = '#fff'
  //ctx.fillRect(x,y,22,20)
  var tanAngle = Math.tan(Math.PI / 4)
  var pMap = {
    1: {
      x: 304,
      y: 310 + 24
    },
    3: {
      x: 402,
      y: 292
    },
    5: {
      x: 400,
      y: 310
    },
    7: {
      x: 304,
      y: 310 - 42
    }
  }

  if (pMap[dir]) {
    ctx.setTransform(3.8, (dir == 1 || dir == 5 ? -1 : 1) * tanAngle, 0, 4, pMap[dir].x, pMap[dir].y)
  }

  //draw character
  ctx.drawImage(image, col * 22, row * 20, 22, 20, x, y, 22, 20)
  ctx.restore()

}

function setState(state) {
  arena = state
  draw()
}

// This diff will be sent and applied by the client to sync their arena
// diff[0-2] = players
// diff[0] = new players (append to end)
// diff[1] = del players indicies (splice, starting in reverse order)
// diff[2] = player updates (i:index, updated attrs)
// diff[3-5] = bullets
// diff[6-8] = items
function mergeDiff(diff) {

  // players
  for (var i = 0; i < diff[0].length; i++) {
    arena.players.push(diff[0][i])
  }
  for (var i = 0; i < diff[1].length; i++) {
    if (arena.players[diff[1][i]].n == name) drawInstructions()
    arena.players.splice(diff[1][i], 1)
  }
  for (var i = 0; i < diff[2].length; i++) {
    var update = diff[2][i]
    var index = update.i
    delete update.i
    for (var key in update) {
      arena.players[index][key] = update[key]
    }
  }

  // bullets
  for (var i = 0; i < diff[3].length; i++) {
    arena.bullets.push(diff[3][i])
  }
  for (var i = 0; i < diff[4].length; i++) {
    arena.bullets.splice(diff[4][i], 1)
  }
  for (var i = 0; i < diff[5].length; i++) {
    var update = diff[5][i]
    var index = update.i
    delete update.i
    for (var key in update) {
      arena.bullets[index][key] = update[key]
    }
  }

  // items
  for (var i = 0; i < diff[6].length; i++) {
    arena.items.push(diff[6][i])
  }
  for (var i = 0; i < diff[7].length; i++) {
    arena.items.splice(diff[7][i])
  }
  for (var i = 0; i < diff[8].length; i++) {
    var update = diff[8][i]
    var index = update.i
    delete update.i
    for (var key in update) {
      arena.items[index][key] = update[key]
    }
  }

  draw()
}<|endoftext|>


<commit_before>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var net = require('net');
var cbt = require('pelger-cbt')();
var _ = require('underscore');

/**
 * nfd client sdk
 */
module.exports = function() {
  var _client;
  var _stdoutCb;
  var _stderrCb;

  var connect = function(options, cb) {
    _client = net.connect(options, function() {
      cb();
    });

    _client.on('data', function(data) {
      var str = data.toString('utf8');
      var lines;
      var callback;
      var json;

      lines = str.split('\n');
      _.each(lines, function(line) {
        if (line.length > 0) {
          json = JSON.parse(line);

          if (json.responseType === 'stdout') {
            if (_stdoutCb) {
              _stdoutCb(json);
            }
          }
          else if (json.responseType === 'stderr') {
            if (_stderrCb) {
              _stderrCb(json);
            }
          }
          else if (json.responseType === 'response') {
            callback = cbt.fetch(json.request);
            callback(json.response);
          }
        }
      });
    });

    _client.on('end', function() {
    });
  };

  var listSystems = function(cb) {
    cbt.trackById('list systems', cb);
    _client.write('list systems\n');
  };

  var createSystem = function(name, namespace, cb) {
    cbt.trackById('create system', cb);
    _client.write('create system ' + name + ' ' + namespace + '\n');
  };

  var getSystem = function(systemId, cb) {
    cbt.trackById('get system', cb);
    _client.write('get system ' + systemId + '\n');
  };

  var deleteSystem = function(systemId, cb) {
    cbt.trackById('delete system', cb);
    _client.write('delete system ' + systemId + '\n');
  };

  var putSystem = function(systemJson, cb) {
    cbt.trackById('put system', cb);
    _client.write('put system\n');
    _client.write(systemJson + '\n');
    _client.write('END\n');
  };

  var listContainers = function(systemId, cb) {
    cbt.trackById('list containers', cb);
    _client.write('list containers ' + systemId + '\n');
  };

  var addContainer = function(systemId, containerJson, cb) {
    cbt.trackById('add container', cb);
    _client.write('add container ' + systemId + '\n');
    _client.write(containerJson + '\n');
    _client.write('END\n');
  };

  var putContainer = function(systemId, containerJson, cb) {
    cbt.trackById('put container', cb);
    _client.write('put container ' + systemId + '\n');
    _client.write(containerJson + '\n');
    _client.write('END\n');
  };

  var deleteContainer = function(systemId, containerId, cb) {
    cbt.trackById('delete container', cb);
    _client.write('delete container ' + systemId + ' ' + containerId + '\n');
  };

  var buildContainer = function(systemId, containerId, cb) {
    cbt.trackById('build container', cb);
    _client.write('build container ' + systemId + ' ' + containerId + '\n');
  };

  var deploySystem = function(systemId, revisionId, cb) {
    cbt.trackById('deploy system', cb);
    _client.write('deploy system ' + systemId + ' ' + revisionId + '\n');
  };

  var deployAll = function(systemId, revisionId, cb) {
    cbt.trackById('deploy all', cb);
    _client.write('deploy all ' + systemId + ' ' + revisionId + '\n');
  };

  var listRevisions = function(systemId, cb) {
    cbt.trackById('list revisions', cb);
    _client.write('list revisions ' + systemId + '\n');
  };

  var getRevision = function(systemId, revisionId, cb) {
    cbt.trackById('get revision ', cb);
    _client.write('get revision ' + systemId + ' ' + revisionId + '\n');
  };

  var timeline = function(systemId, containerId, user, cb) {
    cbt.trackById('list timeline', cb);
    _client.write('list timeline ' + systemId + ' ' + containerId + ' ' + user + '\n');
  };

  var addToTimeline = function(timelineJson, cb) {
    cbt.trackById('add timeline', cb);
    _client.write('add timeline\n');
    _client.write(timelineJson + '\n');
    _client.write('END\n');
  };

  var quit = function(cb) {
    cbt.trackById('quit', cb);
    _client.write('quit\n');
  };

  var ioHandlers = function(stdoutCb, stderrCb) {
    _stdoutCb = stdoutCb;
    _stderrCb = stderrCb;
  };

  return {
    connect: connect,
    quit: quit,
    createSystem: createSystem,
    listSystems: listSystems,
    getSystem: getSystem,
    putSystem: putSystem,
    deleteSystem: deleteSystem,

    putContainer: putContainer,
    deleteContainer: deleteContainer,
    addContainer: addContainer,
    listContainers: listContainers,
    buildContainer: buildContainer,
    deploySystem: deploySystem,
    deployAll: deployAll,
    ioHandlers: ioHandlers,

    listRevisions: listRevisions,
    getRevision: getRevision,

    timeline: timeline,
    addToTimeline: addToTimeline
  };
};

<commit_msg>for merge<commit_after>/*
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

'use strict';

var net = require('net');
var cbt = require('pelger-cbt')();
var _ = require('underscore');

/**
 * nfd client sdk
 */
module.exports = function() {
  var _client;
  var _stdoutCb;
  var _stderrCb;
  var doc = '';

  var connect = function(options, cb) {
    _client = net.connect(options, function() {
      cb();
    });

    _client.on('data', function(data) {
      var str = data.toString('utf8');
      var lines;
      var callback;
      var json;

      doc += str;
      lines = doc.split('\n');
      _.each(lines, function(line) {
        if (line.length > 0) {
          try {
            json = JSON.parse(line);
            if (json.responseType === 'stdout') {
              if (_stdoutCb) {
                _stdoutCb(json);
              }
            }
            else if (json.responseType === 'stderr') {
              if (_stderrCb) {
                _stderrCb(json);
              }
            }
            else if (json.responseType === 'response') {
              callback = cbt.fetch(json.request);
              callback(json.response);
            }
            doc = '';
          }
          catch (e) {
            // parse failed doc incomplete swallow exception
          }
        }
      });
    });

    _client.on('end', function() {
    });
  };

  var listSystems = function(cb) {
    cbt.trackById('list systems', cb);
    _client.write('list systems\n');
  };

  var createSystem = function(name, namespace, cb) {
    cbt.trackById('create system', cb);
    _client.write('create system ' + name + ' ' + namespace + '\n');
  };

  var getSystem = function(systemId, cb) {
    cbt.trackById('get system', cb);
    _client.write('get system ' + systemId + '\n');
  };

  var deleteSystem = function(systemId, cb) {
    cbt.trackById('delete system', cb);
    _client.write('delete system ' + systemId + '\n');
  };

  var putSystem = function(systemJson, cb) {
    cbt.trackById('put system', cb);
    _client.write('put system\n');
    _client.write(systemJson + '\n');
    _client.write('END\n');
  };

  var listContainers = function(systemId, cb) {
    cbt.trackById('list containers', cb);
    _client.write('list containers ' + systemId + '\n');
  };

  var addContainer = function(systemId, containerJson, cb) {
    cbt.trackById('add container', cb);
    _client.write('add container ' + systemId + '\n');
    _client.write(containerJson + '\n');
    _client.write('END\n');
  };

  var putContainer = function(systemId, containerJson, cb) {
    cbt.trackById('put container', cb);
    _client.write('put container ' + systemId + '\n');
    _client.write(containerJson + '\n');
    _client.write('END\n');
  };

  var deleteContainer = function(systemId, containerId, cb) {
    cbt.trackById('delete container', cb);
    _client.write('delete container ' + systemId + ' ' + containerId + '\n');
  };

  var buildContainer = function(systemId, containerId, cb) {
    cbt.trackById('build container', cb);
    _client.write('build container ' + systemId + ' ' + containerId + '\n');
  };

  var deploySystem = function(systemId, revisionId, cb) {
    cbt.trackById('deploy system', cb);
    _client.write('deploy system ' + systemId + ' ' + revisionId + '\n');
  };

  var deployAll = function(systemId, revisionId, cb) {
    cbt.trackById('deploy all', cb);
    _client.write('deploy all ' + systemId + ' ' + revisionId + '\n');
  };

  var listRevisions = function(systemId, cb) {
    cbt.trackById('list revisions', cb);
    _client.write('list revisions ' + systemId + '\n');
  };

  var getRevision = function(systemId, revisionId, cb) {
    cbt.trackById('get revision ', cb);
    _client.write('get revision ' + systemId + ' ' + revisionId + '\n');
  };

  var timeline = function(systemId, containerId, user, cb) {
    cbt.trackById('list timeline', cb);
    _client.write('list timeline ' + systemId + ' ' + containerId + ' ' + user + '\n');
  };

  var addToTimeline = function(timelineJson, cb) {
    cbt.trackById('add timeline', cb);
    _client.write('add timeline\n');
    _client.write(timelineJson + '\n');
    _client.write('END\n');
  };

  var quit = function(cb) {
    cbt.trackById('quit', cb);
    _client.write('quit\n');
  };

  var ioHandlers = function(stdoutCb, stderrCb) {
    _stdoutCb = stdoutCb;
    _stderrCb = stderrCb;
  };

  return {
    connect: connect,
    quit: quit,
    createSystem: createSystem,
    listSystems: listSystems,
    getSystem: getSystem,
    putSystem: putSystem,
    deleteSystem: deleteSystem,

    putContainer: putContainer,
    deleteContainer: deleteContainer,
    addContainer: addContainer,
    listContainers: listContainers,
    buildContainer: buildContainer,
    deploySystem: deploySystem,
    deployAll: deployAll,
    ioHandlers: ioHandlers,

    listRevisions: listRevisions,
    getRevision: getRevision,

    timeline: timeline,
    addToTimeline: addToTimeline
  };
};

<|endoftext|>


<commit_before>"use strict";
//Dependencies.
var React = require('react');
var isString = require('lodash/lang/isString');
var isArray = require('lodash/lang/isArray');

/**
 * Expose a React type validation for the component properties validation.
 * @see http://facebook.github.io/react/docs/reusable-components.html
 * @param  {string} type - String or array of the types to use.
 * @return {object} The corresponding react type.
 */
module.exports = function(type){
  var isStringType = isString(type);
  if(!isStringType && !isArray(type)){
    throw new Error('The type should be a string or an array');
  }
  if(isStringType){
    return React.PropTypes[type];
  }
  return React.PropTypes.oneOf(type);

};
<commit_msg>[types] Add correct multi type gestion<commit_after>"use strict";
//Dependencies.
var React = require('react');
var isString = require('lodash/lang/isString');
var isArray = require('lodash/lang/isArray');

/**
 * Expose a React type validation for the component properties validation.
 * @see http://facebook.github.io/react/docs/reusable-components.html
 * @param  {string} type - String or array of the types to use.
 * @return {object} The corresponding react type.
 */
module.exports = function(type){
  var isStringType = isString(type);
  if(!isStringType && !isArray(type)){
    throw new Error('The type should be a string or an array');
  }
  if(isStringType){
    return React.PropTypes[type];
  }
  return React.PropTypes.oneOfType(type.map((type)=>{return React.PropTypes[type]}));

};
<|endoftext|>