Descendo de plataformas com Arcade Physics do Phaser JS - Skate Platformer Game Devlog #06
Escrito em 1 de outubro de 2020 - 🕒 3 min. de leituraFala pessoal! O Game Devlog dessa semana é um pouco longo, 15 minutos, mas vale a pena assistir, pois, tem muitas coisas interessantes sobre o jogo.
Seleção de Fases
Para facilitar o teste de novas fases, eu decidi adicionar uma tela de seleção de estágio básica, para que eu pudesse testar várias fases no mesmo build ao invés de ficar alterando o mesmo arquivo de fase toda a hora. Agora, sempre que adiciono um novo arquivo de estágio à pasta de fases, essa fase será automaticamente incluída no bundle do jogo, graças a algumas configurações personalizadas no Webpack.
const CopyWebpackPlugin = require('copy-webpack-plugin');
const { promises: fs } = require('fs');
const stageFiles = await fs.readdir(STAGES_PATH);
// get only the JSON files
const stageJsons = stageFiles
.filter((stage) => stage.split('.')[1] === 'json');
const GAME_STAGES = JSON.stringify(
stageJsons.map((stage) => {
// eslint-disable-next-line import/no-dynamic-require
const stageData = require(`${STAGES_PATH}/${stage}`);
const stageName = getStageNameFromMap(stageData);
return {
stageName,
stageKey: stage.split('.')[0],
};
})
);
module.exports = {
plugins: [
new webpack.DefinePlugin({
GAME_STAGES,
}),
],
};
Na scene de seleção de fases, você pode acessar os dados de fases na variável GAME_STAGES
, então eu faço um loop por esses dados das fases e crio um seletor de fases.
let posX = 20;
let posY = 50;
GAME_STAGES.forEach((stageData, index) => {
const { stageKey, stageName } = stageData;
const stageSelector = new StageSelector({
scene: this,
x: posX,
y: posY,
stageKey,
stageName,
onClickCallback: (data) => {
this.scene.start('GameScene', data);
},
});
this.add.text(
posX + 8,
posY + 8,
`${index + 1}`.padStart(2, '0')
).setDepth(50);
this.add.existing(stageSelector);
stageSelectors.add(stageSelector);
posX += 52;
if ((index + 1) % 7 === 0) {
posY += 52;
posX = 20;
}
});
Parallax Effect
O jogo não estaria completo sem um bom parallax effect, e para conseguir isso eu decidi adicionar algumas propriedades personalizadas às layers do Tiled e acesso elas na função update da game scene.
update(time, delta) {
const { dynamicLayers } = this.mapData;
Object.values(dynamicLayers).forEach((dynamicLayer) => {
dynamicLayer.layer.properties.forEach((property) => {
const { name, value } = property;
if (value !== 1) {
if (name === 'parallaxSpeedX') {
dynamicLayer.setX(
this.cameras.main.scrollX * value
);
} else if (name === 'parallaxSpeedY') {
dynamicLayer.setY(
this.cameras.main.scrollY * value
);
}
}
});
});
}
Obs: Depois de escrever esse post, eu descobri a função setScrollFactor e com ela é possível definir um atributo direto na layer ao invés de fazer um loop na função update.
Descendo de Plataformas
Para fazer isso eu pesquisei um pouco, e acabei fazendo de um jeito que é meio que uma gambiarra, mas funciona por enquanto, então decidi seguir em frente.
Primeiro eu verifico se o hero está no chão, se há um elemento encostando no hero por baixo e se o botão para baixo está sendo pressionado. Caso positivo, desabilitamos a colisão do baixo do hero por 150 milissegundos.
// Handle hero going down through element
if (
this.isHeroOnGround()
&& this.isDownJustDown()
&& this.touchingDownObject
) {
this.body.checkCollision.down = false;
this.scene.time.delayedCall(
150,
() => {
this.body.checkCollision.down = true;
}
);
}
Isso é bastante simples, mas como podemos acessar o atributo this.touchingDownObject
? Bom, essa é a maior parte da gambiarra dessa solução. Primeiro, precisamos adicionar um collider entre o hero e a layer do mapa com uma função de callback que irá verificar algumas coisas e definir o atributo this.touchingDownObject
para o hero.
this.physics.add.collider(
dynamicLayers.ground,
this.hero,
(objectA, objectB) => {
const [hero, element] = this.getHeroAndObject(objectA, objectB);
if (
hero.isHeroOnGround()
&& element.properties.collidesUp
&& element.properties.canFallThrough
) {
hero.touchingDownObject = element; // TODO?
} else {
hero.touchingDownObject = null;
}
}
);
E é isso aí! Espero que tenham gostado e não esqueçam de deixar um comentário se acharam post útil.
Tags:
- programação
- jogos
- javascript
- phaser
- phaser 3
- game devlog
- gamedev
- skate platformer
- super ollie vs pebble corp
- webpack
- tiled
Posts relacionados
Publicar um comentário
Comentários
Nenhum comentário.