inetraction stuff
This commit is contained in:
@@ -1 +1,12 @@
|
||||
<p>food-pantry works!</p>
|
||||
<div class="h-full w-full absolute bg-red-300">
|
||||
<div class="py-4 container mx-auto">
|
||||
<div class="flex flex-row justify-between">
|
||||
<p>food-pantry works!</p>
|
||||
<ff-button (click)="onClose.emit(true)">X</ff-button>
|
||||
</div>
|
||||
<ff-grid
|
||||
[gridItems]="foods()"
|
||||
(onSelect)="onFoodChosen.emit($event)"
|
||||
></ff-grid>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,19 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, inject, output, OutputEmitterRef, Signal } from '@angular/core';
|
||||
import { ButtonComponent } from "../ui-elements/button/button.component";
|
||||
import { Food } from '../../types/food';
|
||||
import { FoodStore } from '../../api/food.store';
|
||||
import { GridComponent } from "../grid/grid.component";
|
||||
|
||||
@Component({
|
||||
selector: 'ff-food-pantry',
|
||||
imports: [],
|
||||
imports: [ButtonComponent, GridComponent],
|
||||
templateUrl: './food-pantry.component.html',
|
||||
})
|
||||
export class FoodPantryComponent {
|
||||
public readonly onClose: OutputEmitterRef<true> = output<true>();
|
||||
public readonly onFoodChosen: OutputEmitterRef<Food> = output<Food>();
|
||||
|
||||
private readonly foodStore: FoodStore = inject(FoodStore);
|
||||
|
||||
protected readonly foods: Signal<Food[]> = this.foodStore.foods;
|
||||
}
|
||||
|
||||
12
src/app/components/grid/grid.component.html
Normal file
12
src/app/components/grid/grid.component.html
Normal file
@@ -0,0 +1,12 @@
|
||||
<div class="w-full flex flex-row flex-wrap gap-3">
|
||||
@for (item of gridItems(); track $index) {
|
||||
<div
|
||||
(click)="onSelect.emit(item)"
|
||||
class="rounded-lg bg-primary-400 cursor-pointer"
|
||||
[ngStyle]="{
|
||||
width: size() + 'rem',
|
||||
height: size() + 'rem',
|
||||
}"
|
||||
></div>
|
||||
}
|
||||
</div>
|
||||
23
src/app/components/grid/grid.component.spec.ts
Normal file
23
src/app/components/grid/grid.component.spec.ts
Normal file
@@ -0,0 +1,23 @@
|
||||
import { ComponentFixture, TestBed } from '@angular/core/testing';
|
||||
|
||||
import { GridComponent } from './grid.component';
|
||||
|
||||
describe('GridComponent', () => {
|
||||
let component: GridComponent<any>;
|
||||
let fixture: ComponentFixture<GridComponent<any>>;
|
||||
|
||||
beforeEach(async () => {
|
||||
await TestBed.configureTestingModule({
|
||||
imports: [GridComponent]
|
||||
})
|
||||
.compileComponents();
|
||||
|
||||
fixture = TestBed.createComponent(GridComponent);
|
||||
component = fixture.componentInstance;
|
||||
fixture.detectChanges();
|
||||
});
|
||||
|
||||
it('should create', () => {
|
||||
expect(component).toBeTruthy();
|
||||
});
|
||||
});
|
||||
14
src/app/components/grid/grid.component.ts
Normal file
14
src/app/components/grid/grid.component.ts
Normal file
@@ -0,0 +1,14 @@
|
||||
import { NgStyle } from '@angular/common';
|
||||
import { Component, input, InputSignal, output, OutputEmitterRef } from '@angular/core';
|
||||
|
||||
@Component({
|
||||
selector: 'ff-grid',
|
||||
imports: [NgStyle],
|
||||
templateUrl: './grid.component.html',
|
||||
})
|
||||
export class GridComponent<T> {
|
||||
public readonly gridItems: InputSignal<T[]> = input.required();
|
||||
public readonly size: InputSignal<number> = input<number>(5);
|
||||
|
||||
public readonly onSelect: OutputEmitterRef<T> = output<T>();
|
||||
}
|
||||
@@ -1 +1,8 @@
|
||||
<p>inventory works!</p>
|
||||
<div class="h-full w-full absolute bg-blue-300">
|
||||
<div class="py-4 container mx-auto">
|
||||
<div class="flex flex-row justify-between">
|
||||
<p>inventory works!</p>
|
||||
<ff-button (click)="onClose.emit()">X</ff-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { Component, output, OutputEmitterRef } from '@angular/core';
|
||||
import { ButtonComponent } from "../ui-elements/button/button.component";
|
||||
|
||||
@Component({
|
||||
selector: 'ff-inventory',
|
||||
imports: [],
|
||||
imports: [ButtonComponent],
|
||||
templateUrl: './inventory.component.html',
|
||||
})
|
||||
export class InventoryComponent {
|
||||
public readonly onClose: OutputEmitterRef<void> = output<void>();
|
||||
public readonly onItemChosen: OutputEmitterRef<any> = output<any>();
|
||||
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<button
|
||||
type="button"
|
||||
class="rounded-lg bg-primary-500 hover:bg-primary-700 cursor-pointer text-white px-4 py-2"
|
||||
class="rounded-lg bg-primary-500 hover:bg-primary-700 cursor-pointer text-white px-4 py-2 flex flex-row items-center justify-center"
|
||||
>
|
||||
<ng-content></ng-content>
|
||||
</button>
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
import { Chibi } from "../../types/chibi/chibi";
|
||||
import { EChibiInteraction } from "../../types/chibi/chibi-interaction";
|
||||
import { EChibiStateName } from "../../types/chibi/chibi-state-name";
|
||||
import { Food } from "../../types/food";
|
||||
|
||||
export interface IBrain {
|
||||
|
||||
//function for time passegs + autonomous state changes
|
||||
exist(chibi: Chibi): void;
|
||||
|
||||
resolveInteraction(state: EChibiStateName, interaction: EChibiInteraction): EChibiStateName
|
||||
resolveInteraction(chibi: Chibi, interaction: EChibiInteraction, item?: Food): void
|
||||
}
|
||||
@@ -1,12 +1,29 @@
|
||||
import { Chibi } from "../../../types/chibi/chibi";
|
||||
import { EChibiInteraction } from "../../../types/chibi/chibi-interaction";
|
||||
import { EChibiStateName } from "../../../types/chibi/chibi-state-name";
|
||||
import { Food } from "../../../types/food";
|
||||
import { IBrain } from "../brain";
|
||||
|
||||
export class Aperio implements IBrain {
|
||||
resolveInteraction(state: EChibiStateName, interaction: EChibiInteraction): EChibiStateName {
|
||||
switch (state) {
|
||||
case EChibiStateName.Sleeping: return this.resolveSleepingInteraction(interaction);
|
||||
default: return EChibiStateName.Sleeping;
|
||||
|
||||
private hasBeenAwakeFor: number = 0;
|
||||
|
||||
exist(chibi: Chibi): void {
|
||||
console.log('Brain is braining');
|
||||
if (!EChibiStateName.Sleeping) {
|
||||
this.hasBeenAwakeFor++;
|
||||
if (this.hasBeenAwakeFor > 60) {
|
||||
chibi.state = EChibiStateName.Sleeping;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
resolveInteraction(chibi: Chibi, interaction: EChibiInteraction, item?: Food): void {
|
||||
switch (chibi.state) {
|
||||
case EChibiStateName.Sleeping: chibi.state = this.resolveSleepingInteraction(interaction); break;
|
||||
case EChibiStateName.Awake: chibi.state = this.resolveAwakeInteraction(interaction, item); break;
|
||||
default:
|
||||
chibi.state = EChibiStateName.Sleeping; break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +56,11 @@ export class Aperio implements IBrain {
|
||||
}
|
||||
return EChibiStateName.Sleeping;
|
||||
}
|
||||
|
||||
private resolveAwakeInteraction(interaction: EChibiInteraction, item?: Food): EChibiStateName {
|
||||
if (EChibiInteraction.Feed) {
|
||||
return EChibiStateName.Eating;
|
||||
}
|
||||
return EChibiStateName.Idle;
|
||||
}
|
||||
};
|
||||
@@ -1,5 +1,6 @@
|
||||
import { Component } from '@angular/core';
|
||||
import { RouterLink } from "@angular/router";
|
||||
import { TranslateableComponent } from '../../components/translateable.component';
|
||||
|
||||
@Component({
|
||||
selector: 'ff-home',
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
@let shownMenu = interactionMenuState();
|
||||
<div class="flex flex-col h-[100vh]">
|
||||
<div class="min-h-56 h-2/3 max-h-2/3">
|
||||
@if (chibi()) {
|
||||
@@ -12,11 +13,26 @@
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
<div class="h-1/3 min-h-20 bg-primary-300">
|
||||
<ff-food-pantry></ff-food-pantry>
|
||||
<ff-inventory></ff-inventory>
|
||||
<ff-button (click)="interact(EChibiInteraction.WakeUp)">{{
|
||||
lang.game.actions.wakeUp
|
||||
}}</ff-button>
|
||||
<div class="h-1/3 min-h-20 bg-primary-300 relative">
|
||||
@if (shownMenu == EInteractionMenuState.Pantry) {
|
||||
<ff-food-pantry
|
||||
(onClose)="closeMenu()"
|
||||
(onFoodChosen)="interact(EChibiInteraction.Feed, $event)"
|
||||
></ff-food-pantry>
|
||||
}
|
||||
@if (shownMenu == EInteractionMenuState.Inventory) {
|
||||
<ff-inventory (onClose)="closeMenu()"></ff-inventory>
|
||||
}
|
||||
<div class="flex flex-row gap-5 py-4 container mx-auto">
|
||||
<ff-button (click)="openInventory()">{{
|
||||
lang.game.actions.giveItem
|
||||
}}</ff-button>
|
||||
<ff-button (click)="openFoodPantry()">{{
|
||||
lang.game.actions.feed
|
||||
}}</ff-button>
|
||||
<ff-button (click)="interact(EChibiInteraction.WakeUp)">{{
|
||||
lang.game.actions.wakeUp
|
||||
}}</ff-button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Component, computed, effect, inject, input, InputSignal, Signal } from '@angular/core';
|
||||
import { Component, computed, effect, inject, input, InputSignal, signal, Signal, WritableSignal } from '@angular/core';
|
||||
import { HeaderComponent } from "../../components/ui-elements/header/header.component";
|
||||
import { ERouteKey } from '../../types/route-key';
|
||||
import { Chibi, ChibiId } from '../../types/chibi/chibi';
|
||||
@@ -11,6 +11,14 @@ import { EChibiInteraction } from '../../types/chibi/chibi-interaction';
|
||||
import { IBrain } from '../../logic/chibi-behaviour/brain';
|
||||
import { BRAIN_MAP } from '../../logic/chibi-behaviour/brain-map';
|
||||
import { TranslateableComponent } from '../../components/translateable.component';
|
||||
import { Food } from '../../types/food';
|
||||
import { interval } from 'rxjs';
|
||||
|
||||
enum EInteractionMenuState {
|
||||
Neutral,
|
||||
Pantry,
|
||||
Inventory
|
||||
}
|
||||
|
||||
@Component({
|
||||
selector: 'ff-interactions',
|
||||
@@ -25,23 +33,41 @@ export class InteractionsComponent extends TranslateableComponent {
|
||||
protected readonly chibi: Signal<Chibi> = computed(() => {
|
||||
return this.chibiStore.chibis().find((chibi: Chibi) => chibi.id === this.chibiId()) as Chibi;
|
||||
});
|
||||
protected readonly interactionMenuState: WritableSignal<EInteractionMenuState> = signal(EInteractionMenuState.Neutral);
|
||||
|
||||
protected readonly EInteractionMenuState: typeof EInteractionMenuState = EInteractionMenuState;
|
||||
protected readonly ERouteKey: typeof ERouteKey = ERouteKey;
|
||||
protected readonly EChibiInteraction: typeof EChibiInteraction = EChibiInteraction;
|
||||
|
||||
private brain!: IBrain;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
effect(() => {
|
||||
if (this.chibi()) {
|
||||
this.brain = BRAIN_MAP[this.chibi().name]!;
|
||||
}
|
||||
})
|
||||
interval(1000).subscribe(() => {
|
||||
this.brain.exist(this.chibi());
|
||||
})
|
||||
}
|
||||
|
||||
public interact(interaction: EChibiInteraction): void {
|
||||
console.log(`${interaction} ${this.chibi().name}`);
|
||||
this.chibi().state = this.brain.resolveInteraction(this.chibi().state, interaction);
|
||||
public interact(interaction: EChibiInteraction, item?: Food): void {
|
||||
console.log(`${interaction} ${this.chibi().name} and item ${item}`);
|
||||
this.brain.resolveInteraction(this.chibi(), interaction, item);
|
||||
}
|
||||
|
||||
public openFoodPantry(): void {
|
||||
this.interactionMenuState.set(EInteractionMenuState.Pantry);
|
||||
}
|
||||
|
||||
public openInventory(): void {
|
||||
this.interactionMenuState.set(EInteractionMenuState.Inventory);
|
||||
}
|
||||
|
||||
public closeMenu(): void {
|
||||
this.interactionMenuState.set(EInteractionMenuState.Neutral);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -15,7 +15,9 @@ export const ENG_TRANSLATIONS: Translation = {
|
||||
foodPantry: {},
|
||||
inventory: {},
|
||||
actions: {
|
||||
wakeUp: 'Wake up!'
|
||||
wakeUp: 'Wake up!',
|
||||
feed: 'Feed',
|
||||
giveItem: 'Give Item'
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,8 @@ export type Translation = {
|
||||
inventory: {},
|
||||
actions: {
|
||||
wakeUp: string;
|
||||
feed: string;
|
||||
giveItem: string;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user