SDL2 游戏开发日记(九) 单机麻将

Pearl ·
更新时间:2024-09-20
· 537 次阅读

SDL2 游戏开发日记(九) 单机麻将

单机麻将的基本功能其实年前已经完成了,只是写文档麻烦,再加上懒癌和重度拖延症,就一直拖着没更新。今天周末一个人没什么事干,抽空把它更新了。

麻将的表示

用数组表示,int card[136];值分别是 0-135;

值/4

0-8:表示万,9-17:表示饼,18-26:表示条,27-33:表示东南西北中发白

class MahjongCard : public Renderable{ private : int mCardNumber; //牌值,0-135 bool mIsSelected; //是否被选中的状态,玩家鼠标选择出牌时用 Vector2I mOffset; //选中后的位置偏移量,鼠标选择出牌时用 public : void SetCardNumber(int cardNumber){ mCardNumber = cardNumber; } int GetCardNumber(){ return mCardNumber; } bool IsSelected(){ return mIsSelected; } void SetSelected(bool bSelected){ mIsSelected = bSelected; } void SetOffset(int xOffset, int yOffset){ mOffset.x = xOffset; mOffset.y = yOffset; } Vector2I &GetOffset(){ return mOffset; } }; 麻将算法

分为胡牌算法和出牌ai

胡牌算法:声明一个辅助数组 int cardAssists[38],用0填充。如果是判断自摸,则遍历手上的牌并根据index的值填充辅助数组。如果是判断吃胡,则遍历手上的牌和最后一张打出的牌。并根据index的值填充辅助数字。

index = 具体的牌值/4:如果值小于等于8,cardAssists[index+1] ++;即cardAssists数组的1-9表示万,

如果index的值大于等于9并且小于等于17,cardAssists[index+2] ++;即11-19表示饼

如果index的值大于等于18并且小于等于26,cardAssists[index+3]++;即21-29表示条。

如果index的值大于等于27,cardAssists[index+4] ++;即31-37表示字牌。

class MahjongAI{ //递归调用 bool IsHu(){ int sum = 0; for (int i = 0; i < 38; i++){ sum += mCardAssistArray[i]; } if (sum == 0){ //匹配完了,如果有找到将牌,表示可以胡牌了。 if (mIsFindJiang) return true; else return false; } int index = 0; //跳过没有的牌 for (index = 0; index = 3){ mCardAssistArray[index] -= 3; //再判断剩下的牌是否胡牌。 if (IsHu()){ return true; } //没有胡牌,把这一刻加回去 mCardAssistArray[index] += 3; } //如果是一对,并且还未找到将牌, if (mCardAssistArray[index] >= 2 && !mIsFindJiang){ mIsFindJiang = true; mCardAssistArray[index] -= 2; //去掉,并判断剩下的牌能不能胡 if (IsHu()){ return true; } mIsFindJiang = false; //不能胡,加回去 mCardAssistArray[index] += 2; } //索引大于30的不判断顺子 if (index > 30) return false; //判断如果能组成顺子,把顺子牌拿掉, if (mCardAssistArray[index + 1] >= 1 && mCardAssistArray[index + 2] >= 1){ mCardAssistArray[index] --; mCardAssistArray[index + 1] --; mCardAssistArray[index + 2] --; //判断剩下的牌能不能胡牌 if (IsHu()){ return true; } //不能胡牌,加回数组中 mCardAssistArray[index] ++; mCardAssistArray[index + 1] ++; mCardAssistArray[index + 2] ++; } return false; } }

出牌ai:判断有没有单独的字牌和单独的牌->拆掉那些不是对子并且不是顺子的牌->判断最佳的听牌组合->经过上面的方法还选不出来该出的牌?那就随机出牌。

MahjongCard *MahjongAI::GetBestOutCard(){ MahjongCard *card = NULL; QueryInCards(); vector randomCardList,allCardList; CardMap &inHandcard = mPlayer->GetInHandCard(); printf("inhandcard size:%d\n",inHandcard.size()); CardMap::reverse_iterator iter = inHandcard.rbegin(); while (iter != inHandcard.rend()){ int cardIndex = GetCardIndex(iter->second); if (cardIndex > 30){ if (mCardAssistArray[cardIndex] == 1){ //printf("单独的字牌:%d\n", cardIndex); randomCardList.push_back(iter->second); } } else{ if (mCardAssistArray[cardIndex] == 1){ if (mCardAssistArray[cardIndex - 1] == 0 && mCardAssistArray[cardIndex+1] == 0){ //printf("单独的牌:%d\n", cardIndex); randomCardList.push_back(iter->second); } } } allCardList.push_back(iter->second); iter++; printf("%d,",cardIndex); } printf("\n"); if (randomCardList.size() == 0){ printf("不知道打什么牌1:进一步选择"); while (iter != inHandcard.rend()){ int cardIndex = GetCardIndex(iter->second); if (cardIndex > 30){ break; } else{ if (mCardAssistArray[cardIndex] == 1){ if (mCardAssistArray[cardIndex - 1] >= 1 && mCardAssistArray[cardIndex + 1] >= 1){ iter++; continue; } else if (mCardAssistArray[cardIndex + 1] >= 1 && mCardAssistArray[cardIndex + 2] >= 1){ iter++; continue; } else{ if (cardIndex % 10>2){ if (mCardAssistArray[cardIndex - 2] >= 1 && mCardAssistArray[cardIndex - 1] >= 1){ iter++; continue; } } } card = iter->second; printf(":%d\n", GetCardIndex(card)); break; } } } } else{ int index = rand() % randomCardList.size(); card = randomCardList[index]; } if (card == NULL){ printf("进一步选择失败,判断ting\n"); int assistArray[38]; int bestIndex = -1, bestTingCount = -1; for (int i = 0; i 0){ printf_s("Ting:%d,cardIndex:%d\n",tingCount,i); if (tingCount > bestTingCount){ bestTingCount = tingCount; bestIndex = i; } } mCardAssistArray[i]++; } if (bestIndex == -1){ int index = rand() % allCardList.size(); card = allCardList[index]; printf_s("最后还是随机出:%d\n", GetCardIndex(card)); } else{ iter = inHandcard.rbegin(); while (iter != inHandcard.rend()){ int cardIndex = GetCardIndex(iter->second); //printf("%d-----%d\n",cardIndex,bestIndex); if (bestIndex == cardIndex){ printf_s("TING:%d\n",iter->second->GetCardNumber()); card = iter->second; break; } iter++; } } } printf("%s-----out:%d\n",typeid(*mPlayer).name(), GetCardIndex(card)); return card; } 玩家

一个玩家,三个AI

#include "MahjongCard.h" #include "MahjongAI.h" #include #include #include #include using namespace std; typedef map CardMap; typedef vector CardVector; typedef dequeCardQueue; class Player : public Renderable{ protected: //手上的牌 CardMap mInHandCard; //打出去的牌 CardVector mOutCard; //碰或者杠的牌 CardVector mSpecialCard; //未知的牌 CardQueue mUnknownCardList; //牌的位置 Vector2I mInHandCardPos, mOutCardPos, mSpecialCardPos, mUnknownCardPos; //ai MahjongAI *mAI; MahjongCard *mNewCard; bool mIsChange; //下家 Player *mNextPlayer; bool mIsGameEnd; public: Player(){ mAI = new MahjongAI(this); mNextPlayer = NULL; } virtual ~Player(){ if (mTexture != NULL){ SDL_DestroyTexture(mTexture); mTexture = NULL; } SAFE_DELETE(mAI); } MahjongAI *GetAI(){ return mAI; } //设置牌的位置 void SetInHandCardPos(int x, int y){ mInHandCardPos.x = x; mInHandCardPos.y = y; } void SetOutCardPos(int x, int y){ mOutCardPos.x = x; mOutCardPos.y = y; } void SetSpecialCardPos(int x, int y){ mSpecialCardPos.x = x; mSpecialCardPos.y = y; } void SetUnknownCardPos(int x, int y){ mUnknownCardPos.x = x; mUnknownCardPos.y = y; } //创建纹理 void CreateRenderTexture(int x,int y,int width, int height); virtual void Update(float time_step){} virtual void HandleEvent(SDL_Event &ev){} //把牌放到未知的牌中 void PutUnknowCard(MahjongCard*card){ mUnknownCardList.push_back(card); mIsChange = true; } //获取一张未知的牌 virtual MahjongCard* PopUnknownCard(){ MahjongCard *card = NULL; if (!mUnknownCardList.empty()){ card = mUnknownCardList.back(); mUnknownCardList.pop_back(); mIsChange = true; } return card; } //手上的牌的数量 int GetInHandCardCount(){ return mInHandCard.size(); } //出牌 void PopCardOut(MahjongCard *outCard){ PopCardOut(outCard->GetCardNumber()); } //出牌 void PopCardOut(int cardNumber){ CardMap::iterator it = mInHandCard.find(cardNumber); if (it != mInHandCard.end()){ mOutCard.push_back(it->second); mInHandCard.erase(it); } mNewCard = NULL; mIsChange = true; } //把最后一张出的牌移走,被/碰/杠时用 void RemoveOutCard(){ mOutCard.pop_back(); mIsChange = true; } //摸牌 void PutCardIn(MahjongCard *card,bool IsStart = true){ assert(card != NULL && ": CARD IS NULL."); mIsChange = true; mInHandCard.insert(make_pair(card->GetCardNumber(),card)); if (IsStart){ mNewCard = card; } } //碰,杠 把牌放到特殊列表里 void PutToSpecialCard(MahjongCard*card,int count){ CardMap::iterator it = mInHandCard.begin(); mSpecialCard.push_back(card); while(it != mInHandCard.end()){ MahjongCard *c = it->second; if (c->GetCardNumber() / 4 == card->GetCardNumber() / 4 && c != card){ mSpecialCard.push_back(c); it = mInHandCard.erase(it); count--; if (count == 0) break; } else{ it++; } } mIsChange = true; } //重新开始 void Restart(){ SetGameEnd(false); mInHandCard.clear(); mOutCard.clear(); mSpecialCard.clear(); mUnknownCardList.clear(); } CardMap &GetInHandCard(){ return mInHandCard; } CardVector &GetSpecialCard(){ return mSpecialCard; } virtual void Render(); virtual void RenderUnknowCard() = 0; virtual void RenderInHandCard() = 0; virtual void RenderOutCard() = 0; virtual void RenderSpecialCard() = 0; virtual MahjongCard* HandleMouseEvent(int type, int x, int y){ return NULL; } Player *GetNextPlayer(){ return mNextPlayer; } void SetNextPlayer(Player*nextPlayer){ mNextPlayer = nextPlayer; } //设置游戏结束状态,游戏结束时,所有人的牌都能被看到 void SetGameEnd(bool IsEnd){ mIsGameEnd = IsEnd; mIsChange = true; } }; class MyPlayer : public Player{ private: public: virtual void Update(float time_step); virtual void HandleEvent(SDL_Event &ev); virtual void RenderUnknowCard(); virtual void RenderInHandCard(); virtual void RenderOutCard(); virtual void RenderSpecialCard(); virtual MahjongCard* HandleMouseEvent(int type ,int x, int y); }; class NextPlayer :public Player{ private : public: virtual void Update(float time_step); virtual void RenderUnknowCard(); virtual void RenderInHandCard(); virtual void RenderOutCard(); virtual void RenderSpecialCard(); }; class OppositePlayer :public Player{ public: virtual void Update(float time_step); virtual void RenderUnknowCard(); virtual void RenderInHandCard(); virtual void RenderOutCard(); virtual void RenderSpecialCard(); }; class PrevPlayer :public Player{ private : public: virtual void Update(float time_step); virtual void RenderUnknowCard(); virtual void RenderInHandCard(); virtual void RenderOutCard(); virtual void RenderSpecialCard(); }; #include "stdafx.h" #include "Player.h" #include "../SDLGame/SDLGame.h" void Player::CreateRenderTexture(int x,int y,int width, int height){ mTexture = SDL_CreateTexture(theGame.getRenderer(), SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET, width, height); if (mRenderRect == NULL) mRenderRect = new SDL_Rect(); mTextureWidth = width; mTextureHeight = height; mRenderRect->w = width; mRenderRect->h = height; SetPos(x, y); mIsChange = true; } void Player::Render(){ if (mIsChange){ SDL_SetRenderTarget(theGame.getRenderer(), mTexture); SDL_SetRenderDrawColor(theGame.getRenderer(), 0x00, 0x00, 0x00, 0x00); SDL_RenderClear(theGame.getRenderer()); // RenderUnknowCard(); RenderInHandCard(); RenderOutCard(); RenderSpecialCard(); SDL_SetRenderTarget(theGame.getRenderer(), NULL); SDL_SetTextureBlendMode(mTexture, SDL_BLENDMODE_BLEND); mIsChange = false; } SDL_RenderCopyEx(theGame.getRenderer(), mTexture, mClipRect, mRenderRect, 0, NULL, SDL_FLIP_NONE); } 麻将场景

包括一个背景,2个对话框(事件对话框,结束对话框),4个玩家,管理0-135共136个牌,处理游戏流程 洗牌->发牌->打牌->游戏结束。

#pragma once #include "../SDLGame/Scene.h" #include "../SDLGame/Common.h" #include "../SDLGame/MessageListener.h" #include "Player.h" #include #include #include "EventDialog.h" #include "GameEndDialog.h" #include "../SDLGame/MessageDispatcher.h" using namespace std; enum GameState{ START = 0, RIFFLECARD,SEND_CARD, RUNNING, END, WAIT_FOR_INPUT,WAIT_FOR_DIALOG,IDLE,WAIT_FOR_END_DIALOG }; enum SCENE_MSG_TYPE{ MSG_GIVE_UP = 0, MSG_PENG, MSG_GANG, MSG_HU, MSG_RESTART, MSG_GET_CARD,MSG_OUT_CARD }; //自定义消息的扩展消息 struct EVENT_EXTRA{ Player *outPlayer; Player *handlePlayer; MahjongCard *outCard; }; class MahjongScene : public Scene,public MessageListener{ private: //背景 Renderable *mBackground; //事件对话框 EventDialog *mEventDialog; //结束对话框 GameEndDialog *mGameEndDialog; //玩家 Player *mMyPlayer, *mNextPlayer, *mOppositePlayer, *mPrevPlayer; vector mPlayers; Player *mCurrentPlayer; //发牌时用到的标记 int mCurrentPopIndex; int mServerIndex; int mCurrentGetIndex; //牌的表示 int mCard[136]; float mDelayTime = 1.0f; float mTimeElapse = 0.0f; //牌池 CardMap mCardPool; //当前游戏状态 GameState mCurrentState; //最后一张出的牌 MahjongCard *mLastCard; public: MahjongScene(){ //初始化麻将牌 for (int i = 0; i SetCardNumber(i); mCardPool.insert(make_pair(i, card)); } mCurrentState = START; } void NextPopCardIndex(){ mCurrentPopIndex--; if (mCurrentPopIndex 3) mCurrentGetIndex = 0; } bool IsSendCardComplete(){ bool IsComplete = true; for (int i = 0; i GetInHandCardCount() != 13){ IsComplete = false; break; } } return IsComplete; } void SetServerIndex(int index){ mServerIndex = index; } void RandServer(){ srand((uint32_t)time(NULL)); int index = rand() % 4; SetServerIndex(index); } void RandPopIndex(){ srand((uint32_t)time(NULL)); int index = rand() % 4; mCurrentPopIndex = index; } //处理摸牌消息 void HandleCardInEvent(Player *player,MahjongCard *inCard){ //调用ai判断摸牌事件 int ev = player->GetAI()->CardInEvent(inCard); printf("%s---cardIN EV:%d\n", typeid(*player).name(),ev); if (ev & EVENT_HU){ //胡牌,2秒后发送胡牌消息。() Dispatcher.DispatchMsg(2.0f, this, this, MSG_HU); } else if (ev & EVENT_GANG){ //杠,把牌放到特殊牌中,2秒后再摸牌 player->PutToSpecialCard(inCard,4); Dispatcher.DispatchMsg(2.0f, this, this, MSG_GET_CARD, player); } else{ //没事件,2秒后出牌 Dispatcher.DispatchMsg(2.0f, this, this, MSG_OUT_CARD, player); } } //其他玩家处理出牌消息 void HandleCardOutEvent(MahjongCard *outCard, Player *player){ int ev = 0; bool bHandelEvent = false; for (int i = 0; i GetAI()->CardOutEvent(outCard, player); //如果玩家触发了事件,玩家弹出对话框,其他的就不用处理了。 //其实按正常的逻辑,是先判断每个人的事件,然后对应的人去选择处理,选择完了后,按照胡牌优先的顺序处理事件。这里单机玩的,所以玩家优先。 if (ev >= 0x01 && mPlayers[i] == mMyPlayer){ mEventDialog->ShowEvent(ev); mEventDialog->SetTag(player); mCurrentState = WAIT_FOR_DIALOG; mLastCard = outCard; bHandelEvent = true; break; } if (ev & EVENT_HU){ printf_s("%s----HU:%d\n", typeid(*mPlayers[i]).name(),i); EVENT_EXTRA *extra = new EVENT_EXTRA(); extra->outPlayer = player; extra->handlePlayer = mPlayers[i]; extra->outCard = outCard; Dispatcher.DispatchMsg(2.0f, this, this, MSG_HU, extra); bHandelEvent = true; break; } else if (ev & EVENT_GANG){ bHandelEvent = true; EVENT_EXTRA *extra = new EVENT_EXTRA(); extra->outPlayer = player; extra->handlePlayer = mPlayers[i]; extra->outCard = outCard; Dispatcher.DispatchMsg(2.0f, this, this, MSG_GANG, extra); } else if (ev & EVENT_PENG){ bHandelEvent = true; EVENT_EXTRA *extra = new EVENT_EXTRA(); extra->outPlayer = player; extra->handlePlayer = mPlayers[i]; extra->outCard = outCard; Dispatcher.DispatchMsg(2.0f, this, this, MSG_PENG, extra); } } if (!bHandelEvent){ //没人触发事件,2秒后下一家摸牌 Dispatcher.DispatchMsg(2.0f, this, this, MSG_GET_CARD, player->GetNextPlayer()); } } //弹出一张未知牌 MahjongCard *PopUnknownCard(){ MahjongCard *card = NULL; int count = 0; while (card == NULL) { card = mPlayers[mCurrentPopIndex]->PopUnknownCard(); if (card == NULL){ NextPopCardIndex(); count++; //都没有牌可弹出 if (count >= 4) break; } } return card; } //洗牌 void RiffleCard(){ srand((uint32_t)time(NULL)); for (int i = 0; i < 300; i++){ int m = rand() % 136; int n = rand() % 136; //随机交换两个牌的位置; int temp = mCard[m]; mCard[m] = mCard[n]; mCard[n] = temp; } //把交换后的牌分发到每一个玩家的未知牌里 for (int i = 0; i second; switch (index){ case 0: mMyPlayer->PutUnknowCard(card); break; case 1: mNextPlayer->PutUnknowCard(card); break; case 2: mOppositePlayer->PutUnknowCard(card); break; case 3: mPrevPlayer->PutUnknowCard(card); break; } } } } virtual void LoadScene(); ~MahjongScene(){ CardMap::iterator it = mCardPool.begin(); while (it != mCardPool.end()){ delete (it->second); it++; } mCardPool.clear(); } //鼠标事件 virtual void HandleEvent(SDL_Event &ev); virtual void Update(float); //自定义事件的处理 virtual bool OnMessage(const GameMessage &msg); }; #include "stdafx.h" #include "MahjongScene.h" #include "../SDLGame/SDLGame.h" #include "EventDialog.h" #include "GameEndDialog.h" #include "../SDLGame/GameMessage.h" #include void MahjongScene::LoadScene(){ mBackground = new Renderable(); if (mBackground->LoadTexture("background.png")){ this->AddRenderable(mBackground); } int windowWidth = theGame.GetWindowWidth(); int windowHeight = theGame.GetWindowHeight(); //我 mMyPlayer = new MyPlayer(); mMyPlayer->CreateRenderTexture(300, windowHeight-320, windowWidth-300, 320); mMyPlayer->SetInHandCardPos(10, 200); mMyPlayer->SetUnknownCardPos(85, 20); mMyPlayer->SetOutCardPos(10, 100); mMyPlayer->SetSpecialCardPos(0,0); this->AddRenderable(mMyPlayer); //下家 mNextPlayer = new NextPlayer(); mNextPlayer->CreateRenderTexture(windowWidth - 350, 0, 350, windowHeight); mNextPlayer->SetInHandCardPos(300, windowHeight - 250); mNextPlayer->SetUnknownCardPos(0, windowHeight - 250); mNextPlayer->SetOutCardPos(100, windowHeight - 250); this->AddRenderable(mNextPlayer); //上家 mPrevPlayer = new PrevPlayer(); mPrevPlayer->CreateRenderTexture(0, 0, 350, windowHeight); mPrevPlayer->SetInHandCardPos(50, 210); mPrevPlayer->SetUnknownCardPos(314, 210); mPrevPlayer->SetOutCardPos(220,210); this->AddRenderable(mPrevPlayer); //对家 mOppositePlayer = new OppositePlayer(); mOppositePlayer->CreateRenderTexture(0, 0, windowWidth, 300); mOppositePlayer->SetInHandCardPos(windowWidth - 240, 30); mOppositePlayer->SetUnknownCardPos(windowWidth - 415, 260); mOppositePlayer->SetOutCardPos(windowWidth - 415, 180); this->AddRenderable(mOppositePlayer); mPlayers.push_back(mMyPlayer); mPlayers.push_back(mNextPlayer); mPlayers.push_back(mOppositePlayer); mPlayers.push_back(mPrevPlayer); mMyPlayer->SetNextPlayer(mNextPlayer); mNextPlayer->SetNextPlayer(mOppositePlayer); mOppositePlayer->SetNextPlayer(mPrevPlayer); mPrevPlayer->SetNextPlayer(mMyPlayer); mCurrentPopIndex = 0; mCurrentGetIndex = 0; //事件对话框 EventDialog *diag = new EventDialog(); diag->CreateRenderTexture(windowWidth - 368, windowHeight - 300, 368, 206); diag->LoadButtons(); diag->SetVisible(false); this->AddRenderable(diag); diag->RegisterListener(this); mEventDialog = diag; //游戏结束对话框 GameEndDialog *endDialog = new GameEndDialog(); endDialog->CreateRenderTexture((windowWidth - 611)/2, (windowHeight - 600)/2, 611, 600); endDialog->LoadButtons(); endDialog->SetVisible(false); this->AddRenderable(endDialog); endDialog->RegisterListener(this); mGameEndDialog = endDialog; } //处理鼠标事件 void MahjongScene::HandleEvent(SDL_Event &ev){ int x = 0, y = 0; switch (ev.type){ case SDL_MOUSEBUTTONDOWN: if (ev.button.button == SDL_BUTTON_LEFT){ x = ev.button.x; y = ev.button.y; if (mCurrentState == WAIT_FOR_INPUT){ MahjongCard* card = mMyPlayer->HandleMouseEvent(ev.type, x, y); if (card != NULL){ mMyPlayer->PopCardOut(card); HandleCardOutEvent(card, mMyPlayer); mCurrentState = RUNNING; } } } break; case SDL_MOUSEMOTION: x = ev.motion.x; y = ev.motion.y; mMyPlayer->HandleMouseEvent(ev.type, x, y); break; } if (mCurrentState == WAIT_FOR_DIALOG){ mEventDialog->HandleEvent(ev); } else if (mCurrentState == WAIT_FOR_END_DIALOG){ mGameEndDialog->HandleEvent(ev); } } void MahjongScene::Update(float time_step){ mTimeElapse += time_step; if (mTimeElapse > 1.0f){ mTimeElapse -= 1.0f; MahjongCard *card = NULL; //printf("state:%d\n",mCurrentState); switch (mCurrentState) { case START: printf("start\n"); mCurrentState = RIFFLECARD; break; case RIFFLECARD: printf("riffle card\n"); RiffleCard(); mCurrentState = SEND_CARD; break; case SEND_CARD: //发牌 for (int i = 0; i PutCardIn(card,false); printf("%d,",card->GetCardNumber()); if (mPlayers[mCurrentGetIndex]->GetInHandCardCount() == 13) break; } printf("\n"); NextGetCardIndex(); if (IsSendCardComplete()){ mCurrentState = RUNNING;//(GameState)((int)MY_TURN + mCurrentGetIndex); //mCurrentPlayer = mMyPlayer; Dispatcher.DispatchMsg(2.0f, this, this, MSG_GET_CARD, mMyPlayer); } break; case RUNNING: break; case END: printf("game end\n"); { mGameEndDialog->SetVisible(true); mCurrentState = WAIT_FOR_END_DIALOG; } break; default: break; } for (int i = 0; i Update(time_step); } } } //自定义消息处理 bool MahjongScene::OnMessage(const GameMessage &msg){ int ev = msg.message; if (ev == MSG_GIVE_UP){ Dispatcher.DispatchMsg(2.0f, this, this, MSG_GET_CARD, mCurrentPlayer->GetNextPlayer()); mEventDialog->SetVisible(false); } else if (ev == MSG_PENG){ EVENT_EXTRA *extra = (EVENT_EXTRA*)msg.ExtraInfo; if (extra != NULL){ extra->outPlayer->RemoveOutCard(); extra->handlePlayer->PutToSpecialCard(extra->outCard, 2); Dispatcher.DispatchMsg(2.0f, this, this, MSG_OUT_CARD, extra->handlePlayer); } else{ Player *lastPlayer = (Player*)mEventDialog->GetTag(); if (lastPlayer != NULL){ lastPlayer->RemoveOutCard(); } mMyPlayer->PutToSpecialCard(mLastCard, 2); mCurrentState = WAIT_FOR_INPUT; mEventDialog->SetVisible(false); mEventDialog->SetTag(NULL); } SAFE_DELETE(extra); } else if (ev == MSG_GANG){ EVENT_EXTRA *extra = (EVENT_EXTRA*)msg.ExtraInfo; if (extra != NULL){ extra->outPlayer->RemoveOutCard(); extra->handlePlayer->PutToSpecialCard(extra->outCard, 3); Dispatcher.DispatchMsg(2.0f, this, this, MSG_GET_CARD, extra->handlePlayer); } else{ Player *lastPlayer = (Player*)mEventDialog->GetTag(); if (lastPlayer != NULL){ lastPlayer->RemoveOutCard(); } mMyPlayer->PutToSpecialCard(mLastCard, 4); Dispatcher.DispatchMsg(2.0f, this, this, MSG_GET_CARD, mMyPlayer); mEventDialog->SetVisible(false); mEventDialog->SetTag(NULL); } SAFE_DELETE(extra); } else if (ev == MSG_HU){ mCurrentState = END; mEventDialog->SetVisible(false); mEventDialog->SetTag(NULL); for (int i = 0; i SetGameEnd(true); } } else{ Player* player; MahjongCard *card; switch (ev) { case MSG_RESTART: for (int i = 0; i Restart(); } mCurrentState = START; mGameEndDialog->SetVisible(false); break; case MSG_GET_CARD: card = PopUnknownCard(); if (card == NULL){ mCurrentState = END; break; } player = (Player*)msg.ExtraInfo; player->PutCardIn(card); mCurrentPlayer = player; if (player == mMyPlayer){ mCurrentState = WAIT_FOR_INPUT; int e = mMyPlayer->GetAI()->CardInEvent(card); if (e > 0){ mLastCard = card; mEventDialog->ShowEvent(e); mEventDialog->SetTag(NULL); mCurrentState = WAIT_FOR_DIALOG; } } else{ HandleCardInEvent(player, card); } break; case MSG_OUT_CARD: player = (Player*)msg.ExtraInfo; card = player->GetAI()->GetBestOutCard(); player->PopCardOut(card); HandleCardOutEvent(card, player); break; } } return true; } 效果图

本来以为这文档会很快写完,谁知到修修改改加上注释,花了将近4个小时的时间,写文档果然是不擅长啊。

在这里插入图片描述


作者:drizzlemao



sdl 游戏开发

需要 登录 后方可回复, 如果你还没有账号请 注册新账号