边写边学GDI,最后勉勉强强写了出来,主要部分已经完成,边边角角的我自己太懒了没写出来
#include "stdafx.h"
#include "2048.h"#include "2048Dlg.h"
#include "afxdialogex.h"
#include "time.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#define white RGB(255,255,255)
#define num_1 CRect(10,10,90,90)
#define num_2 CRect(100,10,180,90)
#define num_3 CRect(190,10,270,90)
#define num_4 CRect(280,10,360,90)
#define num_5 CRect(10,100,90,180)
#define num_6 CRect(100,100,180,180)
#define num_7 CRect(190,100,270,180)
#define num_8 CRect(280,100,360,180)
#define num_9 CRect(10,190,90,270)
#define num_10 CRect(100,190,180,270)
#define num_11 CRect(190,190,270,270)
#define num_12 CRect(280,190,360,270)
#define num_13 CRect(100,280,180,360)
#define num_14 CRect(10,280,90,360)
#define num_15 CRect(190,280,270,360)
#define num_16 CRect(280,280,360,360)
int a[4][4]={0};
const DWORD dwTextColors[] = {
RGB( 0, 0, 0),
RGB(119, 110, 101), //1次方 2
RGB(119, 110, 101), //2次方 4
RGB(251, 255, 253), //3次方 8
RGB(251, 255, 253), //4次方 16
RGB(251, 255, 253), //5次方 32
RGB(251, 255, 253), //6次方 64
RGB(251, 255, 253), //7次方 128
RGB(251, 255, 253), //8次方 256
RGB(251, 255, 253), //9次方 512
RGB(251, 255, 253), //10次方 1024
RGB(251, 255, 253), //11次方 2048
RGB(251, 255, 253), //12次方 4096
};
const DWORD dwSquareColors[] = {
//RGB(255, 0, 0),
RGB(238, 228, 218), //1次方 2
RGB(236, 236, 200), //2次方 4
RGB(242, 177, 119), //3次方 8
RGB(236, 141, 83), //4次方 16
RGB(245, 124, 95), //5次方 32
RGB(233, 89, 55), //6次方 64
RGB(243, 217, 107), //7次方 128
RGB(241, 208, 75), //8次方 256
RGB(228, 192, 42), //9次方 512
RGB(227, 186, 20), //10次方 1024
RGB(236, 196, 0), //11次方 2048
RGB( 94, 218, 146), //12次方 4096
};
// 用于应用程序“关于”菜单项的 CAboutDlg 对话框
class CAboutDlg : public CDialogEx
{
public:
CAboutDlg();
// 对话框数据
enum { IDD = IDD_ABOUTBOX };
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
DECLARE_MESSAGE_MAP()
public:
// afx_msg void OnTimer(UINT_PTR nIDEvent);
// afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
// afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
virtual BOOL PreTranslateMessage(MSG* pMsg);
};
CAboutDlg::CAboutDlg() : CDialogEx(CAboutDlg::IDD)
{
}
void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CAboutDlg, CDialogEx)
// ON_WM_TIMER()
// ON_WM_CTLCOLOR()
// ON_WM_CTLCOLOR()
END_MESSAGE_MAP()
// CMy2048Dlg 对话框
CMy2048Dlg::CMy2048Dlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CMy2048Dlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
}
void CMy2048Dlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
}
BEGIN_MESSAGE_MAP(CMy2048Dlg, CDialogEx)
ON_WM_SYSCOMMAND()
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
ON_WM_CTLCOLOR()
ON_BN_CLICKED(IDC_BUTTON1, &CMy2048Dlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CMy2048Dlg::OnBnClickedButton2)
ON_BN_CLICKED(IDC_BUTTON3, &CMy2048Dlg::OnBnClickedButton3)
ON_BN_CLICKED(IDC_BUTTON4, &CMy2048Dlg::OnBnClickedButton4)
ON_BN_CLICKED(IDC_BUTTON5, &CMy2048Dlg::OnBnClickedButton5)
END_MESSAGE_MAP()
// CMy2048Dlg 消息处理程序
BOOL CMy2048Dlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 将“关于...”菜单项添加到系统菜单中。
// IDM_ABOUTBOX 必须在系统命令范围内。
ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
ASSERT(IDM_ABOUTBOX < 0xF000);
CMenu* pSysMenu = GetSystemMenu(FALSE);
if (pSysMenu != NULL)
{
BOOL bNameValid;
CString strAboutMenu;
bNameValid = strAboutMenu.LoadString(IDS_ABOUTBOX);
ASSERT(bNameValid);
if (!strAboutMenu.IsEmpty())
{
pSysMenu->AppendMenu(MF_SEPARATOR);
pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
}
}
// 设置此对话框的图标。当应用程序主窗口不是对话框时,框架将自动
// 执行此操作
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// TODO: 在此添加额外的初始化代码
SetTimer(0,100,NULL);
SetTimer(1,100,NULL);
return TRUE; // 除非将焦点设置到控件,否则返回 TRUE
}
void CMy2048Dlg::OnSysCommand(UINT nID, LPARAM lParam)
{
if ((nID & 0xFFF0) == IDM_ABOUTBOX)
{
CAboutDlg dlgAbout;
dlgAbout.DoModal();
}
else
{
CDialogEx::OnSysCommand(nID, lParam);
}
}
// 如果向对话框添加最小化按钮,则需要下面的代码
// 来绘制该图标。对于使用文档/视图模型的 MFC 应用程序,
// 这将由框架自动完成。
void CMy2048Dlg::OnPaint()
{
CFont *pfont=GetFont();
CPaintDC dc(this);
CBrush brush1(RGB(184,175,158));
dc.FillRect(CRect(0,0,1180,990),&brush1);
CBrush mybrush(RGB(204,192,178));
CRect rect(10,10,90,90); //1
dc.FillRect(rect,&mybrush);
dc.FillRect(CRect(100,10,180,90),&mybrush); //2
dc.FillRect(CRect(190,10,270,90),&mybrush); //3
dc.FillRect(CRect(280,10,360,90),&mybrush); //4
dc.FillRect(CRect(10,100,90,180),&mybrush);
dc.FillRect(CRect(10,190,90,270),&mybrush);//5
dc.FillRect(CRect(10,280,90,360),&mybrush); //9
dc.FillRect(CRect(10,100,90,180),&mybrush);//13
dc.FillRect(CRect(100,100,180,180),&mybrush);//9
dc.FillRect(CRect(190,190,270,270),&mybrush);//11
dc.FillRect(CRect(190,100,270,180),&mybrush);//7
dc.FillRect(CRect(280,100,360,180),&mybrush);//8
dc.FillRect(CRect(280,280,360,360),&mybrush);//16
dc.FillRect(CRect(280,190,360,270),&mybrush);//12
dc.FillRect(CRect(100,190,180,270),&mybrush);//10
dc.FillRect(CRect(100,280,180,360),&mybrush);//14
dc.FillRect(CRect(190,280,270,360),&mybrush);//15
}
//当用户拖动最小化窗口时系统调用此函数取得光标显示。
HCURSOR CMy2048Dlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CMy2048Dlg::OnTimer(UINT_PTR nIDEvent)
{
CFont *pfont=GetFont();
CDC *dc=GetDC();
// TODO: 在此添加消息处理程序代码和/或调用默认值
switch(nIDEvent)
{
case 0:Invalidate(TRUE);
OnPaint();
randa(dc,pfont);
return;
}
ReleaseDC(dc);
DeleteObject(pfont);
}
HBRUSH CMy2048Dlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
{
HBRUSH hbr = CDialogEx::OnCtlColor(pDC, pWnd, nCtlColor);
// TODO: 在此更改 DC 的任何特性
return hbr;
}
void CMy2048Dlg::font(CDC* pDC, CFont* pfont)
{
pDC->SelectObject(pfont);
}
void CMy2048Dlg::randa(CDC* pdc, CFont * pfont)
{
int i=0,j;
static int flag=0,max,x,y;
srand((unsigned)time(NULL) );
max=RAND_MAX;
while(flag<10)
{
i=(int)(rand()*(1550-0)/max)/100;
flag++;
}
x=i/4;
y=i%4;
a[x][y]=randb();
CString str;
str.Format(L"%d",a[x][y]);
pdc->SetTextColor(dwTextColors[color(a[x][y])]);
drawc(pdc,i,dwSquareColors[color(a[x][y])],str);
if(i<12)
i+=3;
else
i-=1;
j=i;
x=i/4;
y=i%4;
a[x][y]=randb();
str.Format(L"%d",a[x][y]);
pdc->SetTextColor(dwTextColors[color(a[x][y])]);
drawc(pdc,j,dwSquareColors[color(a[x][y])],str);
KillTimer(0);
}
void CMy2048Dlg::OnBnClickedButton1()
{
// TODO: 在此添加控件通知处理程序代码
}
BOOL CAboutDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: 在此添加专用代码和/或调用基类
if(pMsg->message == WM_KEYDOWN)
{
switch(pMsg->wParam)
{
case VK_RETURN: // 屏蔽回车
return true;
}
}
return CDialogEx::PreTranslateMessage(pMsg);
}
void CMy2048Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
CString str;
CFont *pfont=GetFont();
CDC *dc=GetDC();
int m,n,number,flag=0;
number=randb();
for(int i=1;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0&&a[i-1][j]==0)
{
a[i-1][j]=a[i][j];
a[i][j]=0;
i=1;j=-1;
}
}
for(int i=0;i<3;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]==a[i+1][j]&&a[i][j]!=0)
{
a[i][j]=a[i][j]*2;
a[i+1][j]=0;
}
}
for(int i=1;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0&&a[i-1][j]==0)
{
a[i-1][j]=a[i][j];
a[i][j]=0;
i=1;j=-1;
}
}
if(2==check())
{
m=Generate()/4;
n=Generate()%4;
a[m][n]=number;
}
if(0==check())
{
MessageBox(L"游戏结束");
}
Invalidate(TRUE);
UpdateWindow();
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0)
{
str.Format(L"%d",a[i][j]);
dc->SetTextColor(dwTextColors[color(a[i][j])]);
drawc(dc,4*i+j,dwSquareColors[color(a[i][j])],str);
}
}
ReleaseDC(dc);
}
int CMy2048Dlg::randb(void)
{
int max,num,flag=0;
srand((unsigned)time( NULL ) );
max=RAND_MAX;
while(flag<10)
{
num=(int)(rand()*(214-0)/max);
flag++;
}
if(num<=100)
return 2;
else
return 4;
}
void CMy2048Dlg::OnBnClickedButton3()
{
// TODO: 在此添加控件通知处理程序代码
CString str;
CFont *pfont=GetFont();
CDC *dc=GetDC();
int m,n,number,flag=0;
number=randb();
for(int i=2;i>-1;i--)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0&&a[i+1][j]==0)
{
a[i+1][j]=a[i][j];
a[i][j]=0;
i=2;j=-1;
}
}
for(int i=3;i>0;i--)
for(int j=0;j<4;j++)
{
if(a[i][j]==a[i-1][j]&&a[i][j]!=0)
{
a[i][j]=a[i][j]*2;
a[i-1][j]=0;
}
}
for(int i=2;i>-1;i--)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0&&a[i+1][j]==0)
{
a[i+1][j]=a[i][j];
a[i][j]=0;
i=2;j=-1;
}
}
if(2==check())
{
m=Generate()/4;
n=Generate()%4;
a[m][n]=number;
}
if(0==check())
{
MessageBox(L"游戏结束");
}
Invalidate(TRUE);
UpdateWindow();
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0)
{
str.Format(L"%d",a[i][j]);
dc->SetTextColor(dwTextColors[color(a[i][j])]);
drawc(dc,4*i+j,dwSquareColors[color(a[i][j])],str);
}
}
ReleaseDC(dc);
}
void CMy2048Dlg::OnBnClickedButton4()
{
// TODO: 在此添加控件通知处理程序代码
CString str;
CFont *pfont=GetFont();
CDC *dc=GetDC();
int m,n,number,flag=0;
number=randb();
for(int j=2;j>-1;j--)
for(int i=0;i<4;i++)
{
if(a[i][j]!=0&&a[i][j+1]==0)
{
a[i][j+1]=a[i][j];
a[i][j]=0;
i=-1;j=2;
}
}
for(int j=3;j>0;j--)
for(int i=0;i<4;i++)
{
if(a[i][j]==a[i][j-1]&&a[i][j]!=0)
{
a[i][j]=a[i][j]*2;
a[i][j-1]=0;
}
}
for(int j=2;j>-1;j--)
for(int i=0;i<4;i++)
{
if(a[i][j]!=0&&a[i][j+1]==0)
{
a[i][j+1]=a[i][j];
a[i][j]=0;
i=-1;j=2;
}
}
if(2==check())
{
m=Generate()/4;
n=Generate()%4;
a[m][n]=number;
}
if(0==check())
{
MessageBox(L"游戏结束");
}
Invalidate(TRUE);
UpdateWindow();
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0)
{
str.Format(L"%d",a[i][j]);
dc->SetTextColor(dwTextColors[color(a[i][j])]);
drawc(dc,4*i+j,dwSquareColors[color(a[i][j])],str);
}
}
ReleaseDC(dc);
}
void CMy2048Dlg::OnBnClickedButton5()
{
// TODO: 在此添加控件通知处理程序代码
CString str;
CFont *pfont=GetFont();
CDC *dc=GetDC();
int m,n,number,flag=0;
number=randb();
for(int j=1;j<4;j++)
for(int i=0;i<4;i++)
{
if(a[i][j]!=0&&a[i][j-1]==0)
{
a[i][j-1]=a[i][j];
a[i][j]=0;
j=1;i=-1;
}
}
for(int j=0;j<4;j++)
for(int i=0;i<4;i++)
{
if(a[i][j]==a[i][j+1]&&a[i][j]!=0)
{
a[i][j]=a[i][j]*2;
a[i][j+1]=0;
}
}
for(int j=1;j<4;j++)
for(int i=0;i<4;i++)
{
if(a[i][j]!=0&&a[i][j-1]==0)
{
a[i][j-1]=a[i][j];
a[i][j]=0;
j=1;i=-1;
}
}
if(2==check())
{
m=Generate()/4;
n=Generate()%4;
a[m][n]=number;
}
if(0==check())
{
MessageBox(L"游戏结束");
}
Invalidate(TRUE);
UpdateWindow();
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]!=0)
{
str.Format(L"%d",a[i][j]);
dc->SetTextColor(dwTextColors[color(a[i][j])]);
drawc(dc,4*i+j,dwSquareColors[color(a[i][j])],str);
}
}
ReleaseDC(dc);
}
int CMy2048Dlg::color(int a)
{
int count=0;
while(a!=1)
{
count++;
a=a/2;
}
return count;
}
void CMy2048Dlg::drawc(CDC* pdc, int x, COLORREF color, CString str)
{
CFont *pfont;
CFont font;
LOGFONT log={0};
pdc->SetBkMode(TRANSPARENT);
log.lfHeight=-MulDiv(22, pdc->GetDeviceCaps(LOGPIXELSY), 72);;
log.lfWidth=20;
font.CreateFontIndirectW(&log);
pfont=pdc->SelectObject(&font);
switch(x)
{
case 0: pdc->FillRect(CRect(10,10,90,90) ,&CBrush(color));
pdc->DrawText(str,num_1,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 1: pdc->FillRect(CRect(100,10,180,90),&CBrush(color) );
pdc->DrawText(str,num_2,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 2:
pdc->FillRect(CRect(190,10,270,90),&CBrush(color) );
pdc->DrawText(str,num_3,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 3:
pdc->FillRect(CRect(280,10,360,90),&CBrush(color) );
pdc->DrawText(str,num_4,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 4:
pdc->FillRect(CRect(10,100,90,180),&CBrush(color) );
pdc->DrawText(str,num_5,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 5:
pdc->FillRect(CRect(100,100,180,180),&CBrush(color) );
pdc->DrawText(str,num_6,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 6:
pdc->FillRect(CRect(190,100,270,180),&CBrush(color) );
pdc->DrawText(str,num_7,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 7:
pdc->FillRect(CRect(280,100,360,180),&CBrush(color) );
pdc->DrawText(str,num_8,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 8:
pdc->FillRect(CRect(10,190,90,270),&CBrush(color) );
pdc->DrawText(str,num_9,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 9:
pdc->FillRect(CRect(100,190,180,270),&CBrush(color) );
pdc->DrawText(str,num_10,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 10:
pdc->FillRect(CRect(190,190,270,270),&CBrush(color) );
pdc->DrawText(str,num_11,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 11:
pdc->FillRect(CRect(280,190,360,270),&CBrush(color) );
pdc->DrawText(str,num_12,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 13:
pdc->FillRect(CRect(100,280,180,360),&CBrush(color) );
pdc->DrawText(str,num_13,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 12:
pdc->FillRect(CRect(10,280,90,360),&CBrush(color) );
pdc->DrawText(str,num_14,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 14:
pdc->FillRect(CRect(190,280,270,360),&CBrush(color) );
pdc->DrawText(str,num_15,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
case 15:
pdc->FillRect(CRect(280,280,360,360),&CBrush(color) );
pdc->DrawText(str,num_16,DT_SINGLELINE|DT_CENTER|DT_VCENTER);
return;
}
pfont->DeleteObject();
}
int CMy2048Dlg::check(void)
{
int count=0;
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]==0)
{
count=2;
}
}
if(count==2)
return 2;
else
{
for(int i=0;i<4;i++)
for(int j=0;j<4;j++)
{
if(a[i][j]==a[i+1][j]||a[i][j]==a[i][j+1])
{
count=1;
return 1;
}
}
}
return 0;
}
int CMy2048Dlg::Generate(void)
{
int num;
int flag=0,flag1=0;
srand((unsigned)time(NULL));
do
{
while(flag<10)
{
num=(int)(rand()*(16-0)/RAND_MAX);
flag++;
}
flag=0;
if(a[num/4][num%4]==0)
break;
}while(a[num/4][num%4]!=0);
return num;
}