📄 gamemap.cpp
字号:
#include "stdafx.h"
#include "gamemap.h"
#include "resource.h"
#include "time.h"
#include "tool.h"
#include "filereport.h"
//FILEREPORT f1("m1.txt");
#define FROM_REST 0
#define FROM_FINISH 1
#define FROM_COL 2
#define ISNORMAL(x) ((x)>=0 && (x)<52)
#define ISBACK(x) ((x)>=52 && (x)<104)
GAMEMAP::GAMEMAP()
{
iLevel=0;
}
GAMEMAP::~GAMEMAP()
{
}
void GAMEMAP::SetDC(HDC hdest,HDC hsrc)
{
hdcdest=hdest;
hdcsrc=hsrc;
}
void GAMEMAP::Init(HINSTANCE hInstance)
{
hPaperBack=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP_PAPER_BACK));
hPaper=LoadBitmap(hInstance,MAKEINTRESOURCE(IDB_BITMAP_PAPER));
//hBrushEmpty=(HBRUSH)CreateSolidBrush(HS_CROSS,RGB(0,128,0));
hBrushEmpty=(HBRUSH)GetStockObject(NULL_BRUSH);
hback=(HBRUSH)CreateSolidBrush(RGB(0,128,0));
}
void GAMEMAP::Show()
{
int i,j;
int tempy,tempx;
//背景
SelectObject(hdcdest,hback);
Rectangle(hdcdest,0,0,GAMEWIDTH,GAMEHEIGHT);
//左上角
ShowRestPaper();
//右上角
ShowFinishPaper();
//摆七列牌
for(i=0;i<7;i++)
{
tempy=PAPER_Y;
tempx=PAPER_X+i*(PAPERWIDTH + PAPER_BETWEEN_WIDTH);
for(j=0;j<pColNum[i];j++)
{
if(pCol[i*20+j]<52)
{
if(!IsMove[pCol[i*20+j]])
{
DrawPaper(pCol[i*20+j],tempx,tempy);
tempy+=PAPER_BETWEEN;
}
}
else
{
DrawClosePaper(tempx,tempy);
tempy+=PAPER_BACK_BETWEEN;
}
}
}
}
void GAMEMAP::SetPaper()
{
int temppaper[52];
int i,j,ipaper;
int addr;
//洗牌
memset(temppaper,-1,sizeof(temppaper));
srand(time(NULL));
for(i=0;i<52;i++)
{
addr=rand()%52;
while(temppaper[addr]!=-1)
{
addr+=3;
addr%=52;
}
temppaper[addr]=i;
}
memset(pCol,-1,sizeof(pCol));
ipaper=0;
//摆七列牌
for(i=0;i<7;i++)
{
//每列的数量
pColNum[i]=i+1;
for(j=0;j<=i;j++)
{
pCol[i*20+j]=temppaper[ipaper];
ipaper++;
}
}
memset(pColTopY,0,sizeof(pColTopY));
for(i=0;i<7;i++)
{
pColTopY[i]=PAPER_Y + i*PAPER_BACK_BETWEEN;
}
//剩余的牌
memset(pRest,-1,sizeof(pRest));
for(i=0;ipaper<52;i++)
{
pRest[i]=temppaper[ipaper];
ipaper++;
}
iRestNum=24;
//初始化背面的牌,原牌值+52
for(i=1;i<7;i++)
{
for(j=0;j<i;j++)
{
pCol[i*20+j]+=52;
}
}
//
iRestPaperNow=-1;
memset(CatchPaper,-1,sizeof(CatchPaper));
//右上角
memset(pFinish,-1,sizeof(pFinish));
memset(pFinishNum,0,sizeof(pFinishNum));
//移动状态标记数组
memset(IsMove,0,sizeof(IsMove));
//过关动画
memset(&aniwin,0,sizeof(aniwin));
iShowBack=0;
}
//牌的序号0-51
//背面朝上的牌52-103
void GAMEMAP::DrawPaper(int id,int x,int y)
{
if(id<0 || id>51)
return;
if(0==iLevel)
{
if(id>=26)
{
id-=26;
}
}
SelectObject(hdcsrc,hPaper);
BitBlt(hdcdest,x,y,PAPERWIDTH,PAPERHEIGHT,hdcsrc,
(id%13)*PAPERWIDTH,(id/13)*PAPERHEIGHT,SRCCOPY);
}
void GAMEMAP::DrawClosePaper(int x,int y)
{
SelectObject(hdcsrc,hPaperBack);
BitBlt(hdcdest,x,y,PAPERWIDTH,PAPERHEIGHT,hdcsrc,
0,0,SRCCOPY);
}
void GAMEMAP::DrawCatchPaper()
{
int i;
int tempx,tempy;
tempx=moveposx-moveoffx;
tempy=moveposy-moveoffy;
for(i=0;i<13;i++)
{
if(-1==CatchPaper[i])
{
break;
}
DrawPaper(CatchPaper[i],tempx,tempy);
tempy+=PAPER_BETWEEN;
}
}
void GAMEMAP::LUPproc(int x,int y)
{
int iCol,i;
if(-1== CatchPaper[0])
{
//检测左上角,翻剩余的牌
if(PointInRect(x,y,REST_X,REST_Y,PAPERWIDTH,PAPERHEIGHT))
{
GetOneRestPaper();
memset(CatchPaper,-1,sizeof(CatchPaper));
return;
}
//检测是否翻开牌
iCol=GetPutCol(x,y);
if(iCol>=0 && iCol<7)
{
if(ISBACK(pCol[iCol*20+pColNum[iCol]-1]))
{
pCol[iCol*20+pColNum[iCol]-1]-=52;
}
}
}
else
{
//检查是否能放到下边七列中
iCol=GetPutCol(x,y);
if(iCol>=0 && iCol<7)
{
AddCol(iCol);
}
else
{
//是否是右上角的四个格
iCol=GetPutFinish(x,y);
if(iCol>=0 && iCol<4)
{
AddFinish(iCol);
}
}
//清除当前移动的牌
memset(CatchPaper,-1,sizeof(CatchPaper));
//清除牌的移动状态
memset(IsMove,0,sizeof(IsMove));
}
}
void GAMEMAP::LDOWNproc(int x,int y)
{
int iCol;
int i;
if(CatchPaper[0]!=-1)
{
//如果当前正在移动牌
memset(CatchPaper,-1,sizeof(CatchPaper));
return;
}
//检测拾取的牌
if(PointInRect(x,y,REST_X+PAPERWIDTH + PAPER_BETWEEN_WIDTH,REST_Y,
PAPERWIDTH,PAPERHEIGHT))
{
if(-1 !=iRestPaperNow)
{
memset(CatchPaper,-1,sizeof(CatchPaper));
CatchPaper[0]=pRest[iRestPaperNow];
//
moveposx=x;
moveposy=y;
moveoffx=x-REST_X-PAPERWIDTH-PAPER_BETWEEN_WIDTH;
moveoffy=y-REST_Y;
//from
ipaperfrom=FROM_REST;
}
}
else
{
//从右上角取牌
iCol=GetPutFinish(x,y);
if(iCol>=0 && iCol<4)
{
if(0 == pFinishNum[iCol])
return;
memset(CatchPaper,-1,sizeof(CatchPaper));
CatchPaper[0]=pFinish[iCol*13+pFinishNum[iCol]-1];
moveposx=x;
moveposy=y;
moveoffx=x-REST_X-(iCol+3)*(PAPERWIDTH+PAPER_BETWEEN_WIDTH);
moveoffy=y-REST_Y;
ipaperfrom=FROM_FINISH;
}
else
{
GetPickCol(x,y);
}
}
//设置移动的牌的状态
for(i=0;i<13;i++)
{
if(-1 == CatchPaper[i])
{
break;
}
else
{
IsMove[CatchPaper[i]]=1;
}
}
}
//移动拾取的牌
void GAMEMAP::LMOVEproc(int x,int y)
{
if(-1==CatchPaper[0])
{
//没有拾取的牌
return;
}
moveposx=x;
moveposy=y;
}
//左上角弹出的牌
void GAMEMAP::ShowRestPaper()
{
int i;
//画背面的图案
SelectObject(hdcsrc,hPaperBack);
if(0==iRestNum || iRestNum-1==iRestPaperNow)
{
//已经取到最后一张牌
//没有剩余的牌
BitBlt(hdcdest,REST_X,REST_Y,PAPERWIDTH,PAPERHEIGHT,hdcsrc,PAPERWIDTH,0,SRCCOPY);
}
else
{
BitBlt(hdcdest,REST_X,REST_Y,PAPERWIDTH,PAPERHEIGHT,hdcsrc,0,0,SRCCOPY);
}
//显示当前翻出的牌
for(i=0;i<=iRestPaperNow;i++)
{
if(!IsMove[pRest[i]])
{
DrawPaper(pRest[i],REST_X+PAPERWIDTH + PAPER_BETWEEN_WIDTH,REST_Y);
}
}
}
void GAMEMAP::GetOneRestPaper()
{
if(iRestNum<=0)
{
return;
}
//依次从剩余的牌中,找出一张
if(-1==iRestPaperNow)
{
iRestPaperNow=0;
}
else
{
iRestPaperNow++;
//下标最大
if(iRestPaperNow>23 || pRest[iRestPaperNow]==-1)
{
iRestPaperNow=-1;
}
}
}
void GAMEMAP::ClearPaper()
{
int i,j;
switch(ipaperfrom)
{
case FROM_REST:
pRest[iRestPaperNow]=-1;
//从剩余牌中取出
for(i=iRestPaperNow;i<23;i++)
{
pRest[i]=pRest[i+1];
}
pRest[23]=-1;
iRestPaperNow--;
iRestNum--;
break;
case FROM_FINISH:
//从完成的牌中取出
for(i=0;i<52;i++)
{
if(pFinish[i]==CatchPaper[0])
{
pFinish[i]=-1;
pFinishNum[i/13]--;
break;
}
}
break;
case FROM_COL:
//从下边的牌中取出
i=iColFrom*20;
while(pCol[i]!=CatchPaper[0] )
{
i++;
}
//找到该列
for(j=0;j<13;j++)
{
if(-1 == CatchPaper[j])
break;
pCol[i]=-1;
pColNum[i/20]--;
pColTopY[i/20] -= PAPER_BETWEEN;
i++;
}
break;
}
}
//放到哪一列中
int GAMEMAP::GetPutCol(int x,int y)
{
int iCol,tempy;
int i;
int iback=0;
int inormal=0;
//放到下边的七列中
iCol=(x-PAPER_X )/(PAPERWIDTH +PAPER_BETWEEN_WIDTH );
if(iCol>=0 && iCol<7)
{
if(x-PAPER_X-iCol*(PAPERWIDTH +PAPER_BETWEEN_WIDTH) > PAPERWIDTH )
{
iCol=-1;
}
else
{
tempy=PAPER_Y;
for(i=0;i<pColNum[iCol];i++)
{
if(ISBACK(pCol[20*iCol+i]))
{
tempy+=PAPER_BACK_BETWEEN;
}
else
{
tempy+=PAPER_BETWEEN ;
}
}
if(y<tempy || y>tempy+PAPERHEIGHT )
{
iCol=-1;
}
}
}
else
{
iCol=-1;
}
return iCol;
}
//右上角
int GAMEMAP::GetPutFinish(int x,int y)
{
int iCol;
iCol=(x-PAPER_X-3*(PAPERWIDTH +PAPER_BETWEEN_WIDTH) )
/(PAPERWIDTH +PAPER_BETWEEN_WIDTH );
if(iCol>=0 && iCol<4)
{
if(x-PAPER_X-3*(PAPERWIDTH +PAPER_BETWEEN_WIDTH)
-iCol*(PAPERWIDTH +PAPER_BETWEEN_WIDTH) > PAPERWIDTH )
{
iCol=-1;
}
else
{
if(y<REST_Y || y>REST_Y+PAPERHEIGHT )
{
iCol=-1;
}
}
}
else
{
iCol=-1;
}
return iCol;
}
void GAMEMAP::ShowFinishPaper()
{
int i,j;
int tempx;
tempx=PAPER_X+3*(PAPERWIDTH + PAPER_BETWEEN_WIDTH);
for(i=0;i<4;i++)
{
SelectObject(hdcdest,hBrushEmpty);
Rectangle(hdcdest,
tempx,
REST_Y,
tempx+PAPERWIDTH,
REST_Y + PAPERHEIGHT);
for(j=12;j>=0;j--)
{
if(pFinish[i*13+j]!=-1 && !IsMove[pFinish[i*13+j]] )
break;
}
if(j>=0 && j<13)
{
DrawPaper(pFinish[i*13+j],tempx,REST_Y);
}
tempx+=PAPERWIDTH + PAPER_BETWEEN_WIDTH;
}
}
int GAMEMAP::AddFinish(int icol)
{
int i=0;
int ivalue,ikind,ikind2;
//右上角的牌不能互相移动
if(ipaperfrom == FROM_FINISH)
return 0;
//移动的牌多于1张返回
if(CatchPaper[1]!=-1)
{
return 0;
}
//当前已经放满了十三张牌,返回零
while(i<13 && pFinish[icol*13+i]!=-1 )
{
i++;
}
if(i>=13)
{
return 0;
}
if(i>0)
{
if(0==iLevel)
{
//初级,只区分两种花色
ikind=(pFinish[icol*13+i-1]/13)%2;
ikind2=(CatchPaper[0]/13)%2;
}
else
{
ikind=pFinish[icol*13+i-1]/13;
ikind2=CatchPaper[0]/13;
}
if(ikind!=ikind2)
{
return 0;
}
ivalue=pFinish[icol*13+i-1]%13;
//每张牌递增
if(ivalue!=CatchPaper[0]%13-1)
return 0;
}
else
{
//第一张牌是A
if(CatchPaper[0]%13 != 0)
return 0;
}
pFinish[icol*13+i]=CatchPaper[0];
//设置数量
pFinishNum[icol]++;
ClearPaper();
return 1;
}
int GAMEMAP::AddCol(int iCol)
{
int i,ikind,ivalue;
//如果移动前后属于同一列
if( ipaperfrom == FROM_COL && iColFrom == iCol )
return 0;
//该列最上面的牌是背面朝上
if(0!=pColNum[iCol])
{
if( ISBACK(pCol[iCol*20+pColNum[iCol]-1]))
return 0;
//ikind 0 红 1黑
ikind= (pCol[iCol*20+pColNum[iCol]-1]/13)%2;
if(ikind == (CatchPaper[0]/13)%2 )
return 0;
//每张牌递减
ivalue=pCol[iCol*20+pColNum[iCol]-1]%13;
if(ivalue != CatchPaper[0]%13 + 1 )
return 0;
}
else
{
//空的列只能放k
if(CatchPaper[0]%13 != 12 )
return 0;
}
for(i=0;i<13;i++)
{
if(CatchPaper[i]==-1)
{
break;
}
pCol[iCol*20+pColNum[iCol]] = CatchPaper[i];
pColNum[iCol]++;
pColTopY[iCol] += PAPER_BETWEEN;
}
ClearPaper();
return 1;
}
void GAMEMAP::GetPickCol(int x,int y)
{
int i,iCol,tempy,iPick;
//从下边的七列中取牌
iCol=(x-PAPER_X )/(PAPERWIDTH +PAPER_BETWEEN_WIDTH );
if(iCol>=0 && iCol<7)
{
if(x-PAPER_X-iCol*(PAPERWIDTH +PAPER_BETWEEN_WIDTH) > PAPERWIDTH )
{
iCol=-1;
}
}
else
{
iCol=-1;
}
if(-1== iCol)
return;
//判断纵坐标
if(iCol>=0 && iCol<7)
{
tempy=PAPER_Y;
iPick=-1;
for(i=0;i<pColNum[iCol];i++)
{
if(!ISNORMAL(pCol[iCol*20+i]))
{
tempy+=PAPER_BACK_BETWEEN;
continue;
}
if(i==pColNum[iCol]-1)
{
if(y>tempy && y<(tempy+ PAPERHEIGHT ) )
{
iPick=i;
break;
}
}
else
{
if(y>tempy && y<(tempy+ PAPER_BETWEEN ) )
{
iPick=i;
break;
}
}
tempy+=PAPER_BETWEEN;
}
//如果当前有牌
//如果牌正面朝上
if(iPick>=0 && iPick<pColNum[iCol])
{
memset(CatchPaper,-1,sizeof(CatchPaper));
i=0;
while(iPick < pColNum[iCol])
{
CatchPaper[i]=pCol[iCol*20+iPick];
iPick++;
i++;
}
ipaperfrom=FROM_COL;
iColFrom=iCol;
}
}
//
moveposx=x;
moveposy=y;
moveoffx=x-PAPER_X -iCol*(PAPERWIDTH+PAPER_BETWEEN_WIDTH);
moveoffy=y-tempy;
}
int GAMEMAP::CheckWin()
{
int i;
for(i=0;i<4;i++)
{
if(pFinish[i*13+12]==-1)
return 0;
}
return 1;
}
void GAMEMAP::ShowWin()
{
if(!aniwin.iStart)
return;
DrawPaper(aniwin.id,aniwin.x,aniwin.y);
//扑克牌的弹跳
aniwin.x+=aniwin.xoff;
aniwin.y+=aniwin.yoff;
if(aniwin.yoff>0)
{
aniwin.yoff+=2;
}
else if(aniwin.yoff<0)
{
aniwin.yoff+=2;
if(aniwin.yoff>=0)
{
aniwin.yoff=5;
}
}
else
{
}
if(aniwin.x<-PAPERWIDTH || aniwin.x>GAMEWIDTH)
{
//下一张牌
aniwin.i++;
if(aniwin.i>3)
{
aniwin.i=0;
aniwin.j--;
if(aniwin.j<0)
{
aniwin.iStart=0;//动画结束
}
}
aniwin.id=pFinish[aniwin.i*13+aniwin.j];
aniwin.x=PAPER_X+(3+aniwin.i)*(PAPERWIDTH + PAPER_BETWEEN_WIDTH);
aniwin.y=REST_Y;
aniwin.xoff=-10+(rand()%10)*2;
if(0==aniwin.xoff)
aniwin.xoff=-3;
aniwin.yoff=5;
}
if(aniwin.y>GAMEHEIGHT-PAPERHEIGHT )
{
aniwin.y=GAMEHEIGHT-PAPERHEIGHT;
if(aniwin.yoff>=0 && aniwin.yoff<=10)
{
aniwin.yoff=0;
}
else
{
aniwin.yoff/=2;
aniwin.yoff=-aniwin.yoff;
}
}
}
void GAMEMAP::ShowWinStart()
{
aniwin.iStart=1;
aniwin.i=0;
aniwin.j=12;
aniwin.id=pFinish[aniwin.i*13+aniwin.j];
aniwin.x=PAPER_X+(3+aniwin.i)*(PAPERWIDTH + PAPER_BETWEEN_WIDTH);
aniwin.y=REST_Y;
aniwin.xoff=-3;
aniwin.yoff=5;
}
void GAMEMAP::SetLevel(int i)
{
iLevel=i;
}
void GAMEMAP::ClearCatchPaper()
{
//清除当前移动的牌
memset(CatchPaper,-1,sizeof(CatchPaper));
//清除牌的移动状态
memset(IsMove,0,sizeof(IsMove));
}
//显示背面的牌
void GAMEMAP::ShowBack()
{
int i,j,id;
int tempx,tempy;
if(!iShowBack)
return;
tempx=PAPER_X+PAPER_BETWEEN_WIDTH+PAPERWIDTH ;
SelectObject(hdcsrc,hPaper);
for(i=1;i<7;i++)
{
tempy=PAPER_Y -PAPER_BETWEEN ;
for(j=0;j<20;j++)
{
id=pCol[i*20+j];
if(!ISBACK(id))
break;
//得到这张背面牌的牌值
id-=52;
if(0==iLevel)
{
if(id>=26)
{
id-=26;
}
}
BitBlt(hdcdest,tempx+j*11,tempy,14,PAPER_BETWEEN ,hdcsrc,
(id%13)*PAPERWIDTH,(id/13)*PAPERHEIGHT,SRCCOPY);
tempy+=PAPER_BACK_BETWEEN;
}
tempx+=PAPER_BETWEEN_WIDTH+PAPERWIDTH ;
}
}
void GAMEMAP::SetShowBack(int i)
{
iShowBack=i;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -