祖玛游戏3D版源代码

今天断粮了,饿了一天,到了晚上八点终于买到份四百块钱的水饺。吃撑了,写点东西消化一下。这是一个3D版祖玛小游戏,使用的还是crapell引擎,c++开发,感觉现在还用c++开发游戏的好像不多了,代码比较简单,只有基本的功能,细节就不完善了。

和经典的祖玛游戏玩法类似,发射子弹,三个颜色相同的球连在一起可以消除。小球在路径上推挤前进,路径可以做成架起的铁轨或挖出的河道。有一些想法没做,因为在其它的小游戏中已经实现过,这里就不重复了,比如小球可以由物理引擎驱动,或者加入复杂的地形机关。

暂时写了一个简单的自动挂机算法,没有加入联机功能。

有个直觉,坚持了十几年的游戏开发事业可能快到头了,打算把自己写的一个游戏引擎和二三十个小游戏总结一下。

 

小球类:


//========================================================
//  @Date:     2016.05
//  @File:     Include/Zuma/ZumaBall.h
//  @Brief:     ZumaBall
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================


#ifndef _ZumaBall_H
#define _ZumaBall_H

#include "General/Pch.h"
#include "Render/Texture.h"

#define ZumaBallRadius 20
#define ZumaBulletSpeed  400
#define ZumaBallFit 7 //万能匹配球

//todov地图上挖沟或建铁轨或随水流   特殊点可以汇聚到轨道上的河或站台上
//
//参考平衡球 管道阻挡   吹起ball   ball进入弹跳板 重力

class MiniGameZuma;
class ZumaPath;
class ZumaBallBase
{
public:
	ZumaBallBase();
	virtual void Render(){};
	virtual void Update (float frameTime);
	void SetSize(float size);
	void SetRot(vec3& axis);

public:
	float m_radius;
	int   m_color;

	int   m_state;	
	float m_stateTime;
	
	vec3  m_pos;
	vec3  m_speed;

	vec3  m_rotAxis;
	float m_rot;

	ZumaPath* m_path;
};

//祖玛球
class ZumaBall:public ZumaBallBase
{
public:
	enum State
	{
		Inactive=-1,
		Running=1,
		Exploiding,
	};
	ZumaBall();
	virtual void Render();
	virtual void Update(float frameTime);

public:
	float m_pathPos;
	float m_pathSpeed;
};

#endif
//========================================================
//  @Date:     2016.05
//  @File:     Include/Render/Curve.h
//  @Brief:     Curve
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================

#include "General/Pch.h"
#include "General/Timer.h"
#include "Math/MathLib.h"
#include "Zuma/ZumaBall.h"
#include "Zuma/ZumaBullet.h"
#include "Zuma/MiniGameZuma.h"
#include "Render/RendDriver.h"
#include "Render/Curve.h"
#include "General/Pce.h"


ZumaBallBase::ZumaBallBase()
:m_path(NULL)
,m_color(0)
,m_state(0)
,m_radius(ZumaBallRadius)
{

}
void ZumaBallBase::SetSize(float size)
{
	m_radius = size;
}
void ZumaBallBase::SetRot(vec3& axis)
{
	m_rotAxis = axis;
	m_rot = 0;
}
void ZumaBallBase::Update(float frameTime)
{
	if (m_state == false)
	{
		return;
	}
}

ZumaBall::ZumaBall()
:m_pathPos(0)
,m_pathSpeed(0)
{

}

void ZumaBall::Render()
{
	if (m_state == Inactive)
	{
		return;
	}
	mat4 trans;
	trans.FromTranslate(m_pos.x,m_pos.y,m_pos.z);

	mat4 rot1;
	rot1.FromToDir(vec3(0,1,0),m_rotAxis);

	m_rot = m_path->m_curve->Path2Length(m_pathPos)/m_radius;

	mat4 rot2;
	rot2.FromRotateX(m_rot);


	G_RendDriver->PushMatrix();

	G_RendDriver->MultMatrix(trans*rot1*rot2);

	if (m_state == Exploiding)
	{
		if (Rand()%2)
		{
			G_RendDriver->BlendFunc(Blend_Additive);
		}
		else
		{
			G_RendDriver->BlendFunc(Blend_Filter);
		}
	}
	else
	{
		G_RendDriver->BlendFunc(Blend_Filter);
	}
	G_ZumaGame->m_ballMovie[m_color]->GetMaterial()->Bind();
	G_ZumaGame->m_ballMovie[m_color]->GetMesh()->Render();

	G_RendDriver->PopMatrix();
}

