Brick-dungeon: add monsters images
This commit is contained in:
parent
655ecf6858
commit
db83a7a566
|
|
@ -1,6 +1,6 @@
|
|||
import { render } from "preact";
|
||||
import type { Display } from ".";
|
||||
import { clamp, ensureImageLoaded, range } from "@common/utils";
|
||||
import { clamp, range } from "@common/utils";
|
||||
import classNames from "classnames";
|
||||
|
||||
import styles from './assets/brick.module.css';
|
||||
|
|
@ -12,7 +12,7 @@ const FIELD_HEIGHT = 20;
|
|||
const MINI_FIELD_WIDTH = 4;
|
||||
const MINI_FIELD_HEIGHT = 4;
|
||||
|
||||
interface BrickDisplayImage {
|
||||
export interface BrickDisplayImage {
|
||||
image: boolean[];
|
||||
width: number;
|
||||
height: number;
|
||||
|
|
@ -241,20 +241,18 @@ export class BrickDisplay implements Display {
|
|||
height: 0,
|
||||
}
|
||||
|
||||
ensureImageLoaded(image).then(() => {
|
||||
const canvas = document.createElement('canvas');
|
||||
result.width = canvas.width = image.naturalWidth;
|
||||
result.height = canvas.height = image.naturalHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (ctx) {
|
||||
ctx.drawImage(image, 0, 0);
|
||||
const pxData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
const canvas = document.createElement('canvas');
|
||||
result.width = canvas.width = image.naturalWidth;
|
||||
result.height = canvas.height = image.naturalHeight;
|
||||
const ctx = canvas.getContext('2d');
|
||||
if (ctx) {
|
||||
ctx.drawImage(image, 0, 0);
|
||||
const pxData = ctx.getImageData(0, 0, canvas.width, canvas.height);
|
||||
|
||||
for (let i = 0; i < pxData.data.length; i += 4) {
|
||||
result.image[i >> 2] = pxData.data[i] < 128;
|
||||
}
|
||||
for (let i = 0; i < pxData.data.length; i += 4) {
|
||||
result.image[i >> 2] = pxData.data[i] < 128;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,4 +3,4 @@ export interface Display {
|
|||
update(): void;
|
||||
}
|
||||
|
||||
export { BrickDisplay } from './brick';
|
||||
export { BrickDisplay, type BrickDisplayImage } from './brick';
|
||||
|
|
@ -21,9 +21,4 @@ export const intHash = (seed: number, ...parts: number[]) => {
|
|||
h1 ^= Math.imul(h2 ^ (h2 >>> 13), 3266489909);
|
||||
return h1;
|
||||
};
|
||||
export const sinHash = (...data: number[]) => data.reduce((hash, n) => Math.sin((hash * 123.12 + n) * 756.12), 0) / 2 + 0.5;
|
||||
|
||||
export const ensureImageLoaded = async (image: HTMLImageElement): Promise<void> =>
|
||||
image.naturalWidth === 0
|
||||
? new Promise(r => image.addEventListener('load', () => r()))
|
||||
: void 0;
|
||||
export const sinHash = (...data: number[]) => data.reduce((hash, n) => Math.sin((hash * 123.12 + n) * 756.12), 0) / 2 + 0.5;
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 145 B |
Binary file not shown.
|
Before Width: | Height: | Size: 198 B After Width: | Height: | Size: 203 B |
|
|
@ -1,15 +1,19 @@
|
|||
import { BrickDisplay } from "@common/display";
|
||||
import { delay, randBool, randInt } from "@common/utils";
|
||||
import { BrickDisplay, type BrickDisplayImage } from "@common/display";
|
||||
import { delay } from "@common/utils";
|
||||
import { isPressed, updateKeys } from "@common/input";
|
||||
|
||||
import iconImage from './assets/icon.png';
|
||||
import background from './assets/background.png';
|
||||
import backgroundImage from './assets/background.png';
|
||||
import spritesheetImage from './assets/spritesheet.png';
|
||||
|
||||
let display: BrickDisplay;
|
||||
|
||||
const iconSprite = BrickDisplay.convertImage(iconImage);
|
||||
const backgroundSprite = BrickDisplay.convertImage(background);
|
||||
let background: BrickDisplayImage;
|
||||
let player: BrickDisplayImage;
|
||||
const weapons: BrickDisplayImage[] = [];
|
||||
const monsters: BrickDisplayImage[] = [];
|
||||
|
||||
let bgY = 0;
|
||||
let weapon = 0;
|
||||
let monster = 0;
|
||||
|
||||
function moveBackground() {
|
||||
bgY++;
|
||||
|
|
@ -18,19 +22,43 @@ function moveBackground() {
|
|||
}
|
||||
}
|
||||
|
||||
let frames = 0;
|
||||
let prevFrameTime: number = 0;
|
||||
async function loop(time: number) {
|
||||
frames++;
|
||||
const dt = time - prevFrameTime;
|
||||
prevFrameTime = time;
|
||||
|
||||
moveBackground();
|
||||
if (frames > 10) {
|
||||
moveBackground();
|
||||
frames = 0;
|
||||
}
|
||||
|
||||
display.clear();
|
||||
display.drawImage(backgroundSprite, 0, bgY);
|
||||
display.drawImage(backgroundSprite, 0, bgY + display.height);
|
||||
display.clear(true);
|
||||
|
||||
display.drawImage(background, 0, bgY);
|
||||
display.drawImage(background, 0, bgY + display.height);
|
||||
|
||||
display.drawImage(player, 3, 14);
|
||||
display.drawImage(monsters[monster], 3, 2);
|
||||
|
||||
display.drawImage(weapons[weapon], 0, 0, true);
|
||||
|
||||
display.update();
|
||||
await delay(100);
|
||||
|
||||
if (isPressed('arrowleft')) {
|
||||
weapon = (weapon + weapons.length - 1) % weapons.length;
|
||||
} else if (isPressed('arrowright')) {
|
||||
weapon = (weapon + 1) % weapons.length;
|
||||
}
|
||||
if (isPressed('arrowup')) {
|
||||
monster = (monster + monsters.length - 1) % monsters.length;
|
||||
} else if (isPressed('arrowdown')) {
|
||||
monster = (monster + 1) % monsters.length;
|
||||
}
|
||||
|
||||
updateKeys();
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
|
||||
|
|
@ -38,5 +66,19 @@ export default function main() {
|
|||
display = new BrickDisplay();
|
||||
display.init();
|
||||
|
||||
background = BrickDisplay.convertImage(backgroundImage);
|
||||
const spritesheet = BrickDisplay.convertImage(spritesheetImage);
|
||||
|
||||
for (let i = 0; i < 4; i++) {
|
||||
weapons.push(BrickDisplay.extractSprite(spritesheet, i * 4, 0, 4, 4));
|
||||
}
|
||||
for (let i = 0; i < 6; i++) {
|
||||
monsters.push(BrickDisplay.extractSprite(spritesheet, i * 4, 12, 4, 4));
|
||||
}
|
||||
for (let i = 0; i < 3; i++) {
|
||||
monsters.push(BrickDisplay.extractSprite(spritesheet, i * 4, 16, 4, 4));
|
||||
}
|
||||
player = BrickDisplay.extractSprite(spritesheet, 0, 8, 4, 4)
|
||||
|
||||
requestAnimationFrame(loop);
|
||||
}
|
||||
Loading…
Reference in New Issue