fixed production backend url

This commit is contained in:
2024-02-12 13:36:20 +01:00
parent 8bd6938706
commit 6129f4ce89
5 changed files with 220 additions and 485 deletions

268
'
View File

@@ -1,268 +0,0 @@
<script setup lang="ts">
import { Ref, computed, onMounted, ref } from 'vue';
const grid = ref(genGrid(30, 30))
const currentCoin = ref(spawnCoin())
const direction: Ref<'left' | 'right' | 'top' | 'bottom' | undefined> = ref(undefined)
const snake = ref(spawnSnake())
const score = ref(0)
const lastScore: Ref<undefined | number> = ref(undefined)
const scores: Ref<Score[]> = ref([])
const backendUrl = import.meta.env.BACKENDURL ? import.meta.env.BACKENDURL : 'http://localhost:5000'
interface Cell {
x: number
y: number
color: 'white' | 'yellow' | 'green'
}
interface Snake {
cell: Cell
history: Cell[]
length: number
}
interface Score {
username: String
score: number
}
function genGrid(length: number, height: number) {
const grid: Cell[][] = []
for (let i = 0; i < length; i++) {
const currentRow: Cell[] = []
for (let j = 0; j < height; j++) {
currentRow[j] = {
x: i,
y: j,
color: 'white'
}
}
grid[i] = currentRow
}
return grid
}
function spawnCoin() {
const cell = randomCell()
cell.color = 'yellow'
return cell
}
function spawnSnake(): Snake {
const row = random(grid.value)
const cell = random(row)
cell.color = 'green'
return {
cell: cell,
history: [cell],
length: 3
}
}
function random<T>(array: Array<T>) {
return array[Math.floor(Math.random() * array.length)]
}
function randomCell() {
const randomRow = random(grid.value)
const randomCell = random(randomRow)
return randomCell
}
function moveSnake(x: number, y: number) {
const current = snake.value.cell
const newCell = getCell(current.x + x, current.y + y);
if (newCell === undefined || newCell.color === 'green') {
death()
return;
}
newCell.color = 'green'
snake.value.cell = newCell
snake.value.history.push(newCell)
if (snake.value.history.length > length) {
const currentLength = snake.value.history.length
const allowedLength = snake.value.length
if (currentLength > allowedLength) {
const toDelete = snake.value.history.shift()
if (toDelete !== undefined) {
toDelete.color = 'white'
}
}
}
}
function getCell(x: number, y: number) {
try {
return grid.value[x][y]
} catch {
return undefined
}
}
function death() {
killSnake()
killCoin()
currentCoin.value = spawnCoin()
snake.value = spawnSnake()
direction.value = undefined;
lastScore.value = score.value
score.value = 0
clearInterval(currentInterval)
currentInterval = createInterval()
}
function killSnake() {
snake.value.history
for (const cell of snake.value.history) {
cell.color = 'white'
}
}
function killCoin() {
const coinCell = grid.value[currentCoin.value.x][currentCoin.value.y]
coinCell.color = 'white'
}
const speed = computed(() => {
return 500 / (score.value + 1)
})
let currentInterval = createInterval()
function createInterval() {
return setInterval(() => {
if (direction.value === undefined) {
return
}
switch (direction.value) {
case 'left':
moveSnake(-1, 0)
break
case 'right':
moveSnake(1, 0)
break
case 'top':
moveSnake(0, -1)
break
case 'bottom':
moveSnake(0, 1)
break
}
if (currentCoin.value.x === snake.value.cell.x && currentCoin.value.y === snake.value.cell.y) {
snake.value.length + 10
currentCoin.value = spawnCoin()
score.value++
if (currentInterval) {
clearInterval(currentInterval)
currentInterval = createInterval()
}
}
}, speed.value);
}
function keydown(event: KeyboardEvent) {
switch (event.key) {
case 'ArrowRight': direction.value = direction.value !== 'left' ? 'right' : 'left'
break
case 'ArrowLeft': direction.value = direction.value !== 'right' ? 'left' : 'right'
break
case 'ArrowUp': direction.value = direction.value !== 'bottom' ? 'top' : 'bottom'
break
case 'ArrowDown': direction.value = direction.value !== 'top' ? 'bottom' : 'top'
break
}
}
async function loadDashboard() {
const response = await fetch(`${backendUrl}/score`)
const data = await response.json()
scores.value = data
console.log('scors', data)
}
onMounted(async () => {
await loadDashboard()
})
window.addEventListener('keydown', keydown)
</script>
<template>
<h1>Score {{ score }}</h1>
<h2 v-if="lastScore">Last Score {{ lastScore }}</h2>
<main>
<div class="grid" @keyup="keydown($event)">
<div class="row" v-for="row in grid">
<div class="cell" :class="`cell-${cell.y}-${cell.x}`" v-for="cell in row"
:style="{ backgroundColor: cell.color }">
</div>
</div>
</div>
<ul class="scoreboard">
<li v-for="score in scores">
{{ score.username }} : {{ score.score }}
</li>
</ul>
</main>
</template>
<style scoped>
.grid {
display: flex;
justify-content: center;
align-items: center;
padding: 10px;
border-radius: 10px;
-webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
}
.row {
display: flex;
justify-content: center;
flex-direction: column;
align-items: center;
}
.cell {
height: 10px;
width: 10px;
overflow: hidden;
}
main {
display: flex;
flex-direction: row;
}
.scoreboard {
padding: 10px;
border-radius: 10px;
-webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
}
</style>

