diff --git a/res/aseprite/pointers.aseprite b/res/aseprite/pointers.aseprite new file mode 100644 index 0000000..43f0653 Binary files /dev/null and b/res/aseprite/pointers.aseprite differ diff --git a/res/pointers.png b/res/pointers.png new file mode 100644 index 0000000..c58d4f4 Binary files /dev/null and b/res/pointers.png differ diff --git a/src/entities/bullet.js b/src/entities/bullet.js new file mode 100644 index 0000000..bd152b6 --- /dev/null +++ b/src/entities/bullet.js @@ -0,0 +1,52 @@ +var asdf = require("asdf-games"); +// eslint-disable-next-line no-unused-vars +const { Texture, TileSprite, AnimManager, wallslide, entity } = asdf; + +const texture = new Texture("./res/tilemap.png"); + +class Bullet extends TileSprite { + constructor(pos, angle, parent, player, level) { + super(texture, 32, 32); + this.pos = pos; + this.pivot = { x: 21, y: 17 }; + this.rotation = angle; + this.scale = { x: 1, y: 1 }; + this.frame = { x: 1, y: 9 }; + + this.parent = parent; + this.player = player; + this.level = level; + + this.lifetime = 2.5; + this.speed = 100; + this.hitBox = { + x: 4, + y: 10, + w: 24, + h: 14 + }; + } + + update(dt) { + this.lifetime -= dt; + + if (this.lifetime <= 0) { + this.parent.bullet = false; + this.dead = true; + } else { + if (entity.hit(this, this.player)) { + this.player.lives -= 1; + this.parent.bullet = false; + this.dead = true; + } else { + const xo = Math.cos(this.rotation) * 100 * dt; + const yo = Math.sin(this.rotation) * 100 * dt; + + this.pos.x += xo; + this.pos.y += yo; + } + } + } +} + +module.exports = Bullet; \ No newline at end of file diff --git a/src/entities/chest.js b/src/entities/chest.js index 7abb59d..113a245 100644 --- a/src/entities/chest.js +++ b/src/entities/chest.js @@ -3,28 +3,32 @@ var asdf = require("asdf-games"); const { Texture, TileSprite, AnimManager, entity } = asdf; var texture = new Texture("./res/tilemap.png"); +var Pointer = require("./pointer.js"); const state = { open: 0, closed: 1 }; +const frames = { + closed: { x: 2, y: 6 }, + open: { x: 3, y: 6 } +}; + class Chest extends TileSprite { - constructor(pos, player, keys, action) { + constructor(pos, player, keys, level, action) { super(texture, 32, 32); this.pos = pos; this.scale = { x: 1, y: 1 }; - this.anims = new AnimManager(this); - this.anims.add("open", [{ x: 3, y: 6 }], 0.1); - this.anims.add("closed", [{ x: 2, y: 6 }], 0.1); - - this.anims.play("closed"); - + this.frame = frames.closed; this.state = state.closed; this.player = player; this.keys = keys; this.action = action; + this.level = level; + + this.pointer = false; this.hitBox = { x: 1, @@ -36,15 +40,36 @@ class Chest extends TileSprite { update(dt) { super.update(dt); - if (entity.hit(this, this.player) && this.keys.action && this.state == state.closed) { - this.state = state.open; - this.action(); + + if (entity.hit(this, this.player)) { + if (!this.pointer) { + var pointer = new Pointer({ + x: (this.pos.x + this.tileW / 2) - 8, + y: this.pos.y - 16 + }); + this.level.entities.add(pointer); + this.pointer = pointer; + } + + if (this.state == state.closed) { + this.pointer.anims.play("white"); + } else { + this.pointer.anims.play("red"); + } + + if (this.keys.action && this.state == state.closed) { + this.state = state.open; + this.action(); + } + } else { + this.level.entities.remove(this.pointer); + this.pointer = false; } if (this.state == state.closed) { - this.anims.play("closed"); + this.frame = frames.closed; } else if (this.state == state.open) { - this.anims.play("open"); + this.frame = frames.open; } } } diff --git a/src/entities/mage.js b/src/entities/mage.js index 4c79aec..161a275 100644 --- a/src/entities/mage.js +++ b/src/entities/mage.js @@ -2,12 +2,13 @@ var asdf = require("asdf-games"); // eslint-disable-next-line no-unused-vars const { Texture, TileSprite, AnimManager, wallslide, entity } = asdf; -var texture = new Texture("./res/mage.png"); +const Bullet = require("./bullet.js"); +const texture = new Texture("./res/mage.png"); const states = { idle: 0, attack: 1, - evade: 2 + move: 2 }; class Mage extends TileSprite { @@ -18,19 +19,28 @@ class Mage extends TileSprite { this.anims = new AnimManager(this); // North - this.anims.add("move_n", [4, 5, 6, 7].map(x => ({ x, y: 0 })), 0.1); + this.anims.add("move_n", [4, 5, 6, 7].map(x => ({ x, y: 0 })), 0.15); + this.anims.add("attack_n", [{ x: 4, y: 0 }], 0.1); // East - this.anims.add("move_e", [0, 1, 2, 3].map(x => ({ x, y: 1 })), 0.1); + this.anims.add("move_e", [0, 1, 2, 3].map(x => ({ x, y: 1 })), 0.15); + this.anims.add("attack_e", [{ x: 0, y: 1 }], 0.1); // South - this.anims.add("move_s", [0, 1, 2, 3].map(x => ({ x, y: 0 })), 0.1); + this.anims.add("move_s", [0, 1, 2, 3].map(x => ({ x, y: 0 })), 0.15); + this.anims.add("attack_s", [{ x: 0, y: 0 }], 0.1); // West - this.anims.add("move_w", [4, 5, 6, 7].map(x => ({ x, y: 1 })), 0.1); + this.anims.add("move_w", [4, 5, 6, 7].map(x => ({ x, y: 1 })), 0.15); + this.anims.add("attack_w", [{ x: 4, y: 1 }], 0.1); // Inactive this.anims.add("idle", [{ x: 0, y: 2 }], 0.1); this.anims.play("idle"); this.state = states.idle; + this.bullet = false; + this.shootrate = { + current: 0.5, + max: 2 + }; this.level = level; this.player = player; @@ -45,21 +55,23 @@ class Mage extends TileSprite { update(dt) { super.update(dt); + const angle = entity.angle(this.player, this); - if (entity.distance(this.player, this) < 100) { - this.state = states.attack; + if (entity.distance(this.player, this) <= 200) { + if (entity.distance(this.player, this) <= 100) { + this.state = states.attack; + } else { + this.state = states.move; + } } else { this.state = states.idle; } + + const xo = Math.cos(angle) * 75 * dt; + const yo = Math.sin(angle) * 75 * dt; + const r = wallslide.wallslide(this, this.level, xo, yo); - if (this.state != states.idle) { - // Move - - const angle = entity.angle(this.player, this); - const xo = Math.cos(angle) * 100 * dt; - const yo = Math.sin(angle) * 100 * dt; - const r = wallslide.wallslide(this, this.level, xo, yo); - + if (this.state == states.move && !this.bullet) { if (this.player.items.repellant) { this.pos.x -= r.x; this.pos.y -= r.y; @@ -84,10 +96,45 @@ class Mage extends TileSprite { this.anims.play("move_n"); } } + } else if (this.state == states.attack) { + if (this.shootrate.current <= 0 && !this.bullet) { + this.shoot(angle); + this.shootrate.current = this.shootrate.max; + } else { + this.shootrate.current -= dt; + } + + if (Math.abs(r.x) > Math.abs(r.y)) { + // Animation x axis + if (r.x >= 0) { + this.anims.play("attack_e"); + } else { + this.anims.play("attack_w"); + } + } else { + // Animation y axis + if (r.y >= 0) { + this.anims.play("attack_s"); + } else { + this.anims.play("attack_n"); + } + } + } else { this.anims.play("idle"); } } + + shoot(angle) { + console.log("shoot"); + this.bullet = true; + var pos = { + x: this.pos.x + 8, + y: this.pos.y + 8 + }; + var bullet = new Bullet(pos, angle, this, this.player, this.level); + this.level.entities.add(bullet); + } } module.exports = Mage; \ No newline at end of file diff --git a/src/entities/player.js b/src/entities/player.js index 1a5aaed..d6a734a 100644 --- a/src/entities/player.js +++ b/src/entities/player.js @@ -39,7 +39,7 @@ class Player extends TileSprite { this.lives = 5; this.items = { - keys: [], + keys: [ ], repellant: false }; diff --git a/src/entities/pointer.js b/src/entities/pointer.js new file mode 100644 index 0000000..ac637db --- /dev/null +++ b/src/entities/pointer.js @@ -0,0 +1,30 @@ +var asdf = require("asdf-games"); +// eslint-disable-next-line no-unused-vars +const { Texture, TileSprite, AnimManager, entity } = asdf; + +const texture = new Texture("./res/pointers.png"); + +// const states = { +// white: 0, +// red: 1 +// }; + +class Pointer extends TileSprite { + constructor(pos) { + super(texture, 8, 8); + this.pos = pos; + this.scale = { x: 2, y: 2 }; + + this.anims = new AnimManager(this); + this.anims.add("white", [0, 1, 2, 1].map(x => ({ x, y: 0 })), 0.15); + this.anims.add("red", [0, 1, 2, 1].map(x => ({ x, y: 1 })), 0.15); + + this.anims.play("white"); + } + + update(dt) { + super.update(dt); + } +} + +module.exports = Pointer; \ No newline at end of file diff --git a/src/entities/portal.js b/src/entities/portal.js index 0d1cef3..42c654b 100644 --- a/src/entities/portal.js +++ b/src/entities/portal.js @@ -3,15 +3,18 @@ var asdf = require("asdf-games"); const { Texture, TileSprite, entity } = asdf; var texture = new Texture("./res/tilemap.png"); +var Pointer = require("./pointer.js"); class Portal extends TileSprite { - constructor(pos, player, keys, type, action, key) { + constructor(pos, player, keys, level, type, action, key) { super(texture, 32, 32); this.pos = pos; this.scale = { x: 1, y: 1 }; this.player = player; + this.level = level; this.action = action; + this.pointer = false; this.keys = keys; this.key = key; @@ -57,26 +60,47 @@ class Portal extends TileSprite { update(dt) { super.update(dt); - if (entity.hit(this, this.player) && this.keys.action) { + + if (entity.hit(this, this.player)) { + if (!this.pointer) { + var pointer = new Pointer({ + x: (this.pos.x + this.tileW / 2) - 8, + y: this.pos.y - 16 + }); + this.level.entities.add(pointer); + this.pointer = pointer; + } + if (this.key != "") { if (this.player.items.keys.length > 0) { for (let index = 0; index < this.player.items.keys.length; index++) { const element = this.player.items.keys[index]; if (element == this.key) { - this.action(); + // Correct key + this.pointer.anims.play("white"); + if (this.keys.action) { + this.action(); + } break; } else { // Not the correct key + this.pointer.anims.play("red"); console.log("correct keyn't"); } } } else { // No keys at all + this.pointer.anims.play("red"); console.log("keyn't"); } } else { - this.action(); + if (this.keys.action) { + this.action(); + } } + } else { + this.level.entities.remove(this.pointer); + this.pointer = false; } } } diff --git a/src/game.js b/src/game.js index ae9a514..4290e42 100644 --- a/src/game.js +++ b/src/game.js @@ -14,21 +14,20 @@ const { scene } = game; const mouseAim = new MouseControls(document.getElementById("board")); const keys = new KeyControls(); +const Stats = require("./src/helpers/stats.js"); var Player = require("./src/entities/player.js"); -var Level = require("./src/levels/level.js"); +var Level = require("./src/helpers/level.js"); // Initialise first level 1-1.js at startPosition 0 var player = new Player(keys, window); -var level = new Level(require("./src/levels/1-2.js"), keys, player); +var level = new Level(require("./src/levels/1-1.js"), keys, player); player.pos.x = level.startPos[0].x / 1; player.pos.y = level.startPos[0].y / 1; player.level = level; const camera = new Camera(player, window, { w: level.w * 2, h: level.h * 2 }); - -const Stats = require("./src/entities/stats.js"); -const stats = new Stats(player); +var stats = new Stats(player); scene.add(camera); camera.add(level); @@ -36,21 +35,33 @@ camera.add(player); scene.add(stats); function switchLevel(module, pos = 0) { + scene.remove(stats); + console.log(scene); camera.map(function(e) { camera.remove(e); if (e instanceof Level) { + var lives = player.lives; var items = player.items; - player = new Player(keys, window); + + var p = new Player(keys, window); + player = p; + e = new Level(module, keys, player); level = e; + player.pos.x = level.startPos[pos].x / 1; player.pos.y = level.startPos[pos].y / 1; + + player.lives = lives; player.items = items; player.level = e; + stats = new Stats(player); + camera.add(e); camera.add(player); camera.setSubject(player); + scene.add(stats); } }); } @@ -59,7 +70,7 @@ game.run(() => { // Debugging tools if (mouseAim.isDown) { console.log("cliccccccccccc"); - console.log(player.items); + console.log(player); console.log(level); } @@ -75,8 +86,6 @@ game.run(() => { camera.setSubject(player); player.refocus = false; } - - }); diff --git a/src/levels/level.js b/src/helpers/level.js similarity index 81% rename from src/levels/level.js rename to src/helpers/level.js index 2f4cdc9..2cbe0fb 100644 --- a/src/levels/level.js +++ b/src/helpers/level.js @@ -1,6 +1,6 @@ var asdf = require("asdf-games"); // eslint-disable-next-line no-unused-vars -const { Texture, TileMap, entity } = asdf; +const { Texture, TileMap, entity, Container } = asdf; const texture = new Texture("./res/tilemap.png"); const tiles = require("../../res/tilemap.js"); @@ -27,6 +27,8 @@ class Level extends TileMap { this.keys = keys; this.player = player; + this.switch = false; + // Handle Entities for (let index = 0; index < level.entities.length; index++) { let e = level.entities[index]; @@ -35,15 +37,18 @@ class Level extends TileMap { e.entity = new Mage({ x: e.pos.x / 1, y: e.pos.y / 1 }, this.player, this); break; case "Chest": - e.entity = new Chest({ x: e.pos.x / 1, y: e.pos.y / 1 }, this.player, this.keys, () => { return e.action(this.player); }); + e.entity = new Chest({ x: e.pos.x / 1, y: e.pos.y / 1 }, this.player, this.keys, this, () => { return e.action(this.player); }); break; case "Portal": - e.entity = new Portal({ x: e.pos.x / 1, y: e.pos.y / 1 }, this.player, this.keys, e.texture, () => { return e.action(this.player, this); }, e.key); + e.entity = new Portal({ x: e.pos.x / 1, y: e.pos.y / 1 }, this.player, this.keys, this, e.texture, () => { return e.action(this.player, this); }, e.key); break; } this.children.push(e.entity); } + this.entities = new Container(); + this.children.push(this.entities); + } update(dt) { diff --git a/src/entities/stats.js b/src/helpers/stats.js similarity index 100% rename from src/entities/stats.js rename to src/helpers/stats.js