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

📄 game.cpp

📁 Torus 3D Engine is an open-source OpenGL ES 3D Engine for creating your own games in BREW environmen
💻 CPP
📖 第 1 页 / 共 3 页
字号:
// ==========================================================================================================
//
// EspacoX 3D
// Copyright (C)2005, Imersiva Interactive
// Written by Vander Nunes
//
// ==========================================================================================================

#include "game.h"


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
int AEEClsCreateInstance(AEECLSID ClsId, IShell *pIShell, IModule *po, void **ppObj)
{
	*ppObj = NULL;

	if (ClsId == AEECLSID_GAME)
		if (AEEApplet_New(sizeof(CGame), ClsId, pIShell, po, (IApplet**)ppObj, (AEEHANDLER)CGame::HandleInitEvent,(PFNFREEAPPDATA)CGame::Destroy) == TRUE)
			return AEE_SUCCESS;

	return EFAILED;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CGame::CGame()
{
	m_key_state = 0;
	m_kSELECT = m_kLEFT = m_kRIGHT = m_kUP = m_kDOWN = m_kCLEAR = FALSE;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
CGame::~CGame()
{
	CleanUp();
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::Destroy(CGame* pGame)
{
	pGame->CleanUp();
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CGame::Init()
{
	// initialize the 3D engine
	m_pEngine = new CEngine(&m_applet);
	if (!m_pEngine) return FALSE;
	if (!m_pEngine->Init()) return FALSE;

	// instanciate the camera
	m_pCam = new CCamera(m_pEngine);
	m_pCam->Setup(1.0f, 250.0f, 1.0f);

	// start clean game data
	m_pScene = NULL;
	m_pPlayer = NULL;
	m_klastLEFT = m_klastRIGHT = m_klastUP = m_klastDOWN = FALSE;
	m_pMusIntro = NULL;
	m_pSndLevel = NULL;
	m_pSndBonus = NULL;
	m_pSndSpecialBonus = NULL;
	m_pSndBang = NULL;

	word xx;

	for (xx=0; xx<MAX_SHIPS; xx++)
		m_pEnemies[xx] = NULL;

	for (xx=0; xx<MAX_FLAGS; xx++)
		m_pFlags[xx] = NULL;

	for (xx=0; xx<GRID_SIZE*GRID_SIZE; xx++)
		m_pTiles[xx] = NULL;

	#if USE_LIGHT
		//
		// enable a directional lighting
		//
		glShadeModel(GL_SMOOTH);
		glEnable(GL_LIGHTING);
		AddLight();
	#endif

	m_dwFrame = 0;
	m_jGameStatus = STATUS_START;

	NextFrame(this);

	return TRUE;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CGame::LoadResources()
{
	// load "press start" sprite
	m_pSprPressStart = new CSprite(m_pEngine);
	if (!m_pSprPressStart->LoadFromVfs("game.dat", "pressstart.bmp"))
		return FALSE;

	// load "level" sprite
	m_pSprLevel = new CSprite(m_pEngine);
	if (!m_pSprLevel->LoadFromVfs("game.dat", "level.bmp"))
		return FALSE;

	// load "game over" sprite
	m_pSprGameOver = new CSprite(m_pEngine);
	if (!m_pSprGameOver->LoadFromVfs("game.dat", "gameover.bmp"))
		return FALSE;

	// load "score" sprite
	m_pSprScore = new CSprite(m_pEngine);
	if (!m_pSprScore->LoadFromVfs("game.dat", "score.bmp"))
		return FALSE;

	// load "get ready" sprite
	m_pSprGetReady = new CSprite(m_pEngine);
	if (!m_pSprGetReady->LoadFromVfs("game.dat", "getready.bmp"))
		return FALSE;

	// load lifes icon sprite
	m_pSprLive = new CSprite(m_pEngine);
	if (!m_pSprLive->LoadFromVfs("game.dat", "live.bmp"))
		return FALSE;

	// load small font numbers sprite
	m_pSprNumbers = new CSprite(m_pEngine);
	if (!m_pSprNumbers->LoadFromVfs("game.dat", "font_small_n.bmp"))
		return FALSE;

	// configure the font number frames
	int16 jFrmNumbers[] =
	{
		// offsetx, offsety, addx, addy, width, height for each frame
		0,0, 0,0, 5,5,			// frame 0
		5,0, 0,0, 5,5,			// frame 1
		10,0, 0,0, 5,5,			// frame 2
		15,0, 0,0, 5,5,			// frame 3
		20,0, 0,0, 5,5,			// frame 4
		25,0, 0,0, 5,5,			// frame 5
		30,0, 0,0, 5,5,			// frame 6
		35,0, 0,0, 5,5,			// frame 7
		40,0, 0,0, 5,5,			// frame 8
		45,0, 0,0, 5,5,			// frame 9
	};
	m_pSprNumbers->Config(10, jFrmNumbers);

	// load in-game sounds
	m_pSndLevel = new CMusic(m_pEngine);
	if (!m_pSndLevel->LoadFromVfs("game.dat", "snd_level.qcp")) return FALSE;
	m_pSndBonus = new CMusic(m_pEngine);
	if (!m_pSndBonus->LoadFromVfs("game.dat", "snd_bonus.qcp")) return FALSE;
	m_pSndSpecialBonus = new CMusic(m_pEngine);
	if (!m_pSndSpecialBonus->LoadFromVfs("game.dat", "snd_spbonus.qcp")) return FALSE;
	m_pSndBang = new CMusic(m_pEngine);
	if (!m_pSndBang->LoadFromVfs("game.dat", "snd_bang.qcp")) return FALSE;

	return TRUE;
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::AddLight(void)
{
	int Ambient    [4] = {ITOX(0), ITOX(0), ITOX(0), ITOX(0)};
	int Diffuse    [4] = {ITOX(5), ITOX(5), ITOX(5), ITOX(5)};
	int Specular   [4] = {ITOX(6), ITOX(6), ITOX(6), ITOX(6)};
	int Position   [3] = { ITOX(512), ITOX(512), ITOX(512) };

	glEnable(GL_LIGHT0);
	glLightxv(GL_LIGHT0, GL_POSITION, Position);
	glLightxv(GL_LIGHT0, GL_AMBIENT,  Ambient);
	glLightxv(GL_LIGHT0, GL_DIFFUSE,  Diffuse);
	glLightxv(GL_LIGHT0, GL_SPECULAR, Specular);
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CGame::LoadLevel(char* szPakFile, byte jLevel)
{
	// create an empty scenegraph
	m_pScene = new CSceneGraph(m_pEngine);

	// load the ship model and two textures, one for the player and one for the enemies
	if (!m_pScene->LoadModel("spaceship2.mob", 0.02f, 0.02f, 0.02f)) return FALSE;
	if (!m_pScene->LoadTexture("spaceship2a.tga")) return FALSE;
	if (!m_pScene->LoadTexture("spaceship2b.tga")) return FALSE;

	// ------------------------------------------------------------------------------------
	// load the cube tile model and a texture for it
	if (!m_pScene->LoadModel("cube.mob", 0.1f, 0.1f, 0.1f)) return FALSE;
	// *** use a hack to randomize the palette of the texture...
	// *** so we wont load the usual way.
	CTexture* pTex = m_pScene->CreateTexture();
	CTGA Tga;
	Tga.Load(&m_applet, "game.dat", "cube.tga");
	// randomize palette index 0 & 1 from cube.tga
	byte *pPal = Tga.Palette();
	byte r,g,b;
	GETRAND(&r,1); GETRAND(&g,1); GETRAND(&b,1);
	g &= 63;
	pPal[767] = r | 127;
	pPal[766] = g | 127;
	pPal[765] = b | 127;
	pPal[764] = r >> 1;
	pPal[763] = g >> 1;
	pPal[762] = b >> 1;
	pTex->LoadFromMemory(&Tga);
	Tga.Reset();
	// ------------------------------------------------------------------------------------

	// load the flag model and two textures
	if (!m_pScene->LoadModel("pyramid.mob", 0.1f, 0.1f, 0.1f)) return FALSE;
	if (!m_pScene->LoadTexture("pyramid_a.tga")) return FALSE;
	if (!m_pScene->LoadTexture("pyramid_b.tga")) return FALSE;

	m_jEnemyTurns = 0xB1; // 10110001b

	m_pLevelGrid = (byte*)API_MALLOC(GRID_SIZE*GRID_SIZE);
	if (!m_pLevelGrid) return FALSE;

	// pointers to the objects at each grid position
	m_pPtrGrid = (CSceneItem**)API_MALLOC(GRID_SIZE*GRID_SIZE*sizeof(CSceneItem*));
	if (!m_pPtrGrid) return FALSE;

	// reset some ingame keys and counters
	m_jTurnLeft = m_jTurnRight = 0;
	m_klastLEFT = m_klastRIGHT = m_klastUP = m_klastDOWN = FALSE;

	// level_XX.raw
	char szFile[13];

	SPRINTF(szFile, "level_%02u.raw", jLevel);

	CVfs Vfs;
	if (!Vfs.Unpack(szPakFile, szFile, &m_applet))
		return FALSE;

	m_jEnemyCount = 0;
	m_jFlagsCount = m_jFlagsLeft = 0;

	// decode the level
	if (m_pLevelGrid)
	{
		// read
		Vfs.Read(m_pLevelGrid, GRID_SIZE*GRID_SIZE);

		// decode
		word xx;					// tile counter
		int tpx = 0;			// tile px
		int tpz = 0;			// tile pz

		for (xx=0; xx<GRID_SIZE*GRID_SIZE; xx++)
		{
			byte c = m_pLevelGrid[xx];

			/*
						00 - wall
						01 - player
						02 - special flag
						03 - normal flag
						04 - enemy
						05 - track
			*/

			switch (c)
			{
				case 0:
				{
					// wall
					m_pTiles[xx] = new CSceneItem(m_pScene, 1, 2);	// ### hardcoded mesh and texture...
					m_pPtrGrid[xx] = m_pTiles[xx];
					m_pScene->AddItem(m_pScene->Root(), m_pTiles[xx]);
					m_pTiles[xx]->TranslateTo(ITOX(tpx), 0, ITOX(tpz));
					break;
				}

				case 1:
				{
					// player
					m_pPlayer = new CSceneItem(m_pScene, 0, 0);	// ### hardcoded mesh and texture...
					m_pScene->AddItem(m_pScene->Root(), m_pPlayer);
					m_pPlayer->TranslateTo(ITOX(tpx), 0, ITOX(tpz));
					m_pPlayer->UpdateDirection();
					VectorCopy(m_pPlayer->Position(), m_PlayerStartPos);
					break;
				}

				case 2:
				{
					// special flag
					m_pFlags[m_jFlagsCount] = new CSceneItem(m_pScene, 2, 4);	// ### hardcoded mesh and texture...
					m_pPtrGrid[xx] = m_pFlags[m_jFlagsCount];
					m_pScene->AddItem(m_pScene->Root(), m_pFlags[m_jFlagsCount]);
					m_pFlags[m_jFlagsCount]->TranslateTo(ITOX(tpx), 0, ITOX(tpz));
					m_jFlagsCount++;
					break;
				}

				case 3:
				{
					// normal flag
					m_pFlags[m_jFlagsCount] = new CSceneItem(m_pScene, 2, 3);	// ### hardcoded mesh and texture...
					m_pPtrGrid[xx] = m_pFlags[m_jFlagsCount];
					m_pScene->AddItem(m_pScene->Root(), m_pFlags[m_jFlagsCount]);
					m_pFlags[m_jFlagsCount]->TranslateTo(ITOX(tpx), 0, ITOX(tpz));
					m_jFlagsCount++;
					break;
				}

				case 4:
				{
					// enemy
					m_pEnemies[m_jEnemyCount] = new CSceneItem(m_pScene, 0, 1);	// ### hardcoded mesh and texture...
					m_pScene->AddItem(m_pScene->Root(), m_pEnemies[m_jEnemyCount]);
					m_pEnemies[m_jEnemyCount]->TranslateTo(ITOX(tpx), 0, ITOX(tpz));
					GETRAND(&m_jEnemyStepsToTurn[m_jEnemyCount],1);
					if (!m_jEnemyStepsToTurn[m_jEnemyCount]) m_jEnemyStepsToTurn[m_jEnemyCount] = ENEMY_STEPS_TURN;
					m_pEnemies[m_jEnemyCount]->UpdateDirection();
					VectorCopy(m_pEnemies[m_jEnemyCount]->Position(), m_EnemyStartPos[m_jEnemyCount]);
					m_jOldValue[m_jEnemyCount] = 5;
					m_jEnemyCount++;
					break;
				}

				case 5:
				{
					// track
					break;
				}
			}

			// next tile position
			tpx += 10;
			if (tpx >= 310)
			{
				tpx = 0;
				tpz += 10;
			}
		}
	}

	Vfs.Finish();

	m_jFlagsLeft = m_jFlagsCount;

	return true;
}


// ----------------------------------------------------------------------------------------------------------
//
// Turn enemy
//
// ----------------------------------------------------------------------------------------------------------
void CGame::TurnEnemy(byte idx)
{
	if (m_jEnemyTurns & 1)
	{
		// shift rotate the turn bits keeping last bit set
		m_jEnemyTurns >>= 1;
		m_jEnemyTurns |= 128;
		// turn enemy left
		m_pEnemies[idx]->AddRotation(0, ITOX(90), 0);
	}
	else
	{
		// shift rotate the turn bits keeping last bit unset
		m_jEnemyTurns >>= 1;
		// turn enemy right
		m_pEnemies[idx]->AddRotation(0, ITOX(-90), 0);
	}
	m_pEnemies[idx]->UpdateDirection();
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::CleanUp()
{
	// release level data
	CleanUpLevel();

	// release camera
	DeletePtr(m_pCam);

	// release sprites
	DeletePtr(m_pSpr8x13);
	DeletePtr(m_pSprNumbers);
	DeletePtr(m_pSprGameOver);
	DeletePtr(m_pSprScore);
	DeletePtr(m_pSprLevel);
	DeletePtr(m_pSprLive);
	DeletePtr(m_pSprPressStart);
	DeletePtr(m_pSprGetReady);

	// release in-game sounds
	if (m_pMusIntro) { m_pMusIntro->Stop(); DeletePtr(m_pMusIntro); }
	if (m_pSndLevel) { m_pSndLevel->Stop(); DeletePtr(m_pSndLevel); }
	if (m_pSndBonus) { m_pSndBonus->Stop(); DeletePtr(m_pSndBonus); }
	if (m_pSndSpecialBonus) { m_pSndSpecialBonus->Stop(); DeletePtr(m_pSndSpecialBonus); }
	if (m_pSndBang) { m_pSndBang->Stop(); DeletePtr(m_pSndBang); }

	// release engine
	DeletePtr(m_pEngine);
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
void CGame::CleanUpLevel()
{
	word xx;

	for (xx=0; xx<MAX_SHIPS; xx++)
		DeletePtr(m_pEnemies[xx]);

	for (xx=0; xx<MAX_FLAGS; xx++)
		DeletePtr(m_pFlags[xx]);

	for (xx=0; xx<GRID_SIZE*GRID_SIZE; xx++)
		DeletePtr(m_pTiles[xx]);

	DeletePtr(m_pPlayer);
	DeletePtr(m_pScene);
	if (m_pLevelGrid) { API_FREE(m_pLevelGrid); m_pLevelGrid = NULL; }
	if (m_pPtrGrid) { API_FREE(m_pPtrGrid); m_pPtrGrid = NULL; }
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CGame::HandleInitEvent(CGame* pGame, AEEEvent event, uint16 wParam, uint32 dwParam)
{
	switch (event)
	{
		case EVT_APP_START:
		{
			return pGame->Init();
		}

		case EVT_APP_STOP:
		{
			return TRUE;
		}
	}

	return pGame->HandleEvent(event, wParam, dwParam);
}


// ----------------------------------------------------------------------------------------------------------
//
//
//
// ----------------------------------------------------------------------------------------------------------
boolean CGame::HandleEvent(AEEEvent event, uint16 wParam, uint32 dwParam)
{
	switch (event)
	{
		case EVT_APP_SUSPEND:
		{
			ISHELL_CancelTimer(m_applet.m_pIShell, NULL, (void *)this);
			return TRUE;
		}

		case EVT_APP_RESUME:
		{
			NextFrame(this);
			return TRUE;
		}

		case EVT_APP_NO_SLEEP:
		{
			return TRUE;
		}

		case EVT_KEY_PRESS:
		{
			m_key_state = 1;
			m_key_wParam = wParam;
			KeyPressEvent(wParam);
			return TRUE;
		}

		case EVT_KEY_RELEASE:
		{
			m_key_state = 0;
			m_key_wParam = wParam;
			KeyReleaseEvent(wParam);
			return TRUE;
		}

		case EVT_KEY:
		{
			return TRUE;
		}
	}

	return TRUE;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -