init repo

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

13
.editorconfig Normal file
View File

@ -0,0 +1,13 @@
# editorconfig.org
root = true
[*]
indent_style = space
indent_size = 2
end_of_line = lf
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[*.md]
trim_trailing_whitespace = false

15
.eslintrc.js Normal file
View File

@ -0,0 +1,15 @@
module.exports = {
root: true,
env: {
browser: true,
node: true,
},
parserOptions: {
parser: '@babel/eslint-parser',
requireConfigFile: false,
},
extends: ['@nuxtjs', 'plugin:nuxt/recommended', 'prettier'],
plugins: [],
// add your custom rules here
rules: {},
}

90
.gitignore vendored Normal file
View File

@ -0,0 +1,90 @@
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
/logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# Nuxt generate
dist
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# IDE / Editor
.idea
# Service worker
sw.*
# macOS
.DS_Store
# Vim swap files
*.swp

96
.prettierignore Normal file
View File

@ -0,0 +1,96 @@
###
# Place your Prettier ignore content here
###
# .gitignore content is duplicated here due to https://github.com/prettier/prettier/issues/8506
# Created by .ignore support plugin (hsz.mobi)
### Node template
# Logs
/logs
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
# Runtime data
pids
*.pid
*.seed
*.pid.lock
# Directory for instrumented libs generated by jscoverage/JSCover
lib-cov
# Coverage directory used by tools like istanbul
coverage
# nyc test coverage
.nyc_output
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
.grunt
# Bower dependency directory (https://bower.io/)
bower_components
# node-waf configuration
.lock-wscript
# Compiled binary addons (https://nodejs.org/api/addons.html)
build/Release
# Dependency directories
node_modules/
jspm_packages/
# TypeScript v1 declaration files
typings/
# Optional npm cache directory
.npm
# Optional eslint cache
.eslintcache
# Optional REPL history
.node_repl_history
# Output of 'npm pack'
*.tgz
# Yarn Integrity file
.yarn-integrity
# dotenv environment variables file
.env
# parcel-bundler cache (https://parceljs.org/)
.cache
# next.js build output
.next
# nuxt.js build output
.nuxt
# Nuxt generate
dist
# vuepress build output
.vuepress/dist
# Serverless directories
.serverless
# IDE / Editor
.idea
# Service worker
sw.*
# macOS
.DS_Store
# Vim swap files
*.swp

4
.prettierrc Normal file
View File

@ -0,0 +1,4 @@
{
"semi": false,
"singleQuote": true
}

70
README.md Normal file
View File

@ -0,0 +1,70 @@
# tale-spinner
we want to build a game. In turn, each player becomes the Narrator. the narrator pushes the "start" button and like a one-armed-bandit a symbol is randomly selected and showed. the player has to tell a story by using this symbol. the random select and storytelling goes on for X iterations. then the next players turn begins. at the start of the game the players set the amount of players, the amount of iterations and amount of turns. later we want to add different modi operandi.
on the startpage we want to introduce the players to the game, describe it and provide an playing instruction. then we got the game page to start a game. we want to enable either local play or online play. at local play all players are at one computer and play with a single webpage. at online play, the users are joining together by using a code and all players screens are synced up but only the player in turn can press any buttons.
we will use nuxtjs as framework. where do we start and how do we structure the project?
## Build Setup
```bash
# install dependencies
$ yarn install
# serve with hot reload at localhost:3000
$ yarn dev
# build for production and launch server
$ yarn build
$ yarn start
# generate static project
$ yarn generate
```
For detailed explanation on how things work, check out the [documentation](https://nuxtjs.org).
## Special Directories
You can create the following extra directories, some of which have special behaviors. Only `pages` is required; you can delete them if you don't want to use their functionality.
### `assets`
The assets directory contains your uncompiled assets such as Stylus or Sass files, images, or fonts.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/assets).
### `components`
The components directory contains your Vue.js components. Components make up the different parts of your page and can be reused and imported into your pages, layouts and even other components.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/components).
### `layouts`
Layouts are a great help when you want to change the look and feel of your Nuxt app, whether you want to include a sidebar or have distinct layouts for mobile and desktop.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/layouts).
### `pages`
This directory contains your application views and routes. Nuxt will read all the `*.vue` files inside this directory and setup Vue Router automatically.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/get-started/routing).
### `plugins`
The plugins directory contains JavaScript plugins that you want to run before instantiating the root Vue.js Application. This is the place to add Vue plugins and to inject functions or constants. Every time you need to use `Vue.use()`, you should create a file in `plugins/` and add its path to plugins in `nuxt.config.js`.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/plugins).
### `static`
This directory contains your static files. Each file inside this directory is mapped to `/`.
Example: `/static/robots.txt` is mapped as `/robots.txt`.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/static).
### `store`
This directory contains your Vuex store files. Creating a file in this directory automatically activates Vuex.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/docs/2.x/directory-structure/store).

1
assets/icons/down.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M233.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L256 338.7 86.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"/></svg>

After

Width:  |  Height:  |  Size: 430 B

1
assets/icons/up.svg Normal file
View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" height="1em" viewBox="0 0 512 512"><!--! Font Awesome Free 6.4.2 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license (Commercial License) Copyright 2023 Fonticons, Inc. --><path d="M233.4 105.4c12.5-12.5 32.8-12.5 45.3 0l192 192c12.5 12.5 12.5 32.8 0 45.3s-32.8 12.5-45.3 0L256 173.3 86.6 342.6c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3l192-192z"/></svg>

After

Width:  |  Height:  |  Size: 430 B

19
components/NuxtLogo.vue Normal file
View File

@ -0,0 +1,19 @@
<template>
<svg
class="nuxt-logo"
viewBox="0 0 45 30"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M24.7203 29.704H41.1008C41.6211 29.7041 42.1322 29.5669 42.5828 29.3061C43.0334 29.0454 43.4075 28.6704 43.6675 28.2188C43.9275 27.7672 44.0643 27.2549 44.0641 26.7335C44.0639 26.2121 43.9266 25.6999 43.6662 25.2485L32.6655 6.15312C32.4055 5.70162 32.0315 5.32667 31.581 5.06598C31.1305 4.8053 30.6195 4.66805 30.0994 4.66805C29.5792 4.66805 29.0682 4.8053 28.6177 5.06598C28.1672 5.32667 27.7932 5.70162 27.5332 6.15312L24.7203 11.039L19.2208 1.48485C18.9606 1.03338 18.5864 0.658493 18.1358 0.397853C17.6852 0.137213 17.1741 0 16.6538 0C16.1336 0 15.6225 0.137213 15.1719 0.397853C14.7213 0.658493 14.3471 1.03338 14.0868 1.48485L0.397874 25.2485C0.137452 25.6999 0.000226653 26.2121 2.8053e-07 26.7335C-0.000226092 27.2549 0.136554 27.7672 0.396584 28.2188C0.656614 28.6704 1.03072 29.0454 1.48129 29.3061C1.93185 29.5669 2.44298 29.7041 2.96326 29.704H13.2456C17.3195 29.704 20.3239 27.9106 22.3912 24.4118L27.4102 15.7008L30.0986 11.039L38.1667 25.0422H27.4102L24.7203 29.704ZM13.0779 25.0374L5.9022 25.0358L16.6586 6.36589L22.0257 15.7008L18.4322 21.9401C17.0593 24.2103 15.4996 25.0374 13.0779 25.0374Z"
fill="#00DC82"
/>
</svg>
</template>
<style>
.nuxt-logo {
height: 180px;
}
</style>

122
components/Tutorial.vue Normal file
View File

@ -0,0 +1,122 @@
<!-- Please remove this file from your project -->
<template>
<div
class="relative flex items-top justify-center min-h-screen bg-gray-100 sm:items-center sm:pt-0"
>
<link
href="https://cdn.jsdelivr.net/npm/tailwindcss@2.1.2/dist/tailwind.min.css"
rel="stylesheet"
/>
<div class="max-w-4xl mx-auto sm:px-6 lg:px-8">
<a
class="flex justify-center pt-8 sm:pt-0"
href="https://nuxtjs.org"
target="_blank"
>
<svg
width="218"
height="45"
viewBox="0 0 159 30"
fill="none"
xmlns="http://www.w3.org/2000/svg"
>
<path
d="M55.5017 6.81866H60.1727L70.0719 22.9912V6.81866H74.3837V29.7345H69.7446L59.8135 13.5955V29.7345H55.5017V6.81866Z"
fill="#003543"
/>
<path
d="M93.657 29.7344H89.6389V27.1747C88.7241 28.9761 86.8628 29.9904 84.5113 29.9904C80.7869 29.9904 78.3684 27.3059 78.3684 23.4423V13.2339H82.3865V22.5976C82.3865 24.8566 83.7594 26.4276 85.8171 26.4276C88.0712 26.4276 89.6389 24.6598 89.6389 22.2377V13.2339H93.657V29.7344Z"
fill="#003543"
/>
<path
d="M107.64 29.7344L103.784 24.2342L99.9291 29.7344H95.6492L101.596 21.1242L96.1074 13.2339H100.485L103.784 17.9821L107.051 13.2339H111.461L105.94 21.1242L111.886 29.7344H107.64Z"
fill="#003543"
/>
<path
d="M120.053 8.25848V13.2339H124.627V16.6063H120.053V24.7974C120.053 25.0725 120.162 25.3363 120.356 25.531C120.55 25.7257 120.813 25.8353 121.087 25.8357H124.627V29.728H121.98C118.386 29.728 116.035 27.6323 116.035 23.9687V16.6095H112.801V13.2339H114.83C115.776 13.2339 116.327 12.6692 116.327 11.7349V8.25848H120.053Z"
fill="#003543"
/>
<path
d="M134.756 24.5446V6.81866H139.066V23.1864C139.066 27.6067 136.943 29.7345 133.349 29.7345H128.332V25.8421H133.461C133.804 25.8421 134.134 25.7054 134.377 25.4621C134.619 25.2188 134.756 24.8888 134.756 24.5446Z"
fill="#003543"
/>
<path
d="M141.649 22.0409H145.799C146.029 24.6006 147.728 26.2308 150.472 26.2308C152.923 26.2308 154.623 25.2501 154.623 23.2199C154.623 18.3085 142.331 21.7129 142.331 12.9395C142.334 9.17515 145.568 6.55945 150.215 6.55945C155.05 6.55945 158.317 9.34153 158.516 13.6306H154.388C154.193 11.6341 152.632 10.2918 150.207 10.2918C147.953 10.2918 146.548 11.3397 146.548 12.9427C146.548 18.0173 159 14.2226 159 23.1576C159 27.4131 155.504 30 150.474 30C145.279 30 141.882 26.8563 141.654 22.0441"
fill="#003543"
/>
<path
d="M24.7203 29.704H41.1008C41.6211 29.7041 42.1322 29.5669 42.5828 29.3061C43.0334 29.0454 43.4075 28.6704 43.6675 28.2188C43.9275 27.7672 44.0643 27.2549 44.0641 26.7335C44.0639 26.2121 43.9266 25.6999 43.6662 25.2485L32.6655 6.15312C32.4055 5.70162 32.0315 5.32667 31.581 5.06598C31.1305 4.8053 30.6195 4.66805 30.0994 4.66805C29.5792 4.66805 29.0682 4.8053 28.6177 5.06598C28.1672 5.32667 27.7932 5.70162 27.5332 6.15312L24.7203 11.039L19.2208 1.48485C18.9606 1.03338 18.5864 0.658493 18.1358 0.397853C17.6852 0.137213 17.1741 0 16.6538 0C16.1336 0 15.6225 0.137213 15.1719 0.397853C14.7213 0.658493 14.3471 1.03338 14.0868 1.48485L0.397874 25.2485C0.137452 25.6999 0.000226653 26.2121 2.8053e-07 26.7335C-0.000226092 27.2549 0.136554 27.7672 0.396584 28.2188C0.656614 28.6704 1.03072 29.0454 1.48129 29.3061C1.93185 29.5669 2.44298 29.7041 2.96326 29.704H13.2456C17.3195 29.704 20.3239 27.9106 22.3912 24.4118L27.4102 15.7008L30.0986 11.039L38.1667 25.0422H27.4102L24.7203 29.704ZM13.0779 25.0374L5.9022 25.0358L16.6586 6.36589L22.0257 15.7008L18.4322 21.9401C17.0593 24.2103 15.4996 25.0374 13.0779 25.0374Z"
fill="#00DC82"
/>
</svg>
</a>
<div class="mt-8 bg-white overflow-hidden shadow sm:rounded-lg p-6">
<h2 class="text-2xl leading-7 font-semibold">
Welcome to your Nuxt Application
</h2>
<p class="mt-3 text-gray-600">
We recommend you take a look at the
<a
href="https://nuxtjs.org"
target="_blank"
class="button--doc text-green-500 hover:underline"
>Nuxt Documentation</a
>, whether you are new or have previous experience with the
framework.<br />
</p>
<p class="mt-4 pt-4 text-gray-800 border-t border-dashed">
To get started, remove
<code class="bg-gray-100 text-sm p-1 rounded border"
>components/Tutorial.vue</code
>
and start coding in
<code class="bg-gray-100 text-sm p-1 rounded border"
>pages/index.vue</code
>. Have fun!
</p>
</div>
<div class="flex justify-center pt-4 space-x-2">
<a href="https://github.com/nuxt/nuxt.js" target="_blank"
><svg
class="w-6 h-6 text-gray-600 hover:text-gray-800 button--github"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
>
<path
d="M12 2.247a10 10 0 0 0-3.162 19.487c.5.088.687-.212.687-.475c0-.237-.012-1.025-.012-1.862c-2.513.462-3.163-.613-3.363-1.175a3.636 3.636 0 0 0-1.025-1.413c-.35-.187-.85-.65-.013-.662a2.001 2.001 0 0 1 1.538 1.025a2.137 2.137 0 0 0 2.912.825a2.104 2.104 0 0 1 .638-1.338c-2.225-.25-4.55-1.112-4.55-4.937a3.892 3.892 0 0 1 1.025-2.688a3.594 3.594 0 0 1 .1-2.65s.837-.262 2.75 1.025a9.427 9.427 0 0 1 5 0c1.912-1.3 2.75-1.025 2.75-1.025a3.593 3.593 0 0 1 .1 2.65a3.869 3.869 0 0 1 1.025 2.688c0 3.837-2.338 4.687-4.563 4.937a2.368 2.368 0 0 1 .675 1.85c0 1.338-.012 2.413-.012 2.75c0 .263.187.575.687.475A10.005 10.005 0 0 0 12 2.247z"
fill="currentColor"
/></svg
></a>
<a href="https://twitter.com/nuxt_js" target="_blank"
><svg
class="w-6 h-6 text-gray-600 hover:text-gray-800"
xmlns="http://www.w3.org/2000/svg"
xmlns:xlink="http://www.w3.org/1999/xlink"
aria-hidden="true"
role="img"
width="32"
height="32"
preserveAspectRatio="xMidYMid meet"
viewBox="0 0 24 24"
>
<path
d="M22.46 6c-.77.35-1.6.58-2.46.69c.88-.53 1.56-1.37 1.88-2.38c-.83.5-1.75.85-2.72 1.05C18.37 4.5 17.26 4 16 4c-2.35 0-4.27 1.92-4.27 4.29c0 .34.04.67.11.98C8.28 9.09 5.11 7.38 3 4.79c-.37.63-.58 1.37-.58 2.15c0 1.49.75 2.81 1.91 3.56c-.71 0-1.37-.2-1.95-.5v.03c0 2.08 1.48 3.82 3.44 4.21a4.22 4.22 0 0 1-1.93.07a4.28 4.28 0 0 0 4 2.98a8.521 8.521 0 0 1-5.33 1.84c-.34 0-.68-.02-1.02-.06C3.44 20.29 5.7 21 8.12 21C16 21 20.33 14.46 20.33 8.79c0-.19 0-.37-.01-.56c.84-.6 1.56-1.36 2.14-2.23z"
fill="currentColor"
/></svg
></a>
</div>
</div>
</div>
</template>
<script>
export default {
name: 'NuxtTutorial',
}
</script>

12
jsconfig.json Normal file
View File

@ -0,0 +1,12 @@
{
"compilerOptions": {
"baseUrl": ".",
"paths": {
"~/*": ["./*"],
"@/*": ["./*"],
"~~/*": ["./*"],
"@@/*": ["./*"]
}
},
"exclude": ["node_modules", ".nuxt", "dist"]
}

51
layouts/default.vue Normal file
View File

@ -0,0 +1,51 @@
<template lang="pug">
.layout
header
.logo(@click="$router.push('/')")
img(src="/talespinner.png" alt="Tale Spinner Logo")
h1 Tale Spinner
a.about-link(href="/about") About
main
nuxt
</template>
<style scoped>
.layout {
min-height: 90vh;
margin: 0;
padding: 0;
}
header {
display: flex;
justify-content: space-between;
align-items: center;
margin: 1rem;
padding: 2rem;
background-color: #3498db8e;
color: #fff;
border-radius: 1rem;
}
.logo {
display: flex;
align-items: center;
cursor: pointer;
}
.logo img {
width: 5rem;
max-width: 100px;
margin-right: 1rem;
}
.about-link {
font-size: 1.2rem;
text-decoration: none;
color: #fff;
}
main {
flex-grow: 1;
padding: 1rem;
}
</style>

40
nuxt.config.js Normal file
View File

@ -0,0 +1,40 @@
export default {
// Target: https://go.nuxtjs.dev/config-target
target: 'static',
// Global page headers: https://go.nuxtjs.dev/config-head
head: {
title: 'tale-spinner',
htmlAttrs: {
lang: 'en',
},
meta: [
{ charset: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
{ hid: 'description', name: 'description', content: '' },
{ name: 'format-detection', content: 'telephone=no' },
],
link: [{ rel: 'icon', type: 'image/x-icon', href: '/favicon.ico' }],
},
// Global CSS: https://go.nuxtjs.dev/config-css
css: [],
// Plugins to run before rendering page: https://go.nuxtjs.dev/config-plugins
plugins: [],
// Auto import components: https://go.nuxtjs.dev/config-components
components: true,
// Modules for dev and build (recommended): https://go.nuxtjs.dev/config-modules
buildModules: [
// https://go.nuxtjs.dev/eslint
'@nuxtjs/eslint-module',
],
// Modules: https://go.nuxtjs.dev/config-modules
modules: [],
// Build Configuration: https://go.nuxtjs.dev/config-build
build: {},
}

34
package.json Normal file
View File

@ -0,0 +1,34 @@
{
"name": "tale-spinner",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint:js": "eslint --ext \".js,.vue\" --ignore-path .gitignore .",
"lint:prettier": "prettier --check .",
"lint": "yarn lint:js && yarn lint:prettier",
"lintfix": "prettier --write --list-different . && yarn lint:js --fix"
},
"dependencies": {
"core-js": "^3.25.3",
"nuxt": "^2.15.8",
"pug": "^3.0.2",
"pug-plain-loader": "^1.1.0",
"vue": "^2.7.10",
"vue-server-renderer": "^2.7.10",
"vue-template-compiler": "^2.7.10"
},
"devDependencies": {
"@babel/eslint-parser": "^7.19.1",
"@nuxtjs/eslint-config": "^11.0.0",
"@nuxtjs/eslint-module": "^3.1.0",
"eslint": "^8.24.0",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-nuxt": "^4.0.0",
"eslint-plugin-vue": "^9.5.1",
"prettier": "^2.7.1"
}
}

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>

Binary file not shown.

After

Width:  |  Height:  |  Size: 88 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 542 KiB

BIN
static/apple-touch-icon.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 78 KiB

BIN
static/favicon-16x16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 982 B

BIN
static/favicon-32x32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

BIN
static/favicon.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

1
static/site.webmanifest Normal file
View File

@ -0,0 +1 @@
{"name":"","short_name":"","icons":[{"src":"/android-chrome-192x192.png","sizes":"192x192","type":"image/png"},{"src":"/android-chrome-512x512.png","sizes":"512x512","type":"image/png"}],"theme_color":"#ffffff","background_color":"#ffffff","display":"standalone"}

BIN
static/talespinner.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

10
store/README.md Normal file
View File

@ -0,0 +1,10 @@
# STORE
**This directory is not required, you can delete it if you don't want to use it.**
This directory contains your Vuex Store files.
Vuex Store option is implemented in the Nuxt.js framework.
Creating a file in this directory automatically activates the option in the framework.
More information about the usage of this directory in [the documentation](https://nuxtjs.org/guide/vuex-store).

24
store/index.js Normal file
View File

@ -0,0 +1,24 @@
export const state = () => ({
gameSettings: {
playerCount: 0,
turnCount: 0,
iterationCount: 0,
},
gameStarted: false,
});
export const mutations = {
SET_GAME_SETTINGS(state, settings) {
state.gameSettings = settings;
},
SET_GAME_STARTED(state, value) {
state.gameStarted = value;
}
};
export const actions = {
initializeGame({ commit }, settings) {
commit('SET_GAME_SETTINGS', settings);
commit('SET_GAME_STARTED', true);
}
};

9509
yarn.lock Normal file

File diff suppressed because it is too large Load Diff