📄 gamesession.cpp
字号:
// GameSession.cpp: implementation of the CGameSession class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "MyGame.h"
#include "GameSession.h"
#include "GameIntro.h"
#include "Exp.h"
#include "Ship3D.h"
#include "Fragment.h"
#include "Audio.h"
#include "utility.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
#ifdef _WIN32
#define drand48() (((float) rand())/((float) RAND_MAX))
#define srand48(x) (srand((x)))
#endif
extern CGameIntro GI;
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CGameSession::CGameSession()
{
PauseFlag=false;
SpaceSize=100;
}
CGameSession::~CGameSession()
{
}
void CGameSession::KeyDown(UINT nChar)
{
int km;
switch(nChar)
{
case VK_SPACE :
if(S->active) Shoot();
else if(deadpause<0) S->active=true;
break;
case 'P' : Pause(); break;
case VK_LEFT :
km = glutGetModifiers();
if(km & GLUT_ACTIVE_ALT) S->StartStrafeLeft();
else S->StartLeft();
break;
case VK_RIGHT :
km = glutGetModifiers();
if(km & GLUT_ACTIVE_ALT) S->StartStrafeRight();
else S->StartRight();
break;
case VK_UP :
km = glutGetModifiers();
S->ThrustOn();
break;
}
}
void CGameSession::KeyUp(UINT nChar)
{
switch (nChar)
{
case VK_LEFT:
S->StopStrafeLeft();
S->StopLeft();
break;
case VK_RIGHT:
S->StopStrafeRight();
S->StopRight();
break;
case VK_UP:
S->ThrustOff();
break;
}
}
void CGameSession::Reshape(int w,int h)
{
ScreenW=w;
ScreenH=h;
float wr=float(w)/h;
float hr=float(h)/w;
if(w>h) hr=1;
else wr=1;
int VL = -SpaceSize*wr;
int VR = SpaceSize*wr;
int VB = -SpaceSize*hr;
int VT = SpaceSize*hr;
glViewport(0,0,w,h);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glOrtho(VL,VR,VB,VT,-100,100);
glMatrixMode(GL_MODELVIEW);
}
int CGameSession::Draw()
{
glColor3f(1,0,0);
m_Utility.glPrintf(ScreenW,ScreenH,10,ScreenH-20,0,10,"SCORE %8i LIVES: %i", Score, Lives);
int nt=0;
glPushMatrix();
glScalef(SpaceSize*2,SpaceSize*2,1);
glTranslatef(0,0,-50);
nt+=SB.Draw();
glPopMatrix();
if(S->active)
nt+=S->Draw();
list<CBullet *>::iterator lib;
for(lib=ActiveBullet.begin();lib!=ActiveBullet.end();++lib)
nt+=(*lib)->Draw();
list<CAst *>::iterator lia;
for(lia=ActiveAst.begin();lia!=ActiveAst.end();++lia)
nt+=(*lia)->Draw();
list<CGameObj *>::iterator li;
for(li=ActiveObj.begin();li!=ActiveObj.end();++li)
nt+=(*li)->Draw();
return nt;
}
void CGameSession::Update(int dt)
{
SB.Update(dt);
if(PauseFlag) return;
if(endlevelpause>0)
{
endlevelpause-=dt;
if(endlevelpause<=0)
{
Game->Init(Score,Lives);
Game->Reshape(ScreenW,ScreenH);
}
}
if(S->active)
{
S->Update(dt);
Clip(S->p);
}
else
{
deadpause-=dt;
if(deadpause<0)
{
if(Lives==0)
{
Game->End();
Game=&GI;
GI.Init();
GI.Reshape(ScreenW,ScreenH);
}
}
}
list<CBullet *>::iterator lib;
for(lib=ActiveBullet.begin();lib!=ActiveBullet.end();++lib)
{
(*lib)->Update(dt);
Clip((*lib)->p);
BulletAstCollision(*lib);
if((*lib)->active==false)
{
CGameObj *todel=*lib;
lib=ActiveBullet.erase(lib);
S->TerminateBullet();
delete todel;
}
if(lib==ActiveBullet.end()) break;
}
list<CAst *>::iterator lia;
for(lia=ActiveAst.begin();lia!=ActiveAst.end();++lia)
{
(*lia)->Update(dt);
Clip((*lia)->p);
AstShipCollision(*lia);
if((*lia)->active==false)
{
CGameObj *todel=*lia;
lia=ActiveAst.erase(lia);
delete todel;
}
if(lia==ActiveAst.end()) break;
}
if(ActiveAst.empty() && endlevelpause==0)
endlevelpause=2000;
list<CGameObj *>::iterator li;
for(li=ActiveObj.begin();li!=ActiveObj.end();++li)
{
(*li)->Update(dt);
Clip((*li)->p);
if((*li)->active==false)
{
CGameObj *todel=*li;
li=ActiveObj.erase(li);
delete todel;
}
if(li==ActiveObj.end()) break;
}
}
void CGameSession::Shoot()
{
if(!S->active) return;
if(AudioFlag)
{
APlayVoice(hVoiceFire, lpWaveFire);
ASetVoiceVolume(hVoiceFire, 48);
ASetVoicePanning(hVoiceFire, 128);
}
S->Shoot(ActiveBullet);
}
void CGameSession::End()
{
CExp::LightOffAll();
}
void CGameSession::Init(int _score, int _lives)
{
deadpause=0;
endlevelpause=0;
Score=_score;
Lives=_lives;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
float lp[4]={1,1,3,0};
glLightfv(GL_LIGHT0,GL_POSITION,lp);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHTING);
float lc[4]={(GLfloat)1.,(GLfloat).7,(GLfloat).5,(GLfloat)1.};
for(int i=0;i<3;i++)
{
glLightfv(GL_LIGHT1+i,GL_DIFFUSE,lc);
glLightf(GL_LIGHT1+i,GL_QUADRATIC_ATTENUATION,.001f);
}
glEnable(GL_CULL_FACE);
glEnable(GL_COLOR_MATERIAL);
glEnable(GL_DEPTH_TEST);
glEnable(GL_NORMALIZE);
ActiveAst.clear();
ActiveBullet.clear();
ActiveObj.clear();
CExp::LightOffAll();
S=new CShip3D("data/newship.raw","data/ship.png");
CAst *a;
CMesh AstM;
AstM.Open("data/tetra.raw");
CAst3DFract::SetSharedTexture("data/ast.png");
for(i=0;i<AstNum;i++)
{
a=new CAst3DFract(AstM,CAst::LargeSize);
do
{
a->p.x()=drand48()*SpaceSize*2 - SpaceSize;
a->p.y()=drand48()*SpaceSize*2 - SpaceSize;
a->p.z()=0;
} while(a->p.Norm()<SpaceSize/2);
a->v.x()=drand48()*40 - 20;
a->v.y()=drand48()*40 - 20;
a->v.z()=0;
a->av=20+drand48()*70;
a->axis=Point3f(drand48(),drand48(),drand48());
a->GenerateSub(AstM);
ActiveAst.push_back(a);
}
}
void CGameSession::AstShipCollision(CAst *a)
{
if(S->active && a->Collide(S)) // Asteroid - Ship Collision
{
if(AudioFlag)
{
APlayVoice(hVoiceExp[0], lpWaveShipExp);
ASetVoiceVolume(hVoiceExp[0], 64);
ASetVoicePanning(hVoiceExp[0], 128);
}
S->active=false;
Lives--;
deadpause=2000;
CExp *e =new CExp();
e->p=(a->p+S->p)/2;
ActiveObj.push_back(e);
CFragment *f;
for(int i=0; i<50;i++)
{
if(i%2) f=new CFragment(Point3f(1,0,0));
else f=new CFragment(Point3f(0,1,0));
f->p=S->p;
f->v=Point3f(drand48()-.5f,drand48()-.5f,0)*30;
f->axis=Normalize(Point3f(drand48(),drand48(),drand48()));
f->av=40+drand48()*100;
f->ttl=2000;
ActiveObj.push_front(f);
}
S->p=S->v=Point3f(0,0,0);
}
}
void CGameSession::BulletAstCollision(CBullet *b)
{
static voice=0;
if(!b->active) return;
list<CAst *>::iterator lia;
for(lia=ActiveAst.begin();lia!=ActiveAst.end();++lia)
if((*lia)->active && (*lia)->Collide(b))
{
b->active=false;
Score+=(*lia)->Points();
if(AudioFlag)
{
voice=(voice+1)%3;
APlayVoice(hVoiceExp[voice], lpWaveExp);
ASetVoiceVolume(hVoiceExp[voice], 32);
ASetVoicePanning(hVoiceExp[voice], 128);
}
(*lia)->Explode(ActiveAst,ActiveObj);
return;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -