Skip to content

Instantly share code, notes, and snippets.

@jonurry
Last active March 28, 2018 13:52
Show Gist options
  • Save jonurry/f118b887c19e0b96f7396c923d97b480 to your computer and use it in GitHub Desktop.
Save jonurry/f118b887c19e0b96f7396c923d97b480 to your computer and use it in GitHub Desktop.
16.3 A Monster (Eloquent JavaScript Solutions)
<link rel="stylesheet" href="css/game.css">
<style>.monster { background: purple }</style>
<body>
<script>
// Complete the constructor, update, and collide methods
class Monster {
constructor(pos, speed, chase) {
this.pos = pos;
this.speed = speed;
this.chase = chase;
}
get type() { return "monster"; }
static create(pos, ch) {
if (ch == 'm') {
// monster that moves back and forth
return new Monster(pos.plus(new Vec(0, -1)), new Vec(3, 0), false);
} else { // 'M'
// monster that chases player
return new Monster(pos.plus(new Vec(0, -1)), new Vec(3, 0), true);
}
}
update(time, state) {
let newPos;
if (this.chase) {
if (state.player.pos.x < this.pos.x) {
this.speed = new Vec(-3, 0);
} else {
this.speed = new Vec(3, 0);
}
}
newPos = this.pos.plus(this.speed.times(time));
if (!state.level.touches(newPos, this.size, "wall")) {
return new Monster(newPos, this.speed, this.chase);
} else {
return new Monster(this.pos, this.speed.times(-1), this.chase);
}
}
collide(state) {
let player = state.player;
let monster = this;
if (monster.pos.y - player.pos.y > 1) {
let filtered = state.actors.filter(a => a != this);
return new State(state.level, filtered, state.status);
} else {
return new State(state.level, state.actors, 'lost');
}
}
}
Monster.prototype.size = new Vec(1.2, 2);
levelChars["m"] = Monster;
levelChars["M"] = Monster;
runLevel(new Level(`
..................................
.################################.
.#..............................#.
.#..............................#.
.#..............................#.
.#...........................o..#.
.#..@...........................#.
.##########..............########.
..........#..o..o..o..o..#........
..........#..m........M..#........
..........################........
..................................
`), DOMDisplay);
</script>
</body>
@jonurry
Copy link
Author

jonurry commented Mar 28, 2018

Hints

If you want to implement a type of motion that is stateful, such as bouncing, make sure you store the necessary state in the actor object—include it as a constructor argument and add it as a property.

Remember that update returns a new object, rather than changing the old one.

When handling collision, find the player in state.actors and compare its position to the monster’s position. To get the bottom of the player, you have to add its vertical size to its vertical position. The creation of an updated state will resemble either Coin’s collide method (removing the actor) or Lava’s (changing the status to "lost"), depending on the player position.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment