Skip to content

Commit

Permalink
Add happiness and task timers
Browse files Browse the repository at this point in the history
  • Loading branch information
Golen87 committed Aug 17, 2024
1 parent 50f6990 commit 02e6607
Show file tree
Hide file tree
Showing 9 changed files with 233 additions and 23 deletions.
1 change: 1 addition & 0 deletions src/assets/assets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ const images: Image[] = [
// UI
image('ui/hud', 'hud'),
image('ui/bubble', 'bubble'),
image('ui/timer', 'timer'),

// Titlescreen
image('titlescreen/sky', 'title_sky'),
Expand Down
Binary file added src/assets/images/ui/timer.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
76 changes: 65 additions & 11 deletions src/components/Customer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import { GameScene } from "@/scenes/GameScene";
import { Button } from "./elements/Button";
import { Station, StationType, StationTypeColors } from "./Station";
import { Employee } from "./Employee";
import { Timer } from "./Timer";
import { interpolateColor } from "@/functions";

export class Customer extends Button {
// Movement
public lastX: number; // Last position on the grid
public lastY: number;
public dragX: number; // Current drag position
Expand All @@ -15,17 +18,18 @@ export class Customer extends Button {
public itinerary: StationType[]; // List of stations to visit
public requestedStation: StationType | null;

// Customer stats
// Stats
public doingCuteThing: boolean;
public tasksCompleted: number;
public moneySpent: number;
public maxHappiness: number;
public happiness: number;

// Customer sprite
// Graphics
private sprite: Phaser.GameObjects.Sprite;

// Request bubble
private bubble: Phaser.GameObjects.Sprite;
private bubbleImage: Phaser.GameObjects.Ellipse;
private happinessTimer: Timer;

constructor(scene: GameScene, x: number, y: number) {
super(scene, x, y);
Expand All @@ -45,6 +49,8 @@ export class Customer extends Button {
this.doingCuteThing = false;
this.tasksCompleted = 0;
this.moneySpent = 0;
this.maxHappiness = 100;
this.happiness = 100;

/* Sprite */
const size = 150;
Expand All @@ -63,6 +69,15 @@ export class Customer extends Button {
this.bubbleImage.setVisible(false);
this.add(this.bubbleImage);

this.happinessTimer = new Timer(
scene,
0.3 * size,
-0.4 * size,
0.6 * size,
0xfa9425
);
this.add(this.happinessTimer);

this.bindInteractive(this.sprite, true);
}

Expand All @@ -71,13 +86,33 @@ export class Customer extends Button {
this.x += (this.dragX - this.x) * 0.5;
this.y += (this.dragY - this.y) * 0.5;

const factor = this.doingCuteThing ? 0.1 : 0.02;
const squish = 1.0 + factor * Math.sin((6 * time) / 1000);
const wobble = this.doingCuteThing ? 0.1 : 0.02;
const squish = 1.0 + wobble * Math.sin((6 * time) / 1000);
this.setScale(1.0, squish);

if (this.isWaiting) {
this.happinessTimer.setVisible(true);
if (!this.dragged) {
this.happiness -= (100 / 20) * (delta / 1000);
}

const factor = this.happiness / this.maxHappiness;
this.happinessTimer.setColor(
interpolateColor(0xff0000, 0x00ff00, factor)
);
this.happinessTimer.redraw(factor);

if (this.happiness <= 0) {
this.leave();
}
} else {
this.happinessTimer.setVisible(false);
}
}

onDragStart(pointer: Phaser.Input.Pointer, dragX: number, dragY: number) {
this.emit("pickup");
this.dragged = true;
}

onDrag(pointer: Phaser.Input.Pointer, dragX: number, dragY: number) {
Expand All @@ -88,6 +123,7 @@ export class Customer extends Button {
}

onDragEnd(pointer: Phaser.Input.Pointer, dragX: number, dragY: number) {
this.dragged = false;
this.emit("drop");
}

Expand All @@ -98,6 +134,12 @@ export class Customer extends Button {

setStation(station: Station | null) {
this.currentStation = station;

if (station) {
this.lastX = station.x;
this.lastY = station.y;
this.happiness = 100;
}
}

setEmployee(employee: Employee | null) {
Expand Down Expand Up @@ -127,19 +169,27 @@ export class Customer extends Button {
if (this.itinerary.length > 0) {
this.setRequest(this.itinerary.shift() || null);
} else {
if (this.currentStation) {
this.currentStation.setCustomer(null);
this.setStation(null);
}
this.emit("pay", this.moneySpent);
this.leave();
}
}

leave() {
this.sprite.input!.enabled = false;

if (this.currentStation) {
this.currentStation.setCustomer(null);
this.setStation(null);
}

if (this.currentEmployee) {
this.currentEmployee.setCustomer(null);
this.setEmployee(null);
}

this.scene.tweens.add({
targets: this,
dragX: this.lastX + 1920,
dragX: "+=1920",
dragY: this.lastY,
duration: 2000,
ease: "Linear",
Expand All @@ -148,4 +198,8 @@ export class Customer extends Button {
},
});
}

get isWaiting(): boolean {
return this.currentStation !== null && this.currentEmployee === null;
}
}
43 changes: 38 additions & 5 deletions src/components/Station.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { GameScene } from "@/scenes/GameScene";
import { Button } from "./elements/Button";
import { Customer } from "./Customer";
import { Timer } from "./Timer";

export enum StationType {
WaitingSeat,
Expand All @@ -18,6 +19,14 @@ export const StationTypeColors: { [key in StationType]: number } = {
[StationType.CashRegister]: 0xffff00,
};

export const StationDuration: { [key in StationType]: number } = {
[StationType.WaitingSeat]: 0,
[StationType.HornAndNails]: 3000,
[StationType.ScalePolish]: 4000,
[StationType.GoldBath]: 2000,
[StationType.CashRegister]: 500,
};

export class Station extends Button {
public stationType: StationType;
public currentCustomer: Customer | null; // The customer using the station
Expand All @@ -27,14 +36,16 @@ export class Station extends Button {
private sprite: Phaser.GameObjects.Rectangle;
private text: Phaser.GameObjects.Text;

private progressTimer: Timer;

constructor(scene: GameScene, x: number, y: number, type: StationType) {
super(scene, x, y);
scene.add.existing(this);
this.scene = scene;
this.stationType = type;

this.currentCustomer = null;
this.taskDuration = 3000;
this.taskDuration = StationDuration[type];
this.admissionFee = 10;

/* Sprite */
Expand All @@ -53,6 +64,16 @@ export class Station extends Button {
this.text.setOrigin(0.5);
this.text.setStroke("#000000", 4);
this.add(this.text);

this.progressTimer = new Timer(
scene,
-0.4 * size,
0.4 * size,
0.8 * size,
0xed51a4
);
this.progressTimer.setVisible(false);
this.add(this.progressTimer);
}

update(time: number, delta: number) {
Expand All @@ -71,10 +92,22 @@ export class Station extends Button {
this.sprite.alpha = 1.0;
this.text.setText("Working");

this.scene.addEvent(this.taskDuration, () => {
this.emit("taskend");
this.sprite.alpha = this.currentCustomer ? 0.75 : 0.5;
this.text.setText("Click me!");
this.scene.tweens.addCounter({
from: 1,
to: 0,
duration: this.taskDuration,
onStart: () => {
this.progressTimer.setVisible(true);
},
onUpdate: (tween) => {
this.progressTimer.redraw(tween.getValue());
},
onComplete: () => {
this.emit("taskend");
this.progressTimer.setVisible(false);
this.sprite.alpha = this.currentCustomer ? 0.75 : 0.5;
this.text.setText("Click me!");
},
});
}
}
52 changes: 52 additions & 0 deletions src/components/Timer.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { GameScene } from "@/scenes/GameScene";

export class Timer extends Phaser.GameObjects.Container {
private background: Phaser.GameObjects.Image;
private graphics: Phaser.GameObjects.Graphics;
private size: number;
private color: number;

constructor(
scene: GameScene,
x: number,
y: number,
size: number,
color: number
) {
super(scene, x, y);
scene.add.existing(this);
this.scene = scene;
this.size = size;
this.color = color;

this.background = this.scene.add.image(0, 0, "timer");
this.background.setScale(size / this.background.width);
this.add(this.background);

this.graphics = this.scene.add.graphics();
this.add(this.graphics);
}

setColor(color: number) {
this.color = color;
}

redraw(factor: number) {
const radius = 0.24 * this.size;
const border = 0.055 * this.size;

this.graphics.clear();
this.graphics.beginPath();
this.graphics.fillStyle(this.color);
this.graphics.moveTo(0, 0);
this.graphics.arc(
0,
0,
radius - border,
-Math.PI / 2,
-Math.PI / 2 + factor * 2 * Math.PI
);
this.graphics.closePath();
this.graphics.fillPath();
}
}
7 changes: 6 additions & 1 deletion src/components/UI.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ export class UI extends Phaser.GameObjects.Container {

this.background = this.scene.add.image(0, 0, "hud");
this.background.setScale(panelHeight / this.background.height);
this.background.setVisible(false);
this.panel.add(this.background);

this.text = this.scene.addText({
x: -50,
y: 0,
size: 60,
color: "#FFFFFF",
text: "Score: 123",
text: "Money: $0",
});
this.text.setStroke("black", 4);
this.text.setOrigin(0, 0.5);
Expand All @@ -39,4 +40,8 @@ export class UI extends Phaser.GameObjects.Container {
}

update(time: number, delta: number) {}

setMoney(money: number) {
this.text.setText(`Money: $${money}`);
}
}
2 changes: 2 additions & 0 deletions src/components/elements/Button.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export class Button extends Phaser.GameObjects.Container {
public scene: BaseScene;
// private hover: boolean;
private _hold: boolean;
protected dragged: boolean;
protected blocked: boolean;
public liftSmooth: number;
public holdSmooth: number;
Expand All @@ -17,6 +18,7 @@ export class Button extends Phaser.GameObjects.Container {

// this.hover = false;
this._hold = false;
this.dragged = false;
this.blocked = false;

this.liftSmooth = 0;
Expand Down
Loading

0 comments on commit 02e6607

Please sign in to comment.