Skip to content

Commit

Permalink
Frontend: add support for buffs.
Browse files Browse the repository at this point in the history
  • Loading branch information
paveloom committed Jun 15, 2024
1 parent 99f252d commit 751bd6a
Show file tree
Hide file tree
Showing 4 changed files with 108 additions and 30 deletions.
35 changes: 35 additions & 0 deletions frontend/src/components/BuffButton.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
<script lang="ts" setup>
defineEmits<{ click: [] }>();
import { computed } from "vue";
import Button from "@/components/Button.vue";
import state from "@/state";
const text = computed(() => {
return `${state.computed.buff.value.toFixed(2)}x`;
});
</script>

<template>
<Button @click="$emit('click')">
<svg viewBox="0 0 36 24" xmlns="http://www.w3.org/2000/svg">
<path class="background" d="m 29.5,6.515 h -23 v 11 h 23 z" fill="none" />
<text x="9.7037077" y="14.074073">
{{ text }}
</text>
<path d="m 6.5,5.515 v 1 h 23 v -1 z" fill="black" />
<path d="m 6.405,17.485 v 1 H 29.405 v -1 z" fill="black" />
<path d="m 30.5,6.515 h -1 v 11 h 1 z" fill="black" />
<path d="m 5.5,17.515 h 1 v -11 h -1 z" fill="black" />
</svg>
</Button>
</template>

<style scoped>
svg > text {
font-size: 5px;
}
</style>
12 changes: 6 additions & 6 deletions frontend/src/components/Button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,12 @@ defineEmits<{ click: [] }>();
</template>

<style>
button {
all: unset;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
button > svg {
height: var(--timer-font-size);
}
Expand All @@ -24,10 +30,4 @@ button.suggested > svg > .background {
button:disabled > svg > .background {
fill: #a2aebb
}
button {
all: unset;
cursor: pointer;
-webkit-tap-highlight-color: transparent;
}
</style>
57 changes: 40 additions & 17 deletions frontend/src/components/Counter.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { computed, ref, watchEffect } from "vue";
import Block from "@/components/Block.vue";
import Box from "@/components/Box.vue";
import BuffButton from "@/components/BuffButton.vue";
import Button from "@/components/Button.vue";
import Text from "@/components/Text.vue";
import Timer from "@/components/Timer.vue";
Expand All @@ -22,13 +23,17 @@ import { formatSeconds, hoursToMilliseconds } from "@/utils";
const nowTime = ref(Date.now());
const isStopping = ref(false);
const currentTime = computed(() => {
const difference = state.targetDate.value.getTime() - nowTime.value;
return Math.sign(difference) * Math.min(Math.abs(difference), state.maxTime.value);
const currentDifference = computed(() => {
const difference = state.refs.targetDate.value - nowTime.value;
let distance = Math.abs(difference);
if (difference < 0) {
distance *= state.computed.buff.value;
}
return Math.sign(difference) * Math.min(distance, state.refs.maxTime.value);
});
const isGameOn = computed(() => {
return state.isReverseOn.value || currentTime.value > 500;
return state.refs.isReverseOn.value || currentDifference.value > 500;
});
const view = computed(() => {
Expand All @@ -38,11 +43,11 @@ const view = computed(() => {
const time = computed(() => {
if (isGameOn.value) {
const elapsedMilliseconds = Math.abs(currentTime.value);
const elapsedMilliseconds = Math.abs(currentDifference.value);
const elapsedSeconds = Math.round(elapsedMilliseconds / 1000);
return formatSeconds(elapsedSeconds);
} else {
const seconds = state.maxTime.value / 1000;
const seconds = state.refs.maxTime.value / 1000;
return formatSeconds(seconds);
}
});
Expand Down Expand Up @@ -84,32 +89,48 @@ const MIN_MAX_TIME = hoursToMilliseconds(24);
const MAX_MAX_TIME = hoursToMilliseconds(72);
function increaseMaxTime() {
state.maxTime.value = Math.min(MAX_MAX_TIME, state.maxTime.value + hoursToMilliseconds(1));
state.refs.maxTime.value = Math.min(MAX_MAX_TIME, state.refs.maxTime.value + hoursToMilliseconds(1));
}
function decreaseMaxTime() {
state.maxTime.value = Math.max(MIN_MAX_TIME, state.maxTime.value - hoursToMilliseconds(1));
state.refs.maxTime.value = Math.max(MIN_MAX_TIME, state.refs.maxTime.value - hoursToMilliseconds(1));
}
function reverseTime() {
state.isReverseOn.value = !state.isReverseOn.value;
state.targetDate.value = new Date(nowTime.value - currentTime.value);
let difference = currentDifference.value;
if (difference > 0) {
difference /= state.computed.buff.value;
}
state.refs.targetDate.value = nowTime.value - difference;
state.refs.isReverseOn.value = !state.refs.isReverseOn.value;
}
function startGame() {
nowTime.value = Date.now();
state.targetDate.value = new Date(nowTime.value + state.maxTime.value);
state.refs.targetDate.value = nowTime.value + state.refs.maxTime.value;
}
function stopGame() {
isStopping.value = false;
state.isReverseOn.value = false;
state.targetDate.value = new Date(nowTime.value);
state.refs.isReverseOn.value = false;
state.refs.targetDate.value = nowTime.value;
}
function toggleStopping() {
isStopping.value = !isStopping.value;
}
function switchBuff() {
const [buff, prevBuff] = state.switchBuff();
const difference = state.refs.targetDate.value - nowTime.value;
let distance = Math.abs(difference);
if (difference < 0) {
distance *= prevBuff;
distance /= buff;
state.refs.targetDate.value = nowTime.value - distance;
}
}
</script>

<template>
Expand All @@ -119,27 +140,29 @@ function toggleStopping() {
<Button @click="startGame">
<PlayIcon />
</Button>
<BuffButton @click="switchBuff" />
<Button
:disabled="state.maxTime.value === MAX_MAX_TIME"
:disabled="state.refs.maxTime.value === MAX_MAX_TIME"
@click="increaseMaxTime"
>
<PlusIcon />
</Button>
<Button
:disabled="state.maxTime.value === MIN_MAX_TIME"
:disabled="state.refs.maxTime.value === MIN_MAX_TIME"
@click="decreaseMaxTime"
>
<MinusIcon />
</Button>
</Block>
<Block v-else-if="view==='gameOn'">
<Button
:class="!state.isReverseOn.value && 'suggested'"
:class="!state.refs.isReverseOn.value && 'suggested'"
@click="reverseTime"
>
<BackwardIcon v-if="state.isReverseOn.value" />
<BackwardIcon v-if="state.refs.isReverseOn.value" />
<ForwardIcon v-else />
</Button>
<BuffButton @click="switchBuff" />
<Button @click="toggleStopping">
<StopIcon />
</Button>
Expand Down
34 changes: 27 additions & 7 deletions frontend/src/state.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,35 @@
import { ref, watch } from "vue";
import { computed, ref, watch } from "vue";

import { hoursToMilliseconds } from "@/utils";

class State {
targetDate = ref(new Date());
isReverseOn = ref(false);
maxTime = ref(hoursToMilliseconds(24));
export class State {
consts = {
availableBuffs: [1.00, 1.25, 1.50, 1.75, 2.00],
};

refs = {
targetDate: ref(Date.now()),
isReverseOn: ref(false),
maxTime: ref(hoursToMilliseconds(24)),
buffIndex: ref(0),
};

computed = {
buff: computed(() => {
return this.consts.availableBuffs[this.refs.buffIndex.value]!;
}),
};

switchBuff(): [number, number] {
const prevBuff = this.consts.availableBuffs[this.refs.buffIndex.value]!;
this.refs.buffIndex.value = (this.refs.buffIndex.value + 1) % this.consts.availableBuffs.length;
const buff = this.consts.availableBuffs[this.refs.buffIndex.value]!;
return [buff, prevBuff];
}

* [Symbol.iterator]() {
for (const property in this) {
yield [this[property], property] as const;
for (const property in this.refs) {
yield [this.refs[property as keyof typeof this.refs], property] as const;
}
}
}
Expand Down

0 comments on commit 751bd6a

Please sign in to comment.