void ZumaBall::Update(float frameTime)
{
	if (m_state == Inactive)
	{
		return;
	}
	//ZumaBallBase::Update(frameTime);

	if(m_pathPos > m_path->m_curve->GetPointNum())
	{
		m_state = Inactive;
	}

	if (m_state == Exploiding)
	{
		if (m_stateTime>0.7f)
		{
			m_state = Inactive;
		}
		m_stateTime += frameTime;
	}
	球和球的作用力
	//{
	//	ZumaBall* ball1,*ball2;
	//	vec3 dif;
	//	vec3 move;
	//	vec3 acc;
	//	float dis;
	//	float radiusSum;

	//	for (int j=i+1;j<MaxBallNum;j++)
	//	{
	//		ball2 = &m_balls[j];
	//		dif = m_pos-ball2->m_pos;
	//		dis = dif.Length();
	//		radiusSum = m_size+ball2->m_size;
	//		if (dis<radiusSum)
	//		{
	//			//分离
	//			acc = (m_speed-ball2->m_speed)*0.5f;
	//			m_speed -= acc;
	//			ball2->m_speed += acc;
	//			if (dis>_EPSILON)
	//			{
	//				move = dif*((radiusSum-dis)/dis);
	//			}
	//			else
	//			{
	//				move = vec3(0.5f,0,0)*(radiusSum-dis);
	//			}
	//			m_pos += move;//*0.1f;
	//			ball2->m_pos -= move;//*0.1f;
	//		}
	//		else if (dis < radiusSum*2)
	//		{
	//			//吸在一起
	//			move = dif*(60/*10*/*frameTime/dis);
	//			m_speed -= move;
	//			ball2->m_speed += move;
	//		}
	//	}
	//}


}


路径类:


//========================================================
//  @Date:     2016.05
//  @File:     Include/Zuma/ZumaBall.h
//  @Brief:     ZumaBall
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================


#ifndef _ZumaPath_H
#define _ZumaPath_H

#include "General/Pch.h"
#include "Render/Texture.h"
#include "Zuma/ZumaBall.h"
#include <list>

class Curve;

typedef std::list<ZumaBall> ZumaBallList;
class ZumaPath
{
public:
	ZumaPath();
	bool Start();
	bool Stop();
	bool Render();
	bool Update(float frameTime);
	bool Free();
	
	ZumaBall* AddBall(const ZumaBall& ball,ZumaBall* pos=NULL,bool prev=false);

	vec3 GetBestPos(int ballColor,const vec3& firePos,float bulletSpeed);

public:
	Curve*     m_curve;
	float      m_lastBallTime;
	int        m_state;

	ZumaBallList m_balls;
};

#endif
//========================================================
//  @Date:     2016.05
//  @File:     Include/Render/Curve.h
//  @Brief:     Curve
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================

#include "General/Pch.h"
#include "General/Timer.h"
#include "Math/MathLib.h"
#include "Zuma/ZumaBall.h"
#include "Zuma/ZumaBullet.h"
#include "Zuma/ZumaPath.h"
#include "Zuma/MiniGameZuma.h"
#include "Render/RendDriver.h"
#include "Render/Curve.h"
#include "General/Pce.h"

ZumaPath::ZumaPath()
{

}

bool ZumaPath::Update(float frameTime)
{
	//碰撞吸入子弹



	if (G_Timer->GetAccumTime()>m_lastBallTime+3.2f)
	{
		//加入新ball
		m_lastBallTime = G_Timer->GetAccumTime();

		ZumaBall ball;
		ball.m_pos = m_curve->GetPos(0);
		//ball.m_speed = vec3(RandRange(-1.0f,1.0f),RandRange(-1.0f,1.0f),RandRange(-1.0f,1.0f))*50;
		vec3 normal(RandRange(-1,1),RandRange(-1,1),RandRange(-1,1));
		normal.Normalize();
		ball.SetRot(normal);
		ball.m_color = Rand()%7;

		AddBall(ball);
	}

	//消除
	{
		bool erase = false;
		for (ZumaBallList::iterator it=m_balls.begin(); it!=m_balls.end(); )
		{
			it->Update(frameTime);
			if (it->m_state==ZumaBall::Inactive)
			{
				it = m_balls.erase(it);
				erase = true;
			}
			else
			{
				++it;
			}
		}
		if (erase)
		{
			G_ZumaGame->PlaySound__("data/sound/ui_quit.wav");
		}
	}


	vec3  lastPos;
	float lastPathPos;
	if (m_balls.size()>0)
	{
		float len2path = m_curve->Length2Path(1);

		//最后一个球推挤 前进
		ZumaBall* thisBall = &m_balls.back();
		lastPos     = thisBall->m_pos;
		lastPathPos = thisBall->m_pathPos;
		thisBall->m_pathPos += thisBall->m_radius*2*len2path*frameTime/1.0f;
		thisBall->m_pos = m_curve->GetPosf(thisBall->m_pathPos);
		thisBall->m_speed     = (thisBall->m_pos-lastPos)/frameTime;
		thisBall->m_pathSpeed = (thisBall->m_pathPos-lastPathPos)/frameTime;

		//球和球的作用力 前进 静止 回退
		{
			ZumaBall* preBall;
			float dis;
			float radiusSum;
			for (ZumaBallList::reverse_iterator it=m_balls.rbegin(); it!=m_balls.rend(); ++it)
			{
				thisBall = &*it;
				//if (thisBall->m_state!=ZumaBall::Running)
				//{
				//	continue;
				//}
				ZumaBallList::reverse_iterator it2 = it;
				++it2;
				if(it2==m_balls.rend())
				{
					break;
				}

				preBall = &*it2;
				lastPos     = preBall->m_pos;
				lastPathPos = preBall->m_pathPos;
				//if (preBall->m_state!=ZumaBall::Running)
				//{
				//	continue;
				//}
				//dis = abs(preBall->m_pathPos - ball->m_pathPos);
				dis = (preBall->m_pathPos - thisBall->m_pathPos);
				radiusSum = (thisBall->m_radius+preBall->m_radius)*len2path;
				if (dis<radiusSum*0.95f)
				{
					//推挤
					preBall->m_pathPos += (radiusSum-dis)*0.5f;
					preBall->m_pos = m_curve->GetPosf(preBall->m_pathPos);
				}
				else if(dis>radiusSum*1.05f && it!=m_balls.rbegin())
				{
					//拉
					preBall->m_pathPos += (radiusSum-dis)*0.05f;
					preBall->m_pos = m_curve->GetPosf(preBall->m_pathPos);
				}

				preBall->m_speed     = (preBall->m_pos-lastPos)/frameTime;
				preBall->m_pathSpeed = (preBall->m_pathPos-lastPathPos)/frameTime;
			}
		}

		//检测3消
		{
			bool exploid = false;
			ZumaBall* nextBall;
			for (ZumaBallList::iterator it=m_balls.begin(); it!=m_balls.end(); ++it)
			{
				thisBall = &*it;
				if (thisBall->m_state!=ZumaBall::Running)
				{
					continue;
				}
				ZumaBallList::iterator it2 = it;
				++it2;
				int num = 1;
				for (; it2!=m_balls.end(); ++it2)
				{
					nextBall = &*it2;
					if (nextBall->m_state!=ZumaBall::Running
						||(nextBall->m_color!=thisBall->m_color && nextBall->m_color!=ZumaBallFit)
						||(thisBall->m_pathPos-nextBall->m_pathPos > ZumaBallRadius*2*len2path*num*1.2f)
						)
					{
						break;
					}
					num++;
				}
				if (num>=3)
				{
					it2 = it;
					for (int j=0; j<num; j++,++it2)
					{
						nextBall = &*it2;
						nextBall->m_state = ZumaBall::Exploiding;
						nextBall->m_stateTime = 0;
						exploid = true;
					}
				}
			}
			if (exploid)
			{
				G_ZumaGame->PlaySound__("data/sound/obj_electric.wav");
			}

		}
	}
	return true;
}

bool ZumaPath::Start()
{
	m_lastBallTime = 0;
	m_balls.clear();

	return true;
}

bool ZumaPath::Stop()
{
	return true;
}

bool ZumaPath::Render()
{
	for (ZumaBallList::iterator it=m_balls.begin(); it!=m_balls.end(); ++it)
	{
		(*it).Render();
	}
	G_RendDriver->BlendFunc(Blend_Filter);
	return true;
}

bool ZumaPath::Free()
{
	return true;
}

ZumaBall* ZumaPath::AddBall(const ZumaBall& ball,ZumaBall* pos,bool prev)
{
	ZumaBall* pBall;
	if (pos==NULL)
	{
		m_balls.push_back(ball);
		pBall = &m_balls.back();
	}
	else
	{
		bool find = false;
		for (ZumaBallList::iterator it=m_balls.begin(); it!=m_balls.end(); ++it)
		{
			if ((&*it)==pos)
			{
				if (prev)
				{
					pBall = &*m_balls.insert(it,ball);
				}
				else
				{
					//if (it== m_balls.end())
					//{
					//	m_balls.push_back(ball);
					//	pBall = &m_balls.back();
					//}
					//else
					{
						++it;
						pBall = &*m_balls.insert(it,ball);
					}
					//pBall = &*m_balls.rinsert(ZumaBallList::reverse_iterator(it),ball);
				}
				find = true;
				break;
			}
		}
		if (find==false)
		{
			m_balls.push_back(ball);
			pBall = &m_balls.back();
		}
	}

	pBall->m_state = ZumaBall::Running;
	pBall->m_path = this;
	//if (erase)
	{
		G_ZumaGame->PlaySound__("data/sound/ui_click.wav");
	}
	return pBall;
}

vec3 ZumaPath::GetBestPos(int ballColor,const vec3& firePos,float bulletSpeed)
{
	if (ballColor==ZumaBallFit)
	{
		if (m_balls.empty()==false)
		{
			return m_balls.front().m_pos;
		}
	}
	ZumaBall* bestBall = NULL;
	for (int tryNum = 4;tryNum>0;tryNum--)
	{
		int continueNum = 0;
		for (ZumaBallList::iterator it=m_balls.begin(); it!=m_balls.end(); ++it)
		{
			if (it->m_state!=ZumaBall::Inactive)
			{
				if (it->m_color==ballColor)
				{
					continueNum++;
					if (continueNum>=tryNum)
					{
						bestBall = &*it;
						break;
					}
				}
				else
				{
					continueNum = 0;
				}
			}
		}
	}
	if (bestBall == NULL)
	{
		return m_curve->GetPosf(RandRange(0.0f,1.0f));
	}
	//预测提前量
	vec3  pos  = bestBall->m_pos;
	float time = (pos-firePos).Length()/bulletSpeed;
	pos = m_curve->GetPosf(bestBall->m_pathPos+ bestBall->m_pathSpeed*time);

	//适当提高目标点? 前面可能有其它球阻挡
	return pos;
}

子弹类


//========================================================
//  @Date:     2016.05
//  @File:     Include/Zuma/ZumaBullet.h
//  @Brief:     ZumaBullet
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================


#ifndef _ZumaBullet_H
#define _ZumaBullet_H

#include "General/Pch.h"
#include "Render/Texture.h"

class MiniGameZuma;
class ZumaPath;
class ZumaBallBase;
子弹从制高点发射 沿地面或架设铁轨前进   直线铁轨或贴地铁轨   纯物理是否可能从沟壕上跳过  
class ZumaBullet:public ZumaBallBase
{
public:
	enum State
	{
		Inactive=-1,
		Running=1,
		Exploiding,
	};
	ZumaBullet();
	void Render();
	void Update(float frameTime);
	void GenBuffer();
};

#endif
//========================================================
//  @Date:     2016.05
//  @File:     Include/Zuma/ZumaBullet.cpp
//  @Brief:     ZumaBullet
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================

#include "General/Pch.h"
#include "General/Timer.h"
#include "Math/MathLib.h"
#include "Zuma/ZumaBall.h"
#include "Zuma/ZumaBullet.h"
#include "Zuma/MiniGameZuma.h"
#include "Render/Curve.h"
#include "Render/RendDriver.h"
#include "General/Pce.h"

ZumaBullet::ZumaBullet()
{
	m_radius = ZumaBallRadius;
	vec3 normal = vec3(RandRange(-1,1),RandRange(-1,1),RandRange(-1,1));
	normal.Normalize();
	SetRot(normal);
	m_color = 0;
	m_state = Inactive;
}

void ZumaBullet::Render()
{
	if (m_state == false)
	{
		return;
	}
	mat4 trans;
	trans.FromTranslate(m_pos.x,m_pos.y,m_pos.z);

	mat4 rot1;
	rot1.FromToDir(vec3(0,1,0),m_rotAxis);

	mat4 rot2;
	rot2.FromRotateY(m_rot);


	G_RendDriver->PushMatrix();

	G_RendDriver->MultMatrix(trans*rot1*rot2);

	G_ZumaGame->m_ballMovie[m_color]->GetMaterial()->Bind();
	G_ZumaGame->m_ballMovie[m_color]->GetMesh()->Render();

	G_RendDriver->PopMatrix();
}

void ZumaBullet::Update(float frameTime)
{
	if (m_state == Inactive)
	{
		return;
	}
	m_pos += m_speed*frameTime;

	//wrap
	float limit = 100;
	if(m_pos.x < G_ZumaGame->m_minBoxPos.x-limit)
	{
		m_state = Inactive;
	}
	else if(m_pos.x > G_ZumaGame->m_maxBoxPos.x+limit)
	{
		m_state = Inactive;
	}

	if(m_pos.y < G_ZumaGame->m_minBoxPos.y-limit)
	{
		m_state = Inactive;
	}
	else if(m_pos.y > G_ZumaGame->m_maxBoxPos.y+limit)
	{
		m_state = Inactive;
	}

	if(m_pos.z < G_ZumaGame->m_minBoxPos.z-limit)
	{
		m_state = Inactive;
	}
	else if(m_pos.z > G_ZumaGame->m_maxBoxPos.z+limit)
	{
		m_state = Inactive;
	}

	//球和子弹的作用力	
	vec3 dif;
	float dis;
	float radiusSum;
	for (int i=0;i<G_ZumaGame->m_pathNum;i++)
	{
		ZumaPath* path = &G_ZumaGame->m_paths[i];
		for (ZumaBallList::iterator it=path->m_balls.begin(); it!=path->m_balls.end(); ++it)
		{
			ZumaBall* ball = &*it;
			if (ball->m_state==ZumaBall::Inactive)
			{
				continue;
			}

			dif = ball->m_pos-m_pos;
			dis = dif.Length();
			radiusSum = ball->m_radius+m_radius;
			if (dis<radiusSum)
			{
				m_state = Inactive;
				if (m_color==ZumaBallFit)  //炸弹
				{
					ball->m_state = ZumaBall::Exploiding;
					ball->m_stateTime = 0;
				}
				//else if (m_color==6 && ball->m_color==6) //紫色
				//{
				//	ball->m_state = ZumaBall::Exploiding;
				//	ball->m_stateTime = 0;
				//}
				else
				{
					vec3 tagent   = ball->m_path->m_curve->GetTangentf(ball->m_pathPos);
					bool prev = false;
					vec3 newSpeed = Reflect(m_speed,m_pos-ball->m_pos);
					if (newSpeed.Dot(tagent) > 0)
					{
						prev = true;
					}
					ZumaBall*newball = ball->m_path->AddBall(*ball,ball,prev);
					newball->m_color = m_color;
				}

				break;
			}
		}
		if (m_state == Inactive)
		{
			break;
		}
	}
}

游戏类

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Zuma/MiniGameZuma.h
//  @Brief:     MiniGameZuma
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#ifndef  __MiniGameZuma__H__
#define  __MiniGameZuma__H__

#include "Math/MathLib.h"
#include "Render/Texture.h"
#include "Rpg/MiniGame.h"
#include "Render/MC_Misc.h"
#include "Zuma/ZumaBall.h"
#include "Zuma/ZumaBullet.h"
#include "Zuma/ZumaPath.h"
#include <list>

enum MiniZumaCmd
{
	CMD_ManShoot,      //
	CMD_GameOver,
	CMD_Restart ,
};
const char* ZumaCmdToString(int enumeration);

class ZumaPlayerRole;
class MiniGameZuma:public MiniGame
{
public:
	MiniGameZuma();
	virtual ~MiniGameZuma();

	virtual bool KeepResource(bool once,int& circle,String& nextTip);
	virtual bool Start();
	virtual bool Stop();
	virtual bool Render();
	virtual void RenderUI();
	virtual bool Update();
	virtual bool Free();
	virtual bool IsEnd();

	//三种类型结构
	virtual MiniPlayer*  CreatePlayer();
	virtual MiniPlayer*  CreateRobot ();
	virtual MiniPlayer*  CreateRole  ();

	//处理游戏网络命令包
	virtual int  ProcessPacketCmd(PacketBase* packet);
	//virtual const char* CmdToString(const char* stream,int len);

	void Restart();

	TexturePtr m_textureSelectGreen;	
	TexturePtr m_textureSelectRed;

	ZumaPlayerRole* m_myRolePlayer;


	void AddBullet(const ZumaBullet& bullet);

	vec3 m_eyePos;
	vec3 m_halfBox;
	vec3 m_minBoxPos;
	vec3 m_maxBoxPos;

#define MaxPathNum 8
	ZumaPath m_paths[MaxPathNum];
	int      m_pathNum;

#define MaxRoadNum 8
	Curve*   m_roads[MaxRoadNum];
	int      m_roadNum;

	typedef std::list<ZumaBullet> ZumaBulletList;
	ZumaBulletList	m_bullets;
	
	float      m_lastFireTime;
	vec3       m_clickPos;
	vec3       m_firePos;
	int        m_fireColor;

	TexturePtr m_textureBall;

	RendSys::MC_Frame*  m_ballMovie[8];
	RendSys::MC_Frame*  m_stickMovie;

	bool  m_workingWithAI;

};
extern MiniGameZuma* G_ZumaGame;
#endif 

//========================================================
//  @Date:     2016.05
//  @File:     SourceDemoClient/Zuma/MiniGameZuma.cpp
//  @Brief:     MiniGameZuma
//  @Author:     LouLei
//  @Email:  twopointfive@163.com
//  @Copyright (Crapell) - All Rights Reserved
//========================================================
 
#include "General/Pch.h"
#include "General/Window.h"
#include "General/Timer.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Input/InputMgr.h"
#include "Zuma/ZumaPath.h"
#include "Zuma/MiniGameZuma.h"
#include "Zuma/MiZuma_PlayGui.h"
#include "Render/RendDriver.h"
#include "Render/Shader.h"
#include "Rpg/SyncGameInfo.h"
#include "Packet/PacketMiniGame.h"
#include "Net/PacketList.h"
#include "Render/Curve.h"
#include "Render/Camera.h"
#include "Math/MathlibAdvance.h"
#include "General/Pce.h"

MiniGameZuma* G_ZumaGame;
MiniGameZuma::MiniGameZuma()
   : m_stickMovie(NULL)
{
	G_ZumaGame = this;
	CmdEnumToString = ZumaCmdToString;
}

MiniGameZuma::~MiniGameZuma()
{
	G_ZumaGame = NULL;
}

bool MiniGameZuma::Start()
{
	if(!MiniGame::Start())
		return false;

	m_workingWithAI = false;

	if (m_movieScene == NULL)
	{
		LoadConfig loader(LoadConfig::GenDonotReShrinkBound, true, true);
		m_movieScene = new RendSys::MovieClip;
		m_movieScene->LoadFromFile("data/minigame/zuma/level001.movie", &loader);

		Frame frame;
		frame.SetPos(m_startPos);
		m_movieScene->SetProgramFrame(&frame);
		m_movieScene->Advance();
	}

	if (m_movieScene->IsLoadComplete() == false)
	{
		m_gameState = MS_End;
		return false;
	}

	//m_firePos;
	m_fireColor = 0;

	char buf[256];
	m_pathNum = 0;
	for (int i=0;i<MaxPathNum;i++)
	{
		sprintf(buf,"path%02d",i);
		MC_Lines* line = dynamic_cast<MC_Lines*>(m_movieScene->GetMovieClip(buf));
		if (line)
		{
			m_paths[m_pathNum].m_curve = line->m_linesWorld;
			m_paths[m_pathNum].Start();
			m_pathNum++;
		}
	}
	if (m_pathNum==0)
	{
		m_gameState = MS_End;
		return false;
	}


	//
	m_roadNum = 0;
	for (int i=0;i<MaxRoadNum;i++)
	{
		sprintf(buf,"road%02d",i);
		MC_Lines* line = dynamic_cast<MC_Lines*>(m_movieScene->GetMovieClip(buf));
		if (line)
		{
			m_roads[m_roadNum] = line->m_linesWorld;
			m_roadNum++;
		}
	}
	if (m_roadNum==0)
	{
		m_gameState = MS_End;
		return false;
	}

	//
	for (int i=0;i<8;i++)
	{
		sprintf(buf,"ball%02d",i);
		m_ballMovie[i] = dynamic_cast<MC_Frame*>(m_movieScene->GetMovieClip(buf));
	}

	m_stickMovie = dynamic_cast<MC_Frame*>(m_movieScene->GetMovieClip("stick"));

	m_gameState= MS_Gamming;

	m_halfBox = vec3(800,500,800);
	m_bullets.clear();

//	char buf[256];

	G_TextureMgr->AddTexture(m_textureBall,"data/minigame/zuma/ball.png");

	m_minBoxPos = m_eyePos-m_halfBox;
	m_maxBoxPos = m_eyePos+m_halfBox;

	m_lastFireTime = 0;

	//进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。
	if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);

	//设置摄像机
	CameraCtrlerTarget* ctrler = new CameraCtrlerTarget(10,2000);
	ctrler->SetDistToTar(300);
	ctrler->SetTarPos(m_startPos);
	G_Camera->PushCtrler(ctrler);	
	G_Camera->SetEuler(0,-30,0);
	//片头摄像机
	PushIntroCamera();

	return true;
}

MiniPlayer* MiniGameZuma::CreatePlayer()
{
	return NULL;//new ChessPlayer;
}

MiniPlayer* MiniGameZuma::CreateRobot()
{
	return NULL;// new ChessPlayerRobot;
}

MiniPlayer* MiniGameZuma::CreateRole()
{
	//m_myRolePlayer = NULL;//new ChessPlayerRole;
	//return m_myRolePlayer;
	return NULL;
}


bool MiniGameZuma::Stop()
{
	//
	{
		if (m_myPlayer && m_myPlayer->m_liveNum>0)
		{
			G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(true);
		}
		else
		{
			G_GuiMgr->GetGui<Rpg_ResultDialog>()->ShowResult(false);
		}
		G_GuiMgr->PushGui("Rpg_ResultDialog",GL_DIALOGBOTTOM); 
	}
	return MiniGame::Stop();
}

bool MiniGameZuma::KeepResource(bool once,int& circle,String& nextTip)
{

	//G_TextureMgr->AddTexture(m_textureBoard,"data/minigame/Zuma/board.png");
//	G_TextureMgr->AddTexture(m_textureCantgo,"data/minigame/Zuma/cantgo.png");

	return true;
}

bool MiniGameZuma::Render()
{
	G_RendDriver->EndUI();
	G_RendDriver->SetViewPortf(0,0,1,1);
	G_RendDriver->DefaultLight();//d3d 不加movie画不出来

	G_RendDriver->Color4f(1,1,1,1);
	G_RendDriver->SetRenderStateEnable(RS_BLEND,true);

	//for(int i = 0; i < m_allPlayerNum; i++)
	//{
	//	dynamic_cast<ZumaPlayer*>(m_miniPlayer[i])->Render();
	//}

	//
	m_movieScene->RendClip();

	G_RendDriver->SetRenderStateEnable(RS_LIGHTING,true);

	//球
	G_RendDriver->DepthMask(true);
	G_RendDriver->SetRenderStateEnable(RS_DEPTH_TEST,true);
	m_textureBall->Bind();
	for (int i=0;i<m_pathNum;i++)
	{
		m_paths[i].Render();
	}

	//
	//G_RendDriver->RendLine(m_firePos,);

	//
	mat4 trans;
	mat4 rot;
	trans.FromTranslate(m_firePos);
	rot.FromRotateX(m_turnTime);
	G_RendDriver->PushMatrix();
	G_RendDriver->MultMatrix(trans*rot);
	G_ZumaGame->m_ballMovie[m_fireColor]->GetMaterial()->Bind();
	G_ZumaGame->m_ballMovie[m_fireColor]->GetMesh()->Render();
	G_RendDriver->PopMatrix();

	trans.FromTranslate(m_clickPos);

	vec3 dir = m_clickPos-m_firePos;
	dir.Normalize();
	rot.FromToDir(vec3(0,0,-1),dir);
	G_RendDriver->PushMatrix();
	G_RendDriver->MultMatrix(trans*rot);
	G_ZumaGame->m_stickMovie->GetMesh()->Render();
	G_RendDriver->PopMatrix();


	//子弹
	for (ZumaBulletList::iterator it=m_bullets.begin(); it!=m_bullets.end(); ++it)
	{
		(*it).Render();
	}
	return true;
}

