Created
November 5, 2015 06:39
-
-
Save tlhunter/887807a01ca3701e3213 to your computer and use it in GitHub Desktop.
Observing and interfering with player-world interaction
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
/** | |
* Represents a single player | |
*/ | |
let Player = function(x, y, health) { | |
this.events = { | |
encroach: [], | |
enter: [], | |
exit: [] | |
}; | |
this.position = { | |
x: x, | |
y: y | |
}; | |
this.health = health; | |
}; | |
/** | |
* Executes a callback when a certain type of event fires | |
*/ | |
Player.prototype.addObserver = function(event, callback) { | |
this.events[event].push(callback); | |
}; | |
/** | |
* Removes the specified observer | |
*/ | |
Player.prototype.removeObserver = function(event, callback) { | |
let observers = this.events[event]; | |
for (let i = 0; i < observers.length; i++) { | |
if (observers[i] === callback) { | |
observers.splice(i, 1); | |
break; | |
} | |
} | |
}; | |
Player.prototype.modifyHealth = function(health_mod) { | |
this.health += health_mod; | |
if (this.health <= 0) { | |
console.log('PLAYER HAS DIED.'); | |
return true; | |
} | |
return false; | |
}; | |
/** | |
* Returns displayable information about our player | |
*/ | |
Player.prototype.toString = function() { | |
return "X: " + this.position.x + ", Y: " + this.position.y + ", HP: " + this.health; | |
}; | |
/** | |
* Attempts to move a player | |
*/ | |
Player.prototype.move = function(x_offset, y_offset) { | |
if (this.health <= 0) { | |
return console.log('CANNOT MOVE, PLAYER IS DEAD'); | |
} | |
let block = false; | |
for (let handler of this.events.exit) { | |
let gonnaBlock = handler(this.position); | |
if (gonnaBlock) { | |
block = true; | |
} | |
} | |
if (this.health <= 0) { return; } | |
if (block) { console.log('NO EXIT'); return console.log(this.toString()); } | |
let target = { | |
x: this.position.x + x_offset, | |
y: this.position.y + y_offset | |
}; | |
console.log('ATTEMPT MOVE TO X: ' + target.x + ', Y: ' + target.y) | |
for (let handler of this.events.encroach) { | |
let gonnaBlock = handler(target); | |
if (gonnaBlock) { | |
block = true; | |
} | |
} | |
if (this.health <= 0) { return; } | |
if (block) { console.log('NO ENCROACH'); return console.log(this.toString()); } | |
for (let handler of this.events.enter) { | |
handler(target); | |
} | |
if (this.health <= 0) { return; } | |
this.position = target; | |
console.log(this.toString()); | |
}; | |
/** | |
* Keeps track of a collection of enemies | |
*/ | |
let Enemies = function() { | |
this.enemies = []; | |
}; | |
/** | |
* Adds an enemy to the collection | |
*/ | |
Enemies.prototype.add = function(x, y, attack) { | |
this.enemies.push({ | |
x: x, | |
y: y, | |
attack: attack | |
}); | |
}; | |
/** | |
* Observes the player for encroach events (the player attempts to collide with enemy) | |
*/ | |
Enemies.prototype.observe = function(player) { | |
const self = this; | |
player.addObserver('encroach', function(coord) { | |
let block = false; | |
for (let enemy of self.enemies) { | |
if (enemy.x === coord.x && enemy.y === coord.y) { | |
block = true; | |
//enemy.health -= player.attack; | |
player.modifyHealth(-1 * enemy.attack); | |
} | |
} | |
return block; | |
}); | |
}; | |
/** | |
* A collection of items | |
*/ | |
let Items = function() { | |
this.items = []; | |
}; | |
/** | |
* Adds a new item | |
*/ | |
Items.prototype.add = function(x, y, health_mod) { | |
this.items.push({ | |
x: x, | |
y: y, | |
health_mod: health_mod | |
}); | |
}; | |
/** | |
* Tracks if a player enters a tile with an item, applies item health mod and destroys item | |
*/ | |
Items.prototype.observe = function(player) { | |
const self = this; | |
player.addObserver('enter', function(coord) { | |
for (let i = 0; i < self.items.length; i++) { | |
let item = self.items[i]; | |
if (item.x === coord.x && item.y === coord.y) { | |
console.log('ITEM AFFECT HEALTH', item.health_mod); | |
player.modifyHealth(item.health_mod); | |
self.items.splice(i, 1); | |
} | |
} | |
return false; | |
}); | |
}; | |
/** | |
* A collection of traps | |
*/ | |
let Traps = function() { | |
this.traps = []; | |
}; | |
/** | |
* Adds a new trap | |
* | |
* @param damage The amount of damage caused to the player | |
* @param stuck Ratio of difficulty of player leaving trap | |
*/ | |
Traps.prototype.add = function(x, y, damage, stuck) { | |
this.traps.push({ | |
x: x, | |
y: y, | |
damage: damage, | |
stuck: stuck | |
}); | |
}; | |
/** | |
* If a player enters a trap, they will receive damage for the trap | |
* If a player exits a trap, we check to see if stuck, preventing them from leaving and damaging | |
*/ | |
Traps.prototype.observe = function(player) { | |
const self = this; | |
player.addObserver('enter', function(coord) { | |
for (let trap of self.traps) { | |
if (trap.x === coord.x && trap.y === coord.y) { | |
player.modifyHealth(-1 * trap.damage); | |
console.log('TRAP DAMAGE', trap.damage); | |
} | |
} | |
return false; | |
}); | |
player.addObserver('exit', function(coord) { | |
let block = false; | |
for (let trap of self.traps) { | |
if (trap.x === coord.x && trap.y === coord.y && trap.stuck >= Math.random()) { | |
console.log('TRAP STUCK', trap.stuck, trap.damage); | |
player.modifyHealth(-1 * trap.damage); | |
block = true; | |
} | |
} | |
return block; | |
}); | |
}; | |
// Initialize game | |
let enemies = new Enemies(); | |
let items = new Items(); | |
let traps = new Traps(); | |
let player = new Player(10, 10, 100); | |
enemies.observe(player); | |
items.observe(player); | |
traps.observe(player); | |
enemies.add(9, 10, 5); // Gnoll | |
enemies.add(11, 10, 25); // Dragon | |
items.add(10, 9, 10); // Potion | |
items.add(10, 8, -50); // Poison | |
traps.add(10, 6, 10, 0.0); // Explosion | |
traps.add(10, 5, 2, 0.9); // Tar Pit | |
// Player moves around a bit | |
player.move(-1, 0); // West, into Gnoll | |
player.move(-1, 0); // West, into Gnoll | |
player.move(-1, 0); // West, into Gnoll | |
player.move(1, 0); // East, into Dragon | |
player.move(0, -1); // North, into Potion | |
player.move(0, -1); // North, into Poison | |
player.move(0, -1); // North | |
player.move(0, -1); // North, into Explosion | |
player.move(0, -1); // North, into Tar Pit | |
player.move(1, 0); // East | |
player.move(1, 0); // East | |
player.move(1, 0); // East | |
player.move(1, 0); // East | |
player.move(1, 0); // East | |
console.log("FINISHED.", player.toString()); |
Author
tlhunter
commented
Nov 5, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment