mirror of
https://github.com/danbulant/slightlyComplicatedTicTacToe
synced 2026-06-20 23:11:17 +00:00
loading screen
This commit is contained in:
parent
f2c794c44c
commit
2cac7aea5f
10 changed files with 276 additions and 50 deletions
|
|
@ -21,6 +21,7 @@ class ConnectedClient extends EventTarget {
|
|||
state: RTCDataChannelState | null = null;
|
||||
readyState: number = 0;
|
||||
pings: number[] = [];
|
||||
score: number = 0;
|
||||
|
||||
constructor(public ws: WebsocketConnection, public name: string) {
|
||||
super();
|
||||
|
|
@ -83,6 +84,9 @@ class ConnectedClient extends EventTarget {
|
|||
this.dispatchEvent(new FastEvent("message", msg.d));
|
||||
messages.update(t => { t.push({ author: this.name, content: msg.d });return t})
|
||||
break;
|
||||
case "start":
|
||||
gameData.set({ score: 0 });
|
||||
// break not on purpose
|
||||
default:
|
||||
console.log("MSG", msg);
|
||||
this.dispatchEvent(new FastEvent(msg.t, msg.d));
|
||||
|
|
@ -266,16 +270,28 @@ export class WebsocketConnection extends EventTarget {
|
|||
|
||||
sendMessage(msg: string) {
|
||||
if (!this.roomName) return console.log("Not in a room");
|
||||
for(const [, client] of this.fast) {
|
||||
client.send({ t: "msg", d: msg });
|
||||
}
|
||||
this.broadcast({ t: "msg", d: msg });
|
||||
messages.update(t => { t.push({ author: this.name, content: msg }); return t });
|
||||
}
|
||||
broadcast(data: any) {
|
||||
if (!this.roomName) return console.log("Not in a room");
|
||||
for(const [, client] of this.fast) {
|
||||
client.send(data);
|
||||
}
|
||||
}
|
||||
|
||||
createGame(name: string) {
|
||||
this.ws.send(JSON.stringify({ t: "create", name: name }));
|
||||
}
|
||||
|
||||
startGame() {
|
||||
if (!this.roomName) return console.log("Not in a room");
|
||||
this.broadcast({ t: "start" });
|
||||
for(const [, client] of this.fast) {
|
||||
client.score = 0;
|
||||
}
|
||||
}
|
||||
|
||||
join(name: string) {
|
||||
this.ws.send(JSON.stringify({ t: "join", name: name }));
|
||||
}
|
||||
|
|
@ -296,4 +312,5 @@ export const listLoading = writable(true);
|
|||
export const lastError: Writable<string> = writable("");
|
||||
export const room: Writable<{ name: string, host: string } | null> = writable(null);
|
||||
export const players: Writable<Map<string, ConnectedClient>> = writable(new Map);
|
||||
export const messages: Writable<{ author: string, content: string }[]> = writable([]);
|
||||
export const messages: Writable<{ author: string, content: string }[]> = writable([]);
|
||||
export const gameData: Writable<{ score: number }|null> = writable(null);
|
||||
|
|
@ -1,5 +1,8 @@
|
|||
<script>
|
||||
export var disabled = false;
|
||||
</script>
|
||||
|
||||
<button on:click><slot /></button>
|
||||
<button on:click {disabled}><slot /></button>
|
||||
|
||||
<style>
|
||||
button {
|
||||
|
|
@ -18,4 +21,10 @@
|
|||
background-color: #bd5ce6;
|
||||
color: #85E65C;
|
||||
}
|
||||
button:disabled {
|
||||
background-color: #85E65C;
|
||||
color: #5f3172;
|
||||
text-decoration: line-through;
|
||||
cursor: not-allowed;
|
||||
}
|
||||
</style>
|
||||
105
client/src/lib/view/components/jump.svelte
Normal file
105
client/src/lib/view/components/jump.svelte
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
<script>
|
||||
const radius = 10;
|
||||
export const color = 'rgb(161, 76, 76)';
|
||||
export const showfaces = false;
|
||||
export const duration = "0.5s"
|
||||
</script>
|
||||
|
||||
<div class="dice" style="animation-duration: {duration}">
|
||||
<svg width="100" height="100" class="front" style="background-color: {color}">
|
||||
{#if showfaces}
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
{/if}
|
||||
</svg>
|
||||
<svg width="100" height="100" class="top" style="background-color: {color}">
|
||||
{#if showfaces}
|
||||
<circle cx="33" cy="33" r={radius} fill="black" />
|
||||
<circle cx="66" cy="66" r={radius} fill="black" />
|
||||
{/if}
|
||||
</svg>
|
||||
<svg width="100" height="100" class="left" style="background-color: {color}">
|
||||
{#if showfaces}
|
||||
<circle cx="30" cy="30" r={radius} fill="black" />
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
<circle cx="70" cy="70" r={radius} fill="black" />
|
||||
{/if}
|
||||
</svg>
|
||||
<svg width="100" height="100" class="back" style="background-color: {color}">
|
||||
{#if showfaces}
|
||||
<circle cx="25" cy="33" r={radius} fill="black" />
|
||||
<circle cx="50" cy="33" r={radius} fill="black" />
|
||||
<circle cx="75" cy="33" r={radius} fill="black" />
|
||||
<circle cx="25" cy="66" r={radius} fill="black" />
|
||||
<circle cx="50" cy="66" r={radius} fill="black" />
|
||||
<circle cx="75" cy="66" r={radius} fill="black" />
|
||||
{/if}
|
||||
</svg>
|
||||
<svg width="100" height="100" class="right" style="background-color: {color}">
|
||||
{#if showfaces}
|
||||
<circle cx="33" cy="33" r={radius} fill="black" />
|
||||
<circle cx="33" cy="66" r={radius} fill="black" />
|
||||
<circle cx="66" cy="33" r={radius} fill="black" />
|
||||
<circle cx="66" cy="66" r={radius} fill="black" />
|
||||
{/if}
|
||||
</svg>
|
||||
<svg width="100" height="100" class="bottom" style="background-color: {color}">
|
||||
{#if showfaces}
|
||||
<circle cx="30" cy="30" r={radius} fill="black" />
|
||||
<circle cx="30" cy="70" r={radius} fill="black" />
|
||||
<circle cx="70" cy="30" r={radius} fill="black" />
|
||||
<circle cx="70" cy="70" r={radius} fill="black" />
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
{/if}
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
border-radius: 5px;
|
||||
border: 1px solid black;
|
||||
box-shadow: 0 0 2px black;
|
||||
position: absolute;
|
||||
backface-visibility: visible;
|
||||
}
|
||||
.front {
|
||||
transform: translateZ(50px);
|
||||
}
|
||||
.top {
|
||||
transform: rotateX(90deg) translateZ(50px);
|
||||
}
|
||||
.bottom {
|
||||
transform: rotateX(-90deg) translateZ(50px);
|
||||
}
|
||||
.left {
|
||||
transform: rotateY(-90deg) translateZ(50px);
|
||||
}
|
||||
.right {
|
||||
transform: rotateY(90deg) translateZ(50px);
|
||||
}
|
||||
.back {
|
||||
transform: rotateY(180deg) translateZ(50px);
|
||||
}
|
||||
.dice {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
transform: rotate3d(1, 0, 0, 0deg);
|
||||
transform-style: preserve-3d;
|
||||
box-sizing: border-box;
|
||||
animation: jump 0.5s;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
@keyframes jump {
|
||||
0% {
|
||||
transform: rotate3d(1, 0, 0, 0deg) scale(1);
|
||||
animation-timing-function: ease-in;
|
||||
}
|
||||
60% {
|
||||
transform: rotate3d(1, 0, 0, 90deg) scale(1.4);
|
||||
animation-timing-function: ease-out;
|
||||
}
|
||||
100% {
|
||||
transform: rotate3d(1, 0, 0, 180deg) scale(1);
|
||||
}
|
||||
}
|
||||
</style>
|
||||
104
client/src/lib/view/components/prestartScreen.svelte
Normal file
104
client/src/lib/view/components/prestartScreen.svelte
Normal file
|
|
@ -0,0 +1,104 @@
|
|||
<script>
|
||||
const radius = 10;
|
||||
</script>
|
||||
|
||||
<div class="container">
|
||||
<div class="dice">
|
||||
<svg width="100" height="100" class="front">
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
</svg>
|
||||
<svg width="100" height="100" class="top">
|
||||
<circle cx="33" cy="33" r={radius} fill="black" />
|
||||
<circle cx="66" cy="66" r={radius} fill="black" />
|
||||
</svg>
|
||||
<svg width="100" height="100" class="left">
|
||||
<circle cx="30" cy="30" r={radius} fill="black" />
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
<circle cx="70" cy="70" r={radius} fill="black" />
|
||||
</svg>
|
||||
<svg width="100" height="100" class="back">
|
||||
<circle cx="25" cy="33" r={radius} fill="black" />
|
||||
<circle cx="50" cy="33" r={radius} fill="black" />
|
||||
<circle cx="75" cy="33" r={radius} fill="black" />
|
||||
<circle cx="25" cy="66" r={radius} fill="black" />
|
||||
<circle cx="50" cy="66" r={radius} fill="black" />
|
||||
<circle cx="75" cy="66" r={radius} fill="black" />
|
||||
</svg>
|
||||
<svg width="100" height="100" class="right">
|
||||
<circle cx="33" cy="33" r={radius} fill="black" />
|
||||
<circle cx="33" cy="66" r={radius} fill="black" />
|
||||
<circle cx="66" cy="33" r={radius} fill="black" />
|
||||
<circle cx="66" cy="66" r={radius} fill="black" />
|
||||
</svg>
|
||||
<svg width="100" height="100" class="bottom">
|
||||
<circle cx="30" cy="30" r={radius} fill="black" />
|
||||
<circle cx="30" cy="70" r={radius} fill="black" />
|
||||
<circle cx="70" cy="30" r={radius} fill="black" />
|
||||
<circle cx="70" cy="70" r={radius} fill="black" />
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
border-radius: 5px;
|
||||
border: 1px solid black;
|
||||
box-shadow: 0 0 2px black;
|
||||
position: absolute;
|
||||
backface-visibility: visible;
|
||||
}
|
||||
.front {
|
||||
transform: translateZ(50px);
|
||||
background-color: rgba(255, 0, 0, 0.7);
|
||||
}
|
||||
.top {
|
||||
transform: rotateX(90deg) translateZ(50px);
|
||||
background-color: rgba(255, 255, 0, 0.7);
|
||||
}
|
||||
.bottom {
|
||||
transform: rotateX(-90deg) translateZ(50px);
|
||||
background-color: rgba(0, 255, 0, 0.7);
|
||||
}
|
||||
.left {
|
||||
transform: rotateY(-90deg) translateZ(50px);
|
||||
background-color: rgba(255, 0, 255, 0.7);
|
||||
}
|
||||
.right {
|
||||
transform: rotateY(90deg) translateZ(50px);
|
||||
background-color: rgba(0, 0, 255, 0.7);
|
||||
}
|
||||
.back {
|
||||
transform: rotateY(180deg) translateZ(50px);
|
||||
background-color: rgba(0, 0, 0, 0.7);
|
||||
}
|
||||
.dice {
|
||||
width: 100px;
|
||||
height: 100px;
|
||||
position: relative;
|
||||
transform: rotate3d(1, 0, 0, 0deg);
|
||||
transform-style: preserve-3d;
|
||||
box-sizing: border-box;
|
||||
animation: dice 1.8s 0.7s ease-in-out;
|
||||
animation-fill-mode: both;
|
||||
}
|
||||
@keyframes dice {
|
||||
0% {
|
||||
transform: rotate3d(0, 1, 0, 90deg); /* 3 */
|
||||
}
|
||||
50% {
|
||||
transform: rotate3d(1, 0, 0, -90deg); /* 2 */
|
||||
}
|
||||
100% {
|
||||
transform: rotate3d(1, 0, 0, 0deg); /* 1 */
|
||||
}
|
||||
}
|
||||
.container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
background-color: #85E65C;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
</style>
|
||||
|
|
@ -1,5 +1,16 @@
|
|||
<script>
|
||||
import Waiting from "./waiting.svelte";
|
||||
import { gameData } from '$lib/Websocket';
|
||||
import GameOverlay from './gameOverlay.svelte';
|
||||
import Scene from './scene.svelte';
|
||||
import TimedPrestartScreen from './timedPrestartScreen.svelte';
|
||||
import Waiting from './waiting.svelte';
|
||||
</script>
|
||||
|
||||
<Waiting />
|
||||
{#if !$gameData}
|
||||
<Waiting />
|
||||
{:else}
|
||||
<TimedPrestartScreen />
|
||||
<GameOverlay>
|
||||
<Scene />
|
||||
</GameOverlay>
|
||||
{/if}
|
||||
|
|
|
|||
2
client/src/lib/view/game/gameOverlay.svelte
Normal file
2
client/src/lib/view/game/gameOverlay.svelte
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
|
||||
<slot />
|
||||
0
client/src/lib/view/game/scene.svelte
Normal file
0
client/src/lib/view/game/scene.svelte
Normal file
17
client/src/lib/view/game/timedPrestartScreen.svelte
Normal file
17
client/src/lib/view/game/timedPrestartScreen.svelte
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
<script>
|
||||
import { onMount } from "svelte";
|
||||
import PrestartScreen from "../components/prestartScreen.svelte";
|
||||
|
||||
let visible = true;
|
||||
|
||||
onMount(() => {
|
||||
let i = setTimeout(() => {
|
||||
visible = false;
|
||||
}, 3000);
|
||||
return () => clearTimeout(i);
|
||||
});
|
||||
</script>
|
||||
|
||||
{#if visible}
|
||||
<PrestartScreen />
|
||||
{/if}
|
||||
|
|
@ -2,7 +2,9 @@
|
|||
import { connection, messages, players, room } from '$lib/Websocket';
|
||||
import Button from '../components/button.svelte';
|
||||
|
||||
function startGame() {}
|
||||
function startGame() {
|
||||
|
||||
}
|
||||
let content = "";
|
||||
function sendMessage() {
|
||||
if(!content.length || content.length > 512) return;
|
||||
|
|
@ -61,7 +63,7 @@
|
|||
{#if $room?.host === $connection?.name}
|
||||
<Button on:click={() => startGame()}>START GAME</Button>
|
||||
{:else}
|
||||
<Button>Ready</Button>
|
||||
<Button disabled>WAIT TO START</Button>
|
||||
{/if}
|
||||
</div>
|
||||
</main>
|
||||
|
|
|
|||
|
|
@ -1,41 +0,0 @@
|
|||
<script>
|
||||
const radius = 10;
|
||||
</script>
|
||||
|
||||
<div class="dice">
|
||||
<svg width="100" height="100" class="front">
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
</svg>
|
||||
<svg width="100" height="100" class="top">
|
||||
<circle cx="33" cy="33" r={radius} fill="black" />
|
||||
<circle cx="66" cy="66" r={radius} fill="black" />
|
||||
</svg>
|
||||
<svg width="100" height="100" class="left">
|
||||
<circle cx="30" cy="30" r={radius} fill="black" />
|
||||
<circle cx="50" cy="50" r={radius} fill="black" />
|
||||
<circle cx="70" cy="70" r={radius} fill="black" />
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
<style>
|
||||
svg {
|
||||
border-radius: 5px;
|
||||
border: 1px solid black;
|
||||
box-shadow: 0 0 2px black;
|
||||
position: absolute;
|
||||
}
|
||||
.front {
|
||||
transform: translateZ(50px);
|
||||
}
|
||||
.top {
|
||||
transform: translateZ(50px) rotateX(90deg);
|
||||
}
|
||||
.left {
|
||||
transform: translateZ(50px) rotateY(-90deg);
|
||||
}
|
||||
.dice {
|
||||
margin-top: 20px;
|
||||
margin-left: 20px;
|
||||
position: relative;
|
||||
}
|
||||
</style>
|
||||
Loading…
Reference in a new issue