这是一款联机版俄罗斯方块游戏。共配置了13种方块。支持ai挂机功能。双人比赛,右下角显示对手的进度。
每消除一行,会给对手投递一个停滞蛛网,暂停对手的进度。连续消除多行时,投递停滞蛛网 + 快进,停滞1秒后跟着有1秒快进。
ai挂机功能使用的算法是遍历方块的旋转和位置,找出最佳着陆点。挂机算法还有一些可改进的地方,比如没考虑快满时来不及变换的情况,没考虑绕过阻挡后横移消除,没考虑同nextbar的配合。
停滞蛛网飞到右下角(对手右下角消除时飞出停滞蛛网)暂时用图片代替,也可以做成3D特效。
玩家类:
#ifndef Tetris_h__
#define Tetris_h__
#include "Math/MathLib.h"
#include "Render/Texture.h"
#define BlockNumW 10
#define BlockNumH 20
//条块类型
struct BlockBarStyle
{
public:
BlockBarStyle();
BlockBarStyle(int l, char *str);
//rot旋转下 xy位置是否实心
char IsSolid(int x, int y, int rot);
static const int MaxRot = 4;
int m_rotNum;
int m_barSize;
char m_mask[MaxRot][4][4];
int ID;
#define MaxBlockColor 12
static Color colors[MaxBlockColor];
};
#define BlockStyleNum 14
extern BlockBarStyle BlockStyles[BlockStyleNum];
class TetrisPlayer;
//一个条块
class BlockBar
{
public:
BlockBar();
void SetStyle(BlockBarStyle *style);
void Render(bool fast);
void DrawUI(const vec2I& pos);
//mov后是否触底
bool IsCollide (const vec2I& mov=vec2I(0, 0), int rot = -1);
//是否超出边框
bool IsOutBoard(const vec2I& mov=vec2I(0, 0), int rot = -1);
//move的得分
float Score(const vec2I& mov=vec2I(0, 0), int rot = -1);
void Rotate(int nTimes = 1);
bool Move(const vec2I& mov);
int m_ID;
vec2I m_point;
int m_curRot;
//Color m_color;
BlockBarStyle* m_style;
TetrisPlayer* m_owner;
};
//游戏状态
enum TetrisState
{
Gaming,
Vanishing, //消除中
ReLifing, //重生中
TimeFrozen, //时间被对手停滞
TimeFrozenTurble, //时间被对手停滞+停滞后激进
};
#define VanishTime 2.0f
#define FrozenTime 1.0f
#define FrozenTurbleTime 2.0f
#define RelifeTime 4.0f
class SoundChannel;
//玩家
class TetrisPlayer: public MiniPlayer
{
public:
TetrisPlayer();
virtual ~TetrisPlayer();
virtual bool Start();
virtual void Update();
virtual void Render();
void RenderBlocks();
virtual void NewBlock();
//是否超出边框
bool IsOutBoard(const vec2I& pos);
//触底后检查消除
void CheckVanishing();
//放入
void PutinCurBlockBar();
//新的一条命
void LifeDown();
RectF GetBlockRect(const vec2I& point);
//当前条块
BlockBar *m_curBlockBar;
//预览下一条块
BlockBar *m_nextBlockBar;
//颜色
int m_blockMap[BlockNumH][BlockNumW];
TetrisState m_state;
float m_stateTime;
//难度
int m_diffcuty;
//
int m_vanishLine;
//连消
int m_continueNum;
//主动快进 带拖尾
bool m_fast;
//时间停滞特效 显示蛛网
MovieClip* m_movieFrozen;
//被动快进特效 无拖尾 显示乱流
MovieClip* m_movieTurble;
RectF m_blockRect;
vec2 m_blockExtend;
double m_diffcultTime;
SoundChannel* m_sound;
};
//机器人
class TetrisPlayerRobot:public TetrisPlayer
{
public:
TetrisPlayerRobot();
virtual bool Start();
virtual void Update();
virtual void Render();
virtual void NewBlock();
void FindBestPoint();
void SetWorkingWithAI(bool working);
vec2I m_bestPoint;
int m_bestRot;
float m_bestScore;
bool m_workingWithAI;
double m_thinkTime;
};
//玩家
class TetrisPlayerRole:public TetrisPlayerRobot
{
public:
virtual bool Start();
virtual void Update();
};
#endif
//========================================================
// @Date: 2016.05
// @File: SourceDemoClient/Chess/MiniGameTetris.cpp
// @Brief: MiniGameTetris
// @Author: LouLei
// @Email: twopointfive@163.com
// @Copyright (Crapell) - All Rights Reserved
//========================================================
#include "General/Pch.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Input/InputMgr.h"
#include "MiniGameTetris.h"
#include "Render/RendDriver.h"
#include "Render/Font.h"
#include "Tetris/Tetris.h"
#include "Packet/PacketMiniGame.h"
#include "Sound/ChannelSound.h"
#include "General/Timer.h"
#include "General/Pce.h"
#include "General/Regulator.h"
#include "Math/MathLib.h"
Regulator LastKeyDownTime(8);
#define BarSize m_style->m_barSize
BlockBarStyle::BlockBarStyle(int size, char *str)
{
m_barSize = size;
memset(m_mask, 0, sizeof(m_mask));
//构建方块
for(int h = 0; h < size; h++)
{
for(int w = 0; w < size; w++)
{
m_mask[0][h][w] = str[h * size + w] - '0';
}
}
//构建旋转
for(int r = 1; r < MaxRot; r++)
{
for(int h = 0; h < m_barSize; h++)
{
for(int w = 0; w < m_barSize; w++)
{
m_mask[r][h][w] = m_mask[r - 1][w][m_barSize - 1 - h];
}
}
}
//旋转数 todo 还有可能是1
m_rotNum = 2;
for(int h = 0; h < m_barSize; h++)
{
for(int w = 0; w < m_barSize; w++)
{
if(m_mask[0][h][w] != m_mask[2][h][w])
{
m_rotNum = 4;//不对称
break;
}
}
}
}
BlockBarStyle::BlockBarStyle()
{
m_barSize = 0;
}
char BlockBarStyle::IsSolid(int x, int y, int rot)
{
//rot旋转时 xy位置是否实心
if (x<0 || x>=m_barSize)
{
return false;
}
if (y<0 || y>=m_barSize)
{
return false;
}
return m_mask[rot][y][x];
}
Color BlockBarStyle::colors[MaxBlockColor] =
{
Color::red ,//无效 red还未初始化
};
//==================^_^==================^_^==================^_^==================^_^
BlockBar::BlockBar()
:m_curRot(0)
{
}
bool BlockBar::Move(const vec2I& mov)
{
Assert(0<=m_curRot&&m_curRot<4,"0<=m_curRot&&m_curRot<4");
if(IsOutBoard(mov))
{
return false;
}
if(IsCollide(mov))
{
return false;
}
m_point += mov;
return true;
}
void BlockBar::Rotate(int nTimes /*= 1*/)
{
int nextRot = (m_curRot + nTimes + m_style->m_rotNum) % m_style->m_rotNum;
if(IsCollide(vec2I(0, 0), nextRot))
{
return;
}
if(IsOutBoard(vec2I(0, 0), nextRot))
{
//todo 旋转后移入边框
return;
}
m_curRot = nextRot;
}
bool BlockBar::IsCollide(const vec2I& mov, int rot /*= -1*/)
{
if (rot==-1)
{
rot = m_curRot;
}
for(int h = 0; h < BarSize; h++)
{
for(int w = 0; w < BarSize; w++)
{
if (m_style->IsSolid(w, h, rot))
{
vec2I pos = m_point + vec2I(w, h) + mov;
if(pos.y>=BlockNumH)
{
return true;//接触底框
}
if(m_owner->m_blockMap[pos.y][pos.x])
{
return true;//接触块
}
}
}
}
return false;
}
bool BlockBar::IsOutBoard(const vec2I& mov, int rot /*= -1*/)
{
if (rot==-1)
{
rot = m_curRot;
}
for(int h = 0; h < BarSize; h++)
{
for(int w = 0; w < BarSize; w++)
{
if (m_style->IsSolid(w, h, rot))
{
vec2I pos = m_point + vec2I(w, h) + mov;
if(m_owner->IsOutBoard(pos))
{
return true;
}
}
}
}
return false;
}
float BlockBar::Score(const vec2I& mov, int rot /*= -1*/)
{
if (rot==-1)
{
rot = m_curRot;
}
float score = 0;
vec2I pos = m_point + mov;
bool fullLine[BlockNumH];
for(int h = BlockNumH-1; h >=0; h--)
{
fullLine[h] = true;
for(int w = 0; w < BlockNumW; w++)
{
if(!(m_owner->m_blockMap[h][w]!=0
||m_style->IsSolid(w-pos.x, h-pos.y, rot)
)
)
{
fullLine[h] = false;
break;
}
}
}
for(int h = BlockNumH-1; h >=0; h--)
{
for(int w = 0; w < BlockNumW; w++)
{
if(m_owner->m_blockMap[h][w]!=0
||m_style->IsSolid(w-pos.x, h-pos.y, rot)
)
{
score += 10*sqrt(float(h));
}
else
{
for (int j=h-1;j>=0;j--)
{
if ((m_owner->m_blockMap[j][w]!=0
||m_style->IsSolid(w-pos.x, j-pos.y, rot)
)
&&fullLine[j] == false//可消除不算遮盖
)
{
score -= 6;//空挡被遮盖 惩罚
break;
}
}
}
}
}
return score;
}
void BlockBar::DrawUI(const vec2I& pos)
{
int h, w;
for(h = 0; h < BarSize; h++)
{
for(w = 0; w < BarSize; w++)
{
if (m_style->IsSolid(w, h, m_curRot))
{
RectF rect(pos.x+w*28,pos.y+h*28,28,28);
G_TetrisGame->m_blockIconN[0]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
}
}
}
void BlockBar::Render(bool fast)
{
if (fast)
{
//拖尾
G_RendDriver->Color3f(1,1,1);
G_RendDriver->BlendFunc(Blend_Additive);
RectF rect;
G_TetrisGame->m_blockTail->Bind();
for(int h = 0; h < BarSize; h++)
{
for(int w = 0; w < BarSize; w++)
{
if (m_style->IsSolid(w, h, m_curRot))
{
vec2I pos = m_point+vec2I(w,h );
rect = m_owner->GetBlockRect(pos);
if(!m_owner->IsOutBoard(pos))
{
rect.height += (rect.y - m_owner->m_blockRect.y);
rect.y = m_owner->m_blockRect.y;
G_RendDriver->DrawTextureRect(rect,RectF(((G_Timer->GetCurrentFrame()/4+w)%4)*0.25f,1,0.25f,1));
}
}
}
}
G_RendDriver->BlendFunc(Blend_Filter);
G_RendDriver->Color4f(1,1,1,1);
}
//方块
Color& color = BlockBarStyle::colors[m_ID % MaxBlockColor];
G_RendDriver->Color4fv(&color.r);
for(int h = 0; h < BarSize; h++)
{
for(int w = 0; w < BarSize; w++)
{
if (m_style->IsSolid(w, h, m_curRot))
{
vec2I pos = m_point+vec2I(w,h );
if(!m_owner->IsOutBoard(pos))
{
G_TetrisGame->m_blockIconN[0]->Bind();
G_RendDriver->DrawTextureRect(m_owner->GetBlockRect(pos));
}
}
}
}
//描边
G_RendDriver->Color3f(1,1,1);
G_RendDriver->BlendFunc(Blend_Additive);
RectF rect;
for(int h = 0; h < BarSize; h++)
{
for(int w = 0; w < BarSize; w++)
{
if (m_style->IsSolid(w, h, m_curRot))
{
vec2I pos = m_point+vec2I(w,h );
rect = m_owner->GetBlockRect(pos);
if(!m_owner->IsOutBoard(pos))
{
if (m_style->IsSolid(w, h-1, m_curRot)==false)
{
G_TetrisGame->m_blockBorder[0]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
if (m_style->IsSolid(w, h+1, m_curRot)==false)
{
G_TetrisGame->m_blockBorder[1]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
if (m_style->IsSolid(w-1, h, m_curRot)==false)
{
G_TetrisGame->m_blockBorder[2]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
if (m_style->IsSolid(w+1, h, m_curRot)==false)
{
G_TetrisGame->m_blockBorder[3]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
}
}
}
}
G_RendDriver->BlendFunc(Blend_Filter);
G_RendDriver->Color4f(1,1,1,1);
}
void BlockBar::SetStyle(BlockBarStyle *style)
{
m_style = style;
}
//==================^_^==================^_^==================^_^==================^_^
TetrisPlayer::TetrisPlayer()
:m_curBlockBar(NULL)
,m_nextBlockBar(NULL)
,m_diffcuty(0)
,m_state(Gaming)
,m_vanishLine(0)
,m_stateTime(0)
,m_continueNum(0)
,m_diffcultTime(0)
,m_fast(false)
{
m_sound = new SoundChannel;
}
TetrisPlayer::~TetrisPlayer()
{
SafeDelete(m_sound);
}
bool TetrisPlayer::Start()
{
m_diffcuty = 1;
m_liveNum = 2;
m_score = 0;
m_diffcultTime = G_Timer->GetAccumTime();
memset(m_blockMap, 0, sizeof(m_blockMap));
if(m_nextBlockBar==NULL)
m_nextBlockBar = new BlockBar();
m_nextBlockBar->m_owner = this;
m_nextBlockBar->m_style = &BlockStyles[Rand() % BlockStyleNum];
if(m_curBlockBar==NULL)
m_curBlockBar = new BlockBar();
m_curBlockBar->m_owner = this;
NewBlock();
m_state = Gaming;
return true;
}
bool TetrisPlayer::IsOutBoard(const vec2I& pos)
{
return pos.x < 0 || pos.y < 0 || pos.x >= BlockNumW || pos.y >= BlockNumH;
}
//触底后检查消除
void TetrisPlayer::CheckVanishing()
{
//检测
m_vanishLine = -1;
for(int h = BlockNumH-1; h >=0; h--)
{
bool fullLine = true;
for(int w = 0; w < BlockNumW; w++)
{
if(m_blockMap[h][w]==0)
{
fullLine = false;
break;
}
}
if(fullLine)
{
m_vanishLine = h;
break;
}
}
if(m_vanishLine!=-1)
{
m_sound->PlaySound__("data/sound/skill_ziyu.wav");
m_state = Vanishing;
m_stateTime = 0;
//m_continueNum++;
//因为只有两个玩家 暂时放在这里 无需同步了
TetrisPlayer* otherPlayer = G_TetrisGame->GetOtherPlayer(this);
if (otherPlayer->m_state==Gaming
||otherPlayer->m_state==TimeFrozen)
{
if (m_continueNum>0)
{
otherPlayer->m_state = TimeFrozenTurble;
}
else
{
otherPlayer->m_state = TimeFrozen;
}
otherPlayer->m_stateTime = 0;
}
}
else
{
m_state = Gaming;
m_continueNum = 0;
}
}
void TetrisPlayer::PutinCurBlockBar()
{
//放入
for(int h = 0; h < m_curBlockBar->BarSize; h++)
{
for(int w = 0; w < m_curBlockBar->BarSize; w++)
{
if (m_curBlockBar->m_style->IsSolid(w, h, m_curBlockBar->m_curRot))
{
vec2I pos = m_curBlockBar->m_point+vec2I(w,h);
if(!IsOutBoard(pos))
{
m_blockMap[pos.y][pos.x] = m_curBlockBar->m_ID;
}
}
}
}
}
//新的一条命
void TetrisPlayer::LifeDown()
{
if(m_liveNum>1)
{
m_liveNum --;
m_state = ReLifing;
m_stateTime = 0;
}
else
{
G_TetrisGame->m_bEndGame = true;
}
m_sound->PlaySound__("data/sound/tetris/tetris_relife.wav");
}
void TetrisPlayer::Update()
{
if(G_TetrisGame->m_bEndGame)
return;
switch(m_state)
{
case TimeFrozen:
m_stateTime+=G_Timer->GetStepTimeLimited();
if(m_stateTime>FrozenTime)
{
m_state = Gaming;
}
break;
case Gaming:
{
float stepTime = 1.0f / m_diffcuty;
if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
{
//触底后还有stepTime的横移反应时间
if (m_curBlockBar->IsCollide(vec2I(0, 1)))
{
PutinCurBlockBar();
CheckVanishing();//消除
NewBlock(); //生成新的
}
}
}
break;
case TimeFrozenTurble:
{
//更复杂的做法: 使用进度控制器列表
m_stateTime+=G_Timer->GetStepTimeLimited();
if(m_stateTime<FrozenTime)
{
}
else if(m_stateTime<FrozenTurbleTime)
{
float stepTime = 1.0f / m_diffcuty/2.0f;
if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
{
//触底后还有stepTime的横移反应时间
if (m_curBlockBar->IsCollide(vec2I(0, 1)))
{
PutinCurBlockBar();
CheckVanishing();//消除
NewBlock(); //生成新的
}
}
}
else
{
m_state = Gaming;
}
}
break;
case Vanishing:
{
m_stateTime+=G_Timer->GetStepTimeLimited();
//闪2秒
if(m_stateTime>VanishTime)
{
m_continueNum++;
//消除一行满的
//降
for(int w = 0; w < BlockNumW; w++)
{
for(int ith = m_vanishLine; ith > 0; ith--)
{
int upblock = m_blockMap[ith-1][w];
m_blockMap[ith][w] = upblock;
}
}
//增加分数?
//m_score += 2 * continueNum - 1;
m_score += m_continueNum * m_continueNum;
//增加难度
if( m_score >= m_diffcuty * m_diffcuty * 10)
{
if(m_diffcuty <= 6)
m_diffcuty ++;
}
//增加生命
if( m_score >= 50 * (m_liveNum + 1))
{
if(m_liveNum <= 6)
m_liveNum ++;
}
CheckVanishing();
}
}
break;
case ReLifing:
m_stateTime +=G_Timer->GetStepTimeLimited();
//闪秒
if(m_stateTime>RelifeTime)
{
m_state = Gaming;
for(int i = BlockNumH - 1; i >= 0; i--)
{
for(int j = BlockNumW - 1; j >= 0; j--)
{
m_blockMap[i][j] = 0;
}
}
}
break;
}
}
void TetrisPlayer::Render()
{
G_RendDriver->Color3f(1,1,1);
//block back
for(int h = 0; h < BlockNumH; h++)
{
for(int w = 0; w < BlockNumW; w++)
{
G_TetrisGame->m_blockBack->Bind();
G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(w,h )));
}
}
//player block
switch(m_state)
{
case TimeFrozen:
{
RenderBlocks();
m_curBlockBar->Render(false);
//todo 可以使用movie
//m_movieFrozen->Advance();
//m_movieFrozen->RendClip();
//时间停滞
G_TetrisGame->m_timePause2->Bind();
RectF rect = GetBlockRect(vec2I(1, 5));
rect.width = m_blockExtend.x*8;
rect.height = m_blockExtend.y*8;
G_RendDriver->DrawTextureRect(rect);
}
break;
case TimeFrozenTurble:
{
if (m_stateTime<TimeFrozen)
{
RenderBlocks();
m_curBlockBar->Render(false);
//时间停滞
G_TetrisGame->m_timePause2->Bind();
RectF rect = GetBlockRect(vec2I(1, 5));
rect.width = m_blockExtend.x*8;
rect.height = m_blockExtend.y*8;
G_RendDriver->DrawTextureRect(rect);
}
else
{
//时间乱流
G_TetrisGame->m_timeTurble->Bind();
RectF rect = GetBlockRect(vec2I(3, 10));
rect.width = m_blockExtend.x*4;
rect.height = m_blockExtend.y*8;
G_RendDriver->DrawTextureRect(rect);
RenderBlocks();
m_curBlockBar->Render(false);
}
}
break;
case Gaming:
{
RenderBlocks();
m_curBlockBar->Render(m_fast);
}
break;
case Vanishing:
{
RenderBlocks();
//m_curBlockBar->Draw(); 已经put
// 每秒闪3次
bool flash = (int(m_stateTime*3))%2;
if (flash)
{
G_RendDriver->BlendFunc(Blend_Additive);
G_TetrisGame->m_blockIconH[0]->Bind();
}
else
{
G_RendDriver->BlendFunc(Blend_Filter);
G_TetrisGame->m_blockIconN[0]->Bind();
}
for(int w = 0; w < BlockNumW; w++)
{
int ID = m_blockMap[m_vanishLine][w];
G_RendDriver->Color4fv(&BlockBarStyle::colors[ID % MaxBlockColor].r);
G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(w, m_vanishLine)));
}
G_RendDriver->Color3f(1,1,1);
//todo 可以使用movie定制更酷炫的动画
//闪电
G_RendDriver->BlendFunc(Blend_Additive);
G_TetrisGame->m_lightning->Bind();
RectF rect = GetBlockRect(vec2I(0, m_vanishLine));
rect.width = m_blockRect.width;
G_RendDriver->DrawTextureRect(rect,RectF(m_stateTime*2.0f,0,1,1));
G_RendDriver->BlendFunc(Blend_Filter);
//对手时间停滞
G_TetrisGame->m_timePause->Bind();
rect = GetBlockRect(vec2I(1, m_vanishLine));
rect.width = m_blockExtend.x*8;
rect.height = m_blockExtend.y*2;
G_RendDriver->DrawTextureRect(rect);
}
break;
case ReLifing:
{
//todo 可以使用movie定制更酷炫的动画
//m_curBlockBar->Draw();
int line = 0;
if (m_stateTime<RelifeTime/2)
{
RenderBlocks();
line = m_stateTime/(RelifeTime/2.1f)*BlockNumH;
}
else
{
line = (2-(m_stateTime/(RelifeTime/2.1f)))*BlockNumH;
}
for(int i = 0; i < line&&i<BlockNumH; i++)
{
for(int j = 0; j < BlockNumW; j++)
{
G_TetrisGame->m_blockIconN[0]->Bind();
G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(j,i )));
}
}
}
break;
}
}
void TetrisPlayer::RenderBlocks()
{
for(int h = 0; h < BlockNumH; h++)
{
for(int w = 0; w < BlockNumW; w++)
{
if (m_blockMap[h][w]>0)
{
G_TetrisGame->m_blockIconN[0]->Bind();
int ID = m_blockMap[h][w];
G_RendDriver->Color4fv(&BlockBarStyle::colors[ID % MaxBlockColor].r);
G_RendDriver->DrawTextureRect(GetBlockRect(vec2I(w,h )));
}
}
}
//描边
G_RendDriver->Color3f(1,1,1);
G_RendDriver->BlendFunc(Blend_Additive);
RectF rect;
for(int h = 0; h < BlockNumH; h++)
{
for(int w = 0; w < BlockNumW; w++)
{
rect = GetBlockRect(vec2I(w,h ));
int id = m_blockMap[h][w];
if (id>0)
{
if (h==0 ||
(h>0 && m_blockMap[h-1][w]!=id)
)
{
G_TetrisGame->m_blockBorder[0]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
if (h==BlockNumH-1 ||
(h<BlockNumH-1 && m_blockMap[h+1][w]!=id)
)
{
G_TetrisGame->m_blockBorder[1]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
if (w==0 ||
(w>0 && m_blockMap[h][w-1]!=id)
)
{
G_TetrisGame->m_blockBorder[2]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
if (w==BlockNumW-1 ||
(w<BlockNumW-1 && m_blockMap[h][w+1]!=id)
)
{
G_TetrisGame->m_blockBorder[3]->Bind();
G_RendDriver->DrawTextureRect(rect);
}
}
}
}
G_RendDriver->BlendFunc(Blend_Filter);
G_RendDriver->Color4f(1,1,1,1);
}
RectF TetrisPlayer::GetBlockRect(const vec2I& point)
{
return RectF(m_blockRect.x+point.x*m_blockExtend.x,m_blockRect.y+point.y*m_blockExtend.y,m_blockExtend.x,m_blockExtend.y);
}
void TetrisPlayer::NewBlock()
{
BlockBarStyle* style = m_nextBlockBar->m_style;
m_curBlockBar->SetStyle(style);
m_curBlockBar->m_curRot = Rand() % style->m_rotNum;
m_curBlockBar->m_point = vec2I(4, 0);
// m_curBlockBar->m_color = (&Color::red)[Rand() % 12];
static int ID = 1;
m_curBlockBar->m_ID = ++ ID;
m_nextBlockBar->SetStyle(&BlockStyles[Rand() % BlockStyleNum]);
//m_nextBlockBar->SetStyle(&BlockStyles[12]);
if(m_curBlockBar->IsCollide(vec2I(0, 0)))
{
//刚生成就触底=》结束
//同步清除,自己计算可能不同步?
LifeDown();
}
}
//==================^_^==================^_^==================^_^==================^_^
TetrisPlayerRobot::TetrisPlayerRobot()
:m_workingWithAI(false)
,m_thinkTime(0)
{
}
bool TetrisPlayerRobot::Start()
{
TetrisPlayer::Start();
m_workingWithAI = true;
m_thinkTime = G_Timer->GetAccumTime();
FindBestPoint();
return true;
}
void TetrisPlayerRobot::Render()
{
TetrisPlayer::Render();
char buf[256];
sprintf(buf,"bestScore = %.1f",m_bestScore);
G_FontMgr->TextAtPos(m_blockRect.GetPos(),buf);
}
void TetrisPlayerRobot::Update()
{
TetrisPlayer::Update();
if(G_TetrisGame->m_bEndGame)
return;
bool move = false;
switch(m_state)
{
case Gaming:
{
float stepTime = 1.0f / m_diffcuty;
if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
{
//触底后还有stepTime的横移反应时间
if (m_curBlockBar->IsCollide(vec2I(0, 1))==false)
{
//未触底 自动下降
m_curBlockBar->Move(vec2I(0, 1));
m_diffcultTime = G_Timer->GetAccumTime();
move = true;
}
}
}
break;
case TimeFrozenTurble:
{
//更复杂的做法: 使用进度控制器列表
m_stateTime+=G_Timer->GetStepTimeLimited();
if(m_stateTime<FrozenTime)
{
}
else if(m_stateTime<FrozenTurbleTime)
{
float stepTime = 1.0f / m_diffcuty/2.0f;
if (G_Timer->GetAccumTime() - m_diffcultTime >= stepTime)
{
//触底后还有stepTime的横移反应时间
if (m_curBlockBar->IsCollide(vec2I(0, 1))==false)
{
//未触底 自动下降
m_curBlockBar->Move(vec2I(0, 1));
m_diffcultTime = G_Timer->GetAccumTime();
move = true;
}
}
}
}
break;
case Vanishing:
{
m_stateTime+=G_Timer->GetStepTimeLimited();
//闪2秒
if(m_stateTime>VanishTime)
{
m_continueNum++;
//消除一行满的
//降
for(int w = 0; w < BlockNumW; w++)
{
for(int ith = m_vanishLine; ith > 0; ith--)
{
int upblock = m_blockMap[ith-1][w];
m_blockMap[ith][w] = upblock;
}
}
//增加分数?
//m_score += 2 * continueNum - 1;
m_score += m_continueNum * m_continueNum;
//增加难度
if( m_score >= m_diffcuty * m_diffcuty * 10)
{
if(m_diffcuty <= 6)
m_diffcuty ++;
}
//增加生命
if( m_score >= 50 * (m_liveNum + 1))
{
if(m_liveNum <= 6)
m_liveNum ++;
}
CheckVanishing();
}
}
break;
}
if (m_workingWithAI)
{
switch(m_state)
{
case Gaming:
{
if (m_curBlockBar->m_curRot == m_bestRot
&&m_curBlockBar->m_point.x == m_bestPoint.x)
{
if (m_fast)
{
m_diffcuty = 6;
//if (G_Timer->GetAccumTime() - m_thinkTime >= 0.1f)
if (G_Timer->GetAccumTime() - m_thinkTime >= 0.01f)
{
m_thinkTime = G_Timer->GetAccumTime();
{
m_curBlockBar->Move(vec2I(0, 1));
move = true;
}
}
}
}
else
{
if (G_Timer->GetAccumTime() - m_thinkTime >= 0.5f *(m_fast?0.1f:1.0f))
//if (G_Timer->GetAccumTime() - m_thinkTime >= 0.05f)
{
m_thinkTime = G_Timer->GetAccumTime();
if (m_curBlockBar->m_curRot < m_bestRot)
{
if (abs(m_curBlockBar->m_curRot-m_bestRot) < 2)//0~12
m_curBlockBar->Rotate(1);
else
m_curBlockBar->Rotate(-1);//0~3
move = true;
}
else if (m_curBlockBar->m_curRot > m_bestRot)
{
if (abs(m_curBlockBar->m_curRot-m_bestRot) < 2)
m_curBlockBar->Rotate(-1);
else
m_curBlockBar->Rotate(1);
move = true;
}
if (m_curBlockBar->m_point.x < m_bestPoint.x)
{
m_curBlockBar->Move(vec2I(1, 0));
move = true;
}
else if (m_curBlockBar->m_point.x > m_bestPoint.x)
{
m_curBlockBar->Move(vec2I(-1, 0));
move = true;
}
}
}
}
break;
}
}
if (move == true)
{
//同步bar的移动
C2SPacketMiniGameCmd packet;
packet.WriteHeader();
packet.WriteValue(CMD_CurBlockBar);
packet.WriteValue(m_roomSlot);
packet.WriteValue(m_curBlockBar->m_point.x);
packet.WriteValue(m_curBlockBar->m_point.y);
packet.WriteValue(m_curBlockBar->m_curRot);
packet.WriteValue(m_curBlockBar->m_style->ID);
G_MiniGame->SendPacketToOther(&packet);
m_sound->PlaySound__("data/sound/ui_click.wav");
}
}
void TetrisPlayerRobot::FindBestPoint()
{
//不考虑来不及变换的情况
//不考虑绕过阻挡后横移
//不考虑同nextbar配合
m_bestRot = 0;
m_bestPoint.x = 4;
m_bestScore = -MaxFloat;
vec2I mov;
int startY = m_curBlockBar->m_point.y;
int rotNum = m_curBlockBar->m_style->m_rotNum;//2 or 4
for (int rot=0;rot<rotNum;rot++)
{
//for (int x=0;x<BlockNumW;x++)
for (int x=-m_curBlockBar->BarSize;x<BlockNumW+m_curBlockBar->BarSize;x++)
{
mov.x = x - m_curBlockBar->m_point.x;
mov.y = 0;
if (m_curBlockBar->IsOutBoard(mov,rot))
{
//左右出框 无法到达
continue;
}
if (m_curBlockBar->IsCollide(mov,rot))
{
//已经接触 无法到达
continue;
}
for (int y=startY;y<BlockNumH;y++)
{
mov.y = y - m_curBlockBar->m_point.y;
if (m_curBlockBar->IsCollide(mov+vec2I(0,1),rot)==true) //将要触底
{
float score = m_curBlockBar->Score(mov,rot);
if (score > m_bestScore)
{
m_bestScore = score;
m_bestRot = rot;
m_bestPoint = vec2I(x,y);
}
break;
}
}
}
}
}
void TetrisPlayerRobot::SetWorkingWithAI(bool working)
{
m_workingWithAI = working;
if (working)
{
FindBestPoint();//可能中途切换
}
}
void TetrisPlayerRobot::NewBlock()
{
TetrisPlayer::NewBlock();
if (m_workingWithAI)
{
FindBestPoint();
}
}
//==================^_^==================^_^==================^_^==================^_^
bool TetrisPlayerRole::Start()
{
TetrisPlayer::Start();
m_workingWithAI = false;
return true;
}
void TetrisPlayerRole::Update()
{
if(G_TetrisGame->m_bEndGame)
return;
if (m_workingWithAI==true)
{
TetrisPlayerRobot::Update();
return;
}
TetrisPlayer::Update();
switch(m_state)
{
case Gaming:
{
vec2I oldPoint = m_curBlockBar->m_point;
int oldRot = m_curBlockBar->m_curRot;
if (G_TetrisGame->IsKeyDowning(KeyUp))
{
m_curBlockBar->Rotate();
LastKeyDownTime.ResetReady();
}
else if (G_TetrisGame->IsKeyDowning(KeyLeft))
{
m_curBlockBar->Move(vec2I(-1, 0));
LastKeyDownTime.ResetReady();
}
else if (G_TetrisGame->IsKeyDowning(KeyRight))
{
m_curBlockBar->Move(vec2I(1, 0));
LastKeyDownTime.ResetReady();
}
else if (G_TetrisGame->IsKeyDowning(KeyDown))
{
if( false == m_curBlockBar->Move(vec2I(0, 2)) )
m_curBlockBar->Move(vec2I(0, 1));
LastKeyDownTime.ResetReady();
}
else if (LastKeyDownTime.IsReady())
{
if (G_TetrisGame->IsKeyPressed(KeyUp))
{
m_curBlockBar->Rotate();
}
if (G_TetrisGame->IsKeyPressed(KeyLeft))
{
m_curBlockBar->Move(vec2I(-1, 0));
}
if (G_TetrisGame->IsKeyPressed(KeyRight))
{
m_curBlockBar->Move(vec2I(1, 0));
}
if (G_TetrisGame->IsKeyPressed(KeyDown))
{
if( false == m_curBlockBar->Move(vec2I(0, 2)) )
m_curBlockBar->Move(vec2I(0, 1));
}
}
if ((oldPoint-m_curBlockBar->m_point).Length()>_EPSILON
||oldRot != m_curBlockBar->m_curRot)
{
//同步bar的移动
C2SPacketMiniGameCmd packet;
packet.WriteHeader();
packet.WriteValue(CMD_CurBlockBar);
packet.WriteValue(m_roomSlot);
packet.WriteValue(m_curBlockBar->m_point.x);
packet.WriteValue(m_curBlockBar->m_point.y);
packet.WriteValue(m_curBlockBar->m_curRot);
packet.WriteValue(m_curBlockBar->m_style->ID);
G_MiniGame->SendPacketToOther(&packet);
m_sound->PlaySound__("data/sound/ui_click.wav");
}
}
break;
}
}
游戏类:
//========================================================
// @Date: 2016.05
// @File: SourceDemoClient/Chess/MiniGameTetris.h
// @Brief: MiniGameTetris
// @Author: LouLei
// @Email: twopointfive@163.com
// @Copyright (Crapell) - All Rights Reserved
//========================================================
#ifndef __MiniGameTetris__H__
#define __MiniGameTetris__H__
#include "Math/MathLib.h"
#include "Render/Texture.h"
#include "Rpg/MiniGame.h"
//双人方块 右下角显示别的玩家进度
//每消除一行 给对手投递一个停滞蛛网到右下角(对手右下角消除时飞出停滞蛛网)
//连消 产生停滞蛛网 + 快进乱流
//对手死亡(右下角表现)
//有些命令没有发送,暂时自己计算,同步情况尚可
enum MiniTetrisCmd
{
CMD_NewBlockBar, //新bar
CMD_CurBlockBar, //下降bar
CMD_Vanishing , //消除中
CMD_ReLifing , //重生中
CMD_TimeFrozen , //冻结
CMD_GameOver ,
CMD_Restart ,
};
const char* TetrisCmdToString(int enumeration);
class TetrisPlayer;
class TetrisPlayerRole;
class MiniGameTetris:public MiniGame
{
public:
MiniGameTetris();
virtual ~MiniGameTetris();
virtual bool Start();
virtual bool ReStart();
virtual bool Stop();
virtual bool Render();
virtual void RenderUI();
virtual bool Update();
virtual bool Free();
virtual bool IsEnd();
virtual void OnSize();
//三种类型结构
virtual MiniPlayer* CreatePlayer();
virtual MiniPlayer* CreateRobot ();
virtual MiniPlayer* CreateRole ();
TetrisPlayer* GetOtherPlayer(TetrisPlayer* self);
//处理游戏网络命令包
virtual int ProcessPacketCmd(PacketBase* packet);
//virtual const char* CmdToString(const char* stream,int len);
//private:
TexturePtr m_blockIconN[4]; //图标
TexturePtr m_blockIconH[4]; //图标
TexturePtr m_blockBack;
TexturePtr m_blockBorder[4];
TexturePtr m_blockTail;
TexturePtr m_lightning;
TexturePtr m_lifeIcon;
TexturePtr m_diffcutyIcon;
TexturePtr m_frameTex;
TexturePtr m_timePause;
TexturePtr m_timePause2;
TexturePtr m_timeTurble;
RectF m_gameRect;
RectF m_scorePannelRect;
TetrisPlayerRole* m_myRolePlayer;
bool m_bEndGame;
};
extern MiniGameTetris* G_TetrisGame;
#endif
//========================================================
// @Date: 2016.05
// @File: SourceDemoClient/Chess/MiniGameTetris.cpp
// @Brief: MiniGameTetris
// @Author: LouLei
// @Email: twopointfive@163.com
// @Copyright (Crapell) - All Rights Reserved
//========================================================
#include "General/Pch.h"
#include "General/Window.h"
#include "Gui/GuiMgr.h"
#include "Gui/RpgGuis.h"
#include "Input/InputMgr.h"
#include "MiniGameTetris.h"
#include "Render/RendDriver.h"
#include "Render/Shader.h"
#include "Render/Font.h"
#include "Tetris/Tetris.h"
#include "Net/PacketList.h"
#include "Rpg/SyncGameInfo.h"
#include "General/Pce.h"
MiniGameTetris* G_TetrisGame = NULL;
BlockBarStyle BlockStyles[BlockStyleNum];
MiniGameTetris::MiniGameTetris()
{
G_TetrisGame = this;
CmdEnumToString = TetrisCmdToString;
}
MiniGameTetris::~MiniGameTetris()
{
G_TetrisGame = NULL;
}
bool MiniGameTetris::Start()
{
m_myRolePlayer = NULL;
if(!MiniGame::Start())
return false;
G_TextureMgr->AddTexture(m_blockIconN[0],"data/minigame/Tetris/block0_n.png");
G_TextureMgr->AddTexture(m_blockIconH[0],"data/minigame/Tetris/block0_h.png");
G_TextureMgr->AddTexture(m_blockBack,"data/minigame/Tetris/blockback.png");
G_TextureMgr->AddTexture(m_blockTail,"data/minigame/Tetris/tail.png");
G_TextureMgr->AddTexture(m_blockBorder[0],"data/minigame/Tetris/blockborder0.png");
G_TextureMgr->AddTexture(m_blockBorder[1],"data/minigame/Tetris/blockborder1.png");
G_TextureMgr->AddTexture(m_blockBorder[2],"data/minigame/Tetris/blockborder2.png");
G_TextureMgr->AddTexture(m_blockBorder[3],"data/minigame/Tetris/blockborder3.png");
G_TextureMgr->AddTexture(m_lightning,"data/minigame/Tetris/lightning.png");
G_TextureMgr->AddTexture(m_frameTex,"data/minigame/Tetris/back.png");
G_TextureMgr->AddTexture(m_lifeIcon,"data/minigame/Tetris/life.png");
G_TextureMgr->AddTexture(m_diffcutyIcon,"data/minigame/Tetris/diffcuty.png");
G_TextureMgr->AddTexture(m_timePause,"data/minigame/Tetris/timepause.png");
G_TextureMgr->AddTexture(m_timePause2,"data/minigame/Tetris/timepause2.png");
G_TextureMgr->AddTexture(m_timeTurble,"data/minigame/Tetris/ghost2.png");
//BlockStyles[0] = BlockBarStyle(2,
// "██"
// "██");
//BlockStyles[1] = BlockBarStyle(3,
// " █ "
// "███"
// " ");
//BlockStyles[2] = BlockBarStyle(3,
// "█ "
// "███"
// " ");
//BlockStyles[3] = BlockBarStyle(3,
// " █"
// "███"
// " ");
//BlockStyles[4] = BlockBarStyle(3,
// "██ "
// " ██"
// " ");
//BlockStyles[5] = BlockBarStyle(3,
// " ██"
// "██ "
// " ");
//BlockStyles[6] = BlockBarStyle(4,
// " █ "
// " █ "
// " █ "
// " █ ");
//BlockStyles[7] = BlockBarStyle(2,
// "█ "
// " █");
//BlockStyles[8] = BlockBarStyle(2,
// " █"
// "██");
//BlockStyles[9] = BlockBarStyle(3,
// " █ "
// " █ "
// " █ ");
//BlockStyles[10] = BlockBarStyle(3,
// "█ "
// " █ "
// " █");
//BlockStyles[11] = BlockBarStyle(3,
// "█ "
// " █"
// " █");
//BlockStyles[12] = BlockBarStyle(3,
// "█ █"
// " "
// "█ █");
//BlockStyles[13] = BlockBarStyle(4,
// " █ "
// " █ "
// " █ "
// "████");
BlockStyles[0] = BlockBarStyle(2,
"11"
"11");
BlockStyles[1] = BlockBarStyle(3,
"010"
"111"
"000");
BlockStyles[2] = BlockBarStyle(3,
"100"
"111"
"000");
BlockStyles[3] = BlockBarStyle(3,
"001"
"111"
"000");
BlockStyles[4] = BlockBarStyle(3,
"110"
"011"
"000");
BlockStyles[5] = BlockBarStyle(3,
"011"
"110"
"000");
BlockStyles[6] = BlockBarStyle(4,
/* "1000"
"1000"
"1000"
"1000"*/
"0100"
"0100"
"0100"
"0100");
BlockStyles[7] = BlockBarStyle(2,
"10"
"01");
BlockStyles[8] = BlockBarStyle(2,
"01"
"11");
BlockStyles[9] = BlockBarStyle(3,
"010"
"010"
"010");
BlockStyles[10] = BlockBarStyle(3,
"100"
"010"
"001");
BlockStyles[11] = BlockBarStyle(3,
"100"
"001"
"001");
BlockStyles[12] = BlockBarStyle(3,
"101"
"000"
"101");
BlockStyles[13] = BlockBarStyle(4,
"0100"
"0100"
"0100"
"1111");
for (int i=0;i<BlockStyleNum;i++)
{
BlockStyles[i].ID = i;
}
for (int i=0;i<MaxBlockColor;i++)
{
float h, s, l;
rgb2hsl(Color::colors[i]->r, Color::colors[i]->g, Color::colors[i]->b, h,s,l);
BlockBarStyle::colors[i].SetFromHLS(h,0.99f,s,1);
}
m_gameRect = RectF(G_Window->m_iWidth/2-300,G_Window->m_iHeight/2-300,600,600);
m_scorePannelRect = RectF(m_gameRect.x+362,m_gameRect.y+19,206,281);
//
for(int i = 0; i < m_allPlayerNum; i++)
{
TetrisPlayer* player = dynamic_cast<TetrisPlayer*>(m_miniPlayer[i]);
if (player == m_myRolePlayer)
{
RectF blockRect(m_gameRect.x+47,m_gameRect.y+18,293,563);
player->m_blockRect = blockRect;
player->m_blockExtend = vec2(blockRect.width/BlockNumW,blockRect.height/BlockNumH);
}
else
{
RectF blockRect(m_gameRect.x+365,m_gameRect.y+318,205,267);
player->m_blockRect = blockRect;
player->m_blockExtend = vec2(blockRect.width/BlockNumW,blockRect.height/BlockNumH);
}
m_miniPlayer[i]->Start();
}
m_bEndGame=false;
//进入miniplaygui,(选人、选关卡都已在房间里进行完毕)。
if(GetStyle()) G_GuiMgr->PushGui(GetStyle()->playGUI.c_str(),GL_DIALOG);
return true;
}
bool MiniGameTetris::ReStart()
{
for(int i = 0; i < m_allPlayerNum; i++)
{
TetrisPlayer* player = dynamic_cast<TetrisPlayer*>(m_miniPlayer[i]);
m_miniPlayer[i]->Start();
}
m_bEndGame=false;
return true;
}
MiniPlayer* MiniGameTetris::CreatePlayer()
{
return new TetrisPlayer;
}
MiniPlayer* MiniGameTetris::CreateRobot()
{
return new TetrisPlayerRobot;
}
MiniPlayer* MiniGameTetris::CreateRole()
{
m_myRolePlayer = new TetrisPlayerRole;
return m_myRolePlayer;
}
bool MiniGameTetris::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 MiniGameTetris::Render()
{
G_RendDriver->BeginUI();
G_RendDriver->Color4f(1,1,1,1);
G_RendDriver->SetRenderStateEnable(RS_BLEND,true);
G_RendDriver->BlendFunc(Blend_Filter);
G_ShaderMgr->PushShader();
m_frameTex->Bind();
G_RendDriver->DrawTextureRect(m_gameRect);
const int Left = m_scorePannelRect.x+96;
得分
char buf[256];
//sprintf(buf,"%d", m_myRolePlayer->m_score);
//G_FontMgr->TextAtPos(vec2(Left,188),buf);
if (m_myRolePlayer)
{
//难度
for(int i = 0; i < m_myRolePlayer->m_diffcuty; i++)
{
m_diffcutyIcon->Bind();
G_RendDriver->DrawTextureRect(RectF(Left+i*28,m_scorePannelRect.y+200,28,28));
}
//生命
for(int i = 0; i < m_myRolePlayer->m_liveNum; i++)
{
m_lifeIcon->Bind();
G_RendDriver->DrawTextureRect(RectF(Left+i*28,m_scorePannelRect.y+241,28,28));
}
//下一个
m_myRolePlayer->m_nextBlockBar->DrawUI(vec2I(m_scorePannelRect.x+62,m_scorePannelRect.y+80));
}
//对手名字
TetrisPlayer* otherPlayer = GetOtherPlayer(m_myRolePlayer);
if (otherPlayer)
{
sprintf(buf,"%s", otherPlayer->GetPlayerInfo()->playerName);
G_FontMgr->TextAtPos(vec2(Left,otherPlayer->m_blockRect.y),buf);
}
for(int i = 0; i < m_allPlayerNum; i++)
{
m_miniPlayer[i]->Render();
}
G_RendDriver->EndUI();
G_ShaderMgr->PopShader();
return true;
}
void MiniGameTetris::RenderUI()
{
Render();
}
bool MiniGameTetris::Update()
{
if(m_bEndGame)
return true;
for(int i = 0; i < m_allPlayerNum; i++)
{
m_miniPlayer[i]->Update();
}
return true;
}
bool MiniGameTetris::Free()
{
MiniGame::Free();
return true;
}
bool MiniGameTetris::IsEnd()
{
return m_bEndGame;
}
int MiniGameTetris::ProcessPacketCmd(PacketBase* packet)
{
int cmd;
packet->ReadValue(cmd);
switch(cmd)
{
case CMD_CurBlockBar:
{
int roomSlot;
packet->ReadValue(roomSlot);
TetrisPlayer* player = (TetrisPlayer*)this->GetPlayerFromSlot(roomSlot);
int ID;
//同步bar的移动
packet->ReadValue(player->m_curBlockBar->m_point.x);
packet->ReadValue(player->m_curBlockBar->m_point.y);
packet->ReadValue(player->m_curBlockBar->m_curRot);
packet->ReadValue(ID);
//省了newblock cmd
player->m_curBlockBar->m_style = &BlockStyles[ID];
player->Update(); //连续收到两个消息 前一个不能无效
}
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;
}
TetrisPlayer* MiniGameTetris::GetOtherPlayer(TetrisPlayer* self)
{
//对手
for(int i = 0; i < m_allPlayerNum; i++)
{
if (self->m_roomSlot != m_miniPlayer[i]->m_roomSlot)
{
return (TetrisPlayer*)m_miniPlayer[i];
}
}
return NULL;
}
void MiniGameTetris::OnSize()
{
m_gameRect = RectF(G_Window->m_iWidth/2-300,G_Window->m_iHeight/2-300,600,600);
m_scorePannelRect = RectF(m_gameRect.x+362,m_gameRect.y+19,206,281);
}
const char* TetrisCmdToString(int enumeration)
{
switch(enumeration)
{
case CMD_CurBlockBar:return "CMD_CurBlockBar";
case CMD_Vanishing :return "CMD_Vanishing ";
case CMD_ReLifing :return "CMD_ReLifing ";
case CMD_GameOver :return "CMD_GameOver ";
case CMD_Restart :return "CMD_Restart ";
default :return "CMD_unknow";
}
return "CMD_unknow";
}
完