void MiniGameZuma::RenderUI()
{
	Render();
}
bool MiniGameZuma::Update() 
{
	if (m_movieScene == NULL)
	{
		return false;
	}

	m_turnTime += G_Timer->GetStepTimeLimited();

	m_movieScene->Advance();

	float frameTime = G_Timer->GetStepTimeLimited();


	for(int i = 0; i < m_allPlayerNum; i++)
	{
	//	dynamic_cast<ZumaPlayer*>(m_miniPlayer[i])->Update();
	}

	m_eyePos = G_Camera->GetEyePos();
	m_minBoxPos = m_eyePos-m_halfBox;
	m_maxBoxPos = m_eyePos+m_halfBox;

	for (int i=0;i<m_pathNum;i++)
	{
		m_paths[i].Update(frameTime);
	}

	m_firePos = G_Camera->GetEyePos()+ ZumaBallRadius * vec3(0,-3,0);

	//
	//发射子弹
	if (m_workingWithAI)
	{
		if (G_Timer->GetAccumTime()>m_lastFireTime+1.2f)
		{
			//不同的路径间产生阻挡?  选择最近的导致远的路径情况越来越糟?
			int path = rand()%m_pathNum;
			m_clickPos = m_paths[path].GetBestPos(m_fireColor,m_firePos,ZumaBulletSpeed);

			m_lastFireTime = G_Timer->GetAccumTime();
			ZumaBullet bullet;
			bullet.m_pos = m_firePos;
			bullet.m_speed = m_clickPos-m_firePos;
			bullet.m_speed.Normalize();
			bullet.m_speed *= ZumaBulletSpeed;
			AddBullet(bullet);
			//
			m_fireColor = Rand()%8;
		}
	}
	else
	{
		vec3 dir;
		vec3 start;
		G_Camera->GetMouseTray(start,dir);
		//和0平面的交点
		IntersectRayPlane(start,dir,m_paths[0].m_curve->GetPosf(0),vec3(0,1,0),m_clickPos);

		if (G_Mouse->IsButtonDowning(MOUSE_LEFT))
		{
			m_lastFireTime = G_Timer->GetAccumTime();
			ZumaBullet bullet;
			bullet.m_pos = m_firePos;
			bullet.m_speed = m_clickPos-m_firePos;
			bullet.m_speed.Normalize();
			bullet.m_speed *= ZumaBulletSpeed;
			AddBullet(bullet);
			//
			m_fireColor = Rand()%8;
		}
	}


	//子弹
	for (ZumaBulletList::iterator it=m_bullets.begin(); it!=m_bullets.end(); )
	{
		it->Update(frameTime);
		if (it->m_state==ZumaBullet::Inactive)
		{
			it = m_bullets.erase(it);
		}
		else
		{
			++it;
		}
	}
	return true;
}

bool MiniGameZuma::Free()
{
	MiniGame::Free();
	return true;
}

bool MiniGameZuma::IsEnd()
{
	return m_gameState == MS_End;
}

int  MiniGameZuma::ProcessPacketCmd(PacketBase* packet)
{
	int cmd;
	packet->ReadValue(cmd);
	switch(cmd)
	{
	case CMD_ManShoot:
		{
			int man = 0;
			vec2I targetPos;
			packet->ReadValue(man);
			packet->ReadValue(targetPos);
 
	
//			TryGo(man,targetPos);
		}
		break;
	case CMD_GameOver:
	//	{
	//		int turn = 0;
	//		packet->ReadValue(turn);
	//		m_winnerTurn = turn;
	//		m_turnTime = 0;
	//		m_gameStatus = Resulting;

	//		char sound[256];
	//		if (m_winnerTurn == m_lordTurn)
	//		{
	//			sprintf(sound,"data/sound/poker/play_lord_win");
	//		}
	//		else
	//		{
	//			sprintf(sound,"data/sound/poker/play_farmer_win");
	//		}
	//		if (m_winnerTurn%2) //
	//			strcat(sound,"_femail.wav");
	//		else
	//			strcat(sound,".wav");
	//		m_players[m_winnerTurn]->m_sound->PlaySound__(sound);

	//	}
		break;
	case CMD_Restart:
	//	Free();
	//	Start();
		break;
	}
	return 0;
}

void MiniGameZuma::AddBullet(const ZumaBullet& bullet)
{
	m_bullets.push_back(bullet);
	ZumaBullet& newBullet = m_bullets.back();
	newBullet.m_state = ZumaBullet::Running;
	newBullet.m_color = m_fireColor;
	PlaySound__("data/sound/gun_shoot.wav");
}

void MiniGameZuma::Restart()
{
	for (int i=0;i<m_pathNum;i++)
	{
		m_paths[i].Start();
	}

}

const char* ZumaCmdToString(int enumeration)
{
	switch(enumeration)
	{
	case CMD_ManShoot:return "CMD_ManShoot";		
	case CMD_GameOver:return "CMD_GameOver";		
	case CMD_Restart :return "CMD_Restart";		
	default                :return "CMD_unknow";
	}
	return "CMD_unknow";
}

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值