联机版俄罗斯方块带自动挂机源码
生活随笔
收集整理的這篇文章主要介紹了
联机版俄罗斯方块带自动挂机源码
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
這是一款聯機版俄羅斯方塊游戲。共配置了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 12static 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.0fclass 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_barSizeBlockBarStyle::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 還有可能是1m_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 backfor(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 blockswitch(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~12m_curBlockBar->Rotate(1);elsem_curBlockBar->Rotate(-1);//0~3move = true;}else if (m_curBlockBar->m_curRot > m_bestRot){if (abs(m_curBlockBar->m_curRot-m_bestRot) < 2)m_curBlockBar->Rotate(-1);elsem_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 4for (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, //新barCMD_CurBlockBar, //下降barCMD_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 cmdplayer->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"; }完
總結
以上是生活随笔為你收集整理的联机版俄罗斯方块带自动挂机源码的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 公司建网站多少钱?【网站多少钱】
- 下一篇: Qt窗口最大化