mirror of
https://github.com/thilo-behnke/wasm-pong.git
synced 2026-07-12 11:09:38 +00:00
wip - local session inputs
This commit is contained in:
@@ -2,7 +2,6 @@
|
||||
import {FieldWrapper} from "wasm-app";
|
||||
import Canvas from "./Canvas.svelte";
|
||||
import Fps from "./Fps.svelte";
|
||||
import {keysPressed} from "./game/engine";
|
||||
import Input from "./Input.svelte";
|
||||
import {setContext} from "svelte";
|
||||
import {sessionContext, sessionStore} from "./game/session";
|
||||
@@ -16,20 +15,6 @@
|
||||
|
||||
let debug = false;
|
||||
|
||||
function handleKeydown({key}) {
|
||||
if ($keysPressed.includes(key)) {
|
||||
return;
|
||||
}
|
||||
$keysPressed = [...$keysPressed, key]
|
||||
}
|
||||
|
||||
function handleKeyup({key}) {
|
||||
if (!$keysPressed.includes(key)) {
|
||||
return;
|
||||
}
|
||||
$keysPressed = $keysPressed.filter(key => key !== key)
|
||||
}
|
||||
|
||||
function localSession() {
|
||||
sessionStore.createLocalSession();
|
||||
}
|
||||
@@ -79,13 +64,12 @@
|
||||
</Canvas>
|
||||
<div class="game-area__hud">
|
||||
<GameSettings on:debug-toggle={() => toggleDebug()}></GameSettings>
|
||||
<Input inputs={$keysPressed}></Input>
|
||||
<Input inputs={$sessionStore.inputProvider?.getInputs()}></Input>
|
||||
</div>
|
||||
</div>
|
||||
</NetworkSessionWrapper>
|
||||
{/if}
|
||||
</main>
|
||||
<svelte:window on:keydown={handleKeydown} on:keyup={handleKeyup}/>
|
||||
|
||||
<style>
|
||||
main {
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
engineCtx,
|
||||
height,
|
||||
pixelRatio,
|
||||
playerInputs,
|
||||
props,
|
||||
renderContext,
|
||||
width
|
||||
@@ -79,7 +78,8 @@
|
||||
}
|
||||
|
||||
function tick(dt) {
|
||||
field.tick($playerInputs, dt);
|
||||
const inputs = $session.inputProvider.getInputs();
|
||||
field.tick(inputs, dt);
|
||||
}
|
||||
|
||||
function render(objects, dt) {
|
||||
|
||||
@@ -7,36 +7,13 @@ export const width = writable(800);
|
||||
export const height = writable(600);
|
||||
export const pixelRatio = writable(window.devicePixelRatio);
|
||||
|
||||
export const keysPressed: Writable<string[]> = writable([])
|
||||
|
||||
export const playerInputs = derived(
|
||||
keysPressed,
|
||||
$keysPressed => {
|
||||
return $keysPressed.map(key => {
|
||||
switch(key.toLowerCase()) {
|
||||
case 'w':
|
||||
return {input: 'UP', obj_id: 0, player: 1}
|
||||
case 's':
|
||||
return {input: 'DOWN', obj_id: 0, player: 1}
|
||||
case 'arrowup':
|
||||
return {input: 'UP', obj_id: 1, player: 2}
|
||||
case 'arrowdown':
|
||||
return {input: 'DOWN', obj_id: 1, player: 2}
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}).filter(it => !!it);
|
||||
}
|
||||
)
|
||||
|
||||
// A more convenient store for grabbing all game props
|
||||
export const props = deriveObject({
|
||||
width,
|
||||
height,
|
||||
pixelRatio,
|
||||
engineCanvas,
|
||||
engineCtx,
|
||||
keysPressed
|
||||
engineCtx
|
||||
});
|
||||
|
||||
export const renderContext = Symbol();
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {readable, writable} from "svelte/store";
|
||||
import {get, Readable, readable, writable, derived} from "svelte/store";
|
||||
|
||||
export enum SessionState {
|
||||
PENDING = 'PENDING', RUNNING = 'RUNNING', CLOSED = 'CLOSED'
|
||||
@@ -29,9 +29,74 @@ export type NetworkSession = {
|
||||
|
||||
export type Session = LocalSession | NetworkSession;
|
||||
|
||||
export type Input = {
|
||||
input: 'UP' | 'DOWN',
|
||||
obj_id: number,
|
||||
player: number
|
||||
}
|
||||
|
||||
export interface InputProvider {
|
||||
getInputs(): Input[]
|
||||
}
|
||||
|
||||
// TODO: Not fired.
|
||||
const keysPressed: Readable<string[]> = readable([], function(set) {
|
||||
let keys = [];
|
||||
|
||||
const onKeydown = ({key}) => {
|
||||
if (keys.includes(key)) {
|
||||
return;
|
||||
}
|
||||
keys = [...keys, key];
|
||||
set(keys);
|
||||
}
|
||||
const onKeyup = ({key}) => {
|
||||
if (!keys.includes(key)) {
|
||||
return;
|
||||
}
|
||||
keys = keys.filter(k => k !== key);
|
||||
set(keys);
|
||||
}
|
||||
|
||||
document.addEventListener('keydown', onKeydown);
|
||||
document.addEventListener('keyup', onKeyup);
|
||||
|
||||
return () => {
|
||||
document.removeEventListener('keydown', onKeydown);
|
||||
document.removeEventListener('keyup', onKeyup);
|
||||
}
|
||||
})
|
||||
|
||||
export const localSessionInputs = derived(
|
||||
keysPressed,
|
||||
$keysPressed => {
|
||||
return $keysPressed.map((key): Input => {
|
||||
switch(key.toLowerCase()) {
|
||||
case 'w':
|
||||
return {input: 'UP', obj_id: 0, player: 1};
|
||||
case 's':
|
||||
return {input: 'DOWN', obj_id: 0, player: 1}
|
||||
case 'arrowup':
|
||||
return {input: 'UP', obj_id: 1, player: 2}
|
||||
case 'arrowdown':
|
||||
return {input: 'DOWN', obj_id: 1, player: 2}
|
||||
default:
|
||||
return null
|
||||
}
|
||||
}).filter(it => !!it);
|
||||
}
|
||||
)
|
||||
|
||||
export class LocalSessionInputProvider implements InputProvider {
|
||||
getInputs(): Input[] {
|
||||
return get(localSessionInputs);
|
||||
}
|
||||
}
|
||||
|
||||
export type SessionStore = {
|
||||
session?: Session,
|
||||
sessionType?: SessionType
|
||||
sessionType?: SessionType,
|
||||
inputProvider?: InputProvider
|
||||
}
|
||||
|
||||
export const sessionContext = Symbol();
|
||||
@@ -39,7 +104,8 @@ export const sessionContext = Symbol();
|
||||
function initialValue(): SessionStore {
|
||||
return {
|
||||
session: null,
|
||||
sessionType: null
|
||||
sessionType: null,
|
||||
inputProvider: null
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,10 +114,26 @@ function makeSessionStore() {
|
||||
|
||||
return {
|
||||
subscribe,
|
||||
createLocalSession: () => update(() => ({session: {state: SessionState.RUNNING}})),
|
||||
createNetworkSession: () => createSession().then(session => update(() => ({session, sessionType: SessionType.HOST}))),
|
||||
joinNetworkSession: (sessionId) => joinSession(sessionId).then(session => update(() => ({session, sessionType: SessionType.PEER}))),
|
||||
watchNetworkSession: (sessionId) => watchSession(sessionId).then(session => update(() => ({session, sessionType: SessionType.OBSERVER}))),
|
||||
createLocalSession: () => update(() => ({
|
||||
session: {state: SessionState.RUNNING},
|
||||
sessionType: SessionType.LOCAL,
|
||||
inputProvider: new LocalSessionInputProvider()
|
||||
})),
|
||||
createNetworkSession: () => createSession().then(session => update(() => ({
|
||||
session,
|
||||
sessionType: SessionType.HOST,
|
||||
inputProvider: new LocalSessionInputProvider()
|
||||
}))),
|
||||
joinNetworkSession: (sessionId) => joinSession(sessionId).then(session => update(() => ({
|
||||
session,
|
||||
sessionType: SessionType.PEER,
|
||||
inputProvider: new LocalSessionInputProvider()
|
||||
}))),
|
||||
watchNetworkSession: (sessionId) => watchSession(sessionId).then(session => update(() => ({
|
||||
session,
|
||||
sessionType: SessionType.OBSERVER,
|
||||
inputProvider: new LocalSessionInputProvider()
|
||||
}))),
|
||||
reset: () => set(initialValue())
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user