Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Popups #12

Merged
merged 6 commits into from
Nov 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,19 @@
"react-refresh/only-export-components": [
"warn",
{ "allowConstantExport": true }
],
"import/order": [
"warn",
{
"newlines-between": "always",
"pathGroups": [
{
"pattern": "@/**",
"group": "external"
}
],
"distinctGroup": false
}
]
},
"settings": {
Expand Down
6 changes: 5 additions & 1 deletion index.html
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/x-icon" href="/src/assets/fuyo.jpg" />
<link
rel="icon"
type="image/x-icon"
href="/src/assets/images/fuyo.jpg"
/>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Peach Colored Hair</title>
</head>
Expand Down
2 changes: 1 addition & 1 deletion src/FuyoClicker.module.css
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
background-attachment: fixed;
animation: 120s slide infinite linear;

& > * {
& > *:not(.popups) {
overflow: hidden;
width: 25rem;
display: flex;
Expand Down
31 changes: 18 additions & 13 deletions src/FuyoClicker.tsx
Original file line number Diff line number Diff line change
@@ -1,24 +1,28 @@
import { useEffect } from "react";
import classes from "./FuyoClicker.module.css";
import Lanes from "./components/lanes";
import News from "./components/news";
import Reproduction from "./components/reproduction";
import Shop from "./components/shop";
import { State, useGameStore } from "./stores/game";
import { DndContext } from "@dnd-kit/core";
import Clicker from "./components/clicker";
import { Divider, Orientation } from "./components/divider";
import { Species } from "./components/species";
import { Lanes } from "@/components/lanes";
import { News } from "@/components/news";
import { Reproduction } from "@/components/reproduction";
import { Shop } from "@/components/shop";
import { State, useGameStore } from "@/stores/game";
import { Clicker } from "@/components/clicker";
import { Divider, Orientation } from "@/components/divider";
import { Species } from "@/components/species";
import { Popups } from "@/components/popups";
import { usePopupsRefs } from "@/components/popups/usePopupsRefs";

import classes from "./FuyoClicker.module.css";

/** Determines the frequency of updates of the game state. */
const TICK_MS = 1000;

/**
* Contains all the game's components, and handles the main game loop.
*/
export default function FuyoClicker() {
export function FuyoClicker() {
const tick = useGameStore(state => state.tick);
const state = useGameStore(state => state.state);
const refs = usePopupsRefs();

useEffect(() => {
if (state === State.PAUSED) return;
Expand All @@ -30,7 +34,7 @@ export default function FuyoClicker() {

return (
<div className={classes["fuyo-clicker"]}>
<Clicker className={classes.left} />
<Clicker ref={refs.clicker} className={classes.left} />
<DndContext>
<div className={classes.middle}>
<Divider />
Expand All @@ -42,12 +46,13 @@ export default function FuyoClicker() {
<Divider />
</div>
<div className={classes.right}>
<Reproduction />
<Reproduction ref={refs.repro} />
<Divider orientation={Orientation.HORIZONTAL} />
<Shop />
<Shop ref={refs.shop} />
</div>
</DndContext>
<Species />
<Popups className={classes.popups} refs={refs} />
</div>
);
}
Binary file added src/assets/images/ending/full.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/ending/normal.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions src/assets/images/shop/upgrades/icons/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { UpgradeType } from "@/components/shop/upgrades/data";

import axes from "./axes";
import barrels from "./barrels";
import bibles from "./bibles";
Expand Down
Binary file added src/assets/images/tutorial/clicker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/tutorial/repro.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added src/assets/images/tutorial/shop.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion src/components/button/index.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
/* eslint-disable react-refresh/only-export-components */
import { ButtonHTMLAttributes, PropsWithChildren } from "react";
import classes from "./index.module.css";
import cx from "classix";

import classes from "./index.module.css";

export enum Variant {
REGULAR,
THIN,
Expand Down
5 changes: 3 additions & 2 deletions src/components/clicker/backdrop/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,10 @@ import { useMemo, useRef, useState } from "react";
import { Sprite as ISprite } from "pixi.js";
import { easings } from "react-spring";
import { useGameStore } from "@/stores/game";
import { ParticleType, Particles } from "./particles";
import { useElementSize } from "usehooks-ts";

import { ParticleType, Particles } from "./particles";

export const PARTICLE_SIZE = 100;

/** The amount of time used to determine the generated coin amount. */
Expand All @@ -21,7 +22,7 @@ export interface BackdropProps {
size: ReturnType<typeof useElementSize>[1];
}

export default function Backdrop({ size }: BackdropProps) {
export function Backdrop({ size }: BackdropProps) {
const rateMs = useGameStore(state => state.coins.rateMs);
const sprites = useRef<ISprite[]>([]);
const [, setRenderCount] = useState(0);
Expand Down
3 changes: 2 additions & 1 deletion src/components/clicker/backdrop/particles.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { useElementSize } from "usehooks-ts";
import { PARTICLE_SIZE } from ".";
import {
xoroshiro128plus,
unsafeUniformIntDistribution as dist,
} from "pure-rand";

import { PARTICLE_SIZE } from ".";

const RNG = xoroshiro128plus(42);

const ANIM_DURATION_RANGE_MS = [5e3, 10e3];
Expand Down
7 changes: 4 additions & 3 deletions src/components/clicker/boosts/index.tsx
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
import cx from "classix";
import { useGameStore } from "@/stores/game";
import classes from "./index.module.css";
import { BoostType } from "./data";
import { useEffect, useRef } from "react";
import { Sound } from "@/utils/audio/sounds";
import { useSettingsStore } from "@/stores/settings";
import { useSoundEmitter } from "@/hooks/useSoundEmitter";

import { BoostType } from "./data";
import classes from "./index.module.css";

/**
* Sound effects to play when activating the boost.
*/
Expand Down Expand Up @@ -34,7 +35,7 @@ const ACTIVATED_SOUNDS = [
Sound.Slurp3,
];

export default function Fuyonade() {
export function Fuyonade() {
const fuyonade = useGameStore(
state => state.boosts.types[BoostType.FUYONADE]
);
Expand Down
6 changes: 4 additions & 2 deletions src/components/clicker/boosts/slice.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { StoreApi } from "zustand";
import { GameState } from "@/stores/game";
import { BoostType, boosts as data } from "./data";
import { resetters } from "../../../stores/game/resetters";
import { produce } from "immer";
import { calcElapsed } from "@/utils/timer";

import { resetters } from "../../../stores/game/resetters";

import { BoostType, boosts as data } from "./data";

export interface Boost {
lastUpdate: number;
progress: number;
Expand Down
1 change: 1 addition & 0 deletions src/components/clicker/calc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { CloverType } from "../clover/data";
import { LaneType, calculateLaneRate } from "../lanes/lane/data";
import { Lane } from "../lanes/slice";
import { LaneTypeUpgradeType, UpgradeType } from "../shop/upgrades/data";

import { BoostType, determineBoost } from "./boosts/data";
import { Boost } from "./boosts/slice";

Expand Down
5 changes: 3 additions & 2 deletions src/components/clicker/coin/hint/coin/index.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { easings, useSpring } from "react-spring";
import { HINT_DURATION, HintProps } from "..";
import { Sprite } from "@pixi/react-animated";
import coin from "@/assets/images/fuyo-coin.png";

export default function Coin({ x, y }: HintProps) {
import { HINT_DURATION, HintProps } from "..";

export function Coin({ x, y }: HintProps) {
const [spring] = useSpring(() => {
const xOffset = -25 + Math.random() * 50;
const rotation = -Math.PI + Math.random() * (Math.PI * 2);
Expand Down
4 changes: 2 additions & 2 deletions src/components/clicker/coin/hint/index.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import Coin from "./coin";
import Label from "./label";
import { Coin } from "./coin";
import { Label } from "./label";

export const HINT_DURATION = 1e3;

Expand Down
5 changes: 3 additions & 2 deletions src/components/clicker/coin/hint/label/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ import { Container } from "@pixi/react-animated";
import { TextStyle } from "pixi.js";
import { easings, useSpring } from "react-spring";
import { Text } from "@pixi/react";
import { HINT_DURATION, HintProps } from "..";
import { formatNumber } from "@/utils/numbers";

export default function Label({ x, y, amount }: HintProps) {
import { HINT_DURATION, HintProps } from "..";

export function Label({ x, y, amount }: HintProps) {
const [spring] = useSpring(() => ({
from: {
y,
Expand Down
5 changes: 3 additions & 2 deletions src/components/clicker/coin/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,21 @@ import coin from "@/assets/images/fuyo-coin.png";
import { useSpring } from "react-spring";
import { useGameStore } from "@/stores/game";
import { useRef, useState } from "react";
import { HINT_DURATION, Hint, HintProps } from "./hint";
import { FederatedPointerEvent } from "pixi.js";
import { useApp } from "@pixi/react";
import { Sound } from "@/utils/audio/sounds";
import { elements } from "@/utils/audio";
import { useSettingsStore } from "@/stores/settings";

import { HINT_DURATION, Hint, HintProps } from "./hint";

const COIN_SIZE = 300;

export interface CoinProps {
audio: AudioContext;
}

export default function Coin() {
export function Coin() {
const play = useSettingsStore(settings => settings.audio.play);
const click = useGameStore(state => state.coins.click);
const [spring, set] = useSpring(() => ({
Expand Down
2 changes: 1 addition & 1 deletion src/components/clicker/hands/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const LOOP_OFFSET = 14;
/** Duration of a poke animation. */
const POKE_DURATION_MS = 5e2;

export default function Hands() {
export function Hands() {
const clickers = useGameStore(state => state.coins.clickers);

const rotationSpring = useSpring(() => ({
Expand Down
5 changes: 3 additions & 2 deletions src/components/clicker/header/index.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import classes from "./index.module.css";
import { HTMLProps, useEffect } from "react";
import { useCounter } from "@/hooks/useCounter";
import { useGameStore } from "@/stores/game";
Expand All @@ -7,9 +6,11 @@ import { formatNumber } from "@/utils/numbers";
import { Button } from "@/components/button";
import { useSettingsStore } from "@/stores/settings";

import classes from "./index.module.css";

const BASE_TITLE = "Fuyo Clicker";

export default function Header(props: HTMLProps<HTMLHeadingElement>) {
export function Header(props: HTMLProps<HTMLHeadingElement>) {
const coins = useGameStore(state => state.coins);
const debug = useSettingsStore(state => state.debug);

Expand Down
89 changes: 49 additions & 40 deletions src/components/clicker/index.tsx
Original file line number Diff line number Diff line change
@@ -1,49 +1,58 @@
import classes from "./index.module.css";
import { HTMLProps, useMemo } from "react";
import Hands from "./hands";
import { HTMLProps, forwardRef, useMemo } from "react";
import { Stage, Container } from "@pixi/react";
import { BlurFilter } from "pixi.js";
import Coin from "./coin";
import Backdrop from "./backdrop";
import Header from "./header";
import Fuyonade from "./boosts";
import cx from "classix";
import { useElementSize } from "usehooks-ts";
import { useSettingsStore } from "@/stores/settings";

import { Quality } from "../news/settings/slice";

export default function Clicker(props: HTMLProps<HTMLDivElement>) {
const [elementRef, size] = useElementSize();
const quality = useSettingsStore(settings => settings.quality);
import { Coin } from "./coin";
import { Backdrop } from "./backdrop";
import { Header } from "./header";
import { Fuyonade } from "./boosts";
import { Hands } from "./hands";
import classes from "./index.module.css";

export const Clicker = forwardRef<HTMLDivElement, HTMLProps<HTMLDivElement>>(
function Clicker(props, ref) {
const [elementRef, size] = useElementSize();

const quality = useSettingsStore(settings => settings.quality);

// [FIXME] Workound https://github.com/pixijs/pixi-react/issues/456
useMemo(() => new BlurFilter(0), []);
// [FIXME] Workound https://github.com/pixijs/pixi-react/issues/456
useMemo(() => new BlurFilter(0), []);

return (
<div
{...props}
className={cx(classes.clicker, props.className)}
ref={elementRef}
>
<Fuyonade />
<Header />
{size.width + size.height !== 0 && (
<Stage
width={size.width}
height={size.height}
options={{
backgroundAlpha: 0,
autoDensity: true,
}}
className={classes.stage}
>
{quality <= Quality.Medium && <Backdrop size={size} />}
<Container x={size.width / 2} y={size.height / 2}>
<Hands />
<Coin />
</Container>
</Stage>
)}
</div>
);
}
return (
<div
{...props}
ref={(element: HTMLDivElement) => {
elementRef(element);
// @ts-expect-error ref typing
ref.current = element;
}}
className={cx(classes.clicker, props.className)}
>
<Fuyonade />
<Header />
{size.width + size.height !== 0 && (
<Stage
width={size.width}
height={size.height}
options={{
backgroundAlpha: 0,
autoDensity: true,
}}
className={classes.stage}
>
{quality <= Quality.Medium && <Backdrop size={size} />}
<Container x={size.width / 2} y={size.height / 2}>
<Hands />
<Coin />
</Container>
</Stage>
)}
</div>
);
}
);
Loading
Loading