Initial commit
This commit is contained in:
@@ -0,0 +1,62 @@
|
||||
import { SLOT_SIZE } from "$/common/constants.ts";
|
||||
import { AssetManager } from "$/client/assets.ts";
|
||||
import { PlayerInventory } from "$/client/components/inventory.ts";
|
||||
import { InputManager } from "$/client/input_manager.ts";
|
||||
import { draw_item, draw_nine_slice } from "./render_utils.ts";
|
||||
|
||||
export function render_player_inventory(ctx: CanvasRenderingContext2D, player_inventory: PlayerInventory) {
|
||||
const PADDING = 10;
|
||||
const ui = AssetManager.instance.get<HTMLImageElement>("bworld:ui");
|
||||
const layout = player_inventory.layout.slots;
|
||||
|
||||
draw_nine_slice(
|
||||
ctx,
|
||||
ui,
|
||||
160,
|
||||
0,
|
||||
16,
|
||||
16,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
0,
|
||||
0,
|
||||
PADDING * 2 + SLOT_SIZE * 9,
|
||||
PADDING * 2 + SLOT_SIZE * 4,
|
||||
);
|
||||
|
||||
for (const [index, slot] of layout.entries()) {
|
||||
const x = slot.x + PADDING;
|
||||
const y = slot.y + PADDING;
|
||||
draw_nine_slice(
|
||||
ctx,
|
||||
ui,
|
||||
player_inventory.hovering_slot === index ? 19 * 16 : 160 + 32,
|
||||
player_inventory.hovering_slot === index ? 16 : 0,
|
||||
16,
|
||||
16,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
4,
|
||||
x,
|
||||
y,
|
||||
SLOT_SIZE,
|
||||
SLOT_SIZE,
|
||||
);
|
||||
}
|
||||
for (const [index, slot] of layout.entries()) {
|
||||
const x = slot.x + PADDING;
|
||||
const y = slot.y + PADDING;
|
||||
const item = player_inventory.container.get_item(index);
|
||||
if (item) {
|
||||
draw_item(ctx, item, x, y);
|
||||
}
|
||||
}
|
||||
|
||||
if (player_inventory.holding_item) {
|
||||
const mouse = InputManager.get_mouse_position();
|
||||
draw_item(ctx, player_inventory.holding_item, mouse.x, mouse.y);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
import { SLOT_SIZE } from "$/common/constants.ts";
|
||||
import { get_sprite_region } from "$/common/utils.ts";
|
||||
import { AssetManager } from "$/client/assets.ts";
|
||||
import { ItemStack } from "$/client/components/inventory.ts";
|
||||
import { draw_text } from "$/client/text_rendering.ts";
|
||||
|
||||
export function draw_nine_slice(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
image: HTMLImageElement,
|
||||
source_x: number,
|
||||
source_y: number,
|
||||
source_width: number,
|
||||
source_height: number,
|
||||
left: number,
|
||||
right: number,
|
||||
top: number,
|
||||
bottom: number,
|
||||
x: number,
|
||||
y: number,
|
||||
width: number,
|
||||
height: number,
|
||||
) {
|
||||
const center_width = source_width - left - right;
|
||||
const center_height = source_height - top - bottom;
|
||||
|
||||
const dest_center_width = width - left - right;
|
||||
const dest_center_height = height - top - bottom;
|
||||
|
||||
// top left
|
||||
ctx.drawImage(image, source_x, source_y, left, top, x, y, left, top);
|
||||
|
||||
// top right
|
||||
ctx.drawImage(image, source_x + source_width - right, source_y, right, top, x + width - right, y, right, top);
|
||||
|
||||
// bottom left
|
||||
ctx.drawImage(
|
||||
image,
|
||||
source_x,
|
||||
source_y + source_height - bottom,
|
||||
left,
|
||||
bottom,
|
||||
x,
|
||||
y + height - bottom,
|
||||
left,
|
||||
bottom,
|
||||
);
|
||||
|
||||
// bottom right
|
||||
ctx.drawImage(
|
||||
image,
|
||||
source_x + source_width - right,
|
||||
source_y + source_height - bottom,
|
||||
right,
|
||||
bottom,
|
||||
x + width - right,
|
||||
y + height - bottom,
|
||||
right,
|
||||
bottom,
|
||||
);
|
||||
|
||||
// top
|
||||
ctx.drawImage(image, source_x + left, source_y, center_width, top, x + left, y, dest_center_width, top);
|
||||
|
||||
// bottom
|
||||
ctx.drawImage(
|
||||
image,
|
||||
source_x + left,
|
||||
source_y + source_height - bottom,
|
||||
center_width,
|
||||
bottom,
|
||||
x + left,
|
||||
y + height - bottom,
|
||||
dest_center_width,
|
||||
bottom,
|
||||
);
|
||||
|
||||
// left
|
||||
ctx.drawImage(image, source_x, source_y + top, left, center_height, x, y + top, left, dest_center_height);
|
||||
|
||||
// right
|
||||
ctx.drawImage(
|
||||
image,
|
||||
source_x + source_width - right,
|
||||
source_y + top,
|
||||
right,
|
||||
center_height,
|
||||
x + width - right,
|
||||
y + top,
|
||||
right,
|
||||
dest_center_height,
|
||||
);
|
||||
|
||||
// center !
|
||||
ctx.drawImage(
|
||||
image,
|
||||
source_x + left,
|
||||
source_y + top,
|
||||
center_width,
|
||||
center_height,
|
||||
x + left,
|
||||
y + top,
|
||||
dest_center_width,
|
||||
dest_center_height,
|
||||
);
|
||||
}
|
||||
|
||||
export function draw_item(ctx: CanvasRenderingContext2D, item: ItemStack, x: number, y: number) {
|
||||
const sprite_region = get_sprite_region(item.type_id);
|
||||
ctx.drawImage(
|
||||
AssetManager.instance.get("bworld:tiny_town"),
|
||||
sprite_region.x * 16,
|
||||
sprite_region.y * 16,
|
||||
16,
|
||||
16,
|
||||
x + 3,
|
||||
y + 3,
|
||||
SLOT_SIZE - 6,
|
||||
SLOT_SIZE - 6,
|
||||
);
|
||||
if (item.max_amount !== 1) {
|
||||
draw_text(
|
||||
ctx,
|
||||
String(item.amount),
|
||||
x + SLOT_SIZE + 2 - 4,
|
||||
y + SLOT_SIZE + 2 - 4,
|
||||
2,
|
||||
"#3f3f3f",
|
||||
"bottom",
|
||||
"right",
|
||||
);
|
||||
draw_text(
|
||||
ctx,
|
||||
String(item.amount),
|
||||
x + SLOT_SIZE - 4,
|
||||
y + SLOT_SIZE - 4,
|
||||
2,
|
||||
"white",
|
||||
"bottom",
|
||||
"right",
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
import { Position } from "$/common/components/position.ts";
|
||||
import { AnimatedSprite, Sprite } from "$/client/components/sprite.ts";
|
||||
|
||||
export function render_sprite(ctx: CanvasRenderingContext2D, sprite: Sprite, position: Position) {
|
||||
ctx.save();
|
||||
|
||||
ctx.translate(
|
||||
Math.floor(sprite.flip_x ? position.x + sprite.width : position.x),
|
||||
Math.floor(sprite.flip_y ? position.y + sprite.height : position.y),
|
||||
);
|
||||
ctx.scale(
|
||||
sprite.flip_x ? -1 : 1,
|
||||
sprite.flip_y ? -1 : 1,
|
||||
);
|
||||
|
||||
ctx.drawImage(
|
||||
sprite.image,
|
||||
sprite.source_x,
|
||||
sprite.source_y,
|
||||
sprite.source_width,
|
||||
sprite.source_height,
|
||||
0,
|
||||
0,
|
||||
sprite.width,
|
||||
sprite.height,
|
||||
);
|
||||
ctx.restore();
|
||||
}
|
||||
|
||||
export function render_animated_sprite(
|
||||
ctx: CanvasRenderingContext2D,
|
||||
animated_sprite: AnimatedSprite,
|
||||
position: Position,
|
||||
) {
|
||||
ctx.save();
|
||||
|
||||
const current_animation = animated_sprite.states[animated_sprite.current_state];
|
||||
if (!current_animation) {
|
||||
console.error(`Missing animation for state ${animated_sprite.current_state}`);
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.translate(
|
||||
Math.floor(animated_sprite.flip_x ? position.x + animated_sprite.width : position.x),
|
||||
Math.floor(animated_sprite.flip_y ? position.y + animated_sprite.height : position.y),
|
||||
);
|
||||
|
||||
ctx.scale(
|
||||
animated_sprite.flip_x ? -1 : 1,
|
||||
animated_sprite.flip_y ? -1 : 1,
|
||||
);
|
||||
|
||||
ctx.drawImage(
|
||||
animated_sprite.image,
|
||||
current_animation.source_x[animated_sprite.animation_frame],
|
||||
current_animation.source_y[animated_sprite.animation_frame],
|
||||
current_animation.source_width,
|
||||
current_animation.source_height,
|
||||
0,
|
||||
0,
|
||||
animated_sprite.width,
|
||||
animated_sprite.height,
|
||||
);
|
||||
|
||||
animated_sprite.timer += 1;
|
||||
if (animated_sprite.timer >= current_animation.duration) {
|
||||
animated_sprite.timer = 0;
|
||||
animated_sprite.animation_frame += 1;
|
||||
|
||||
if (animated_sprite.animation_frame >= current_animation.source_x.length) {
|
||||
animated_sprite.animation_frame = 0;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
import { Tilemap } from "$/client/components/tilemap.ts";
|
||||
|
||||
export function render_tilemap(ctx: CanvasRenderingContext2D, tilemap: Tilemap) {
|
||||
ctx.save();
|
||||
ctx.translate(
|
||||
-Math.floor(ctx.canvas.width / 2),
|
||||
-Math.floor(ctx.canvas.height / 2),
|
||||
);
|
||||
|
||||
for (const tile of tilemap.tiles) {
|
||||
const tx = tile.index % tilemap.columns;
|
||||
const ty = Math.floor(tile.index / tilemap.columns);
|
||||
const sx = tx * tilemap.tile_size + (tx * tilemap.margin);
|
||||
const sy = ty * tilemap.tile_size + (ty * tilemap.margin);
|
||||
|
||||
ctx.drawImage(
|
||||
tilemap.image,
|
||||
sx,
|
||||
sy,
|
||||
tilemap.tile_size,
|
||||
tilemap.tile_size,
|
||||
tile.x * tilemap.tile_size * tilemap.scale,
|
||||
tile.y * tilemap.tile_size * tilemap.scale,
|
||||
tilemap.tile_size * tilemap.scale,
|
||||
tilemap.tile_size * tilemap.scale,
|
||||
);
|
||||
}
|
||||
|
||||
ctx.restore();
|
||||
}
|
||||
Reference in New Issue
Block a user