Chrysthian Simão
#CapiConf
Pós-graduado em Desenvolvimento de Jogos para Computador pela Universidade Positivo
Trabalhei em uma engine de jogos própria, feita em JS utilizando <canvas> na época que era tudo mato
Atualmente arquiteto Front-end na Juno
chrysthian.simao@gmail.com
https://github.com/chrysthian
(calma, ta turubem)
Voce vai precisar de:
git clone https://github.com/chrysthian/capiconf2020.git
npm install
npm startPara facilitar o entendimento eu vou colocar no canto inferior direito dos slides essa legenda, pra saber que parte do código estamos mexendo
<canvas>, Pixi, 60 FPS
React, UI, Virtual DOM, redux, store
No react é bem comum utilizar uma página JSX para consultar o Store do redux
import { connect } from 'react-redux'
function Topbar(props) {
return (
<Container>
Score: {props.score}
</Container>
)
}
const mapStateToProps = store => ({
score: store.score.value
})
export default connect(mapStateToProps, null)(Topbar)No entanto o redux merece uma menção honrosa porque embora normalmente seja utilizado para ser uma fonte de verdade de uma aplicação React, ela pode ser utilizada fora do React
import { store } from 'store'
import { keyDown, keyUp } from 'saga/input/inputAction'
// para consultar valores
store.subscribe(() => {
this.keyboard = store.getState().keyboard
this.mouse = store.getState().mouse
})
//para disparar actions
store.dispatch(keyDown(this.keyboard.pressed))
Mas como ligamos o <canvas> com a camada de UI em React? Há dois ciclos de render distintos, que precisam ser executados em velocidades igualmente distintas
60 FPS
Conforme necessidade do DOM / Virtual DOM
Mantemos os ciclos de render separados e sincronizamos, quando necessário, utilizando o Redux Saga
while(!gameOver){
update()
render()
}É tipo isso, só que super rápido!
60 FPS = 16ms por frame
Então para um movimento suave e consistente:
deslocamento por frame = pixels por segundo * (1 / FPS)
const DEG2RAD = Math.PI / 180
const RAD2DEG = 180 / Math.PI
export const degToRad = degrees => {
return degrees * DEG2RAD
}
export const radToDeg = radians => {
return radians * RAD2DEG
}Para a distância entre objetos (2D)
Familiar? pois é, trigonometria
const dx = objA.x - objB.x
const dy = objA.y - objB.y
Math.sqrt(dx * dx + dy * dy)Para a sua alegria na manhã de sábado, a classe Vector3 dentro do projeto tem cálculo de distância pronto
É um pouco mais complexo por ser em 3D, mas funciona pra 2D também, só o eixo Z ter o mesmo valor nos dois vetores
A base que matemática e física são essenciais
vetores, trigonometria e matrizes são bons pontos de partida
Na próprio fonte do projeto tem uma classe Vector3, que deve ajudar com o pontapé inicial
Para resolver colisões de forma mais esperta e otimizada que nós usamos, estude uma biblioteca de física.
Claro, que ela vai usar vetores, então a base matemática vai precisar estar lá para calibrar a sua lib.
Como sugestão, da uma olhada na matter.js
Shaders, sabe aqueles efeitos visuais impressionantes? Pois é, códigos enviados para rodar na placa de vídeo
https://developer.mozilla.org/en-US/docs/Games/Techniques/3D_on_the_web/GLSL_Shaders
Arte é o processo ou produto de utilizar elementos deliberadamente de forma que afete sentidos e emoções
Jogos são uma experiência estrutural, com regras e objetivos, que é cativante
chrysthian.simao@gmail.com
https://github.com/chrysthian
#CapiConf