Skip to content

Commit

Permalink
Terminate all workflows on start, add demo game
Browse files Browse the repository at this point in the history
  • Loading branch information
Alex-Tideman committed Aug 28, 2024
1 parent a4a0327 commit 040a203
Show file tree
Hide file tree
Showing 10 changed files with 496 additions and 187 deletions.
2 changes: 1 addition & 1 deletion game/src/workflows.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import {

import type * as activities from './activities';

const SNAKE_WORK_DURATION_MS = 1000;
const SNAKE_WORK_DURATION_MS = 50;
const SNAKE_WORKERS_PER_TEAM = 1;
const APPLE_POINTS = 10;

Expand Down
10 changes: 7 additions & 3 deletions snakes/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ button:focus:not(:focus-visible) {

/* Custom CSS */

h1 {
h1, h2 {
font-family: 'VT323', 'Courier New', monospace; /* Retro computer font */
font-size: 3rem;
color: #ff00ff; /* Neon pink */
Expand All @@ -121,7 +121,11 @@ h1 {
z-index: 1;
}

h1::before {
h2 {
font-size: 2rem;
}

h1::before, h2::before {
content: attr(data-text);
position: absolute;
left: 2px;
Expand All @@ -130,7 +134,7 @@ h1::before {
z-index: -1;
}

h1::after {
h1::after, h2::after {
content: attr(data-text);
position: absolute;
left: -2px;
Expand Down
152 changes: 152 additions & 0 deletions snakes/src/lib/pages/DemoRoundPage.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { CELL_SIZE } from '$lib/snake/constants';
import { page } from '$app/stores';
import { io, Socket } from 'socket.io-client';
import type { Snake } from '$lib/snake/types';
import SnakeBody from '$lib/snake/SnakeBody';
$: ({ id: workflowId } = $page.params);
let socket: Socket;
let RoundData;
let SnakeRound;
let SnakeRed1: SnakeBody;
let SnakeRed2: SnakeBody;
let SnakeBlue1: SnakeBody;
let SnakeBlue2: SnakeBody;
let container;
let backgroundCanvas;
let snakeCanvas1;
let snakeCanvas2;
let snakeCanvas3;
let snakeCanvas4;
let width = 100;
let height = 100;
let demoInterval;
function connectSocket() {
socket = io();
socket.on('snakeMoved', (id, segments) => {
if (id === 'red-0') {
SnakeRed1.redraw(segments);
} else if (id === 'red-1') {
SnakeRed2.redraw(segments);
} else if (id === 'blue-0') {
SnakeBlue1.redraw(segments);
} else if (id === 'blue-1') {
SnakeBlue2.redraw(segments);
}
});
socket.on('connect_error', (error) => {
console.error('Socket.io connection error:', error);
setTimeout(connectSocket, 1000);
});
}
const fetchState = async () => {
const response = await fetch('/api/game', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'queryState', workflowId })
});
const result = await response.json();
if (result[0]) {
return result[0];
}
alert('No game state found');
};
onMount(async () => {
const { round, config } = await fetchState();
width = config.width;
height = config.height;
SnakeRound = (await import('$lib/snake/Round')).default;
const cxt = backgroundCanvas.getContext('2d');
demoInterval = setInterval(moveRandomSnake, 50);
const getSnake = (id: string) => {
const snake = round.snakes.find((snake: Snake) => snake.id === id);
return snake
}
// TODO: Make this dynamic based on player count
connectSocket();
RoundData = new SnakeRound(cxt, round, config, socket);
SnakeRed1 = new SnakeBody(RoundData, snakeCanvas1.getContext('2d'), getSnake('red-0'), socket);
SnakeRed2 = new SnakeBody(RoundData, snakeCanvas2.getContext('2d'), getSnake('red-1'), socket);
SnakeBlue1 = new SnakeBody(RoundData, snakeCanvas3.getContext('2d'), getSnake('blue-0'), socket);
SnakeBlue2 = new SnakeBody(RoundData, snakeCanvas4.getContext('2d'), getSnake('blue-1'), socket);
});
const moveRandomSnake = () => {
const snakes = ['red-0', 'red-1', 'blue-0', 'blue-1'];
const direction = ['up', 'down', 'left', 'right'][Math.floor(Math.random() * 4)];
const snake = snakes[Math.floor(Math.random() * snakes.length)];
socket.emit('snakeChangeDirection', snake, direction);
}
onDestroy (() => {
if (socket) {
socket.disconnect();
}
demoInterval = null
});
</script>

<div id="game" bind:this={container}>
<canvas bind:this={backgroundCanvas} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<!-- TODO: Make this dynamic based on player count -->
<canvas bind:this={snakeCanvas1} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<canvas bind:this={snakeCanvas2} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<canvas bind:this={snakeCanvas3} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<canvas bind:this={snakeCanvas4} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<div id="score">
<div id="time" />
<div id="blue" />
<div id="red" />
</div>
</div>

<style>
#game, #game canvas {
position: absolute;
top: 0;
right: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#score {
position: absolute;
top: 0;
right: 0;
padding: 10px;
font-size: 36px;
font-weight: bold;
text-align: center;
background: rgba(0, 0, 0, 0.5);
}
#time {
color: white;
}
#blue {
color: blue;
}
#red {
color: red;
}
</style>
140 changes: 140 additions & 0 deletions snakes/src/lib/pages/SnakeRoundPage.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
<script lang="ts">
import { onDestroy, onMount } from 'svelte';
import { CELL_SIZE } from '$lib/snake/constants';
import { page } from '$app/stores';
import { io, Socket } from 'socket.io-client';
import type { Snake } from '$lib/snake/types';
import SnakeBody from '$lib/snake/SnakeBody';
$: ({ id: workflowId } = $page.params);
let socket: Socket;
let RoundData;
let SnakeRound;
let SnakeRed1: SnakeBody;
let SnakeRed2: SnakeBody;
let SnakeBlue1: SnakeBody;
let SnakeBlue2: SnakeBody;
let container;
let backgroundCanvas;
let snakeCanvas1;
let snakeCanvas2;
let snakeCanvas3;
let snakeCanvas4;
let width = 100;
let height = 100;
function connectSocket() {
socket = io();
socket.on('snakeMoved', (id, segments) => {
if (id === 'red-0') {
SnakeRed1.redraw(segments);
} else if (id === 'red-1') {
SnakeRed2.redraw(segments);
} else if (id === 'blue-0') {
SnakeBlue1.redraw(segments);
} else if (id === 'blue-1') {
SnakeBlue2.redraw(segments);
}
});
socket.on('connect_error', (error) => {
console.error('Socket.io connection error:', error);
setTimeout(connectSocket, 1000);
});
}
const fetchState = async () => {
const response = await fetch('/api/game', {
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ action: 'queryState', workflowId })
});
const result = await response.json();
if (result[0]) {
return result[0];
}
alert('No game state found');
};
onMount(async () => {
const { round, config } = await fetchState();
width = config.width;
height = config.height;
SnakeRound = (await import('$lib/snake/Round')).default;
const cxt = backgroundCanvas.getContext('2d');
const getSnake = (id: string) => {
const snake = round.snakes.find((snake: Snake) => snake.id === id);
return snake
}
// TODO: Make this dynamic based on player count
connectSocket();
RoundData = new SnakeRound(cxt, round, config, socket);
SnakeRed1 = new SnakeBody(RoundData, snakeCanvas1.getContext('2d'), getSnake('red-0'), socket);
SnakeRed2 = new SnakeBody(RoundData, snakeCanvas2.getContext('2d'), getSnake('red-1'), socket);
SnakeBlue1 = new SnakeBody(RoundData, snakeCanvas3.getContext('2d'), getSnake('blue-0'), socket);
SnakeBlue2 = new SnakeBody(RoundData, snakeCanvas4.getContext('2d'), getSnake('blue-1'), socket);
});
onDestroy (() => {
if (socket) {
socket.disconnect();
}
});
</script>

<div id="game" bind:this={container}>
<canvas bind:this={backgroundCanvas} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<!-- TODO: Make this dynamic based on player count -->
<canvas bind:this={snakeCanvas1} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<canvas bind:this={snakeCanvas2} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<canvas bind:this={snakeCanvas3} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<canvas bind:this={snakeCanvas4} width={width * CELL_SIZE} height={height * CELL_SIZE} />
<div id="score">
<div id="time" />
<div id="blue" />
<div id="red" />
</div>
</div>

<style>
#game, #game canvas {
position: absolute;
top: 0;
right: 0;
width: 100vw;
height: 100vh;
overflow: hidden;
}
#score {
position: absolute;
top: 0;
right: 0;
padding: 10px;
font-size: 36px;
font-weight: bold;
text-align: center;
background: rgba(0, 0, 0, 0.5);
}
#time {
color: white;
}
#blue {
color: blue;
}
#red {
color: red;
}
</style>
Loading

0 comments on commit 040a203

Please sign in to comment.