📄 game.cpp
字号:
// ==========================================================================================================
//
// 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 + -