📄 game.cpp
字号:
#include "stdafx.h"
#include "斗地主.h"
#include "MainFrm.h"
#include "My_DirectInput.h"
#include "my_directdraw.h"
#include "Playing_Cards.h"
#include "Game.h"
#include "Draw_Item_Engine.h"
#include "Draw_Cards_Engine.h"
//#include "Single_Game.h"
//主窗口句柄;
HWND hWnd;
//主窗口类指针;设为全局变量便于各个类访问其方法;
CMainFrame* pCMainFrame;
//DirectDraw设备对象指针;
CMyDirectInput* pInput;
CMyDirectDraw* pDraw;
LPDIRECTDRAWSURFACE7 lpddsprimary; // dd primary surface
LPDIRECTDRAWSURFACE7 lpddsback; // dd back surface
LPDIRECTDRAWSURFACE7 lpddsbg_Game; //离屏表面;
//游戏主体框架类指针;
CGame* pGame;
//54张扑克;
CCard g_cAllCards[54];
//存储玩家信息的类;
CPlayerInfo* pCenterPlayer;
CPlayerInfo* pLeftPlayer;
CPlayerInfo* pRightPlayer;
CPlayingCards* pLeftCards; //左边玩家的牌对象;
CPlayingCards* pCenterCards; //主机玩家的牌对象;
CPlayingCards* pRightCards; //右边玩家的牌对象;
//关于其他精灵的绘制引擎;
CDrawItemEngine* pDrawItem;
//关于扑克绘制的引擎;
CDrawCardsEngine* pDrawCards;
//游戏牌面坐标系统;
CCardsMap* pCardsMap;
//网络设备;
CLink* pServerLink1; //连接客户1;
CLink* pServerLink2; //连接客户2;
CLink* pClientLink; //客户端1;
//位置坐标;
int Screen_Width = 1024; int Screen_Height = 768; //屏幕长,宽;
int Cards_Width = 82; int Cards_Height = 114; //扑克长宽;
//int Face_Width = 70; int Face_Height = 70; //头像的长宽;
int Center_x0 = 350; int Center_y0 = 620; //中间玩家未出的牌;
int Center_x1 = 230; int Center_y1 = 470; //中间玩家已经出过的牌;
int Center_x2 = 330; int Center_y2 = 340; //中间玩家刚出的牌;
int Left_x0 = 35; int Left_y0 = 140; //左边玩家未出的牌;
int Left_x1 = 140; int Left_y1 = 30; //左边玩家已经出过的牌;
int Left_x2 = 240; int Left_y2 = 65; //左边玩家刚出的牌;
int Right_x0 = 905; int Right_y0 = 140; //右边玩家未出的牌;
int Right_x1 = 800; int Right_y1 = 30; //右边玩家已经出过的牌;
int Right_x2 = 700; int Right_y2 = 65; //右边玩家刚出的牌;
//三张显示的地主牌;
int Lord_Card1_x = 379; int Lord_Card1_y = 30;
int Lord_Card2_x = 471; int Lord_Card2_y = 30;
int Lord_Card3_x = 563; int Lord_Card3_y = 30;
int Card_x = 471; int Card_y = 190; //发牌的起始位置;
//左,右玩家未出牌和中间玩家已出牌的间距:
int Card_Distance0 = 18;
//左,右玩家已出牌的间距;
int Card_Distance1 = 23;
//中间玩家未出牌和刚出的牌的间距;
int Card_Distance2 = 25;
//中间扑克选择后突出的高度;
int Card_Up = 20;
CPlayerInfo::CPlayerInfo()
{
m_nPlayerType = -1;
m_nFaceID = -1;
m_nScore = 50;
m_nWin = 0;
m_nLose = 0;
}
//游戏屏幕刷新函数;
int RedrawGame(BOOL bSprimary)
{
pDraw->DrawSurface(lpddsbg_Game,0,0, Screen_Width,Screen_Height,lpddsback,0);
//重画整个牌面布局;
pDrawCards->Redraw();
pDrawItem->Redraw();
if(bSprimary == 1)
while (FAILED(lpddsprimary->Flip(NULL, DDFLIP_WAIT)));
return 1;
}
CGame::CGame():m_cCardsRect(Center_x0,
Center_y0,
0, //这个值会变,不定;
Center_y0 + Cards_Height),
m_cCardsUpRect(Center_x0,
Center_y0 - Card_Up,
0, //这个值会变,不定;
Center_y0 + Cards_Height - Card_Up),
m_cOK_RECT(660,550,660+80,550+30),
m_cYES_RECT(335,540,335+80,540+30),
m_cNO_RECT(425,540,425+80,540+30),
m_cEXIT_RECT(900,695,900+100,695+30)
{
m_nCurrentLord = -1;
m_nDefaultLord = -1;
m_nLordLock = -1;
m_bButton = 1;
m_bOperate = FALSE;
m_nRoundCounter = 0;
m_nGameCounter = 0;
m_nBombCounter = 0;
}
CGame::~CGame()
{
}
void CGame::Init()
{
//Dx设备的初始化;
//产生DirctDraw对象;
pDraw = new CMyDirectDraw;
pDraw->Init();
//初始化鼠标输入设备;
pInput = new CMyDirectInput;
pInput->MouseInit();
pLeftCards = new CPlayingCards; //左边玩家的牌对象;
pCenterCards = new CPlayingCards; //主机玩家的牌对象;
pRightCards = new CPlayingCards; //右边玩家的牌对象;
pCardsMap = new CCardsMap;
pDrawItem = new CDrawItemEngine;
pDrawItem->Init();
pDrawCards = new CDrawCardsEngine;
pDrawCards->Init();
}
//新一局,洗牌;
void CGame::NewGame()
{
m_nGameCounter++;
m_nCurrentLord = -1;
m_nDefaultLord = -1;
m_nLordLock = -1;
m_bButton = 1;
m_bOperate = FALSE;
m_nRoundCounter = 0;
m_nBombCounter = 0;
pDrawCards->m_bVisual = FALSE;
pLeftCards->New();
pCenterCards->New();
pRightCards->New();
//让新的地主牌不可见,让发的牌可见;
pCardsMap->m_nLordCards = 1;
pCardsMap->m_cDistributeCard.m_bVisual = 1;
for(int i=0;i<3;i++)
{
pCardsMap->m_cLordCards[i].m_bVisual = 0; //0为不可见;
}
}
//洗牌;
void CGame::ShuffleCards()
{
//将牌放入;
for(int i=3,j=0;j<=12;i++,j++)
{
//黑桃
g_cAllCards[j*4+0].m_nColor = 0;
g_cAllCards[j*4+0].m_nValue = i;
//红桃
g_cAllCards[j*4+1].m_nColor = 1;
g_cAllCards[j*4+1].m_nValue = i;
//梅花
g_cAllCards[j*4+2].m_nColor = 2;
g_cAllCards[j*4+2].m_nValue = i;
//方块
g_cAllCards[j*4+3].m_nColor = 3;
g_cAllCards[j*4+3].m_nValue = i;
}
g_cAllCards[52].m_nColor = 1; //正百搭;
g_cAllCards[52].m_nValue = 16;
g_cAllCards[53].m_nColor = 0; //副百搭;
g_cAllCards[53].m_nValue = 16;
//高效洗牌;
int nRandPos;
CCard cTempCard;
for(int k=0;k<54;k++)
{
//产生一个随机位置;
nRandPos = rand()%54;
//把当前牌与这个随机位置的牌交换;
cTempCard = g_cAllCards[k];
g_cAllCards[k] = g_cAllCards[nRandPos];
g_cAllCards[nRandPos] = cTempCard;
}
}
//当轮到本机玩家出牌时的屏幕刷新函数;
int CGame::RefreshMyTurn()
{
// ::Redraw_Game();
if( m_nLordLock != 1 )
{
if( m_bButton ) //延时锁;
{
//当鼠标点击到按钮并且提起牌数不为0时才执行出牌操作
if( pInput->IsLButtonDown(m_cOK_RECT) )
{
::KillTimer(hWnd,20);
PlaySound(MAKEINTRESOURCE(IDR_DING),AfxGetResourceHandle(),
SND_ASYNC|SND_RESOURCE|SND_NODEFAULT ); //
int i = CenterDoing();
if( i == 0 )
{
::SetTimer(hWnd,20,50,NULL); //恢复计时器;
}
else if( i == 1 )
{
//左边玩家(电脑)思考,并决定要出的牌;
if( RightDoing() == 0 )
{
return 0;
}
//右边玩家(电脑)思考,并决定要出的牌;
if( LeftDoing() == 0 )
{
return 0;
}
::SetTimer(hWnd,20,50,NULL);
}
else if( i == 2 )
{
return 0;
}
}
//
}
}
else
{
::KillTimer(hWnd,20);
CenterDoing();
if( RightDoing() == 0 )
{
return 0;
}
Sleep(1000); //延时;
//右边玩家(电脑)思考,并决定要出的牌;
if( LeftDoing() == 0 )
{
return 0;
}
Sleep(1000); //延时;
::SetTimer(hWnd,20,50,NULL);
}
return 1;
}
//刷新菜单控制整个游戏生命周期的全局线程函数;
DWORD WINAPI CGame::RefreshMenu(LPVOID pParam)
{
int pos;
CPoint point;
while(1)
{
//如果正在游戏当中;
if( pGame->m_bOperate )
{
pGame->m_cCardsRect.right = Center_x0 + Card_Distance1 * (pCenterCards->m_nCardsCounter - 1) + Cards_Width;
pGame->m_cCardsUpRect.right = Center_x0 + Card_Distance1 * (pCenterCards->m_nCardsCounter - 1) + Cards_Width;
if( pInput->IsLButtonDown(pGame->m_cCardsRect) )
{
::GetCursorPos(&point);
pos = (point.x - Center_x0)/Card_Distance1 + 1; //左键点击的牌;
if(pos >= pCenterCards->m_nCardsCounter)
{
if(pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY != Center_y0 - Card_Up)
{
PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
SND_ASYNC|SND_RESOURCE|SND_NODEFAULT ); //
pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY -= Card_Up;
pCardsMap->m_nUpCounter++; //选择提起的牌数加一;
::RedrawGame();
// return 1;
}//end if(pCardsMap->Center0[pCenterCards->Cards_Counter - 1].m_nY == Center_y0 - Card_Up)
}
else
{
if(pCardsMap->Center0[pos - 1].m_nY != Center_y0 - Card_Up)
{
PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
SND_ASYNC|SND_RESOURCE|SND_NODEFAULT ); //
pCardsMap->Center0[pos - 1].m_nY -= Card_Up;
pCardsMap->m_nUpCounter++; //选择提起的牌数加一;
::RedrawGame();
// return 1;
}
}// end if(pos >= pCenterCards->Cards_Counter)
}
else if( pInput->IsRButtonDown(pGame->m_cCardsUpRect) )
{
::GetCursorPos(&point);
pos = (point.x - Center_x0)/Card_Distance1 + 1; //右键点击的牌;
if(pos >= pCenterCards->m_nCardsCounter)
{
if(pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY == Center_y0 - Card_Up)
{
PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
SND_ASYNC|SND_RESOURCE|SND_NODEFAULT ); //
pCardsMap->Center0[pCenterCards->m_nCardsCounter - 1].m_nY += Card_Up;
pCardsMap->m_nUpCounter--; //选择提起的牌数减一;
::RedrawGame();
}
}
else
{
if(pCardsMap->Center0[pos - 1].m_nY == Center_y0 - Card_Up)
{
PlaySound(MAKEINTRESOURCE(IDR_GIVE),AfxGetResourceHandle(),
SND_ASYNC|SND_RESOURCE|SND_NODEFAULT ); //
pCardsMap->Center0[pos - 1].m_nY += Card_Up;
pCardsMap->m_nUpCounter--; //选择提起的牌数减一;
::RedrawGame();
}
}// end if(pos >= pCenterCards->Cards_Counter)
}//end if 点击在未出牌区;
} //end if;
//刷新菜单;
if( pInput->IsLButtonDown(pGame->m_cEXIT_RECT) )
{
::PostMessage(hWnd,WM_CLOSE,NULL,NULL);
::ExitProcess(NULL);
//强制结束游戏;
}
Sleep(20);
}//end while;
return 1;
}
void CGame::AccountScore(int player)
{
//地主胜;
int score = 0;
if( m_nBombCounter == 0 )
{
score = 1;
}
else
{
score = 2;
m_nBombCounter--;
while( m_nBombCounter )
{
score *= 2;
m_nBombCounter--;
}
// char table_info[10];
//左边玩家得分信息;
// sprintf(table_info,"%d",score);
// pDraw->Draw_Text_GDI(table_info,300,300,RGB(255,0,0),500,"华文新魏",lpddsprimary);
// Sleep(2000);
}
if( player == m_nCurrentLord )
{
switch( m_nCurrentLord )
{
case 0:
pLeftPlayer->m_nScore += score*2;
pLeftPlayer->m_nWin++;
pCenterPlayer->m_nScore -= score;
pCenterPlayer->m_nLose++;
pRightPlayer->m_nScore -= score;
pRightPlayer->m_nLose++;
pDrawItem->GameScore(m_nCurrentLord,score*2,-score,-score);
break;
case 1:
pCenterPlayer->m_nScore += score*2;
pCenterPlayer->m_nWin++;
pLeftPlayer->m_nScore -= score;
pLeftPlayer->m_nLose++;
pRightPlayer->m_nScore -= score;
pRightPlayer->m_nLose++;
pDrawItem->GameScore(m_nCurrentLord,-score,score*2,-score);
break;
case 2:
pRightPlayer->m_nScore += score*2;
pRightPlayer->m_nWin++;
pLeftPlayer->m_nScore -= score;
pLeftPlayer->m_nLose++;
pCenterPlayer->m_nScore -= score;
pCenterPlayer->m_nLose++;
pDrawItem->GameScore(m_nCurrentLord,-score,-score,score*2);
break;
}
}
else
{
switch( m_nCurrentLord )
{
case 0:
pLeftPlayer->m_nScore -= score*2;
pLeftPlayer->m_nLose++;
pCenterPlayer->m_nScore += score;
pCenterPlayer->m_nWin++;
pRightPlayer->m_nScore += score;
pRightPlayer->m_nWin++;
pDrawItem->GameScore(m_nCurrentLord,-score*2,score,score);
break;
case 1:
pCenterPlayer->m_nScore -= score*2;
pCenterPlayer->m_nLose++;
pLeftPlayer->m_nScore += score;
pLeftPlayer->m_nWin++;
pRightPlayer->m_nScore += score;
pRightPlayer->m_nWin++;
pDrawItem->GameScore(m_nCurrentLord,score,-score*2,score);
break;
case 2:
pRightPlayer->m_nScore -= score*2;
pRightPlayer->m_nLose++;
pLeftPlayer->m_nScore += score;
pLeftPlayer->m_nWin++;
pCenterPlayer->m_nScore += score;
pCenterPlayer->m_nWin++;
pDrawItem->GameScore(m_nCurrentLord,score,score,-score*2);
break;
}
}
}
//比较当前牌是否为合法;
int CGame::CompareCards()
{
//大小判断;
if( pLeftCards->m_cDiscardingType.m_nTypeNum != 0 )
{
if( pCenterCards->m_cDiscardingType.m_nTypeNum !=
pLeftCards->m_cDiscardingType.m_nTypeNum )
{
if( pCenterCards->m_cDiscardingType.m_nTypeNum == 4 ) //炸弹;
{
return 1; //合法;
}
else
{
return 0; //不合法;
}
}
else
{
//补丁:
if( pLeftCards->m_cDiscardingType.m_nTypeValue == 16 &&
pLeftCards->m_cDiscardingType.m_nTypeNum == 1 )
{
if( pCenterCards->m_cDiscardingType.m_nTypeValue == 16 && //大王,可以出;
pCenterCards->m_cChoosingCards[0].m_nColor == 1 )
{
return 1;
}
else //要不起;
{
return 0;
}
}
//如果牌型相同;
if( pCenterCards->m_cDiscardingType.m_nTypeValue >
pLeftCards->m_cDiscardingType.m_nTypeValue )
{
return 1; //合法;
}
else
{
return 0; //不合法;
}
}
}
//如果左边玩家没出牌,则比较右边玩家;
else if( pRightCards->m_cDiscardingType.m_nTypeNum != 0 )
{
if( pCenterCards->m_cDiscardingType.m_nTypeNum !=
pRightCards->m_cDiscardingType.m_nTypeNum )
{
if( pCenterCards->m_cDiscardingType.m_nTypeNum == 4 ) //炸弹;
{
return 1; //合法;
}
else
{
return 0; //不合法;
}
}
else
{
//补丁:
if( pRightCards->m_cDiscardingType.m_nTypeValue == 16 &&
pRightCards->m_cDiscardingType.m_nTypeNum == 1 )
{
if( pCenterCards->m_cDiscardingType.m_nTypeValue == 16 && //大王,可以出;
pCenterCards->m_cChoosingCards[0].m_nColor == 1 )
{
return 1;
}
else //要不起;
{
return 0;
}
}
//如果牌型相同;
if( pCenterCards->m_cDiscardingType.m_nTypeValue >
pRightCards->m_cDiscardingType.m_nTypeValue )
{
return 1; //合法;
}
else
{
return 0; //不合法;
}
}
}
else
{
m_nLordLock = 3;
return 1;
}
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -