|
@ -196,14 +196,13 @@ class Graphics { |
|
|
this.ctx_.fillText(string, x, y); |
|
|
this.ctx_.fillText(string, x, y); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
drawImage(image, dx, dy) { |
|
|
|
|
|
const src = image[0]; |
|
|
|
|
|
const sx = image[1]; |
|
|
|
|
|
const sy = image[2]; |
|
|
|
|
|
const width = image[3]; |
|
|
|
|
|
const height = image[4]; |
|
|
|
|
|
|
|
|
drawSprite(sprite, dx, dy) { |
|
|
this.ctx_.drawImage( |
|
|
this.ctx_.drawImage( |
|
|
src, sx, sy, width, height, dx, dy, width, height); |
|
|
|
|
|
|
|
|
sprite.image, |
|
|
|
|
|
sprite.ulx, sprite.uly, |
|
|
|
|
|
sprite.width, sprite.height, |
|
|
|
|
|
dx, dy, |
|
|
|
|
|
sprite.width, sprite.height); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
@ -248,7 +247,11 @@ class World { |
|
|
|
|
|
|
|
|
update(timestampMs) { |
|
|
update(timestampMs) { |
|
|
this.fpsCounter_.update(timestampMs); |
|
|
this.fpsCounter_.update(timestampMs); |
|
|
|
|
|
const wasRPressed = this.input_.r; |
|
|
this.input_.update(); |
|
|
this.input_.update(); |
|
|
|
|
|
if (!wasRPressed && this.input_.r) { |
|
|
|
|
|
this.player_.cycleSprite(); |
|
|
|
|
|
} |
|
|
if (this.input_.left) { |
|
|
if (this.input_.left) { |
|
|
this.player_.moveLeft(); |
|
|
this.player_.moveLeft(); |
|
|
} |
|
|
} |
|
@ -272,40 +275,71 @@ class World { |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class Sprite { |
|
|
|
|
|
constructor(image, ulx, uly, width, height) { |
|
|
|
|
|
this.image = image; |
|
|
|
|
|
this.ulx = ulx; |
|
|
|
|
|
this.uly = uly; |
|
|
|
|
|
this.width = width; |
|
|
|
|
|
this.height = height; |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
class CharacterSprite { |
|
|
|
|
|
constructor(image, ulx, uly, tileWidth, tileHeight) { |
|
|
|
|
|
// Assumption: a character sprite consists of 4 rows, which include the
|
|
|
|
|
|
// character facing down, left, right, up (in that order). Each row has 3
|
|
|
|
|
|
// columns, which can be used for a walking animation.
|
|
|
|
|
|
this.down = []; |
|
|
|
|
|
this.left = []; |
|
|
|
|
|
this.right = []; |
|
|
|
|
|
this.up = []; |
|
|
|
|
|
for (let i = 0; i < 3; i++) { |
|
|
|
|
|
const x = ulx + i * tileWidth; |
|
|
|
|
|
this.down.push(new Sprite( |
|
|
|
|
|
image, x, uly, tileWidth, tileHeight)); |
|
|
|
|
|
this.left.push(new Sprite( |
|
|
|
|
|
image, x, uly + tileHeight, tileWidth, tileHeight)); |
|
|
|
|
|
this.right.push(new Sprite( |
|
|
|
|
|
image, x, uly + tileHeight * 2, tileWidth, tileHeight)); |
|
|
|
|
|
this.up.push(new Sprite( |
|
|
|
|
|
image, x, uly + tileHeight * 3, tileWidth, tileHeight)); |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
class Resources { |
|
|
class Resources { |
|
|
constructor() { |
|
|
constructor() { |
|
|
const atlantis = document.getElementById('atlantis'); |
|
|
const atlantis = document.getElementById('atlantis'); |
|
|
const ghost = document.getElementById('ghost'); |
|
|
const ghost = document.getElementById('ghost'); |
|
|
|
|
|
const cats = document.getElementById('cats'); |
|
|
const ts = 16; |
|
|
const ts = 16; |
|
|
this.sprites = { |
|
|
this.sprites = { |
|
|
'ground0': [atlantis, 2 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'ground1': [atlantis, 3 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'ground2': [atlantis, 4 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'ground3': [atlantis, 5 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'ground4': [atlantis, 6 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'ground5': [atlantis, 7 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'ground6': [atlantis, 8 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'rock0': [atlantis, 1 * ts, 2 * ts, 16, 16], |
|
|
|
|
|
'rock1': [atlantis, 2 * ts, 2 * ts, 16, 16], |
|
|
|
|
|
'rock2': [atlantis, 3 * ts, 2 * ts, 16, 16], |
|
|
|
|
|
'anchor0': [atlantis, 21 * ts, 1 * ts, 16, 16], |
|
|
|
|
|
'seaweed0': [atlantis, 20 * ts, 2 * ts, 16, 32], |
|
|
|
|
|
'seaweed1': [atlantis, 16 * ts, 2 * ts, 16, 32], |
|
|
|
|
|
'coral0': [atlantis, 15 * ts, 9 * ts, 32, 16], |
|
|
|
|
|
'rockpile0': [atlantis, 17 * ts, 10 * ts, 32, 32], |
|
|
|
|
|
|
|
|
|
|
|
'ghostdown0': [ghost, 0, 0, 24, 36], |
|
|
|
|
|
'ghostdown1': [ghost, 26, 0, 24, 36], |
|
|
|
|
|
'ghostdown2': [ghost, 52, 0, 24, 36], |
|
|
|
|
|
'ghostleft0': [ghost, 0, 36, 24, 36], |
|
|
|
|
|
'ghostleft1': [ghost, 26, 36, 24, 36], |
|
|
|
|
|
'ghostleft2': [ghost, 52, 36, 24, 36], |
|
|
|
|
|
'ghostright0': [ghost, 0, 72, 24, 36], |
|
|
|
|
|
'ghostright1': [ghost, 26, 72, 24, 36], |
|
|
|
|
|
'ghostright2': [ghost, 52, 72, 24, 36], |
|
|
|
|
|
'ghostup0': [ghost, 0, 108, 24, 36], |
|
|
|
|
|
'ghostup1': [ghost, 26, 108, 24, 36], |
|
|
|
|
|
'ghostup2': [ghost, 52, 108, 24, 36], |
|
|
|
|
|
|
|
|
'ground0': new Sprite(atlantis, 2 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'ground1': new Sprite(atlantis, 3 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'ground2': new Sprite(atlantis, 4 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'ground3': new Sprite(atlantis, 5 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'ground4': new Sprite(atlantis, 6 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'ground5': new Sprite(atlantis, 7 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'ground6': new Sprite(atlantis, 8 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'rock0': new Sprite(atlantis, 1 * ts, 2 * ts, 16, 16), |
|
|
|
|
|
'rock1': new Sprite(atlantis, 2 * ts, 2 * ts, 16, 16), |
|
|
|
|
|
'rock2': new Sprite(atlantis, 3 * ts, 2 * ts, 16, 16), |
|
|
|
|
|
'anchor0': new Sprite(atlantis, 21 * ts, 1 * ts, 16, 16), |
|
|
|
|
|
'seaweed0': new Sprite(atlantis, 20 * ts, 2 * ts, 16, 32), |
|
|
|
|
|
'seaweed1': new Sprite(atlantis, 16 * ts, 2 * ts, 16, 32), |
|
|
|
|
|
'coral0': new Sprite(atlantis, 15 * ts, 9 * ts, 32, 16), |
|
|
|
|
|
'rockpile0': new Sprite(atlantis, 17 * ts, 10 * ts, 32, 32), |
|
|
|
|
|
|
|
|
|
|
|
'ghost': new CharacterSprite(ghost, 0, 0, 26, 36), |
|
|
|
|
|
'cat0': new CharacterSprite(cats, 0, 0, 26, 36), |
|
|
|
|
|
'cat1': new CharacterSprite(cats, 26 * 3, 0, 26, 36), |
|
|
|
|
|
'cat2': new CharacterSprite(cats, 26 * 6, 0, 26, 36), |
|
|
|
|
|
'cat3': new CharacterSprite(cats, 26 * 9, 0, 26, 36), |
|
|
|
|
|
'cat4': new CharacterSprite(cats, 0, 36 * 4, 26, 36), |
|
|
|
|
|
'cat5': new CharacterSprite(cats, 26 * 3, 36 * 4, 26, 36), |
|
|
|
|
|
'cat6': new CharacterSprite(cats, 26 * 6, 36 * 4, 26, 36), |
|
|
|
|
|
'cat7': new CharacterSprite(cats, 26 * 9, 36 * 4, 26, 36), |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -316,6 +350,21 @@ class Player { |
|
|
this.x = (SNES_WIDTH - 26) / 2; |
|
|
this.x = (SNES_WIDTH - 26) / 2; |
|
|
this.y = (SNES_HEIGHT - 36) / 2; |
|
|
this.y = (SNES_HEIGHT - 36) / 2; |
|
|
this.orientation = Orientation.DOWN; |
|
|
this.orientation = Orientation.DOWN; |
|
|
|
|
|
this.spriteNames_ = [ |
|
|
|
|
|
'ghost', 'cat0', 'cat1', 'cat2', 'cat3', 'cat4', 'cat5', 'cat6', |
|
|
|
|
|
'cat7']; |
|
|
|
|
|
this.spriteNamesIdx_ = 3; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
get spriteName() { |
|
|
|
|
|
return this.spriteNames_[this.spriteNamesIdx_]; |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
cycleSprite() { |
|
|
|
|
|
this.spriteNamesIdx_++; |
|
|
|
|
|
if (this.spriteNamesIdx_ >= this.spriteNames_.length) { |
|
|
|
|
|
this.spriteNamesIdx_ = 0; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
moveLeft() { |
|
|
moveLeft() { |
|
@ -359,8 +408,8 @@ class PlayerRenderer { |
|
|
draw(gfx, sprites, player) { |
|
|
draw(gfx, sprites, player) { |
|
|
let spriteIndex = Math.floor((this.frameNum % 40) / 10); |
|
|
let spriteIndex = Math.floor((this.frameNum % 40) / 10); |
|
|
if (spriteIndex == 3) { spriteIndex = 1; } |
|
|
if (spriteIndex == 3) { spriteIndex = 1; } |
|
|
const spriteName = 'ghost' + player.orientation + spriteIndex; |
|
|
|
|
|
gfx.drawImage(sprites[spriteName], player.x, player.y); |
|
|
|
|
|
|
|
|
const charSprite = sprites[player.spriteName][player.orientation][spriteIndex]; |
|
|
|
|
|
gfx.drawSprite(charSprite, player.x, player.y); |
|
|
this.frameNum++; |
|
|
this.frameNum++; |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -423,7 +472,7 @@ class TileRenderer { |
|
|
const dy = tileSize * i; |
|
|
const dy = tileSize * i; |
|
|
const sprite = spriteLookup[layer1[i][j]]; |
|
|
const sprite = spriteLookup[layer1[i][j]]; |
|
|
if (sprite) { |
|
|
if (sprite) { |
|
|
gfx.drawImage(sprite, dx, dy); |
|
|
|
|
|
|
|
|
gfx.drawSprite(sprite, dx, dy); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
@ -433,12 +482,11 @@ class TileRenderer { |
|
|
const dy = tileSize * i; |
|
|
const dy = tileSize * i; |
|
|
const sprite = spriteLookup[layer2[i][j]]; |
|
|
const sprite = spriteLookup[layer2[i][j]]; |
|
|
if (sprite) { |
|
|
if (sprite) { |
|
|
gfx.drawImage(sprite, dx, dy); |
|
|
|
|
|
|
|
|
gfx.drawSprite(sprite, dx, dy); |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
class GamepadRenderer { |
|
|
class GamepadRenderer { |
|
|