Skip to content

Commit fbcec6a

Browse files
committed
update multiplayer and packages
1 parent dbe15f3 commit fbcec6a

File tree

5 files changed

+55
-78
lines changed

5 files changed

+55
-78
lines changed

README.md

+16
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,19 @@ This library is still unstable.
88

99
# Demo
1010
[Demo](https://ygongdev.github.io/jigsaw-canvas/demo)
11+
12+
# Multiplayer Demo (Local Build)
13+
14+
## Install
15+
1. `yarn install`
16+
17+
## Start client server
18+
1. Make sure you're at the `jigsaw-canvas` root directory
19+
2. `npx live-server --host=localhost`
20+
3. Navigate to `localhost:<port>/multiplayer-demo/client` in the browser. `<port>` is whatever the `live-server` is running on, e.g `8080`
21+
22+
## Start backend server
23+
1. `cd multiplayer-demo/server`
24+
2. `npx nodemon server.js`
25+
26+
Open another browser with the same url and you should see real time sync when moving pieces.

multiplayer-demo/client/index.js

+31-12
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ class ServerPuzzleState {
3535

3636
const canvas = document.getElementById('original');
3737
const container = document.getElementById("result");
38+
const playground = document.querySelector('#playground');
39+
3840
let clientPuzzle;
3941
let isDown;
4042
let metadata;
@@ -50,7 +52,6 @@ init().then(puzzle => {
5052
})
5153
);
5254
const serverGameState = new GameState(serverPuzzle);
53-
console.log(serverGameState);
5455
socket.emit('start', serverGameState);
5556
});
5657

@@ -62,7 +63,7 @@ async function init() {
6263
canvas.width = img.width;
6364
canvas.height = img.height;
6465
const context = canvas.getContext('2d');
65-
context.drawImage(img, 0, 0, canvas.width, canvas.height);
66+
// context.drawImage(img, 0, 0, canvas.width, canvas.height);
6667

6768
// Creating the puzzle pieces
6869
const puzzle = await generatePuzzle(img, 25, 25);
@@ -75,7 +76,6 @@ async function init() {
7576
return img;
7677
});
7778

78-
// shuffle(puzzlePieces);
7979
const fragment = document.createDocumentFragment();
8080
puzzlePieces.forEach(piece => {
8181
piece.classList.add("puzzle-piece")
@@ -97,13 +97,13 @@ async function init() {
9797
});
9898

9999
['mousedown', 'touchstart'].forEach(listener => piece.addEventListener(listener, (event) => {
100-
const x = event.clientX || event.touches[0].pageX;
101-
const y = event.clientY || event.touches[0].pageY;
102-
console.log('touchstart');
103100
if (isDown) {
104101
return;
105102
}
106103

104+
let x = event.clientX || event.touches[0].pageX;
105+
let y = event.clientY || event.touches[0].pageY;
106+
107107
isDown = true;
108108
metadata = {
109109
idx,
@@ -115,21 +115,39 @@ async function init() {
115115
}, { passive: false}));
116116
});
117117

118-
['mouseup', 'touchend'].forEach(listener => container.addEventListener(listener, function() {
119-
console.log('touchend');
118+
['mouseup', 'touchend'].forEach(listener => playground.addEventListener(listener, function() {
120119
isDown = false;
121120
metadata = undefined;
122121
}, { passive: false }));
123122

124-
['mousemove', 'touchmove'].forEach(listener => container.addEventListener(listener, (event) => {
123+
['mousemove', 'touchmove'].forEach(listener => playground.addEventListener(listener, (event) => {
125124
event.preventDefault();
126-
console.log(isDown);
127125
if (isDown) {
128126
const piece = puzzlePieces[metadata.idx];
129127
const x = event.clientX || event.touches[0].pageX;
130128
const y = event.clientY || event.touches[0].pageY;
131-
const newX = x + metadata.offset[0];
132-
const newY = y + metadata.offset[1];
129+
let newX = x + metadata.offset[0];
130+
let newY = y + metadata.offset[1];
131+
132+
// Prevent dragging outside of playground boundary.
133+
const playgroundBoundaries = {
134+
minX: playground.offsetLeft,
135+
maxX: playground.offsetLeft + playground.offsetWidth - piece.offsetWidth,
136+
minY: playground.offsetTop,
137+
maxY: playground.offsetTop + playground.offsetHeight - piece.offsetHeight,
138+
}
139+
140+
if (newX < playgroundBoundaries.minX) {
141+
newX = playgroundBoundaries.minX;
142+
} else if (newX > playgroundBoundaries.maxX) {
143+
newX = playgroundBoundaries.maxX;
144+
}
145+
146+
if (newY < playgroundBoundaries.minY) {
147+
newY = playgroundBoundaries.minY;
148+
} else if (newY > playgroundBoundaries.maxY) {
149+
newY = playgroundBoundaries.maxY;
150+
}
133151

134152
piece.style.left = `${newX}px`;
135153
piece.style.top = `${newY}px`;
@@ -148,6 +166,7 @@ function render(gameState) {
148166
const sp = serverPuzzle[i];
149167
const cp = clientPuzzle[i];
150168

169+
// If the client state already matches, don't need to
151170
if (metadata?.idx === i) {
152171
return;
153172
}

multiplayer-demo/server/server.js

+3-6
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,23 @@ const io = require('socket.io')(3000, {
55
});
66

77
let state = {};
8-
let payload = {};
98

109
io.on('connection', client => {
11-
console.log('connected')
1210
client.on('start', handleStart);
1311
client.on('move', handleMove);
1412

15-
1613
function handleStart(gameState) {
1714
state = gameState;
1815
startGameInterval(client);
1916
}
2017

2118
function handleMove({ idx, x, y}) {
22-
console.log(...arguments);
23-
state.puzzle[idx].x = x;
24-
state.puzzle[idx].y = y;
19+
state.puzzle[idx].x = x;
20+
state.puzzle[idx].y = y;
2521
}
2622
});
2723

24+
2825
function startGameInterval(client) {
2926
const intervalId = setInterval(() => {
3027
client.emit('gameState', JSON.stringify(state));

package.json

+4-6
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,10 @@
1010
"release": "release-it"
1111
},
1212
"devDependencies": {
13-
"release-it": "^14.10.0"
14-
},
15-
"dependencies": {
1613
"express": "^4.17.1",
1714
"http": "^0.0.1-security",
18-
"socket.io": "^4.1.3",
19-
"socket.io-client": "^4.1.3"
20-
}
15+
"release-it": "^14.10.0",
16+
"socket.io": "^4.1.3"
17+
},
18+
"dependencies": {}
2119
}

yarn.lock

+1-54
Original file line numberDiff line numberDiff line change
@@ -301,11 +301,6 @@ asynckit@^0.4.0:
301301
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
302302
integrity sha1-x57Zf380y48robyXkLzDZkdLS3k=
303303

304-
backo2@~1.0.2:
305-
version "1.0.2"
306-
resolved "https://registry.yarnpkg.com/backo2/-/backo2-1.0.2.tgz#31ab1ac8b129363463e35b3ebb69f4dfcfba7947"
307-
integrity sha1-MasayLEpNjRj41s+u2n038+6eUc=
308-
309304
balanced-match@^1.0.0:
310305
version "1.0.2"
311306
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.2.tgz#e83e3a7e3f300b34cb9d87f615fa0cbf357690ee"
@@ -762,22 +757,7 @@ end-of-stream@^1.1.0:
762757
dependencies:
763758
once "^1.4.0"
764759

765-
engine.io-client@~5.1.2:
766-
version "5.1.2"
767-
resolved "https://registry.yarnpkg.com/engine.io-client/-/engine.io-client-5.1.2.tgz#27108da9b39ae03262443d945caf2caa3655c4cb"
768-
integrity sha512-blRrgXIE0A/eurWXRzvfCLG7uUFJqfTGFsyJzXSK71srMMGJ2VraBLg8Mdw28uUxSpVicepBN9X7asqpD1mZcQ==
769-
dependencies:
770-
base64-arraybuffer "0.1.4"
771-
component-emitter "~1.3.0"
772-
debug "~4.3.1"
773-
engine.io-parser "~4.0.1"
774-
has-cors "1.1.0"
775-
parseqs "0.0.6"
776-
parseuri "0.0.6"
777-
ws "~7.4.2"
778-
yeast "0.1.2"
779-
780-
engine.io-parser@~4.0.0, engine.io-parser@~4.0.1:
760+
engine.io-parser@~4.0.0:
781761
version "4.0.2"
782762
resolved "https://registry.yarnpkg.com/engine.io-parser/-/engine.io-parser-4.0.2.tgz#e41d0b3fb66f7bf4a3671d2038a154024edb501e"
783763
integrity sha512-sHfEQv6nmtJrq6TKuIz5kyEKH/qSdK56H/A+7DnAuUPWosnIZAS2NHNcPLmyjtY3cGS/MqJdZbUjW97JU72iYg==
@@ -1111,11 +1091,6 @@ graceful-fs@^4.1.2:
11111091
resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.2.6.tgz#ff040b2b0853b23c3d31027523706f1885d76bee"
11121092
integrity sha512-nTnJ528pbqxYanhpDYsi4Rd8MAeaBA67+RZ10CM1m3bTAVFEDcd5AuA4a6W5YkGZ1iNXHzZz8T6TBKLeBuNriQ==
11131093

1114-
has-cors@1.1.0:
1115-
version "1.1.0"
1116-
resolved "https://registry.yarnpkg.com/has-cors/-/has-cors-1.1.0.tgz#5e474793f7ea9843d1bb99c23eef49ff126fff39"
1117-
integrity sha1-XkdHk/fqmEPRu5nCPu9J/xJv/zk=
1118-
11191094
has-flag@^3.0.0:
11201095
version "3.0.0"
11211096
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
@@ -1779,16 +1754,6 @@ parse-url@^6.0.0:
17791754
parse-path "^4.0.0"
17801755
protocols "^1.4.0"
17811756

1782-
parseqs@0.0.6:
1783-
version "0.0.6"
1784-
resolved "https://registry.yarnpkg.com/parseqs/-/parseqs-0.0.6.tgz#8e4bb5a19d1cdc844a08ac974d34e273afa670d5"
1785-
integrity sha512-jeAGzMDbfSHHA091hr0r31eYfTig+29g3GKKE/PPbEQ65X0lmMwlEoqmhzu0iztID5uJpZsFlUPDP8ThPL7M8w==
1786-
1787-
parseuri@0.0.6:
1788-
version "0.0.6"
1789-
resolved "https://registry.yarnpkg.com/parseuri/-/parseuri-0.0.6.tgz#e1496e829e3ac2ff47f39a4dd044b32823c4a25a"
1790-
integrity sha512-AUjen8sAkGgao7UyCX6Ahv0gIK2fABKmYjvP4xmy5JaKvcbTRueIqIPHLAfq30xJddqSE033IOMUSOMCcK3Sow==
1791-
17921757
parseurl@~1.3.3:
17931758
version "1.3.3"
17941759
resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.3.tgz#9da19e7bee8d12dff0513ed5b76957793bc2e8d4"
@@ -2170,19 +2135,6 @@ socket.io-adapter@~2.3.1:
21702135
resolved "https://registry.yarnpkg.com/socket.io-adapter/-/socket.io-adapter-2.3.1.tgz#a442720cb09a4823cfb81287dda1f9b52d4ccdb2"
21712136
integrity sha512-8cVkRxI8Nt2wadkY6u60Y4rpW3ejA1rxgcK2JuyIhmF+RMNpTy1QRtkHIDUOf3B4HlQwakMsWbKftMv/71VMmw==
21722137

2173-
socket.io-client@^4.1.3:
2174-
version "4.1.3"
2175-
resolved "https://registry.yarnpkg.com/socket.io-client/-/socket.io-client-4.1.3.tgz#236daa642a9f229932e00b7221e843bf74232a62"
2176-
integrity sha512-hISFn6PDpgDifVUiNklLHVPTMv1LAk8poHArfIUdXa+gKgbr0MZbAlquDFqCqsF30yBqa+jg42wgos2FK50BHA==
2177-
dependencies:
2178-
"@types/component-emitter" "^1.2.10"
2179-
backo2 "~1.0.2"
2180-
component-emitter "~1.3.0"
2181-
debug "~4.3.1"
2182-
engine.io-client "~5.1.2"
2183-
parseuri "0.0.6"
2184-
socket.io-parser "~4.0.4"
2185-
21862138
socket.io-parser@~4.0.4:
21872139
version "4.0.4"
21882140
resolved "https://registry.yarnpkg.com/socket.io-parser/-/socket.io-parser-4.0.4.tgz#9ea21b0d61508d18196ef04a2c6b9ab630f4c2b0"
@@ -2490,11 +2442,6 @@ yargs-parser@20.2.7:
24902442
resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-20.2.7.tgz#61df85c113edfb5a7a4e36eb8aa60ef423cbc90a"
24912443
integrity sha512-FiNkvbeHzB/syOjIUxFDCnhSfzAL8R5vs40MgLFBorXACCOAEaWu0gRZl14vG8MR9AOJIZbmkjhusqBYZ3HTHw==
24922444

2493-
yeast@0.1.2:
2494-
version "0.1.2"
2495-
resolved "https://registry.yarnpkg.com/yeast/-/yeast-0.1.2.tgz#008e06d8094320c372dbc2f8ed76a0ca6c8ac419"
2496-
integrity sha1-AI4G2AlDIMNy28L47XagymyKxBk=
2497-
24982445
yocto-queue@^0.1.0:
24992446
version "0.1.0"
25002447
resolved "https://registry.yarnpkg.com/yocto-queue/-/yocto-queue-0.1.0.tgz#0294eb3dee05028d31ee1a5fa2c556a6aaf10a1b"

0 commit comments

Comments
 (0)