View File

@@ -1 +0,0 @@
BACKENDURL=localhost:5000

View File

@@ -1 +0,0 @@
BACKENDURL=quirinecker.pythonanywhere.com

View File

@@ -11,226 +11,228 @@ const lastScore: Ref<undefined | number> = ref(undefined)
const scores: Ref<Score[]> = ref([]) const scores: Ref<Score[]> = ref([])
const username = ref('') const username = ref('')
const usernameDialogOpen = ref(false) const usernameDialogOpen = ref(false)
const backendUrl = import.meta.env.BACKENDURL ? import.meta.env.BACKENDURL : 'http://localhost:5000' const backendUrl = import.meta.env.MODE === "production"
? 'http://quirinecker.pythonanywhere.com'
: 'http://localhost:5000'
interface Cell { interface Cell {
x: number x: number
y: number y: number
color: 'white' | 'yellow' | 'green' color: 'white' | 'yellow' | 'green'
} }
interface Snake { interface Snake {
cell: Cell cell: Cell
history: Cell[] history: Cell[]
length: number length: number
} }
interface Score { interface Score {
username: String username: String
score: number score: number
} }
function genGrid(length: number, height: number) { function genGrid(length: number, height: number) {
const grid: Cell[][] = [] const grid: Cell[][] = []
for (let i = 0; i < length; i++) { for (let i = 0; i < length; i++) {
const currentRow: Cell[] = [] const currentRow: Cell[] = []
for (let j = 0; j < height; j++) { for (let j = 0; j < height; j++) {
currentRow[j] = { currentRow[j] = {
x: i, x: i,
y: j, y: j,
color: 'white' color: 'white'
} }
} }
grid[i] = currentRow grid[i] = currentRow
} }
return grid return grid
} }
function spawnCoin() { function spawnCoin() {
const cell = randomCell() const cell = randomCell()
cell.color = 'yellow' cell.color = 'yellow'
return cell return cell
} }
function spawnSnake(): Snake { function spawnSnake(): Snake {
const row = random(grid.value) const row = random(grid.value)
const cell = random(row) const cell = random(row)
cell.color = 'green' cell.color = 'green'
return { return {
cell: cell, cell: cell,
history: [cell], history: [cell],
length: 3 length: 3
} }
} }
function random<T>(array: Array<T>) { function random<T>(array: Array<T>) {
return array[Math.floor(Math.random() * array.length)] return array[Math.floor(Math.random() * array.length)]
} }
function randomCell() { function randomCell() {
const randomRow = random(grid.value) const randomRow = random(grid.value)
const randomCell = random(randomRow) const randomCell = random(randomRow)
return randomCell return randomCell
} }
function moveSnake(x: number, y: number) { function moveSnake(x: number, y: number) {
const current = snake.value.cell const current = snake.value.cell
const newCell = getCell(current.x + x, current.y + y); const newCell = getCell(current.x + x, current.y + y);
if (newCell === undefined || newCell.color === 'green') { if (newCell === undefined || newCell.color === 'green') {
death() death()
return; return;
} }
newCell.color = 'green' newCell.color = 'green'
snake.value.cell = newCell snake.value.cell = newCell
snake.value.history.push(newCell) snake.value.history.push(newCell)
if (snake.value.history.length > length) { if (snake.value.history.length > length) {
const currentLength = snake.value.history.length const currentLength = snake.value.history.length
const allowedLength = snake.value.length const allowedLength = snake.value.length
if (currentLength > allowedLength) { if (currentLength > allowedLength) {
const toDelete = snake.value.history.shift() const toDelete = snake.value.history.shift()
if (toDelete !== undefined) { if (toDelete !== undefined) {
toDelete.color = 'white' toDelete.color = 'white'
} }
} }
} }
} }
function getCell(x: number, y: number) { function getCell(x: number, y: number) {
try { try {
return grid.value[x][y] return grid.value[x][y]
} catch { } catch {
return undefined return undefined
} }
} }
function death() { function death() {
killSnake() killSnake()
killCoin() killCoin()
currentCoin.value = spawnCoin() currentCoin.value = spawnCoin()
snake.value = spawnSnake() snake.value = spawnSnake()
direction.value = undefined; direction.value = undefined;
lastScore.value = score.value lastScore.value = score.value
score.value = 0 score.value = 0
clearInterval(currentInterval) clearInterval(currentInterval)
currentInterval = createInterval() currentInterval = createInterval()
addScore(lastScore.value) addScore(lastScore.value)
} }
function killSnake() { function killSnake() {
snake.value.history snake.value.history
for (const cell of snake.value.history) { for (const cell of snake.value.history) {
cell.color = 'white' cell.color = 'white'
} }
} }
function killCoin() { function killCoin() {
const coinCell = grid.value[currentCoin.value.x][currentCoin.value.y] const coinCell = grid.value[currentCoin.value.x][currentCoin.value.y]
coinCell.color = 'white' coinCell.color = 'white'
} }
const speed = computed(() => { const speed = computed(() => {
return 500 / (score.value + 1) return 500 / (score.value + 1)
}) })
let currentInterval = createInterval() let currentInterval = createInterval()
function createInterval() { function createInterval() {
return setInterval(() => { return setInterval(() => {
if (direction.value === undefined) { if (direction.value === undefined) {
return return
} }
switch (direction.value) { switch (direction.value) {
case 'left': case 'left':
moveSnake(-1, 0) moveSnake(-1, 0)
break break
case 'right': case 'right':
moveSnake(1, 0) moveSnake(1, 0)
break break
case 'top': case 'top':
moveSnake(0, -1) moveSnake(0, -1)
break break
case 'bottom': case 'bottom':
moveSnake(0, 1) moveSnake(0, 1)
break break
} }
if (currentCoin.value.x === snake.value.cell.x && currentCoin.value.y === snake.value.cell.y) { if (currentCoin.value.x === snake.value.cell.x && currentCoin.value.y === snake.value.cell.y) {
snake.value.length++ snake.value.length++
currentCoin.value = spawnCoin() currentCoin.value = spawnCoin()
score.value++ score.value++
if (currentInterval) { if (currentInterval) {
clearInterval(currentInterval) clearInterval(currentInterval)
currentInterval = createInterval() currentInterval = createInterval()
} }
} }
}, speed.value); }, speed.value);
} }
function keydown(event: KeyboardEvent) { function keydown(event: KeyboardEvent) {
switch (event.key) { switch (event.key) {
case 'ArrowRight': direction.value = direction.value !== 'left' ? 'right' : 'left' case 'ArrowRight': direction.value = direction.value !== 'left' ? 'right' : 'left'
break break
case 'ArrowLeft': direction.value = direction.value !== 'right' ? 'left' : 'right' case 'ArrowLeft': direction.value = direction.value !== 'right' ? 'left' : 'right'
break break
case 'ArrowUp': direction.value = direction.value !== 'bottom' ? 'top' : 'bottom' case 'ArrowUp': direction.value = direction.value !== 'bottom' ? 'top' : 'bottom'
break break
case 'ArrowDown': direction.value = direction.value !== 'top' ? 'bottom' : 'top' case 'ArrowDown': direction.value = direction.value !== 'top' ? 'bottom' : 'top'
break break
} }
} }
async function loadDashboard() { async function loadDashboard() {
const response = await fetch(`${backendUrl}/score`) const response = await fetch(`${backendUrl}/score`)
const data = await response.json() const data = await response.json()
scores.value = data scores.value = data
console.log('scors', data) console.log('scors', data)
} }
async function addScore(scoreToAdd: number, force: boolean = false) { async function addScore(scoreToAdd: number, force: boolean = false) {
if (username.value.trim() === '' && !force) { if (username.value.trim() === '' && !force) {
if (scores.value.length === 0 || scoreToAdd > scores.value[Math.min(3, scores.value.length) - 1].score) { if (scores.value.length === 0 || scoreToAdd > scores.value[Math.min(3, scores.value.length) - 1].score) {
usernameDialogOpen.value = true usernameDialogOpen.value = true
} }
return return
} }
const scoreObject: Score = { const scoreObject: Score = {
username: username.value, username: username.value,
score: scoreToAdd score: scoreToAdd
} }
await fetch(`${backendUrl}/score`, { await fetch(`${backendUrl}/score`, {
method: 'POST', method: 'POST',
body: JSON.stringify(scoreObject), body: JSON.stringify(scoreObject),
headers: { headers: {
"Content-Type": "application/json" "Content-Type": "application/json"
} }
}) })
scores.value = [] scores.value = []
await loadDashboard() await loadDashboard()
} }
onMounted(async () => { onMounted(async () => {
await loadDashboard() await loadDashboard()
}) })
window.addEventListener('keydown', keydown) window.addEventListener('keydown', keydown)
@@ -238,107 +240,106 @@ window.addEventListener('keydown', keydown)
</script> </script>
<template> <template>
<h1>Score {{ score }}</h1> <h1>Score {{ score }}</h1>
<h2 v-if="lastScore" class="p-2">Last Score {{ lastScore }}</h2> <h2 v-if="lastScore" class="p-2">Last Score {{ lastScore }}</h2>
<main> <main>
<div class="grid" @keyup="keydown($event)"> <div class="grid" @keyup="keydown($event)">
<div class="row" v-for="row in grid"> <div class="row" v-for="row in grid">
<div class="cell" :class="`cell-${cell.y}-${cell.x}`" v-for="cell in row" <div class="cell" :class="`cell-${cell.y}-${cell.x}`" v-for="cell in row"
:style="{ backgroundColor: cell.color }"> :style="{ backgroundColor: cell.color }">
</div> </div>
</div> </div>
</div> </div>
<div class="scoreboard"> <div class="scoreboard">
<input type="text" placeholder="username" v-model="username"> <input type="text" placeholder="username" v-model="username">
<ul class="scoreboard-list"> <ul class="scoreboard-list">
<li v-for="score in scores"> <li v-for="score in scores">
<span class="scoreboard-username">{{ score.username }}</span> {{ score.score }} <span class="scoreboard-username">{{ score.username }}</span> {{ score.score }}
</li> </li>
</ul> </ul>
</div> </div>
</main> </main>
<Dialog v-model="usernameDialogOpen"> <Dialog v-model="usernameDialogOpen">
<h3>Nice Score. Do you want to share it!</h3> <h3>Nice Score. Do you want to share it!</h3>
<input type="text" v-model="username" placeholder="username" class="mt-5 !w-32"> <input type="text" v-model="username" placeholder="username" class="mt-5 !w-32">
<nav class="flex flex-row justify-center gap-10 m-10"> <nav class="flex flex-row justify-center gap-10 m-10">
<button @click="usernameDialogOpen = false">no</button> <button @click="usernameDialogOpen = false">no</button>
<button @click="() => { <button @click="() => {
console.log(lastScore) console.log(lastScore)
if (lastScore !== undefined) { if (lastScore !== undefined) {
addScore(lastScore, true) addScore(lastScore, true)
usernameDialogOpen = false; usernameDialogOpen = false;
} }
}">save</button> }">save</button>
</nav> </nav>
</Dialog> </Dialog>
</template> </template>
<style scoped> <style scoped>
.grid { .grid {
display: flex; display: flex;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
padding: 10px; padding: 10px;
border-radius: 10px; border-radius: 10px;
-webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75); -webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75); -moz-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75); box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
height: 100%; height: 100%;
} }
.row { .row {
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-direction: column; flex-direction: column;
align-items: center; align-items: center;
} }
.cell { .cell {
height: 10px; height: 10px;
width: 10px; width: 10px;
overflow: hidden; overflow: hidden;
} }
main { main {
display: flex; display: flex;
flex-direction: row; flex-direction: row;
gap: 10px; gap: 10px;
} }
.scoreboard { .scoreboard {
padding: 10px 20px; padding: 10px 20px;
border-radius: 10px; border-radius: 10px;
margin: 0; margin: 0;
width: 200px; width: 200px;
-webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75); -webkit-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
-moz-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75); -moz-box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75); box-shadow: 0px 0px 20px 0px rgba(0, 0, 0, 0.75);
} }
.scoreboard-list { .scoreboard-list {
width: 100%; width: 100%;
padding: 0; padding: 0;
} }
.scoreboard li { .scoreboard li {
all: unset; all: unset;
display: flex; display: flex;
flex-direction: row; flex-direction: row;
justify-content: space-between; justify-content: space-between;
width: 100%; width: 100%;
} }
.scoreboard-username { .scoreboard-username {
font-weight: 600; font-weight: 600;
} }
input { input {
border-radius: 10px; border-radius: 10px;
padding: 5px; padding: 5px;
width: 100%; width: 100%;
} }
</style> </style>

View File

@@ -1,7 +1,11 @@
import { defineConfig } from 'vite' import { defineConfig, loadEnv } from 'vite'
import vue from '@vitejs/plugin-vue' import vue from '@vitejs/plugin-vue'
// https://vitejs.dev/config/ // https://vitejs.dev/config/
export default defineConfig({ export default defineConfig(({mode}) => {
plugins: [vue()], Object.assign(process.env, loadEnv(mode, process.cwd()));
return {
plugins: [vue()],
}
}) })