Skip to content

Instantly share code, notes, and snippets.

@andresaaap
Created February 11, 2018 17:43
Show Gist options
  • Save andresaaap/5cf4bea850e87ddbda01f73e77f823dc to your computer and use it in GitHub Desktop.
Save andresaaap/5cf4bea850e87ddbda01f73e77f823dc to your computer and use it in GitHub Desktop.
'use strict';
//_______________________
//_______________________
//NEW CLASSES
class Game {
constructor() {
this.levels = [];
this.player = new Player(202.5, 383, 'images/char-boy.png', 100);
this.currentLevel = {};
}
}
class Level {
constructor(x, y, sprite, speed = 0) {
this.enemies = [];
}
}
//_______________________
//_______________________
class Character {
constructor(x, y, sprite, speed = 0) {
this.x = x;
this.y = y;
this.sprite = sprite;
this.speed = speed;
}
render() {
ctx.drawImage(Resources.get(this.sprite), this.x, this.y);
}
}
class Enemy extends Character {
constructor(x = 50, y = 80, sprite = enemyImage, speed = 0) {
super(x, y, sprite, speed);
this.width = 75;
this.height = 50;
}
collisionDetection() {
if (newGame.player.x <= this.x + this.width && newGame.player.x +newGame.player.width >= this.x && newGame.player.y <= this.y + this.height && newGame.player.height + newGame.player.y >= this.y) {
console.log('collided');
//check if lives are equal to 0 on detection
if (+$('.lives-number').text() === 1) {
newGame.player.resetPlayer();
+$('.lives-number').text(5);
+$('.score-number').text(0);
}
else {
newGame.player.resetPlayer();
+$('.lives-number').text(+$('.lives-number').text() - 1);
}
}
}
update(dt) {
this.x += this.speed * dt;
//check if enemy reaches end then reset it to start
if (this.x >= 505) {
this.x = 0;
}
// You should multiply any movement by the dt parameter
// which will ensure the game runs at the same speed for
// all computers.
//increase the speed for difficulty
this.speed += 0.005;
//call collision function
this.collisionDetection();
}
}
class Player extends Character {
constructor(x = 202.5, y = 383, sprite, speed) {
super(x, y, sprite, speed);
this.width = 50;
this.height = 50;
}
resetPlayer() {
this.x = 202.5;
this.y = 383;
}
update() {
}
handleInput(keyPress) {
// This listens for key presses and sends the keys to your
if (keyPress === 'left') {
this.x -= this.speed;
}
if (keyPress === 'up') {
this.y -= this.speed - 20;
}
if (keyPress === 'right') {
this.x += this.speed;
}
if (keyPress === 'down') {
this.y += this.speed - 20;
}
//make sure player cannot cross canvas
if (this.y > 383) {
this.y = 383;
}
if (this.x > 402.5) {
this.x = 402.5;
}
if (this.x < 2.5) {
this.x = 2.5
}
//make sure player when wins resets its position
if (this.y <= -17) {
this.resetPlayer();
console.log('you won');
// update the score
+$('.score-number').text(+$('.score-number').text() + 100);
}
}
}
// Player.handleInput() method. You don't need to modify this.
document.addEventListener('keyup', function (e) {
var allowedKeys = {
37: 'left',
38: 'up',
39: 'right',
40: 'down'
};
newGame.player.handleInput(allowedKeys[e.keyCode]);
});
// Now instantiate your objects.
// Place all enemy objects in an array called allEnemies
// Place the player object in a variable called player
var enemyImage = 'images/enemy-bug.png';
var allEnemies = [new Enemy(0, 50, enemyImage, 80), new Enemy(0, 50, enemyImage, 70), new Enemy(0, 130, enemyImage, 70), new Enemy(0, 220, enemyImage, 80), new Enemy(0, 120, enemyImage, 190)];
var newGame = new Game();
/* Engine.js
* This file provides the game loop functionality (update entities and render),
* draws the initial game board on the screen, and then calls the update and
* render methods on your player and enemy objects (defined in your app.js).
*
* A game engine works by drawing the entire game screen over and over, kind of
* like a flipbook you may have created as a kid. When your player moves across
* the screen, it may look like just that image/character is moving or being
* drawn but that is not the case. What's really happening is the entire "scene"
* is being drawn over and over, presenting the illusion of animation.
*
* This engine is available globally via the Engine variable and it also makes
* the canvas' context (ctx) object globally available to make writing app.js
* a little simpler to work with.
*/
var Engine = (function(global) {
/* Predefine the variables we'll be using within this scope,
* create the canvas element, grab the 2D context for that canvas
* set the canvas elements height/width and add it to the DOM.
*/
var doc = global.document,
win = global.window,
canvas = doc.createElement('canvas'),
ctx = canvas.getContext('2d'),
lastTime;
canvas.width = 505;
canvas.height = 606;
doc.body.appendChild(canvas);
/* This function serves as the kickoff point for the game loop itself
* and handles properly calling the update and render methods.
*/
function main() {
/* Get our time delta information which is required if your game
* requires smooth animation. Because everyone's computer processes
* instructions at different speeds we need a constant value that
* would be the same for everyone (regardless of how fast their
* computer is) - hurray time!
*/
var now = Date.now(),
dt = (now - lastTime) / 1000.0;
/* Call our update/render functions, pass along the time delta to
* our update function since it may be used for smooth animation.
*/
update(dt);
render();
/* Set our lastTime variable which is used to determine the time delta
* for the next time this function is called.
*/
lastTime = now;
/* Use the browser's requestAnimationFrame function to call this
* function again as soon as the browser is able to draw another frame.
*/
win.requestAnimationFrame(main);
}
/* This function does some initial setup that should only occur once,
* particularly setting the lastTime variable that is required for the
* game loop.
*/
function init() {
reset();
lastTime = Date.now();
main();
}
/* This function is called by main (our game loop) and itself calls all
* of the functions which may need to update entity's data. Based on how
* you implement your collision detection (when two entities occupy the
* same space, for instance when your character should die), you may find
* the need to add an additional function call here. For now, we've left
* it commented out - you may or may not want to implement this
* functionality this way (you could just implement collision detection
* on the entities themselves within your app.js file).
*/
function update(dt) {
updateEntities(dt);
// checkCollisions();
}
/* This is called by the update function and loops through all of the
* objects within your allEnemies array as defined in app.js and calls
* their update() methods. It will then call the update function for your
* player object. These update methods should focus purely on updating
* the data/properties related to the object. Do your drawing in your
* render methods.
*/
function updateEntities(dt) {
allEnemies.forEach(function(enemy) {
enemy.update(dt);
});
newGame.player.update();
}
/* This function initially draws the "game level", it will then call
* the renderEntities function. Remember, this function is called every
* game tick (or loop of the game engine) because that's how games work -
* they are flipbooks creating the illusion of animation but in reality
* they are just drawing the entire screen over and over.
*/
function render() {
/* This array holds the relative URL to the image used
* for that particular row of the game level.
*/
var rowImages = [
'images/water-block.png', // Top row is water
'images/stone-block.png', // Row 1 of 3 of stone
'images/stone-block.png', // Row 2 of 3 of stone
'images/stone-block.png', // Row 3 of 3 of stone
'images/grass-block.png', // Row 1 of 2 of grass
'images/grass-block.png' // Row 2 of 2 of grass
],
numRows = 6,
numCols = 5,
row, col;
/* Loop through the number of rows and columns we've defined above
* and, using the rowImages array, draw the correct image for that
* portion of the "grid"
*/
for (row = 0; row < numRows; row++) {
for (col = 0; col < numCols; col++) {
/* The drawImage function of the canvas' context element
* requires 3 parameters: the image to draw, the x coordinate
* to start drawing and the y coordinate to start drawing.
* We're using our Resources helpers to refer to our images
* so that we get the benefits of caching these images, since
* we're using them over and over.
*/
ctx.drawImage(Resources.get(rowImages[row]), col * 101, row * 83);
}
}
renderEntities();
}
/* This function is called by the render function and is called on each game
* tick. Its purpose is to then call the render functions you have defined
* on your enemy and player entities within app.js
*/
function renderEntities() {
/* Loop through all of the objects within the allEnemies array and call
* the render function you have defined.
*/
allEnemies.forEach(function(enemy) {
enemy.render();
});
newGame.player.render();
}
/* This function does nothing but it could have been a good place to
* handle game reset states - maybe a new game menu or a game over screen
* those sorts of things. It's only called once by the init() method.
*/
function reset() {
// noop
}
/* Go ahead and load all of the images we know we're going to need to
* draw our game level. Then set init as the callback method, so that when
* all of these images are properly loaded our game will start.
*/
Resources.load([
'images/stone-block.png',
'images/water-block.png',
'images/grass-block.png',
'images/enemy-bug.png',
'images/char-boy.png'
]);
Resources.onReady(init);
/* Assign the canvas' context object to the global variable (the window
* object when run in a browser) so that developers can use it more easily
* from within their app.js files.
*/
global.ctx = ctx;
})(this);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment