some improvements :D

This commit is contained in:
Zutatensuppe 2020-11-07 16:33:28 +01:00
parent 426c8578e5
commit 61837a155f
3 changed files with 180 additions and 176 deletions

View file

@ -56,7 +56,6 @@ export default class WsClient extends WsWrapper {
return return
} }
console.log(`ws dispatch ${type} ${tag}`)
for (const callback of callbacks) { for (const callback of callbacks) {
callback(...args) callback(...args)
} }

View file

@ -252,25 +252,19 @@ function getSurroundingTilesByIdx(puzzle, idx) {
] ]
} }
function determinePuzzleTileShapes (tiles, info) { function determinePuzzleTileShapes (info) {
var tabs = [-1, 1] const tabs = [-1, 1]
for (let IDX in tiles) {
var _X = info.coords[IDX].x
var _Y = info.coords[IDX].y
var topTab = _Y === 0 ? 0 : tiles[IDX - info.tiles_x].tabs.bottom * -1; const shapes = new Array(info.tiles)
var rightTab = _X === info.tiles_x -1 ? 0 : choice(tabs) for (let i = 0; i < info.tiles; i++) {
var leftTab = _X === 0 ? 0 : tiles[IDX - 1].tabs.right * -1 shapes[i] = {
var bottomTab = _Y === info.tiles_y -1 ? 0 : choice(tabs) top: info.coords[i].y === 0 ? 0 : shapes[i - info.tiles_x].bottom * -1,
right: info.coords[i].x === info.tiles_x -1 ? 0 : choice(tabs),
tiles[IDX].tabs = { left: info.coords[i].x === 0 ? 0 : shapes[i - 1].right * -1,
top: topTab, bottom: info.coords[i].y === info.tiles_y -1 ? 0 : choice(tabs),
right: rightTab,
left: leftTab,
bottom: bottomTab,
} }
} }
return tiles return shapes
} }
async function createPuzzleTileBitmaps (bitmap, tiles, info) { async function createPuzzleTileBitmaps (bitmap, tiles, info) {
@ -296,10 +290,10 @@ async function createPuzzleTileBitmaps (bitmap, tiles, info) {
let ctx = c.getContext('2d') let ctx = c.getContext('2d')
ctx.clearRect(0, 0,tileDrawSize, tileDrawSize) ctx.clearRect(0, 0,tileDrawSize, tileDrawSize)
var topTab = tile.tabs.top var topTab = info.shapes[tile.idx].top
var rightTab = tile.tabs.right var rightTab = info.shapes[tile.idx].right
var leftTab = tile.tabs.left var leftTab = info.shapes[tile.idx].left
var bottomTab = tile.tabs.bottom var bottomTab = info.shapes[tile.idx].bottom
var topLeftEdge = new Point(tileMarginWidth, tileMarginWidth); var topLeftEdge = new Point(tileMarginWidth, tileMarginWidth);
ctx.save(); ctx.save();
@ -436,7 +430,7 @@ const unfinishedTileByPos = (puzzle, pos) => {
let tileIdx = -1 let tileIdx = -1
for (let idx = 0; idx < puzzle.tiles.length; idx++) { for (let idx = 0; idx < puzzle.tiles.length; idx++) {
let tile = puzzle.tiles[idx] let tile = puzzle.tiles[idx]
if (tile.finished) { if (tile.owner === -1) {
continue continue
} }
@ -470,7 +464,7 @@ async function loadPuzzleBitmaps(puzzle) {
return bitmaps return bitmaps
} }
async function loadPuzzle(targetTiles, imageUrl) { async function createPuzzle(targetTiles, imageUrl) {
// load bitmap, to determine the original size of the image // load bitmap, to determine the original size of the image
let bitmpTmp = await loadImageToBitmap(imageUrl) let bitmpTmp = await loadImageToBitmap(imageUrl)
@ -483,7 +477,7 @@ async function loadPuzzle(targetTiles, imageUrl) {
idx: i, idx: i,
} }
} }
tiles = await determinePuzzleTileShapes(tiles, info) const shapes = determinePuzzleTileShapes(info)
// Complete puzzle object // Complete puzzle object
const p = { const p = {
@ -493,8 +487,10 @@ async function loadPuzzle(targetTiles, imageUrl) {
idx: tile.idx, // index of tile in the array idx: tile.idx, // index of tile in the array
group: 0, // if grouped with other tiles group: 0, // if grouped with other tiles
z: 0, // z index of the tile z: 0, // z index of the tile
finished: false, // if the tile is in its final position owner: 0, // who owns the tile
tabs: tile.tabs, // tabs :) // 0 = free for taking
// -1 = finished
// other values: id of player who has the tile
// physical current position of the tile (x/y in pixels) // physical current position of the tile (x/y in pixels)
// this position is the initial position only and is the // this position is the initial position only and is the
// value that changes when moving a tile // value that changes when moving a tile
@ -505,7 +501,14 @@ async function loadPuzzle(targetTiles, imageUrl) {
}, },
} }
}), }),
// extra puzzle information // game data for puzzle, data changes during the game
data: {
// TODO: maybe calculate this each time?
maxZ: 0, // max z of all pieces
maxGroup: 0, // max group of all pieces
},
// static puzzle information. stays same for complete duration of
// the game
info: { info: {
// information that was used to create the puzzle // information that was used to create the puzzle
targetTiles: targetTiles, targetTiles: targetTiles,
@ -530,6 +533,7 @@ async function loadPuzzle(targetTiles, imageUrl) {
// the tile_coordinate // the tile_coordinate
// this can be used to determine where the // this can be used to determine where the
// final destination of a tile is // final destination of a tile is
shapes: shapes, // tile shapes
}, },
} }
return p return p
@ -561,13 +565,13 @@ async function main () {
// todo: maybe put in protocols, same as `me()` // todo: maybe put in protocols, same as `me()`
let gameId = 'asdfbla' // uniqId() let gameId = 'asdfbla' // uniqId()
let me = initme() let me = initme()
const player = {x: 0, y: 0, down: false}
let conn = setupNetwork(me + '|' + gameId) let conn = setupNetwork(me + '|' + gameId)
conn.send(JSON.stringify({type: 'init'})) conn.send(JSON.stringify({type: 'init', player}))
conn.onSocket('message', async ({data}) => { conn.onSocket('message', async ({data}) => {
const d = JSON.parse(data) const d = JSON.parse(data)
let puzzle let puzzle
console.log(d)
if (d.type === 'init') { if (d.type === 'init') {
if (d.puzzle) { if (d.puzzle) {
puzzle = d.puzzle puzzle = d.puzzle
@ -576,26 +580,25 @@ async function main () {
// The game doesnt exist yet on the server, so load puzzle // The game doesnt exist yet on the server, so load puzzle
// and then give the server some info about the puzzle // and then give the server some info about the puzzle
// Load puzzle and determine information about it // Load puzzle and determine information about it
console.log(puzzle) // TODO: move puzzle creation to server
puzzle = await loadPuzzle(TARGET_TILES, IMAGE_URL) puzzle = await createPuzzle(TARGET_TILES, IMAGE_URL)
conn.send(JSON.stringify({ conn.send(JSON.stringify({
type: 'init_puzzle', type: 'init_puzzle',
puzzle: puzzle, puzzle: puzzle,
})) }))
console.log('loaded from local config') console.log('loaded from local config')
} }
console.log(puzzle)
console.log('the puzzle ', puzzle)
let bitmaps = await loadPuzzleBitmaps(puzzle) let bitmaps = await loadPuzzleBitmaps(puzzle)
startGame(puzzle, bitmaps, conn) startGame(puzzle, bitmaps, conn)
} else { } else {
console.log(d) // console.log(d)
} }
}) })
const _STATE = { const _STATE = {
m_x: 0, changes: [],
m_y: 0,
m_d: false,
} }
let _STATE_CHANGED = false let _STATE_CHANGED = false
@ -623,20 +626,46 @@ async function main () {
conn.onSocket('message', ({data}) => { conn.onSocket('message', ({data}) => {
const d = JSON.parse(data) const d = JSON.parse(data)
if (d.type === 'tile_changed' && d.origin !== me) { if (d.type === 'state_changed' && d.origin !== me) {
updateDrawMinMax(puzzle.tiles[d.idx].pos, puzzle.info.tileDrawSize) for (let change of d.changes) {
switch (change.type) {
case 'change_tile': {
updateDrawMinMax(puzzle.tiles[change.tile.idx].pos, puzzle.info.tileDrawSize)
puzzle.tiles[d.idx].pos = {x: d.pos.x, y: d.pos.y} puzzle.tiles[change.tile.idx] = change.tile
puzzle.tiles[d.idx].z = d.z
puzzle.tiles[d.idx].group = d.group
puzzle.tiles[d.idx].finished = d.finished
updateDrawMinMax(puzzle.tiles[d.idx].pos, puzzle.info.tileDrawSize) updateDrawMinMax(puzzle.tiles[change.tile.idx].pos, puzzle.info.tileDrawSize)
} break;
case 'change_data': {
puzzle.data = change.data
} break;
}
}
} }
}) })
console.log(puzzle) const changePlayer = (change) => {
for (let k of Object.keys(change)) {
player[k] = change[k]
}
_STATE.changes.push({type: 'change_player', player: player})
_STATE_CHANGED = true
}
const changeData = (change) => {
for (let k of Object.keys(change)) {
puzzle.data[k] = change[k]
}
_STATE.changes.push({type: 'change_data', data: puzzle.data})
_STATE_CHANGED = true
}
const changeTile = (t, change) => {
for (let k of Object.keys(change)) {
t[k] = change[k]
}
_STATE.changes.push({type: 'change_tile', tile: t})
_STATE_CHANGED = true
}
// Create a dom and attach adapters to it so we can work with it // Create a dom and attach adapters to it so we can work with it
const canvas = addCanvasToDom(createCanvas()) const canvas = addCanvasToDom(createCanvas())
@ -656,9 +685,6 @@ async function main () {
// Information about what tile is the player currently grabbing // Information about what tile is the player currently grabbing
let grabbingTileIdx = -1 let grabbingTileIdx = -1
let maxZ = 0
let maxGroup = 0
// The actual place for the puzzle. The tiles may // The actual place for the puzzle. The tiles may
// not be moved around infinitely, just on the (invisible) // not be moved around infinitely, just on the (invisible)
// puzzle table. however, the camera may move away from the table // puzzle table. however, the camera may move away from the table
@ -687,7 +713,7 @@ async function main () {
// --------------------------------------------------------------- // ---------------------------------------------------------------
// get all grouped tiles for a tile // get all grouped tiles for a tile
function getGroupedTiles (tile) { function getGroupedTiles(tile) {
let grouped = [] let grouped = []
if (tile.group) { if (tile.group) {
for (let other of puzzle.tiles) { for (let other of puzzle.tiles) {
@ -716,16 +742,17 @@ async function main () {
} else if (other.group) { } else if (other.group) {
targetGroup = other.group targetGroup = other.group
} else { } else {
maxGroup++ changeData({ maxGroup: puzzle.data.maxGroup + 1 })
targetGroup = maxGroup targetGroup = puzzle.data.maxGroup
} }
tile.group = targetGroup
other.group = targetGroup changeTile(tile, { group: targetGroup })
changeTile(other, { group: targetGroup })
if (searchGroups.length > 0) { if (searchGroups.length > 0) {
for (let tmp of puzzle.tiles) { for (let tmp of puzzle.tiles) {
if (searchGroups.includes(tmp.group)) { if (searchGroups.includes(tmp.group)) {
tmp.group = targetGroup changeTile(tmp, { group: targetGroup })
} }
} }
} }
@ -763,31 +790,24 @@ async function main () {
} }
const setGroupedZIndex = (tile, zIndex) => { const setGroupedZIndex = (tile, zIndex) => {
for(let t of getGroupedTiles(tile)) { for (let t of getGroupedTiles(tile)) {
t.z = zIndex changeTile(t, { z: zIndex })
}
}
conn.send(JSON.stringify({ const setGroupedOwner = (tile, owner) => {
type: 'change_tile', for (let t of getGroupedTiles(tile)) {
idx: t.idx, // may only change own tiles or untaken tiles
pos: t.pos, if (t.owner === me || t.owner === 0) {
z: t.z, changeTile(t, { owner: owner })
group: t.group, }
finished: t.finished,
}))
} }
} }
const moveGroupedTilesDiff = (tile, diffX, diffY) => { const moveGroupedTilesDiff = (tile, diffX, diffY) => {
for (let t of getGroupedTiles(tile)) { for (let t of getGroupedTiles(tile)) {
t.pos = pointAdd(t.pos, {x: diffX, y: diffY}) changeTile(t, { pos: pointAdd(t.pos, { x: diffX, y: diffY }) })
conn.send(JSON.stringify({
type: 'change_tile',
idx: t.idx,
pos: t.pos,
z: t.z,
finished: t.finished,
}))
// TODO: instead there could be a function to // TODO: instead there could be a function to
// get min/max x/y of a group // get min/max x/y of a group
updateDrawMinMax(tileCenterPos(t), puzzle.info.tileDrawSize) updateDrawMinMax(tileCenterPos(t), puzzle.info.tileDrawSize)
@ -799,15 +819,7 @@ async function main () {
} }
const finishGroupedTiles = (tile) => { const finishGroupedTiles = (tile) => {
for (let t of getGroupedTiles(tile)) { for (let t of getGroupedTiles(tile)) {
t.finished = true changeTile(t, {owner: -1, z: 1})
t.z = 1
conn.send(JSON.stringify({
type: 'change_tile',
idx: t.idx,
pos: t.pos,
z: t.z,
finished: t.finished,
}))
} }
} }
// --------------------------------------------------------------- // ---------------------------------------------------------------
@ -831,16 +843,12 @@ async function main () {
for (let mouse of evts.consumeAll()) { for (let mouse of evts.consumeAll()) {
if (mouse.type === 'move') { if (mouse.type === 'move') {
const tp = cam.translateMouse(mouse) const tp = cam.translateMouse(mouse)
_STATE.m_x = tp.x changePlayer({x: tp.x, y: tp.y})
_STATE.m_y = tp.y
_STATE_CHANGED = true
} }
if (mouse.type === 'down') { if (mouse.type === 'down') {
_STATE.m_d = true changePlayer({down: true})
_STATE_CHANGED = true
} else if (mouse.type === 'up') { } else if (mouse.type === 'up') {
_STATE.m_d = false changePlayer({down: false})
_STATE_CHANGED = true
} }
if (mouse.type === 'wheel') { if (mouse.type === 'wheel') {
if (mouse.y < 0) { if (mouse.y < 0) {
@ -864,8 +872,9 @@ async function main () {
grabbingTileIdx = unfinishedTileByPos(puzzle, tp) grabbingTileIdx = unfinishedTileByPos(puzzle, tp)
console.log(grabbingTileIdx) console.log(grabbingTileIdx)
if (grabbingTileIdx >= 0) { if (grabbingTileIdx >= 0) {
maxZ++ changeData({maxZ: puzzle.data.maxZ + 1})
setGroupedZIndex(puzzle.tiles[grabbingTileIdx], maxZ) setGroupedZIndex(puzzle.tiles[grabbingTileIdx], puzzle.data.maxZ)
setGroupedOwner(puzzle.tiles[grabbingTileIdx], me)
} }
console.log('down', tp) console.log('down', tp)
@ -880,6 +889,7 @@ async function main () {
// location // location
let tile = puzzle.tiles[grabbingTileIdx] let tile = puzzle.tiles[grabbingTileIdx]
setGroupedOwner(tile, 0)
let pt = pointSub(tile.pos, boardPos) let pt = pointSub(tile.pos, boardPos)
let dst = tileRectByPos(pt) let dst = tileRectByPos(pt)
let srcRect = srcRectByIdx(puzzle.info, grabbingTileIdx) let srcRect = srcRectByIdx(puzzle.info, grabbingTileIdx)
@ -907,7 +917,7 @@ async function main () {
] ]
const check = (t, off, other) => { const check = (t, off, other) => {
if (snapped || !other || other.finished || areGrouped(t, other)) { if (snapped || !other || (other.owner === -1) || areGrouped(t, other)) {
return return
} }
let trec_ = tileRectByTile(t) let trec_ = tileRectByTile(t)
@ -1003,6 +1013,7 @@ async function main () {
type: 'state', type: 'state',
state: _STATE, state: _STATE,
})) }))
_STATE.changes = []
_STATE_CHANGED = false _STATE_CHANGED = false
} }
} }

View file

@ -26,8 +26,6 @@ app.use('/', (req, res, next) => {
}) })
app.listen(port, hostname, () => console.log(`server running on http://${hostname}:${port}`)) app.listen(port, hostname, () => console.log(`server running on http://${hostname}:${port}`))
const players = {}
const games = {} const games = {}
const wss = new WebSocketServer(config.ws); const wss = new WebSocketServer(config.ws);
@ -47,42 +45,38 @@ wss.on('message', ({socket, data}) => {
switch (parsed.type) { switch (parsed.type) {
case 'init': { case 'init': {
// a new player (or previous player) joined // a new player (or previous player) joined
players[uid] = players[uid] || {} games[gid] = games[gid] || {puzzle: null, players: {}}
players[uid].id = uid
players[uid].tiles = players[uid].tiles || 0 games[gid].players[uid] = parsed.player
players[uid].m_x = players[uid].x || null
players[uid].m_y = players[uid].y || null wss.notifyOne({
players[uid].m_d = false type: 'init',
console.log('init', players) puzzle: games[gid].puzzle,
const puzzle = games[gid] ? games[gid].puzzle : null players: games[gid].players,
console.log('init', games[gid]) }, socket)
wss.notifyOne({type: 'init', puzzle: puzzle}, socket)
} break; } break;
// new puzzle was created and sent to us
case 'init_puzzle': { case 'init_puzzle': {
games[gid] = { games[gid].puzzle = parsed.puzzle
puzzle: parsed.puzzle,
}
} break; } break;
// somebody has changed the state
case 'state': { case 'state': {
players[uid].m_x = parsed.state.m_x for (let change of parsed.state.changes) {
players[uid].m_y = parsed.state.m_y switch (change.type) {
players[uid].m_d = parsed.state.m_d case 'change_player': {
games[gid].players[uid] = change.player
} break; } break;
case 'change_tile': { case 'change_tile': {
let idx = parsed.idx games[gid].puzzle.tiles[change.tile.idx] = change.tile
let z = parsed.z } break;
let finished = parsed.finished case 'change_data': {
let pos = { x: parsed.pos.x, y: parsed.pos.y } games[gid].puzzle.data = change.data
let group = parsed.group } break;
// games[gid].puzzle.tiles[idx] = games[gid].puzzle.tiles[idx] || {} }
games[gid].puzzle.tiles[idx].pos = pos }
games[gid].puzzle.tiles[idx].z = z notify({type:'state_changed', origin: uid, changes: parsed.state.changes})
games[gid].puzzle.tiles[idx].finished = finished
games[gid].puzzle.tiles[idx].group = group
notify({type:'tile_changed', origin: uid, idx, pos, z, finished, group})
} break; } break;
} }
} catch (e) { } catch (e) {