今天断粮了,饿了一天,到了晚上八点终于买到份四百块钱的水饺。吃撑了,写点东西消化一下。这是一个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";
}
完