// BlockyFroggy
// Copyright © 2017 John Ryland.
// All rights reserved.
#include "GameState.h"
#include "Graphics.h"
REGISTER_GAME_STATE(GameState)
void GameState::enter(GameGraphics& graphics)
{
graphics.resetVertexBuffers(m_sim.objectLists());
}
void GameState::exit(GameGraphics& /*graphics*/)
{
}
float GameState::getTime()
{
return m_sim.getTime();
}
void GameState::draw(GameGraphics& graphics)
{
if (m_needReset) {
// reset the vertex buffers
graphics.resetVertexBuffers(m_sim.objectLists());
m_needReset = false;
m_frame = 0;
}
graphics.draw();
}
// temp
void GameState::getPlayerPos(float pos[3])
{
const GameSim::GameObject& player = m_sim.objectLists().back()->front();
pos[0] = player.m_x;
pos[1] = player.m_y;
pos[2] = m_sim.getPlayerHeight();
}
void GameState::getCameras(float cameraStyle[8], float lightParams[8], float debugCameraParams[8], float elapsed)
{
const GameSim::GameObject& player = m_sim.objectLists().back()->front();
float xOff = -player.m_x + 20;
float yOff = -player.m_y - 100;
float zOff = 20.0; // height of camera, smaller is higher
// lerp camera pos towards the player's position (avoids jumpy camera movements, feels nicer)
static float lastXOff = xOff;
static float lastYOff = yOff;
//const float cameraLerpSpeed = 10.0;
xOff = Math::lerp(lastXOff, xOff, 0.05);//a_elapsed / cameraLerpSpeed);
yOff = Math::lerp(lastYOff, yOff, 0.05);//a_elapsed / cameraLerpSpeed);
lastXOff = xOff;
lastYOff = yOff;
// Layout of camera style parameters:
// float cameraStyle[8] = { fov, rx, ry, rz, s, tx, ty, tz };
// Frogger mode (perspective devolved to ortho and with top down view)
float debugCameraStyle[8] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.0035f, -20.0f, 20.0f, 80.0f }; // Debug Style - 2D top down mode
// float topDownCameraStyle[8] = { 1.0f, 0.0f, 0.0f, 0.0f, 0.02f, -20.0f, 20.0f, 80.0f }; // Frogger Style - 2D top down mode
//float topDownCameraStyle[8] = { 5.0f, 0.0f, 0.0f, 0.0f, 0.15f, -20.0f, 60.0f, 80.0f }; // Frogger Style - 2D top down mode
float topDownCameraStyle[8] = { 5.0f, -45.0f, 0.0f, -20.0f, 0.15f, 0.0f, 20.0f, 0.0f }; // Crossy Road Style - nearly isometric / orthographic
float isoCameraStyle[8] = { 5.0f, -45.0f, 0.0f, -20.0f, 0.15f, 0.0f, 20.0f, 0.0f }; // Crossy Road Style - nearly isometric / orthographic
float perspectiveCameraStyle[8] = { 65.0f, -45.0f, 0.0f, -20.0f, 1.0f, 0.0f, 20.0f, 0.0f }; // Normal as designed style with perspective
float* defaultCameraStyle = perspectiveCameraStyle;
bool useIso = true;
if (useIso)
defaultCameraStyle = isoCameraStyle;
#if 0
const int cameraTransitionFrames = 30; // Fast for quicker debugging
const int cameraWaitFrames = 50; // Fast for quicker debugging
#else
const int cameraTransitionFrames = 150; // Nice value
const int cameraWaitFrames = 250;
#endif
const int cwf = cameraWaitFrames;
const int ctf = cameraTransitionFrames;
// float cameraStyle[8];
if (m_frame < cwf)
for (int i = 0; i < 8; i++)
cameraStyle[i] = topDownCameraStyle[i];
else if (m_frame < cwf+ctf)
for (int i = 0; i < 8; i++)
cameraStyle[i] = Math::lerp(topDownCameraStyle[i], isoCameraStyle[i], (m_frame-cwf) / float(ctf));
else if (m_frame < 2*cwf+ctf)
for (int i = 0; i < 8; i++)
cameraStyle[i] = isoCameraStyle[i];
else if (m_frame < 2*(cwf+ctf))
for (int i = 0; i < 8; i++)
cameraStyle[i] = Math::lerp(isoCameraStyle[i], defaultCameraStyle[i], (m_frame-(2*cwf+ctf)) / float(ctf));
else
for (int i = 0; i < 8; i++)
cameraStyle[i] = defaultCameraStyle[i];
/*
if (debugCameraView)
for (int i = 0; i < 8; i++)
cameraStyle[i] = debugCameraStyle[i];
*/
/*
m_polyUniforms.m_shadowStrength = float(m_frame) / (3*cwf+2*ctf);
if (float(m_frame) >= (3*cwf+2*ctf))
m_polyUniforms.m_shadowStrength = 1.0f;
*/
m_frame++;
cameraStyle[4] *= 0.01f;
cameraStyle[5] += xOff;
cameraStyle[6] += yOff;
cameraStyle[7] += zOff;
/*
m_camera.build(cameraStyle[0], a_aspect, &cameraStyle[1], cameraStyle[4] * 0.01f, xOff + cameraStyle[5], yOff + cameraStyle[6], zOff + cameraStyle[7]);
*/
/*
Log(LL_Trace, "mvp[] = {");
Log(LL_Trace, " %f %f %f %f", m_modelViewProjectionMatrix[0], m_modelViewProjectionMatrix[1], m_modelViewProjectionMatrix[2], m_modelViewProjectionMatrix[3]);
Log(LL_Trace, " %f %f %f %f", m_modelViewProjectionMatrix[4], m_modelViewProjectionMatrix[5], m_modelViewProjectionMatrix[6], m_modelViewProjectionMatrix[7]);
Log(LL_Trace, " %f %f %f %f", m_modelViewProjectionMatrix[8], m_modelViewProjectionMatrix[9], m_modelViewProjectionMatrix[10], m_modelViewProjectionMatrix[11]);
Log(LL_Trace, " %f %f %f %f", m_modelViewProjectionMatrix[12], m_modelViewProjectionMatrix[13], m_modelViewProjectionMatrix[14], m_modelViewProjectionMatrix[15]);
Log(LL_Trace, "};");
*/
/*
if (debugCameraView)
{
for (int i = 0; i < 8; i++)
cameraStyle[i] = debugCameraStyle[i];
m_debugCamera.build(cameraStyle[0], a_aspect, &cameraStyle[1], cameraStyle[4] * 0.01f, xOff + cameraStyle[5], yOff + cameraStyle[6], zOff + cameraStyle[7]);
}
*/
for (int i = 0; i < 8; i++)
debugCameraParams[i] = debugCameraStyle[i];
debugCameraParams[4] *= 0.01f;
debugCameraParams[5] += xOff;
debugCameraParams[6] += yOff;
debugCameraParams[7] += zOff;
//m_cameraX-20.0, m_cameraY+45.0, 20.0
float lightTemplate[8] = { 1.0f, -65.0f, 0.0f, -25.0f, 0.025f, -20.0f, 35.0f, 0.0f };
for (int i = 0; i < 8; i++)
lightParams[i] = lightTemplate[i];
/*
lightParams[0] = 1.0f; // FOV
lightParams[1] = -65.0f; // rotX
lightParams[2] = 0.0f; // rotY
lightParams[3] = -25.0f; // rotZ
lightParams[4] = 0.025;//175f;// scale
*/
lightParams[5] += xOff;
lightParams[6] += yOff + 40.0;
lightParams[7] += zOff;
}
bool GameState::update(GameUi::UpdateState& state, float elapsed)
{
bool ret = true;
if (m_isRunning)
{
m_sim.update(elapsed);
m_time += elapsed;
if (m_sim.isGameOver())
{
ret = false;
notifyPlayerGameOver();
/*
m_isRunning = false;
if ( m_score > m_highScore )
{
m_highScore = m_score;
}
m_restartCountDown = 10;
*/
}
}
else
{
if (m_restartCountDown)
{
m_restartCountDown--;
}
}
state.m_variables["SCORE"] = std::to_string(m_score);
state.m_variables["HIGH_SCORE"] = std::to_string(m_highScore);
return ret;
}
bool GameState::touchesChanged(int x, int y, TouchState ts)
{
if (ts == TouchDown) {
m_touchMoving = false;
m_touchX = x;
m_touchY = y;
} else if (ts == TouchMove) {
m_touchMoving = true;
} else {
if (m_isRunning)
{
if (m_touchMoving)
{
float dx = m_touchX - x;
float dy = m_touchY - y;
if (dx < 0) dx = -dx;
if (dy < 0) dy = -dy;
if (dx > dy) {
if (dx > 15)
{
m_sim.movePlayer((x > m_touchX) ? GameSim::Right : GameSim::Left);
}
} else {
if (dy > 15)
{
m_sim.movePlayer((y > m_touchY) ? GameSim::Backward : GameSim::Forward);
if (m_nominalScore >= 100)
m_nominalScore += (y > m_touchY) ? -100 : 100;
if (m_nominalScore > m_score)
m_score = m_nominalScore;
}
}
} else {
m_sim.movePlayer(GameSim::Forward);
m_nominalScore += 100;
if (m_nominalScore > m_score)
m_score = m_nominalScore;
}
if (m_sim.isGameOver())
{
notifyPlayerGameOver();
}
}
else
{
if (!m_restartCountDown)
{
m_nominalScore = 0;
m_score = 0;
m_sim.reset();
m_needReset = true;
m_isRunning = true;
m_time = 0.0;
}
}
}
return false;
}
void GameState::notifyPlayerGameOver()
{
m_isRunning = false;
// Must be inited, and assume must be atleast 320x320
if ( m_score > m_highScore )
{
m_highScore = m_score;
}
// Need to change states, go to EndGameState / EndScreenState or something, perhaps the state object is looked up from game flow steps
//m_ui.onGameOver();
m_restartCountDown = 10;
}