init repo

This commit is contained in:
2023-10-29 21:25:36 +01:00
commit 1dd04b7216
29 changed files with 10556 additions and 0 deletions

26
pages/about.vue Normal file
View File

@@ -0,0 +1,26 @@
<template lang="pug">
.aboutpage
h1 About
p Hi, my name is Wieerwill. <br/> This project is a little hobby i realized on a fun weekend. I do not tend to make money from it in any way, so it stays free of ads or anything else. So have fun and let your creativity flow.
p If you have any suggestions, just write me a mail to
a(href="mailto:jeutter@wieerwill.de") jeutter[at]wieerwill.de
p You can find more projects and infos about me at
a(href="https://wieerwill.de") wieerwill.de
</template>
<style scoped>
.aboutpage {
margin: 4rem;
margin-bottom: 1rem;
}
h1 {
font-size: 3rem;
text-align: center;
}
p {
font-size: 1.5rem;
margin-bottom: 1rem;
line-height: 1.5;
}
</style>

116
pages/gameplay.vue Normal file
View File

@@ -0,0 +1,116 @@
// pages/gameplay.vue
<template lang="pug">
.gameplay
.info-row
.info-column Current Player: {{ currentPlayerName }}
.info-column Current Turn: {{ currentTurn }} / {{ totalTurns }}
.info-column Current Iteration: {{ currentIteration }} / {{ totalIterations }}
.symbol-display
p(v-if="currentSymbol") {{ currentSymbol }}
//.story
textarea(v-model="currentStory" readonly)
.controls
button(@click="randomizeSymbol" :disabled="isIterationEnd || isGameFinished") Get Symbol
button(@click="nextPlayer" :disabled="!isIterationEnd") Next Player
.player-info
table
tr(v-for="(player, index) in players" :key="index" :class="{ 'current-player': currentPlayer === index + 1 }")
td
input(v-if="player.isEditing" v-model="player.name" @blur="player.isEditing = false")
span(v-else @click="player.isEditing = true") {{ player.name }}
button(@click="player.isEditing = !player.isEditing") Edit
td(v-for="(symbol, index) in player.symbols" :key="index") {{ symbol }}
.game-over(v-if="isGameFinished")
h2 There are no turns left
button(@click="playAgain") Play Again
</template>
<script>
export default {
data() {
return {
currentSymbol: '',
currentStory: '',
currentPlayer: 1,
currentTurn: 1,
currentIteration: 0,
isIterationEnd: false,
isGameFinished: false,
players: Array.from({ length: this.$store.state.gameSettings.playerCount }, (_, index) => ({
name: `Player ${index + 1}`,
symbols: [],
isEditing: false,
})),
}
},
computed: {
totalPlayers() {
return this.$store.state.gameSettings.playerCount;
},
totalTurns() {
return this.$store.state.gameSettings.turnCount;
},
totalIterations() {
return this.$store.state.gameSettings.iterationCount;
},
currentPlayerName() {
return this.players[this.currentPlayer - 1]?.name || '';
},
},
created() {
const { playerCount, turnCount, iterationCount } = this.$store.state.gameSettings;
if (!playerCount || !turnCount || !iterationCount) {
this.$router.push('/setup');
}
},
methods: {
randomizeSymbol() {
const symbols = ['🌟', '🚀', '👑', '🐉', '🎩', '🔮', '🏰', '🌈', '🦄'];
this.currentSymbol = symbols[Math.floor(Math.random() * symbols.length)];
this.players[this.currentPlayer - 1].symbols.push(this.currentSymbol);
this.currentIteration++;
this.isIterationEnd = this.currentIteration === this.totalIterations;
},
nextPlayer() {
if (this.currentPlayer < this.totalPlayers) {
this.currentPlayer++;
} else if (this.currentTurn < this.totalTurns) {
this.currentTurn++;
this.currentPlayer = 1;
} else {
this.isGameFinished = true;
}
this.currentIteration = 0;
this.isIterationEnd = false;
},
playAgain() {
this.$router.push('/setup');
},
},
}
</script>
<style scoped>
.info-row {
display: flex;
justify-content: space-around;
margin-bottom: 2rem;
}
.info-column {
flex: 1;
text-align: center;
padding: 1rem;
background-color: #ecf0f1;
border-radius: 0.5rem;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
}
.controls {
margin-bottom: 2rem;
text-align: center;
}
.current-player {
background-color: #d1f2eb;
}
</style>

