www.pudn.com > MyGame.rar > 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::iterator lib; 
	for(lib=ActiveBullet.begin();lib!=ActiveBullet.end();++lib) 
		nt+=(*lib)->Draw(); 
	list::iterator lia; 
	for(lia=ActiveAst.begin();lia!=ActiveAst.end();++lia) 
		nt+=(*lia)->Draw(); 
	list::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::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::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::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;ip.x()=drand48()*SpaceSize*2 - SpaceSize;	 
			a->p.y()=drand48()*SpaceSize*2 - SpaceSize; 
			a->p.z()=0; 
		} while(a->p.Norm()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::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; 
		} 
}