⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 game.cpp

📁 小型的3D游戏引擎
💻 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 + -