161
pages/index.vue Normal file
View File

@@ -0,0 +1,161 @@
<template lang="pug">
.container
h1 Tale Spinner: The Game of Imaginative Storytelling!
.section
p Welcome, aspiring storytellers, to the whimsical world of Tale Spinner! Are you ready to embark on a narrative adventure filled with endless creativity, laughter, and camaraderie? Gather your fellow tale spinners, fuel your imagination, and let's begin the storytelling journey!
img.biglogo(src="/talespinner.png" alt="Tale Spinner Logo")
.section
p The objective of Tale Spinner is to collaboratively create a captivating tale that not only entertains but also challenges your imaginative boundaries. Through a series of turns and iterations, each player will contribute to the unfolding story by narrating a part of it based on a random symbol they receive.
.section
h2 Setting Up The Game
ol
li
strong Starting Up:
| Begin by navigating to the game setup page. Here, you'll set the number of players, turns, and iterations for the game.
li
strong Player Count:
| Decide how many imaginative minds will be partaking in the storytelling extravaganza.
li
strong Turn Count:
| Set the number of turns each player gets to add a twist to the tale.
li
strong Iteration Count:
| Determine the number of times a player will receive a new symbol during their turn.
li
strong Hit Start:
| Once you've set your preferences, hit the "Start Game" button to venture into the storytelling realm!
.section
h2 Playing The Game
ol
li
strong Your Turn:
| When it's your turn, you'll click the "Get Symbol" button to receive a random symbol.
li
strong Spin Your Tale:
| Use the symbol as inspiration to narrate a part of the story. Your narrative could be funny, suspenseful, whimsical, or dramatic the sky's the limit! There are no wrong stories or imaginations. Be creative.
li
strong Log Your Symbol:
| Your symbol will be logged next to your name for everyone to see.
li
strong Pass The Baton:
| Once you've completed your iterations, pass the storytelling baton to the next player.
li
strong Continue the Cycle:
| The game continues with each player adding to the story, inspired by their unique symbols, until all turns are completed.
h3 Variations
ul
li You can spin your whole iterations at once an tell a story by using all your symbols at once.
li Imagine a story for each iteration and draw a new symbol after you used your current up.
li Create an epic story with your whole party. The first start with the intro, the next player continues the story and so on till the last player finishes your groups story with an end.
li Be creative and play with your own rules.
.section
h2 Ending The Game
ul
li
strong The Grand Finale:
| When the final turn and iteration are done, relish in the fantastical tale you've crafted together!
li
strong Play Again:
| Enjoyed your storytelling adventure? Click the "Play Again" button to start afresh with a new set of creative challenges!
.section
p Unleash your inner bard, let the symbols guide your imagination, and create a tale that echoes through the annals of Tale Spinner! Every symbol is a doorway to endless possibilities, and every narrative a journey. So, gather around, let the symbols roll, and may your tales be as boundless as your imagination!
div.link
a(href="/setup")
button Start Game
</template>
<script>
</script>
<style scoped>
.container {
display: flex;
flex-direction: column;
justify-content: center;
align-items: center;
color: #2c3e50;
margin: 2rem auto;
padding: 2rem;
max-width: 800px;
min-height: 100vh;
border-radius: 10px;
box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);
}
.section {
margin-bottom: 2rem;
}
h1 {
font-size: 3rem;
margin-bottom: 1rem;
color: #3498db;
text-align: center;
}
h2 {
font-size: 2rem;
margin-bottom: 0.5rem;
color: #e74c3c;
text-align: center;
}
h3 {
font-size: 1rem;
margin-bottom: 0.5rem;
color: #3fe73c;
text-align: center;
}
p,
li {
font-size: 1.5rem;
margin-bottom: 1rem;
line-height: 1.5;
}
.biglogo{
display:block;
max-width: 500px;
margin: auto;
}
.link {
display: block;
text-align: center;
align-items: center;
margin: auto;
width: 100%;
}
button {
padding: 0.5rem 1rem;
font-size: 1.5rem;
border: none;
border-radius: 0.5rem;
background-color: #3498db;
color: #ffffff;
cursor: pointer;
transition: background-color 0.3s;
}
button:hover {
background-color: #2980b9;
}
@media (max-width: 768px) {
.content {
padding: 1rem;
}
h1 {
font-size: 2rem;
}
h2 {
font-size: 1.5rem;
}
p {
font-size: 1rem;
}
}
</style>

