📄 game.cpp
字号:
#include "game.h"
#include <application.h>
#include <gimcrack/opengl/opengl.h>
#include <gimcrack/math/vector.h>
#include <gimcrack/math/plane.h>
////////////////////////////////////////////////////////////////////////////////////
Game::Game():
gameState(GAME_INIT),
tree(NULL)
{
}
////////////////////////////////////////////////////////////////////////////////////
Game::~Game()
{
}
////////////////////////////////////////////////////////////////////////////////////
void Game::CoreLoop()
{
//Win32Application::CoreLoop();
switch(gameState)
{
case GAME_RUNNING: GameRunning(); break;
case GAME_INIT: Init(); break;
case GAME_CLOSING: Close(); break;
default: break;
}
}
//////////////////////////////////////////////////////////////////////////
void Game::GameRunning()
{
if(KEYDOWN(VK_ESCAPE)) {
gameState = GAME_CLOSING;
}
PreRender();
Render();
PostRender();
}
//////////////////////////////////////////////////////////////////////////
void Game::Render()
{
// Clear the screen
renderdevice.Clear();
camera.Update();
if(KEYDOWN(VK_SPACE)) {
camera.CheckMovement(timer.CalcMove(2700));
}
else {
camera.CheckMovement(timer.CalcMove(900));
}
camera.MouseLook();
if(GcSettings::DrawSkybox()) {
skybox.Draw();
}
// Render the tree (the terrain and all objects
tree->Render();
water.Render();
cube.Draw();
// Render a triangle
GcTriangle tri;
tri.a = GcVector3(400.0f, 600.0f, 250.0f);
tri.b = GcVector3(400.0f, 700.0f, 250.0f);
tri.c = GcVector3(400.0f, 600.0f, 750.0f);
lastpos2 = testmodel2->GetTranslation();
// Render the models
testmodel1.RenderKeyFrame(0);
testmodel2->RenderKeyFrame();
// Render the cacti
cacti.Render();
// Render a outline for the models
if(GcSettings::ShowDebug()) // FIX ME: show debug?
{
testmodel1.RenderOutlines();
testmodel2->RenderOutlines();
aabb1.RenderOutlines();
aabb2.RenderOutlines();
plane.RenderOutlines();
}
// Show the FPS in the window title bar
SetWindowText(GetHandle(), timer.FPS());
// Draw the GUI
gui.Begin();
glColor3f(1.0f, 1.0f, 1.0f);
GcVector3 pos = camera.Position();
// Render the HUD?
if(GcSettings::ShowHUD()) {
gui.Draw(pos.x, pos.z);
}
console.Draw();
// Print debug info?
if(GcSettings::ShowDebug())
{
gui.Print("Using Vertex Array", 0, GcSettings::ScreenHeight() - 70);
// Print the FPS
gui.Print(timer.FPS(), 0, GcSettings::ScreenHeight() - 50);
}
if(testmodel1.Intersects(aabb1))
{
glColor3f(1.0f, 0.8f, 1.0f);
gui.Print("AHH SHIT TIPTOP!", 20, 20);
testmodel1.SetTranslation(lastpos1);
testmodel2->SetTranslation(lastpos2);
}
if(testmodel1.Intersects(tri))
{
glColor3f(1.0f, 0.8f, 1.0f);
gui.Print("AHH SHIT TIPTOP!", 20, 20);
testmodel1.SetTranslation(lastpos1);
testmodel2->SetTranslation(lastpos2);
}
if(testmodel2->Intersects(testmodel1))
{
testmodel2->SetTranslation(lastpos2);
}
lastpos1 = testmodel1.GetTranslation();
gui.End();
// Flip the buffers
renderdevice.Flip();
}
////////////////////////////////////////////////////////////////////////////////////
void Game::PreRender()
{
static int speed = 0;
// Do the timer
timer.DoTimer();
// Move the cube
cube.Move(0, -2.5f, 0, terrain.Height(cube.Xpos(), cube.Zpos()));
// Get the current camera position
GcVector3 pos = camera.Position();
GcVector3 view = camera.View();
// Increase the falling speed with the acceleration
if(GcSettings::Gravity())
{
speed += 1;
pos.y -= speed;
view.y -= speed;
}
// Check for collision against the terrain
if(pos.y < terrain.Height(pos.x, pos.z) + 100)
{
// Calculate the view (change with as much that the y pos has been moved)
view.y += (terrain.Height(pos.x, pos.z) + 100) - pos.y;
// Calculate the new y position
pos.y = terrain.Height(pos.x, pos.z) + 100;
speed = 0;
}
// Update the camera position
camera.SetPostion(pos);
camera.SetView(view);
if(KEYDOWN(VK_NUMPAD9)) {
testmodel1.Rotate(GcVector3(0, 0, -2));
}
if(KEYDOWN(VK_NUMPAD3)) {
aabb1.Translate(GcVector3(2, 0, 0));
}
if(KEYDOWN(VK_NUMPAD1)) {
aabb1.Translate(GcVector3(-2, 0, 0));
}
if(KEYDOWN(VK_NUMPAD7)) {
aabb1.Translate(GcVector3(0, 2, 0));
}
if(KEYDOWN(VK_NUMPAD4)) {
aabb1.Translate(GcVector3(0, -2, 0));
}
if(KEYDOWN(VK_NUMPAD5)) {
aabb1.Translate(GcVector3(0, 0, 2));
}
if(KEYDOWN(VK_NUMPAD2)) {
aabb1.Translate(GcVector3(0, 0, -2));
}
if(KEYDOWN(VK_HOME)) {
testmodel2->Rotate(GcVector3(0, 0, -2));
}
if(KEYDOWN(VK_END)) {
testmodel2->Rotate(GcVector3(0, 0, 2));
}
}
//////////////////////////////////////////////////////////////////////////
void Game::PostRender()
{
}
////////////////////////////////////////////////////////////////////////////////////
void Game::OnKeyDown( uint key )
{
if( console.Active() )
{
console.SendKey(key);
return;
}
switch( key )
{
// Turn the console on/off
//case VK_INSERT: console.TurnOn(); break;
//case VK_DELETE: console.TurnOff(); break;
// Change the water height
case '9': water.SetWaterHeight(water.GetWaterHeight() + 10); break;
case '8': water.SetWaterHeight(water.GetWaterHeight() - 10); break;
case 'B': cube.SetPosition(0, 0, terrain.Height(0, 0)); break;
// Change betwen lines and textured
case 'L': glPolygonMode(GL_FRONT, GL_LINE); glDisable(GL_TEXTURE_2D); break;
case 'P': glPolygonMode(GL_FRONT, GL_FILL); glEnable(GL_TEXTURE_2D); break;
// Turn HUD on off
//case 'Z': GcSettings::ShowHUD(true); break;
//case 'X': GcSettings::ShowHUD(false); break;
// Turn fog on off
case 'F': GcSettings::Fog(true); glEnable(GL_FOG); break;
case 'G': GcSettings::Fog(false); glDisable(GL_FOG); break;
// Increase/decrease fog
// case VK_ADD: settings.FogDepth(settings.FogDepth() + 10); break;
// case VK_SUBTRACT: settings.FogDepth(settings.FogDepth() - 10); break;
case '1': GcSettings::DrawSkybox(true); break;
case '2': GcSettings::DrawSkybox(false); break;
case '3': GcSettings::Gravity(true); break;
case '4': GcSettings::Gravity(false); break;
// Change rendering method
// case 'T': settings.RenderMethod(REND_USE_ARRAY); break;
// case 'Y': settings.RenderMethod(REND_USE_IMMEDIATE); break;
// Take a screenshot
case VK_F2: screenshot.Screenshot("screen.tga",
GcSettings::ScreenWidth(),
GcSettings::ScreenHeight(),
GcSettings::ScreenDepth()); break;
}
}
////////////////////////////////////////////////////////////////////////////////////
void Game::OnKeyUp( uint key )
{
if( key == VK_INSERT )
{
console.Toggle();
}
switch( key )
{
case 'C': /*settings.ToggleDebug();*/ tree->ToggleDebugMode(); break;
case 'Z': GcSettings::ToggleShowHUD(); break;
}
}
////////////////////////////////////////////////////////////////////////////////////
bool Game::Init()
{
Win32Application::Init();
// Hide the cursor
GetWindow()->HideCursor();
EngineInit();
renderdevice.Init(GetHandle(), GcSettings::ScreenWidth(),
GcSettings::ScreenHeight(),
GcSettings::ScreenDepth());
_g_Debug->GetInfo();
plane.SetPlane(GcVector3(0, 1, 0), 20);
g_DebugConsole->Move(-10, 0);
aabb1.SetExtents(GcVector3(20.0f, 20.0f, 20.0f));
aabb2.SetExtents(GcVector3(20.0f, 20.0f, 20.0f));
aabb1.Translate(GcVector3(210.0f, 500.0f, 500.0f));
aabb2.Translate(GcVector3(250.0f, 500.0f, 500.0f));
// Set the lenght and height scale before initializing the terrain
terrain.SetScale(GcSettings::Scale());
terrain.SetHeightScale(GcSettings::HeightScael());
testmodel1.Load("data/models/tank.md2");
testmodel1.Translate(GcVector3(3000.0f, 400, 7000.0f));
testmodel1.Rotate(-90, 0, 0);
testmodel2 = new GcMS3D;
testmodel2->Load("data/models/car01.ms3d");
testmodel2->Translate(GcVector3(3000.0f, 375, 6500.0f));
testmodel2->Scale(GcVector3(3.0f, 3.0f, 3.0f));
// Build the quadtree
tree = new GcQuadtree;
tree->SetNodeHeight(255.0f * GcSettings::HeightScael());
tree->Create(5, 16 * GcSettings::Scale());
// Initialize the terrain
if(!terrain.Init(tree, GcSettings::HeightmapPath(), GcSettings::LandTexPath(),
"data/detail.tga"))
{
MessageBox(NULL, "Initializing terrain failed.", "ERROR", MB_OK);
return false;
}
// Set the cammera position
camera.SetCamera(0.0f, 1900.0f, 500.0f, 1000, 1500, 1000, 0, 1, 0);
// Set the cubes starting position
cube.SetPosition(0, 0, terrain.Height(0, 0));
cube.SetSize(10);
// Load the GUI
gui.Load(terrain.GetLandTexture(), terrain.GetMapWidth());
console.Load();
// Load the skybox
skybox.LoadSide("data/brightblue_ft.tga", North);
skybox.LoadSide("data/brightblue_bk.tga", South);
skybox.LoadSide("data/brightblue_lf.tga", West);
skybox.LoadSide("data/brightblue_rt.tga", East);
skybox.LoadSide("data/brightblue_up.tga", Up);
skybox.LoadSide("data/brightblue_dn.tga", Down);
// Star the timer (for fps and fps independent movement)
timer.StartTimer();
if(!tree->AttachNode(testmodel2)) {
MessageBox(NULL, "Couldn't add object!", "Error!", MB_OK );
}
// Initialize the water
water.Init("data/water.tga", 256 * GcSettings::Scale(), 1500);
// If the fog is on, turn off the water
if(GcSettings::Fog()) {
water.SetWaterHeight(-500);
}
// Loade the cacti
cacti.Load("data/cacti. tga", GcPoint3(3000.0f, 500, 8000.0f));
// The game is ready to run
gameState = GAME_RUNNING;
return true;
}
////////////////////////////////////////////////////////////////////////////////////
void Game::Close()
{
//skybox.Unload();
tree->Destroy();
terrain.Close();
renderdevice.Close();
if(tree) {
delete tree;
tree = NULL;
}
EngineShutdown();
// Quit the game
PostQuitMessage(0);
}
////////////////////////////////////////////////////////////////////////////////////
void Game::OnActivate(BOOL active)
{
Win32Application::OnActivate(active);
/*
if(active)
{
// The game is activated, change back to game screen settings
//GetWindow()->SwitchMode();
// Return the window to its previus state
ShowWindow(GetHandle(), SW_RESTORE);
// Hide the cursor
::ShowCursor(false);
}
else
{
// The game is inactivated, change to orgianl secreen settings
//p_main->m_app.SetOrginalScreen();
GetWindow()->RestoreResolution();
// Minimize the window
ShowWindow(GetHandle(), SW_MINIMIZE);
// Show the cursor
::ShowCursor(true);
}
*/
}
////////////////////////////////////////////////////////////////////////////////////
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -