Crops !
This commit is contained in:
@@ -8,7 +8,9 @@ import { TileEditorSystem } from "$/client/systems/tile_editor_system.ts";
|
|||||||
import { InventorySystem } from "$/client/systems/inventory_system.ts";
|
import { InventorySystem } from "$/client/systems/inventory_system.ts";
|
||||||
import { UIInteractionSystem } from "$/client/systems/ui_interaction_system.ts";
|
import { UIInteractionSystem } from "$/client/systems/ui_interaction_system.ts";
|
||||||
import { UIRenderSystem } from "$/client/systems/ui_render_system.ts";
|
import { UIRenderSystem } from "$/client/systems/ui_render_system.ts";
|
||||||
|
import { CropSystem } from "$/client/systems/crop_system.ts";
|
||||||
import { create_main_menu } from "./main_menu.ts";
|
import { create_main_menu } from "./main_menu.ts";
|
||||||
|
import { ClickableSystem } from "./systems/clickable_system.ts";
|
||||||
|
|
||||||
export class ClientWorld extends World {
|
export class ClientWorld extends World {
|
||||||
canvas: HTMLCanvasElement;
|
canvas: HTMLCanvasElement;
|
||||||
@@ -56,9 +58,11 @@ export class ClientWorld extends World {
|
|||||||
// Logic systems
|
// Logic systems
|
||||||
this.add_system(new UIInteractionSystem(), "main_menu");
|
this.add_system(new UIInteractionSystem(), "main_menu");
|
||||||
this.add_system(new UIInteractionSystem(), "paused");
|
this.add_system(new UIInteractionSystem(), "paused");
|
||||||
|
this.add_system(new ClickableSystem(), "game");
|
||||||
this.add_system(new InventorySystem(), "game");
|
this.add_system(new InventorySystem(), "game");
|
||||||
this.add_system(new PlayerControlsSystem(), "game");
|
this.add_system(new PlayerControlsSystem(), "game");
|
||||||
this.add_system(new MovementSystem(), "game");
|
this.add_system(new MovementSystem(), "game");
|
||||||
|
this.add_system(new CropSystem(), "game");
|
||||||
|
|
||||||
// render systems
|
// render systems
|
||||||
this.add_system(new RenderSystem(this.ctx), "game");
|
this.add_system(new RenderSystem(this.ctx), "game");
|
||||||
|
|||||||
@@ -13,3 +13,16 @@ export class Camera extends Component {
|
|||||||
this.zoom = zoom;
|
this.zoom = zoom;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function screen_to_world(
|
||||||
|
screen_x: number,
|
||||||
|
screen_y: number,
|
||||||
|
camera: Camera,
|
||||||
|
screen_width: number,
|
||||||
|
screen_height: number,
|
||||||
|
) {
|
||||||
|
return {
|
||||||
|
x: (screen_x - screen_width / 2) / camera.zoom + camera.x,
|
||||||
|
y: (screen_y - screen_height / 2) / camera.zoom + camera.y,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
import { Component } from "$/common/ecs/mod.ts";
|
||||||
|
|
||||||
|
export class ClickableSprite extends Component {
|
||||||
|
clicked = false;
|
||||||
|
button: number;
|
||||||
|
access_range: number;
|
||||||
|
|
||||||
|
constructor(button: number = 0, access_range = 2) {
|
||||||
|
super();
|
||||||
|
this.button = button;
|
||||||
|
this.access_range = access_range;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,35 @@
|
|||||||
|
import { Component, Entity } from "$/common/ecs/mod.ts";
|
||||||
|
import { Position } from "$/common/components/position.ts";
|
||||||
|
import { AssetManager } from "../assets.ts";
|
||||||
|
import { Sprite } from "./sprite.ts";
|
||||||
|
import { ClickableSprite } from "./clickable.ts";
|
||||||
|
|
||||||
|
export class Crop extends Component {
|
||||||
|
current_stage = 0;
|
||||||
|
growth_time = 0;
|
||||||
|
total_stages: number;
|
||||||
|
time_to_grow: number[];
|
||||||
|
item_drop: string;
|
||||||
|
|
||||||
|
// you know ["bworld:carrot_seeds", "bworld:carrot_stage_1", "bworld:carrot_stage_2" ...]
|
||||||
|
sprite_ids: string[];
|
||||||
|
|
||||||
|
constructor(total_stages: number, time_to_grow: number[], sprite_ids: string[], item_drop: string) {
|
||||||
|
super();
|
||||||
|
this.total_stages = total_stages;
|
||||||
|
this.time_to_grow = time_to_grow;
|
||||||
|
this.sprite_ids = sprite_ids;
|
||||||
|
this.item_drop = item_drop;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function create_crop_entity(x: number, y: number, crop: Crop) {
|
||||||
|
const crop_entity = new Entity("crop");
|
||||||
|
crop_entity.add(new Position(x, y));
|
||||||
|
crop_entity.add(new Sprite(AssetManager.instance.get("bworld:textures"), 32, 32, 0, 0, 16, 16));
|
||||||
|
crop_entity.add(crop);
|
||||||
|
crop_entity.add(
|
||||||
|
new ClickableSprite(2),
|
||||||
|
);
|
||||||
|
return crop_entity;
|
||||||
|
}
|
||||||
@@ -6,6 +6,7 @@ import { AssetManager } from "./assets.ts";
|
|||||||
import { create_player } from "./player.ts";
|
import { create_player } from "./player.ts";
|
||||||
import { UIButton } from "./components/ui_components.ts";
|
import { UIButton } from "./components/ui_components.ts";
|
||||||
import { open_about } from "./about.ts";
|
import { open_about } from "./about.ts";
|
||||||
|
import { create_crop_entity, Crop } from "./components/crop.ts";
|
||||||
|
|
||||||
export function start_game(world: ClientWorld) {
|
export function start_game(world: ClientWorld) {
|
||||||
world.state = "game";
|
world.state = "game";
|
||||||
@@ -35,4 +36,49 @@ export function start_game(world: ClientWorld) {
|
|||||||
about_button.add(new Position(world.canvas.width / 2 - 150, world.canvas.height / 2 + 80));
|
about_button.add(new Position(world.canvas.width / 2 - 150, world.canvas.height / 2 + 80));
|
||||||
about_button.add(new UIButton("About", 320, 64, () => open_about()));
|
about_button.add(new UIButton("About", 320, 64, () => open_about()));
|
||||||
world.add_entity(about_button);
|
world.add_entity(about_button);
|
||||||
|
|
||||||
|
world.add_entity(create_crop_entity(
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
new Crop(5, [4, 4, 4, 4], [
|
||||||
|
"bworld:potato_seeds",
|
||||||
|
"bworld:potato_stage_1",
|
||||||
|
"bworld:potato_stage_2",
|
||||||
|
"bworld:potato_stage_3",
|
||||||
|
"bworld:potato_stage_4",
|
||||||
|
], "bworld:potato"),
|
||||||
|
));
|
||||||
|
world.add_entity(create_crop_entity(
|
||||||
|
32,
|
||||||
|
0,
|
||||||
|
new Crop(5, [5, 5, 5, 5], [
|
||||||
|
"bworld:carrot_seeds",
|
||||||
|
"bworld:carrot_stage_1",
|
||||||
|
"bworld:carrot_stage_2",
|
||||||
|
"bworld:carrot_stage_3",
|
||||||
|
"bworld:carrot_stage_4",
|
||||||
|
], "bworld:carrot"),
|
||||||
|
));
|
||||||
|
world.add_entity(create_crop_entity(
|
||||||
|
0,
|
||||||
|
32,
|
||||||
|
new Crop(5, [10, 10, 10, 10], [
|
||||||
|
"bworld:pumpkin_seeds",
|
||||||
|
"bworld:pumpkin_stage_1",
|
||||||
|
"bworld:pumpkin_stage_2",
|
||||||
|
"bworld:pumpkin_stage_3",
|
||||||
|
"bworld:pumpkin_stage_4",
|
||||||
|
], "bworld:pumpkin"),
|
||||||
|
));
|
||||||
|
world.add_entity(create_crop_entity(
|
||||||
|
32,
|
||||||
|
32,
|
||||||
|
new Crop(5, [7, 7, 7, 7], [
|
||||||
|
"bworld:tomato_seeds",
|
||||||
|
"bworld:tomato_stage_1",
|
||||||
|
"bworld:tomato_stage_2",
|
||||||
|
"bworld:tomato_stage_3",
|
||||||
|
"bworld:tomato_stage_4",
|
||||||
|
], "bworld:tomato"),
|
||||||
|
));
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { System } from "$/common/ecs/mod.ts";
|
||||||
|
import { Position } from "$/common/components/position.ts";
|
||||||
|
import { Sprite } from "../components/sprite.ts";
|
||||||
|
import { ClientWorld } from "../client_world.ts";
|
||||||
|
import { ClickableSprite } from "../components/clickable.ts";
|
||||||
|
import { point_inside_rec } from "$/common/utils.ts";
|
||||||
|
import { InputManager } from "../input_manager.ts";
|
||||||
|
import { Camera, screen_to_world } from "../components/camera.ts";
|
||||||
|
|
||||||
|
export class ClickableSystem extends System {
|
||||||
|
update(world: ClientWorld, _delta: number): void {
|
||||||
|
const [player] = world.get_tag("player")!;
|
||||||
|
const camera = player.get(Camera)!;
|
||||||
|
|
||||||
|
const mouse = InputManager.get_mouse_position();
|
||||||
|
|
||||||
|
const world_mouse = screen_to_world(
|
||||||
|
mouse.x,
|
||||||
|
mouse.y,
|
||||||
|
camera,
|
||||||
|
world.canvas.width,
|
||||||
|
world.canvas.height,
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const entity of world.get_entities()) {
|
||||||
|
const position = entity.get(Position);
|
||||||
|
|
||||||
|
if (!position) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const clickable_sprite = entity.get(ClickableSprite);
|
||||||
|
const sprite = entity.get(Sprite);
|
||||||
|
|
||||||
|
if (clickable_sprite && sprite) {
|
||||||
|
clickable_sprite.clicked = false;
|
||||||
|
const hovered = point_inside_rec(
|
||||||
|
world_mouse.x,
|
||||||
|
world_mouse.y,
|
||||||
|
position.x,
|
||||||
|
position.y,
|
||||||
|
sprite.width,
|
||||||
|
sprite.height,
|
||||||
|
);
|
||||||
|
if (hovered && InputManager.is_mouse_pressed(clickable_sprite.button)) {
|
||||||
|
InputManager.consume_mouse(clickable_sprite.button);
|
||||||
|
clickable_sprite.clicked = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
import { System } from "$/common/ecs/mod.ts";
|
||||||
|
import { Sprite } from "../components/sprite.ts";
|
||||||
|
import { ClientWorld } from "../client_world.ts";
|
||||||
|
import { Crop } from "$/client/components/crop.ts";
|
||||||
|
import { get_sprite_region } from "$/common/utils.ts";
|
||||||
|
import { ClickableSprite } from "../components/clickable.ts";
|
||||||
|
import { ItemStack, PlayerInventory } from "../components/inventory.ts";
|
||||||
|
|
||||||
|
export class CropSystem extends System {
|
||||||
|
update(world: ClientWorld, delta: number): void {
|
||||||
|
for (const entity of world.get_entities()) {
|
||||||
|
const crop = entity.get(Crop);
|
||||||
|
|
||||||
|
if (!crop) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
// finished growing, very good
|
||||||
|
if (crop.total_stages === crop.current_stage + 1) {
|
||||||
|
const clickable_sprite = entity.get(ClickableSprite);
|
||||||
|
if (clickable_sprite && clickable_sprite.clicked) {
|
||||||
|
const [player] = world.get_tag("player")!;
|
||||||
|
const inventory = player.get(PlayerInventory)!;
|
||||||
|
inventory.container.add_item(new ItemStack(crop.item_drop));
|
||||||
|
world.delete_entity(entity);
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
crop.growth_time += delta;
|
||||||
|
if (crop.growth_time >= crop.time_to_grow[crop.current_stage]) {
|
||||||
|
crop.current_stage += 1;
|
||||||
|
crop.growth_time = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
const sprite = entity.get(Sprite);
|
||||||
|
|
||||||
|
if (sprite) {
|
||||||
|
const region = get_sprite_region(crop.sprite_ids[crop.current_stage]);
|
||||||
|
sprite.source_x = region.x * 16;
|
||||||
|
sprite.source_y = region.y * 16;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user