141
pages/setup.vue Normal file
View File

@@ -0,0 +1,141 @@
<template lang="pug">
.game-setup
h1 Setup Your Game
form(@submit.prevent="startGame")
.input-group
label(for="playerCount") Players
.counter
button.minus(tabindex='-1' @click="playerCount > 1 ? playerCount-- : null") -
input(type="number" id="playerCount" v-model.number="playerCount" min="1" readonly)
button.plus(tabindex='-1' @click="playerCount++") +
small Number of players participating in the game.
.input-group
label(for="turnCount") Turns
.counter
button.minus(@click="turnCount > 1 ? turnCount-- : null") -
input(type="number" id="turnCount" v-model.number="turnCount" min="1" readonly)
button.plus(@click="turnCount++") +
small Number of turns each player gets to narrate a part of the story.
.input-group
label(for="iterationCount") Iterations
.counter
button.minus(@click="iterationCount > 1 ? iterationCount-- : null") -
input(type="number" id="iterationCount" v-model.number="iterationCount" min="1" readonly)
button.plus(@click="iterationCount++") +
small Number of iterations in a single turn for each player.
button.submit(type="submit") Start Game
</template>
<script>
export default {
data() {
return {
playerCount: 2,
turnCount: 2,
iterationCount: 3
}
},
methods: {
startGame() {
const gameSettings = {
playerCount: this.playerCount,
turnCount: this.turnCount,
iterationCount: this.iterationCount,
};
this.$store.dispatch('initializeGame', gameSettings);
this.$router.push('/gameplay'); // Assuming the gameplay page is at this route
}
}
}
</script>
<style scoped>
.game-setup {
display: block;
width: 80%;
margin: auto;
justify-content: center;
align-items: center;
text-align: center;
}
h1 {
font-size: 3rem;
margin-bottom: 1rem;
}
.input-group {
display: block;
width: 80%;
max-width: 300px;
margin: auto;
margin-bottom: 2rem;
width: 100%;
}
label {
font-weight: bold;
margin-bottom: 0.5rem;
font-size: 2rem;
color: #3498db;
}
.counter {
display: block;
max-width: 100%;
margin: 0 1rem;
}
.counter>button {
display: inline-block;
background-color: #fff;
border: 0;
font-size: 2rem;
width: 24%;
min-height: 2rem;
margin: 0;
padding: 0;
}
.counter>button:hover {
background-color: #3498db;
border-radius: 1rem;
color: #fff;
}
.counter>input {
display: inline-block;
background-color: #fff;
border: 1px solid #a1a1a1;
font-size: 1.25rem;
width: 50%;
min-height: 2rem;
margin: 0;
padding: 0;
text-align: center;
}
.counter>input::-webkit-outer-spin-button,
input::-webkit-inner-spin-button {
-webkit-appearance: none;
margin: 0;
}
.counter>input[type=number] {
appearance: textfield;
-moz-appearance: textfield;
}
button.submit {
padding: 0.5rem 1rem;
font-size: 1.5rem;
border: none;
border-radius: 0.5rem;
background-color: #3498db;
color: #ffffff;
cursor: pointer;
transition: background-color 0.3s;
}
button.submit:hover {
background-color: #2980b9;
}
</style>