From 7fcef252029656e1b1e054345565f7f4bad65850 Mon Sep 17 00:00:00 2001 From: Nick Kosarev Date: Tue, 18 Jun 2024 11:37:24 +0200 Subject: [PATCH] readme with new info, some fixes --- README.md | 57 +++++---- bun.lockb | Bin 251046 -> 254702 bytes package.json | 12 +- src/lib/game/services/chunk/baseChunk.ts | 49 ++++---- src/lib/game/services/chunk/forestChunk.ts | 4 +- src/lib/game/services/chunk/lakeChunk.ts | 8 +- src/lib/game/services/chunk/villageChunk.ts | 129 ++++++++++---------- src/lib/game/services/wagonService.ts | 1 + 8 files changed, 136 insertions(+), 124 deletions(-) diff --git a/README.md b/README.md index 6c2a4ddc..b2981019 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,45 @@ -# [Twitch Chat Game] Royal Madness 👑 +# 👑 Chat Game for Twitch -đŸ“ē🎮 [Building and playing it live](https://www.twitch.tv/hmbanan666) 👾 [Our community](https://discord.gg/B6etUajrGZ) +- 🏠 [Game Website](https://chatgame.space) +- đŸ“ē [Developing and playing it live](https://www.twitch.tv/hmbanan666) +- 👾 [Our community in Discord](https://discord.gg/B6etUajrGZ) -![Screen](https://github.com/hmbanan666/royal-madness-twitch-game/assets/25910785/a80009a5-ac75-4935-afd2-e1aae16285d6) +![Screen](https://github.com/hmbanan666/chat-game/assets/25910785/a22468a4-0bf1-43e3-91fc-23a1e2a675fc) -🤔 Imagine an open world where your Hero can: +🤔 Imagine procedurally generated world where you and your viewers can: -- đŸ—ēī¸ **Travel**, **defeat** creatures and **find** an infinite number of quests -- 💎 **Gather** loot and a variety of materials -- 🏗ī¸ **Construct** buildings with other Heroes -- đŸ’Ŧ **Chat** with other Heroes in real time -- 🏆 **Earn** more than 1000 achievements! +- đŸ’Ŧ **Use commands** in chat to see actions in real time +- đŸ—ēī¸ **Travel** with the Machine +- đŸĻ„ **Complete** main and side quests from game characters +- 💎 **Gather** a variety of materials +- 🏗ī¸ **Construct** buildings +- 🏆 **Earn** achievements! -Let's build a similar world together! +Let's build a similar world together! ⭐ī¸ Become a Stargazer ⭐ī¸ -## What will be here? +## 🧱 Stack -- [Front] Web client for the game made with **Typescript**, **React** - - simple graphics, top view camera - - interface, menu, inventory slots... -- [Back] Server on **Bun**, where will be a storage for progress of all Heroes +- [PixiJS](https://pixijs.com/): The HTML5 Creation Engine. +- [Svelte](https://svelte.dev/): A new way to build web applications. It's a compiler that takes your declarative components and converts them into efficient JavaScript that surgically updates the DOM. +- [SvelteKit](https://kit.svelte.dev/): A framework for rapidly developing robust, performant web applications using Svelte. +- [Twurple](https://twurple.js.org/): A set of libraries that aims to cover all existing Twitch APIs. +- [Prisma](https://www.prisma.io/): Next-generation Node.js and TypeScript ORM. +- [Howler.js](https://howlerjs.com/): Audio library for the modern web. +- [Lucide Svelte](https://lucide.dev/guide/packages/lucide-svelte): An open-source icon library. +- [Bun](https://bun.sh/): An all-in-one JavaScript runtime & toolkit designed for speed, complete with a bundler, test runner, and Node.js-compatible package manager. +- [TypeScript](https://www.typescriptlang.org/): A strongly typed programming language that builds on JavaScript, giving you better tooling at any scale. +- [ESLint](https://eslint.org/): Statically analyzes a code to quickly find problems. -## Why? +## 🕹ī¸ How to develop -- I want to take a break from product development and develop some game that myself would play in the evenings. -- It will be made using front and back parts, with good code practices (hope so 😀). -- Want to discover something new in software development. Some new challenges and their overcoming! -- I enjoy the new achievements on GitHub, especially Starstruck x4: "Created a repository that has 4096 stars". Why not - to try? +Clone this repo and use standard commands: -⭐ī¸ Become a Stargazer ⭐ī¸ Star this repo. Make forks, issues, PRs, and have fun! Thanks for your ideas and activity! 😉 +```shell +git clone https://github.com/hmbanan666/chat-game +bun install +bun run dev +``` + +## đŸĒ€ License + +This project is licensed under the MIT License - see the [**MIT License**](https://github.com/hmbanan666/chat-game/blob/main/LICENSE) file for details. \ No newline at end of file diff --git a/bun.lockb b/bun.lockb index bb0dcd746c98735e5f183cfeda08ec09118176f9..c6cc083c9d0c63fbaba1d42a87bfa119bf234f1c 100644 GIT binary patch delta 18493 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 JHcCU?{}*~A_ksWb delta 17354 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 b.type === 'WAGON_STOP') as IGameBuildingWagonStop | undefined } + + #initArea({ + width, height, theme, + }: { + width: number + height: number + theme: IGameChunkTheme + }) { + const halfWidth = Math.round(width / 2) + const halfHeight = Math.round(height / 2) + + const area = { + startX: this.center.x - halfWidth, + endX: this.center.x + halfWidth, + startY: this.center.y - halfHeight, + endY: this.center.y + halfHeight, + } + + this.area = new Area({ game: this.game, theme, area }) + this.area.init() + } } diff --git a/src/lib/game/services/chunk/forestChunk.ts b/src/lib/game/services/chunk/forestChunk.ts index 7534289c..442426ae 100644 --- a/src/lib/game/services/chunk/forestChunk.ts +++ b/src/lib/game/services/chunk/forestChunk.ts @@ -39,7 +39,7 @@ export class ForestChunk extends BaseChunk implements IGameForestChunk { #initTrees(count: number) { for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() + const point = this.randomPoint const size = getRandomInRange(75, 90) new TreeObject({ game: this.game, @@ -55,7 +55,7 @@ export class ForestChunk extends BaseChunk implements IGameForestChunk { #initStones(count: number) { for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() + const point = this.randomPoint new StoneObject({ game: this.game, x: point.x, diff --git a/src/lib/game/services/chunk/lakeChunk.ts b/src/lib/game/services/chunk/lakeChunk.ts index dd6f5c24..b61c23dd 100644 --- a/src/lib/game/services/chunk/lakeChunk.ts +++ b/src/lib/game/services/chunk/lakeChunk.ts @@ -11,7 +11,7 @@ import type { IGameLakeChunk, } from '$lib/game/services/chunk/interface' -interface ILakeOptions { +interface LakeChunkOptions { game: Game center: IGameLakeChunk['center'] width: number @@ -20,7 +20,7 @@ interface ILakeOptions { } export class LakeChunk extends BaseChunk implements IGameLakeChunk { - constructor({ game, width, height, center, theme }: ILakeOptions) { + constructor({ game, width, height, center, theme }: LakeChunkOptions) { super({ game, width, @@ -54,7 +54,7 @@ export class LakeChunk extends BaseChunk implements IGameLakeChunk { #initTrees(count: number) { for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() + const point = this.randomPoint const size = getRandomInRange(75, 90) new TreeObject({ game: this.game, @@ -70,7 +70,7 @@ export class LakeChunk extends BaseChunk implements IGameLakeChunk { #initStones(count: number) { for (let i = 0; i < count; i++) { - const point = this.getRandomPoint() + const point = this.randomPoint new StoneObject({ game: this.game, x: point.x, diff --git a/src/lib/game/services/chunk/villageChunk.ts b/src/lib/game/services/chunk/villageChunk.ts index 213603d8..bd017ad8 100644 --- a/src/lib/game/services/chunk/villageChunk.ts +++ b/src/lib/game/services/chunk/villageChunk.ts @@ -24,7 +24,7 @@ import type { IGameVillageChunk, } from '$lib/game/services/chunk/interface' -interface IVillageOptions { +interface VillageChunkOptions { game: Game width: number height: number @@ -33,19 +33,18 @@ interface IVillageOptions { } export class VillageChunk extends BaseChunk implements IGameVillageChunk { - constructor({ width, height, center, theme, game }: IVillageOptions) { + constructor({ width, height, center, theme, game }: VillageChunkOptions) { super({ title: '', type: 'VILLAGE', theme, width, height, center, game }) - this.title = this.getRandomTitle() + this.title = this.#getRandomTitle() - this.initFlags('RESOURCE', 80) + this.#initFlags('RESOURCE', 80) // this.initFlags("MOVEMENT", 30) - this.initTrees(20) - this.initStones(5) - - this.initCourier(1) - this.initFarmer(1) - this.initBuildings() + this.#initTrees(30) + this.#initStones(5) + this.#initCourier(1) + this.#initFarmer(1) + this.#initBuildings() } live() { @@ -64,6 +63,44 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { } } + checkIfNeedToPlantTree() { + const treesNow = this.game.children.filter( + (t) => t instanceof TreeObject && t.chunkId === this.id && t.state !== 'DESTROYED', + ) + if (treesNow.length < 40) { + return this.#getRandomEmptyResourceFlagInVillage() + } + } + + plantNewTree(flag: FlagObject) { + const tree = new TreeObject({ + game: this.game, + x: flag.x, + y: flag.y, + resource: 1, + size: 12, + health: 20, + theme: this.area.theme, + }) + + flag.target = tree + flag.isReserved = false + tree.init() + } + + getTreesAmount() { + return this.game.children.filter( + (obj) => obj instanceof TreeObject && obj.chunkId === this.id && obj.state !== 'DESTROYED', + ).length + } + + checkIfThereAreNotEnoughTrees() { + const max = this.#getResourceFlagInVillageAmount() + const now = this.getTreesAmount() + + return now < max / 3 + } + addTaskToCourier(object: Courier) { const random = getRandomInRange(1, 500) if (random !== 1) { @@ -83,7 +120,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { const buildFunc = (): boolean => { warehouse?.inventory.reduceOrDestroyItem('WOOD', 25) - this.buildStore() + this.#buildStore() return true } @@ -144,7 +181,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { return } - const target = this.getRandomMovementFlagInVillage() + const target = this.#getRandomMovementFlagInVillage() if (!target) { return } @@ -172,7 +209,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { // No Trees needed? const random = getRandomInRange(1, 300) if (random <= 1) { - const target = this.getRandomMovementFlagInVillage() + const target = this.#getRandomMovementFlagInVillage() if (!target) { return } @@ -183,8 +220,8 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { } } - initFlag(variant: GameObjectFlag['variant']) { - const randomPoint = this.getRandomPoint() + #initFlag(variant: GameObjectFlag['variant']) { + const randomPoint = this.randomPoint new FlagObject({ game: this.game, chunkId: this.id, @@ -194,13 +231,13 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { }).init() } - initFlags(variant: GameObjectFlag['variant'], count: number) { + #initFlags(variant: GameObjectFlag['variant'], count: number) { for (let i = 0; i < count; i++) { - this.initFlag(variant) + this.#initFlag(variant) } } - initTrees(count: number) { + #initTrees(count: number) { for (let i = 0; i < count; i++) { const flag = this.#getRandomEmptyResourceFlagInVillage() if (flag) { @@ -220,7 +257,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { } } - initStones(count: number) { + #initStones(count: number) { for (let i = 0; i < count; i++) { const flag = this.#getRandomEmptyResourceFlagInVillage() if (flag) { @@ -236,9 +273,9 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { } } - initCourier(count = 1) { + #initCourier(count = 1) { for (let i = 0; i < count; i++) { - const randomPoint = this.getRandomPoint() + const randomPoint = this.randomPoint new Courier({ game: this.game, x: randomPoint.x, @@ -247,9 +284,9 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { } } - initFarmer(count = 1) { + #initFarmer(count = 1) { for (let i = 0; i < count; i++) { - const randomPoint = this.getRandomPoint() + const randomPoint = this.randomPoint new Farmer({ game: this.game, x: randomPoint.x, @@ -258,7 +295,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { } } - initBuildings() { + #initBuildings() { new Campfire({ game: this.game, x: this.center.x, @@ -284,7 +321,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { }).init() } - buildStore() { + #buildStore() { const constructionArea = this.game.chunkService.chunk?.constructionArea if (!constructionArea) { return @@ -320,7 +357,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { ).length } - getRandomMovementFlagInVillage() { + #getRandomMovementFlagInVillage() { const flags = this.game.children.filter( (f) => f instanceof FlagObject && f.chunkId === this.id && f.variant === 'MOVEMENT', ) @@ -329,7 +366,7 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { : undefined } - getRandomTitle() { + #getRandomTitle() { const titles = [ 'Windy Peak', 'Green Grove', @@ -344,42 +381,4 @@ export class VillageChunk extends BaseChunk implements IGameVillageChunk { ] return titles[Math.floor(Math.random() * titles.length)] } - - checkIfNeedToPlantTree() { - const treesNow = this.game.children.filter( - (t) => t instanceof TreeObject && t.chunkId === this.id && t.state !== 'DESTROYED', - ) - if (treesNow.length < 40) { - return this.#getRandomEmptyResourceFlagInVillage() - } - } - - plantNewTree(flag: FlagObject) { - const tree = new TreeObject({ - game: this.game, - x: flag.x, - y: flag.y, - resource: 1, - size: 12, - health: 20, - theme: this.area.theme, - }) - - flag.target = tree - flag.isReserved = false - tree.init() - } - - getTreesAmount() { - return this.game.children.filter( - (obj) => obj instanceof TreeObject && obj.chunkId === this.id && obj.state !== 'DESTROYED', - ).length - } - - checkIfThereAreNotEnoughTrees() { - const max = this.#getResourceFlagInVillageAmount() - const now = this.getTreesAmount() - - return now < max / 3 - } } diff --git a/src/lib/game/services/wagonService.ts b/src/lib/game/services/wagonService.ts index 4fbf42ac..85631df7 100644 --- a/src/lib/game/services/wagonService.ts +++ b/src/lib/game/services/wagonService.ts @@ -24,6 +24,7 @@ export class WagonService implements GameWagonService { initWagon({ x, y }: { x: number, y: number }) { this.wagon = new BaseWagon({ game: this.game, x, y }) + this.wagon.init() this.#initOutFlags() this.#initNearFlags()