Last active
September 9, 2021 17:45
-
-
Save john-diaz/7417d3edec69c903ab61dae09f760edc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* | |
Game loop for my game "GrandQuest" | |
Written by John S. Diaz 2019 | |
*/ | |
update() { | |
const scene: Scene = game.scene.scenes[0]; | |
if (!global.gameInitialized) { | |
return; | |
} | |
const networkGameState = store.state.combatGame.gameState; | |
/* | |
GAME LOGIC | |
*/ | |
global.gameState.queuedEvents = [...networkGameState.queuedEvents]; | |
/* Level updating / rendering */ | |
// if we are on a different level than on the network | |
if (global.gameState.level !== networkGameState.level && networkGameState.level !== -1) { | |
// update the level locally | |
global.gameState.level = networkGameState.level; | |
// despawn all the characters | |
_.forEach({...global.gameState.players, ...global.gameState.enemies}, (c) => { | |
actions.despawnCharacter(c.id); | |
}); | |
// load the scene | |
actions.startLevel(global.gameState.level); | |
} | |
// generate user placing line | |
if (networkGameState.maxPlayers !== Object.keys(global.playerPlacingLine).length) { | |
// reset players on local state | |
global.gameState.players = {}; | |
// generate empty placing line withing range | |
global.playerPlacingLine = _.reduce(_.range(1, networkGameState.maxPlayers + 1), (memo: object, index: number) => ({ | |
...memo, | |
[String(index)]: { | |
get character() { | |
return null; | |
}, | |
nextIndex: index >= networkGameState.maxPlayers ? 1 : index + 1, | |
index, | |
prevIndex: index === 1 ? networkGameState.maxPlayers : index - 1, | |
}, | |
}), {}); | |
} | |
// generate enemy placing line | |
if (Object.keys(networkGameState.enemies).length !== Object.keys(global.enemyPlacingLine).length) { | |
// despawn any players that could be on it | |
global.gameState.enemies = {}; | |
// generate empty placing line withing range | |
global.enemyPlacingLine = _.reduce(_.range(1, Object.keys(networkGameState.enemies).length + 1), (memo: object, index: number) => ({ | |
...memo, | |
[String(index)]: { | |
get character() { | |
return null; | |
}, | |
nextIndex: index >= Object.keys(networkGameState.enemies).length ? 1 : index + 1, | |
index, | |
prevIndex: index === 1 ? Object.keys(networkGameState.enemies).length : index - 1, | |
}, | |
}), {}); | |
} | |
// Despawn Characters | |
const charactersOnLocal = {...global.gameState.players, ...global.gameState.enemies}; | |
_.forEach(charactersOnLocal, ({ id }) => { | |
const characterOnNetwork = networkGameState.enemies.hasOwnProperty(id) || networkGameState.players.hasOwnProperty(id); | |
if (!characterOnNetwork) { | |
actions.despawnCharacter(id); | |
} | |
}); | |
// Update Characters States | |
_.forEach({...global.gameState.players, ...global.gameState.enemies}, (characterOnLocal) => { | |
const id: string = String(characterOnLocal.id); | |
const characterOnNetwork = characterOnLocal.enemy | |
? networkGameState.enemies[id] | |
: networkGameState.players[id]; | |
if (characterOnLocal.enemy) { | |
global.gameState.enemies = { | |
...global.gameState.enemies, | |
[id]: {...characterOnLocal, ...characterOnNetwork}, | |
}; | |
} else { | |
global.gameState.players = { | |
...global.gameState.players, | |
[id]: {...characterOnLocal, ...characterOnNetwork}, | |
}; | |
} | |
}); | |
// IF the network is at a different turn | |
if (global.gameState.turn !== networkGameState.turn && !global.isAnimating) { | |
// IF we have NOT just joined the match | |
const appliedEvents = networkGameState.turnEvents[global.gameState.turn]; | |
if (appliedEvents && global.gameState.turn !== -1) { | |
if (!appliedEvents.length) { | |
store.commit('SET_COMBAT_GAME_SELECTION_MODE', 'ACTION'); | |
} else { | |
actions.animateEvents(appliedEvents); | |
} | |
} | |
global.gameState.turn = networkGameState.turn; | |
} | |
// play state updating | |
if (!global.isAnimating && networkGameState.playState !== global.gameState.playState) { | |
global.gameState.levelRecord = networkGameState.levelRecord; | |
global.gameState.playState = networkGameState.playState; | |
return; | |
} | |
/* | |
SCENE RENDERING | |
*/ | |
// Cloud animation | |
if (global._gameClouds) { | |
global._gameClouds.tilePositionX += 0.072; | |
} | |
// Create & Update Characters Graphics | |
_.forEach({...networkGameState.players, ...networkGameState.enemies}, (characterOnNetwork) => { | |
const id: string = String(characterOnNetwork.id); | |
let characterOnLocal = characterOnNetwork.enemy | |
? global.gameState.enemies[id] | |
: global.gameState.players[id]; | |
// user does not exist locally, spawn them if game is NOT animating | |
if (!characterOnLocal && !global.isAnimating) { | |
characterOnLocal = actions.spawnCharacter(characterOnNetwork); | |
} else if (!characterOnLocal) { | |
return; | |
} | |
// if game is NOT animating, update their position | |
if (!global.isAnimating) { | |
const coordinates = actions.coordinatesForEntity(characterOnLocal); | |
characterOnLocal.sprite.x = coordinates.x; | |
characterOnLocal.sprite.y = coordinates.y; | |
} | |
// name tag | |
if (!characterOnLocal._nameTag) { | |
characterOnLocal._nameTag = scene.add.text( | |
0, 0, | |
characterOnLocal.username, | |
{ | |
fontSize: '17px', | |
fill: '#fff', | |
backgroundColor: '#0008', | |
align: 'center', | |
}, | |
) | |
.setOrigin(0.5, 0) | |
.setDepth(characterOnLocal.sprite.depth); | |
} | |
characterOnLocal._nameTag.x = characterOnLocal.sprite.x; | |
characterOnLocal._nameTag.y = characterOnLocal.sprite.y - (characterOnLocal.sprite.height * 1.75); | |
characterOnLocal._nameTag.setDepth(characterOnLocal.sprite.depth); | |
// health bar background | |
if (!characterOnLocal._healthBarBackground) { | |
characterOnLocal._healthBarBackground = scene.add.rectangle(0, 0, 0, 0, 0xBEBEBE) | |
.setDepth(characterOnLocal.sprite.depth) | |
.setOrigin(0, 0); | |
} else if (characterOnLocal._healthBarBackground.visible) { | |
characterOnLocal._healthBarBackground.setSize(characterOnLocal._nameTag.width, 9); | |
characterOnLocal._healthBarBackground.x = characterOnLocal._nameTag.x - (characterOnLocal._nameTag.width / 2); | |
characterOnLocal._healthBarBackground.y = characterOnLocal._nameTag.y + characterOnLocal._nameTag.height; | |
} | |
// health bar | |
if (!characterOnLocal._healthBar) { | |
const width = characterOnLocal.entity.health / characterOnLocal.entity.maxHealth * (characterOnLocal._nameTag.displayWidth); | |
characterOnLocal._healthBar = scene | |
.add.rectangle(0, 0, width, 0, 0x56F33E) | |
.setOrigin(0, 0); | |
} else if (characterOnLocal._healthBar.visible) { | |
if (!global.isAnimating) { | |
const width = characterOnLocal.entity.health / characterOnLocal.entity.maxHealth * (characterOnLocal._nameTag.displayWidth); | |
characterOnLocal._healthBar.setSize(width, 10); | |
} | |
characterOnLocal._healthBar.x = characterOnLocal._nameTag.x - (characterOnLocal._nameTag.width / 2); | |
characterOnLocal._healthBar.y = characterOnLocal._nameTag.y + characterOnLocal._nameTag.height; | |
characterOnLocal._healthBar.setDepth(characterOnLocal.sprite.depth + 1); | |
} | |
// health text | |
if (!characterOnLocal._healthText) { | |
characterOnLocal._healthText = scene.add.text( | |
0, 0, '', | |
{ | |
fontSize: '8px', | |
fill: '#fff', | |
backgroundColor: '#0000', | |
align: 'center', | |
baselineY: 0.5, | |
}, | |
) | |
.setOrigin(0.5, 0.5); | |
} else if (characterOnLocal._healthText.visible) { | |
const currentDisplayedHealth = characterOnLocal.entity.maxHealth * (characterOnLocal._healthBar.width / characterOnLocal._nameTag.displayWidth); | |
characterOnLocal._healthText.text = `${Math.round(currentDisplayedHealth / 10) * 10}/${characterOnLocal.entity.maxHealth}`; | |
characterOnLocal._healthText.x = characterOnLocal._healthBarBackground.getCenter().x; | |
characterOnLocal._healthText.y = characterOnLocal._healthBarBackground.getCenter().y + 2; | |
characterOnLocal._healthText.setDepth(characterOnLocal.sprite.depth + 2); | |
} | |
// grave marker | |
if (!characterOnLocal._healthBar.width) { | |
characterOnLocal._healthBar.visible = false; | |
characterOnLocal._healthBarBackground.visible = false; | |
characterOnLocal._healthText.visible = false; | |
characterOnLocal.sprite.play('grave-marker'); | |
if (characterOnLocal.enemy) { | |
characterOnLocal.sprite.scaleX = -Math.abs(characterOnLocal.sprite.scaleX); | |
} | |
} | |
}); | |
// target selection hand | |
if (global.targetHand) { | |
const currentPlayer = store.state.user.id ? global.gameState.players[store.state.user.id] : null; | |
// remove the target hand if game is animating or the user already selected the target & action | |
if (currentPlayer && currentPlayer.selectionStatus === 1 || global.isAnimating || store.state.combatGame.selectionMode !== 'TARGET') { | |
actions.removeTargetHand(); | |
} else { | |
// update selection hand coordinates | |
const placingLine = global.currentTargetSide === 0 | |
? global.playerPlacingLine | |
: global.enemyPlacingLine; | |
const character = placingLine[global.currentTargetIndex].character; | |
if (character && character.sprite.depth === 15) { | |
global.targetHand.x = character.sprite.getCenter().x; | |
global.targetHand.y = character._nameTag.y - 15; | |
global.targetHand.setDepth(character.sprite.depth); | |
} else { | |
actions.removeTargetHand(); | |
} | |
} | |
} else if (store.state.combatGame.selectionMode === 'TARGET' && !global.isAnimating) { | |
actions.addTargetHand(); | |
} | |
// update fadeScreen size | |
if (global._fadeScreen) { | |
const currentPlayer = _.find(networkGameState.players, p => p.id === store.state.user.id); | |
if (global.isAnimating || (currentPlayer && currentPlayer.entity.health === 0)) { | |
global.highlightCharacters(false); | |
global._fadeScreen.destroy(); | |
global._fadeScreen = null; | |
} else { | |
global._fadeScreen | |
.setSize(scene.game.canvas.offsetWidth, scene.game.canvas.offsetHeight); | |
} | |
} | |
}, |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment