vc项目日志,俄罗斯方块开发
----July
mfc初学一个月时,所写的俄罗斯方块。共享下源码。
July、2010/10/21
-------------------------------------------------------------
此为View.h文件
- /*-------------------------------------
- View.h文件
- July/2010、10月
- --------------------------------------*/
- // skyjuly_RecTTView.h : interface of the CSkyjuly_RecTTView class
- //
- /////////////////////////////////////////////////////////////////////////////
- #if !defined(AFX_SKYJULY_RECTTVIEW_H__BBD13113_594E_4BE6_9DA5_1DAE3EC53ED8__INCLUDED_)
- #define AFX_SKYJULY_RECTTVIEW_H__BBD13113_594E_4BE6_9DA5_1DAE3EC53ED8__INCLUDED_
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- // 宏变量:白色和黑色
- #define WHITE RGB(255,255,255)
- #define BLACK RGB(0,0,0)
- #define BLUE RGB(0,0,255)
- //中断操作的运动趋势
- #define LEFT 0 //向左移动
- #define RIGHT 1 //向左移动
- #define UP 2 //向上(变形)
- #define DOWN 3 //向下移动(加速)
- //游戏区域地图最大限制
- #define MAX_ROW 100 //地图的最大行数
- #define MAX_COL 100 //地图的最大列数
- //地图状态
- #define MAP_STATE_EMPTY 0 //空(未被占据)
- #define MAP_STATE_NOT_EMPTY 1 //被占据
- class
CSkyjuly_RecTTView :
public
CView
- {
- protected
:
// create from serialization only
- CSkyjuly_RecTTView();
- DECLARE_DYNCREATE(CSkyjuly_RecTTView)
- // Attributes
- public
:
- CSkyjuly_RecTTDoc* GetDocument();
- // Operations
- public
:
- // Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(CSkyblue_RectView)
- public
:
- virtual
void
OnDraw(CDC* pDC);
// overridden to draw this view
- virtual
BOOL
PreCreateWindow(CREATESTRUCT& cs);
- //}}AFX_VIRTUAL
- // Implementation
- public
:
- virtual
~CSkyjuly_RecTTView();
- protected
:
- int
m_nWidth;
//子窗口的宽度
- int
m_nHeight;
//子窗口的高度
- //列与行的数量
- int
m_iCol;
- int
m_iRow;
- //小方块的大小,它会随着行与列的不同而不同,具体为:
- // 12行10列,30个象素的正方形
- // 18行15列,20
- // 24行20列,15
- // 30行25列,12
- int
m_iLarge;
- //当前的级别,换算成速度的算法为:1500 - m_iLevel*200
- int
m_iLevel;
- //当前选择的方块显示样式
- int
m_iBlockSytle;
- //游戏区域左上角的坐标
- int
m_iStartX;
- int
m_iStartY;
- BOOL
IsLeftLimit();
//下坠物件是否可向左移动
- BOOL
IsRightLimit();
- //接触面二维数组,记录1~7种下坠物的1~4种形态的接触面信息
- //我们把该下坠物的某种形态种的4个方块,有接触面则记录方位,无则为-1标识。
- int
InterFace[74][4];
- //当前的方块形状
- int
m_currentRect;
- //判断当前方块是否到底
- void
IsBottom();
- //当前方块下降
- void
RectDown();
- //当前方块加速:UP,左移:LEFT,右移:RIGHT
- void
RectArrow(
int
m_Type);
- //根据下坠物的类型映射出它的具体形态 功能组
- //根据旧的下一下坠物映射出当前激活状态下的下坠物形态
- void
RectStatusToActiveStatus(
int
m_which);
- //根据下坠物形态映射出下一下坠物的形态
- void
RectStatusToNextStatus(
int
m_which);
- //将当前的状态映射到地图游戏区域
- void
ActiveStatusToGameStatus();
- int
Random(
int
MaxNumber);
- //标识方块已到底的变量,到底为TRUE
- BOOL
m_isBottom;
- //用于标志方块状态的数组,大小由横格与竖格数据决定,为1表示该方块显示,或者不显示
- //画形状只需要修改数组中相应元素的状态值即可
- //由时钟控制,定时在OnPaint函数中根据数组画方块
- int
GameStatus[MAX_ROW][MAX_COL];
- //用于保存当前方块的动态位置,4个小方块分别在大数组中的位置
- //存放位置为先左后右,每一列又遵循先上后下的原则
- int
ActiveStatus[4][2];
- //存入下一次要出来的方块的模样的数组
- int
NextStatus[4][2];
- // Generated message map functions
- protected
:
- BOOL
m_bGamePaush;
- void
StopMid();
- void
PlayMid();
- void
CurrentAreaAndLevel();
- //用于记录当前区域大小与当前级别的字符串,用于显示在屏幕上提示用户当前状态
- CString m_strArea;
- CString m_strLevel;
- //当前的样式 ,下一个将会出现的样式
- int
m_icurrentStatus;
- int
m_inextStatus;
- //OnDraw中需要用到的设备名称
- CPen *m_pBlackPen;
- CBrush *m_pGrayBrush;
- CBrush *m_pBlackBrush;
- //是否画网格线
- BOOL
m_bDrawGrid;
- //是否插放背景音乐
- BOOL
m_bMusic;
- //游戏总成绩
- int
m_iPerformance;
- //游戏是否已结束,为FALSE表示开始,否则为结束
- BOOL
m_bGameEnd;
- //刷新指定的区域,它的大小为:四个小方块所在的正方形的大小
- void
InvalidateCurrent();
- //内存绘图设备的处理
- CDC m_memDC; //内存设备环境
- CBitmap m_memBmp; //内存位图
- CDC m_memRectDC; //方块内存设备环境
- HBITMAP
m_hMemRectBmp;
//方块内存位图句柄
- int
m_bFistPlay;
//是否是第一次开始游戏
- void
DcEnvInitial(
void
);
- void
DCEnvClear(
void
);
- void
DrawGame(CDC *pDC);
- // Generated message map functions
- protected
:
- void
RectChange();
- //{{AFX_MSG(CSkyjuly_RecTTView)
- afx_msg void
OnGameStart();
- afx_msg void
OnGamePaush();
- afx_msg void
OnGameEnd();
- afx_msg void
OnGameExit();
- afx_msg void
OnGameOption();
- afx_msg int
OnCreate(LPCREATESTRUCT lpCreateStruct);
- afx_msg void
OnTimer(
UINT
nIDEvent);
- afx_msg void
OnKeyDown(
UINT
nChar,
UINT
nRepCnt,
UINT
nFlags);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- #ifndef _DEBUG // debug version in skyjuly_RecTTView.cpp
- inline
CSkyjuly_RecTTDoc* CSkyjuly_RecTTView::GetDocument()
- { return
(CSkyjuly_RecTTDoc*)m_pDocument; }
- #endif
- /////////////////////////////////////////////////////////////////////////////
- //{{AFX_INSERT_LOCATION}}
- // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
- #endif // !defined(AFX_SKYJULY_RECTTVIEW_H__BBD13113_594E_4BE6_9DA5_1DAE3EC53ED8__INCLUDED_)
// 宏变量:白色和黑色
#define WHITE RGB(255,255,255)
#define BLACK RGB(0,0,0)
#define BLUE RGB(0,0,255)
//中断操作的运动趋势
#define LEFT 0 //向左移动
#define RIGHT 1 //向左移动
#define UP 2 //向上(变形)
#define DOWN 3 //向下移动(加速)
//游戏区域地图最大限制
#define MAX_ROW 100 //地图的最大行数
#define MAX_COL 100 //地图的最大列数
//地图状态
#define MAP_STATE_EMPTY 0 //空(未被占据)
#define MAP_STATE_NOT_EMPTY 1 //被占据
class CSkyjuly_RecTTView : public CView
{
protected: // create from serialization only
CSkyjuly_RecTTView();
DECLARE_DYNCREATE(CSkyjuly_RecTTView)
// Attributes
public:
CSkyjuly_RecTTDoc* GetDocument();
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CSkyblue_RectView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CSkyjuly_RecTTView();
protected:
int m_nWidth; //子窗口的宽度
int m_nHeight; //子窗口的高度
//列与行的数量
int m_iCol;
int m_iRow;
//小方块的大小,它会随着行与列的不同而不同,具体为:
// 12行10列,30个象素的正方形
// 18行15列,20
// 24行20列,15
// 30行25列,12
int m_iLarge;
//当前的级别,换算成速度的算法为:1500 - m_iLevel*200
int m_iLevel;
//当前选择的方块显示样式
int m_iBlockSytle;
//游戏区域左上角的坐标
int m_iStartX;
int m_iStartY;
BOOL IsLeftLimit(); //下坠物件是否可向左移动
BOOL IsRightLimit();
//接触面二维数组,记录1~7种下坠物的1~4种形态的接触面信息
//我们把该下坠物的某种形态种的4个方块,有接触面则记录方位,无则为-1标识。
int InterFace[74][4];
//当前的方块形状
int m_currentRect;
//判断当前方块是否到底
void IsBottom();
//当前方块下降
void RectDown();
//当前方块加速:UP,左移:LEFT,右移:RIGHT
void RectArrow(int m_Type);
//根据下坠物的类型映射出它的具体形态 功能组
//根据旧的下一下坠物映射出当前激活状态下的下坠物形态
void RectStatusToActiveStatus(int m_which);
//根据下坠物形态映射出下一下坠物的形态
void RectStatusToNextStatus(int m_which);
//将当前的状态映射到地图游戏区域
void ActiveStatusToGameStatus();
int Random(int MaxNumber);
//标识方块已到底的变量,到底为TRUE
BOOL m_isBottom;
//用于标志方块状态的数组,大小由横格与竖格数据决定,为1表示该方块显示,或者不显示
//画形状只需要修改数组中相应元素的状态值即可
//由时钟控制,定时在OnPaint函数中根据数组画方块
int GameStatus[MAX_ROW][MAX_COL];
//用于保存当前方块的动态位置,4个小方块分别在大数组中的位置
//存放位置为先左后右,每一列又遵循先上后下的原则
int ActiveStatus[4][2];
//存入下一次要出来的方块的模样的数组
int NextStatus[4][2];
// Generated message map functions
protected:
BOOL m_bGamePaush;
void StopMid();
void PlayMid();
void CurrentAreaAndLevel();
//用于记录当前区域大小与当前级别的字符串,用于显示在屏幕上提示用户当前状态
CString m_strArea;
CString m_strLevel;
//当前的样式 ,下一个将会出现的样式
int m_icurrentStatus;
int m_inextStatus;
//OnDraw中需要用到的设备名称
CPen *m_pBlackPen;
CBrush *m_pGrayBrush;
CBrush *m_pBlackBrush;
//是否画网格线
BOOL m_bDrawGrid;
//是否插放背景音乐
BOOL m_bMusic;
//游戏总成绩
int m_iPerformance;
//游戏是否已结束,为FALSE表示开始,否则为结束
BOOL m_bGameEnd;
//刷新指定的区域,它的大小为:四个小方块所在的正方形的大小
void InvalidateCurrent();
//内存绘图设备的处理
CDC m_memDC; //内存设备环境
CBitmap m_memBmp; //内存位图
CDC m_memRectDC; //方块内存设备环境
HBITMAP m_hMemRectBmp; //方块内存位图句柄
int m_bFistPlay; //是否是第一次开始游戏
void DcEnvInitial(void);
void DCEnvClear(void);
void DrawGame(CDC *pDC);
// Generated message map functions
protected:
void RectChange();
//{{AFX_MSG(CSkyjuly_RecTTView)
afx_msg void OnGameStart();
afx_msg void OnGamePaush();
afx_msg void OnGameEnd();
afx_msg void OnGameExit();
afx_msg void OnGameOption();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnTimer(UINT nIDEvent);
afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
#ifndef _DEBUG // debug version in skyjuly_RecTTView.cpp
inline CSkyjuly_RecTTDoc* CSkyjuly_RecTTView::GetDocument()
{ return (CSkyjuly_RecTTDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_SKYJULY_RECTTVIEW_H__BBD13113_594E_4BE6_9DA5_1DAE3EC53ED8__INCLUDED_)
以下为View.cpp文件。
- /*--------------------------------------
- View.cpp文件。
- July、2010/10月
- --------------------------------------*/
- // skyjuly_RecTTView.cpp : implementation of the CSkyjuly_RecTTView class
- //
- #include "stdafx.h"
- #include "skyjuly_RecTT.h"
- #include "skyjuly_RecTTDoc.h"
- #include "skyjuly_RecTTView.h"
- #include "OptionDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static
char
THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // CSkyjuly_RecTTView
- IMPLEMENT_DYNCREATE(CSkyjuly_RecTTView, CView)
- BEGIN_MESSAGE_MAP(CSkyjuly_RecTTView, CView)
- //{{AFX_MSG_MAP(CSkyjuly_RecTTView)
- ON_COMMAND(ID_GAME_START, OnGameStart)
- ON_COMMAND(ID_GAME_PAUSH, OnGamePaush)
- ON_COMMAND(ID_GAME_END, OnGameEnd)
- ON_COMMAND(ID_GAME_EXIT, OnGameExit)
- ON_COMMAND(ID_GAME_OPTION, OnGameOption)
- ON_WM_CREATE()
- ON_WM_TIMER()
- ON_WM_KEYDOWN()
- //}}AFX_MSG_MAP
- // Standard printing commands
- ON_COMMAND(ID_FILE_PRINT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_DIRECT, CView::OnFilePrint)
- ON_COMMAND(ID_FILE_PRINT_PREVIEW, CView::OnFilePrintPreview)
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // CSkyjuly_RecTTView construction/destruction
- CSkyjuly_RecTTView::CSkyjuly_RecTTView()
- {
- // TODO: add construction code here
- //第一次开始游戏
- m_bFistPlay = TRUE;
- //缺省为不是游戏暂停状态
- m_bGamePaush = FALSE;
- //缺省为不插放背景音乐
- m_bMusic = FALSE;
- //缺省为画网格线
- m_bDrawGrid = TRUE;
- //总分值清零
- m_iPerformance = 0;
- //测试值:为12行,10列
- m_iRow = 12;
- m_iCol = 10;
- //左上角X,Y坐标
- m_iStartX = 10;
- m_iStartY = 10;
- //缺省级别为3级
- m_iLevel = 2;
- //第一种样式
- m_iBlockSytle = 0;
- //缺省方块大小为m_iLarge个象素
- m_iLarge = 30;
- //缺省游戏是结束的
- m_bGameEnd = TRUE;
- int
i,j;
- //赋初值
- for
(i=0;i<100;i++)
- for
(j=0;j<100;j++)
- GameStatus[i][j]=0;
- //各种形状方块的接触面数据,参见设计书的接触面表格,
- //如果某种形状的方块没有4个接触面,则后面的数据填-1
- for
(i=0;i<74;i++)
- for
(j=0;j<4;j++)
- InterFace[i][j] = -1;
- /*
- 1 ----
- */
- InterFace[1][0] = 3;
- InterFace[11][0] = 0; InterFace[11][1] = 1; InterFace[11][2] = 2; InterFace[11][3] = 3;
- /*
- 2 --
- --
- */
- InterFace[2][0] = 1; InterFace[2][1] = 3;
- /*
- 3 -
- ---
- */
- InterFace[3][0] = 0; InterFace[3][1] = 2; InterFace[3][2] = 3;
- InterFace[31][0] = 2; InterFace[31][1] = 3;
- InterFace[32][0] = 0; InterFace[32][1] = 2; InterFace[32][2] = 3;
- InterFace[33][0] = 0; InterFace[33][1] = 3;
- /*
- 4 --
- --
- */
- InterFace[4][0] = 1; InterFace[4][1] = 3;
- InterFace[41][0] = 0; InterFace[41][1] = 2; InterFace[41][2] = 3;
- /*
- 5 --
- --
- */
- InterFace[5][0] = 1; InterFace[5][1] = 3;
- InterFace[51][0] = 0; InterFace[51][1] = 2; InterFace[51][2] = 3;
- /*
- 6 --
- -
- -
- */
- InterFace[6][0] = 0; InterFace[6][1] = 3;
- InterFace[61][0] = 1; InterFace[61][1] = 2; InterFace[61][2] = 3;
- InterFace[62][0] = 2; InterFace[62][1] = 3;
- InterFace[63][0] = 0; InterFace[63][1] = 1; InterFace[63][2] = 3;
- /*
- 7 --
- -
- -
- */
- InterFace[7][0] = 2; InterFace[7][1] = 3;
- InterFace[71][0] = 1; InterFace[71][1] = 2; InterFace[71][2] = 3;
- InterFace[72][0] = 0; InterFace[72][1] = 3;
- InterFace[73][0] = 0; InterFace[73][1] = 1; InterFace[73][2] = 3;
- }
- CSkyjuly_RecTTView::~CSkyjuly_RecTTView()
- {
- }
- BOOL
CSkyjuly_RecTTView::PreCreateWindow(CREATESTRUCT& cs)
- {
- // TODO: Modify the Window class or styles here by modifying
- // the CREATESTRUCT cs
- return
CView::PreCreateWindow(cs);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CSkyjuly_RecTTView drawing
- void
CSkyjuly_RecTTView::OnDraw(CDC* pDC)
- {
- /*CSkyjuly_RecTTDoc* pDoc = GetDocument();
- ASSERT_VALID(pDoc);*/
- // TODO: add draw code for native data here
- DcEnvInitial();
- DrawGame(&m_memDC); //在内存位图的游戏区域绘制
- pDC->BitBlt(0,0,m_nWidth,m_nHeight,&m_memDC,0,0,SRCCOPY);
- }
- /////////////////////////////////////////////////////////////////////////////
- // CSkyjuly_RecTTView diagnostics
- #ifdef _DEBUG
- #endif //_DEBUG
- /////////////////////////////////////////////////////////////////////////////
- // CSkyjuly_RecTTView message handlers
- void
CSkyjuly_RecTTView::OnGameStart()
- {
- // TODO: Add your command handler code here
- if
(!m_bGamePaush)
//如果不是游戏暂停状态,则必须作些初始工作
- {
- m_bGameEnd = FALSE;
- //总分值清零, 并显示总分记分牌
- m_iPerformance = 0;
- //显示当前的区域及游戏级别的汉字描述
- // CurrentAreaAndLevel();
- CRect rect(m_iStartY, m_iStartX, m_iStartY+440, m_iStartX+370);
- InvalidateRect(&rect);
- }
- m_bGamePaush = FALSE;
- SetTimer(1,1500-250*m_iLevel,NULL);
- }
- void
CSkyjuly_RecTTView::OnGamePaush()
- {
- // TODO: Add your command handler code here
- m_bGamePaush = TRUE;
- KillTimer(1);
- }
- void
CSkyjuly_RecTTView::OnGameEnd()
- {
- // TODO: Add your command handler code here
- m_bGameEnd = TRUE;
- int
i,j;
- for
(i=0;i<m_iRow;i++)
- for
(j=0;j<m_iCol;j++)
- GameStatus[i][j]=0;
- CRect rect(m_iStartY, m_iStartX, m_iStartY+440, m_iStartX+370);
- InvalidateRect(&rect);
- m_bGamePaush = FALSE; //清除游戏暂停状态
- KillTimer(1);
- }
- void
CSkyjuly_RecTTView::OnGameExit()
- {
- // TODO: Add your command handler code here
- }
- void
CSkyjuly_RecTTView::OnGameOption()
- {
- // TODO: Add your command handler code here
- //参数顺序: 区域大小代码:0-3,分别为:12X10,18X15,24X20,m_iLargeX25
- //级别:0-5,分别为:1500,1200,1000,800,600,400
- //背景音乐:TRUE 或者 FALSE
- int
m_lsArea;
- /* switch(m_iRow)
- {
- case 12:
- m_lsArea = 0;
- break;
- case 18:
- m_lsArea = 1;
- break;
- case 24:
- m_lsArea = 2;
- break;
- case 30:
- m_lsArea = 3;
- break;
- }*/
- COptionDlg dlg(m_lsArea,m_iLevel,m_iBlockSytle,m_bMusic,m_bDrawGrid);
- if
(dlg.DoModal()==IDOK)
- {
- //确定区域的大小
- /* switch(dlg.m_iArea)
- {
- case 0:
- m_iRow = 12;
- m_iCol = 10;
- m_iLarge = 30;
- break;
- case 1:
- m_iRow = 18;
- m_iCol = 15;
- m_iLarge = 20;
- break;
- case 2:
- m_iRow = 24;
- m_iCol = 20;
- m_iLarge = 15;
- break;
- case 3:
- m_iRow = 30;
- m_iCol = 25;
- m_iLarge = 12;
- break;
- }
- //确定级别
- m_iLevel = dlg.m_iLevel;
- //选择的样式
- m_iBlockSytle = dlg.m_iBlockStyle;
- //确定是否绘网格背景
- m_bDrawGrid = dlg.m_bDrawGrid;
- //检查是否插放音乐
- m_bMusic = dlg.m_bMusic;
- // if (m_bMusic)
- // PlayMid();
- // else
- // StopMid();
- Invalidate();*/
- }
- }
- void
CSkyjuly_RecTTView::DrawGame(CDC *pDC)
- {
- int
i,j;
- //选用黑色画刷,绘制整个游戏所在窗口的背景
- pDC -> SelectObject(m_pBlackBrush);
- CRect rect;
- GetClientRect(&rect);
- pDC -> Rectangle(rect);
- //选用灰色画刷,绘制游戏区域的背景
- pDC -> SelectObject(m_pGrayBrush);
- pDC -> Rectangle(m_iStartY ,m_iStartX, m_iStartY + 301, m_iStartX + 360);
- pDC->SelectObject(m_pBlackPen);
- //画网格线
- if
(m_bDrawGrid)
- {
- //画横线
- for
(i=0;i<m_iRow;i++)
- {
- pDC->MoveTo(m_iStartY, m_iStartX + i*m_iLarge);
- pDC->LineTo(m_iStartY+300, m_iStartX +i*m_iLarge);
- }
- //画竖线
- for
(i=0;i<m_iCol;i++)
- {
- pDC->MoveTo(m_iStartY+i*m_iLarge, m_iStartX);
- pDC->LineTo(m_iStartY+i*m_iLarge, m_iStartX+360);
- }
- }
- int
x,y,nW,nH;
- //小方块的绘制
- for
(i=0;i<m_iRow;i++)
- for
(j=0;j<m_iCol;j++)
- {
- if
(GameStatus[i][j]==MAP_STATE_NOT_EMPTY)
- {
- //在游戏区域中状态为被占用状态的区域绘制小方块
- x = m_iStartY+j*m_iLarge +2;
- y = m_iStartX+i*m_iLarge +2;
- nW = m_iLarge-4;
- nH = m_iLarge-4;
- pDC->BitBlt(x,y,nW,nH,&m_memRectDC,m_iBlockSytle*30,0,SRCCOPY);
- }
- }
- //显示游戏区域及游戏级别的汉字描述
- if
(!m_bGameEnd)
- {
- pDC -> SetBkColor(BLACK);
- pDC -> SetTextColor(WHITE);
- pDC -> TextOut(m_iStartY+320, m_iStartX+220, "游戏区域大小:"
);
- pDC -> TextOut(m_iStartY+320, m_iStartX+240,m_strArea);
- pDC -> TextOut(m_iStartY+320, m_iStartX+280, "游戏级别:"
);
- pDC -> TextOut(m_iStartY+320, m_iStartX+300,m_strLevel);
- }
- //显示总分
- if
(!m_bGameEnd)
- {
- CString lsStr;
- lsStr.Format("总分为:%d 分"
,m_iPerformance);
- pDC -> SetBkColor(BLACK);
- pDC -> SetTextColor(WHITE);
- pDC -> TextOut(m_iStartY+320, m_iStartX+180,lsStr);
- }
- //画下一次将要出现的方块,用于提示用户
- if
(!m_bGameEnd)
- {
- pDC -> SetBkColor(BLACK);
- pDC -> SetTextColor(WHITE);
- pDC -> TextOut(m_iStartY+320, m_iStartX,"下一个方块:"
);
- int
x,y,nW,nH;
- for
(
UINT
k=0;k<4;k++)
- {
- i = NextStatus[k][0];
- j = NextStatus[k][1];
- x = m_iStartY+j*30 +2+320;
- y = m_iStartX+i*30 +2+30;
- nW = m_iLarge-4;
- nH = m_iLarge-4;
- pDC->BitBlt(x,y,nW,nH,&m_memRectDC,m_iBlockSytle*30,0,SRCCOPY);
- }
- }
- }
- void
CSkyjuly_RecTTView::DcEnvInitial()
- {
- if
(m_bFistPlay)
- {
- m_bFistPlay = FALSE;
- //用默认的参数,获取当前屏幕设备环境
- CDC *pWindowDC = GetDC();
- //1.用于映射屏幕的内存设备环境
- //获取游戏窗口的大小用于下面设置内存位图的尺寸
- CRect windowRect;
- GetClientRect(&windowRect);
- m_nWidth = windowRect.Width();
- m_nHeight = windowRect.Height();
- //内存设备环境与屏幕设备环境关联(兼容)
- m_memDC.CreateCompatibleDC(pWindowDC);
- //内存位图与与屏幕关联(兼容),大小为游戏窗口的尺寸
- m_memBmp.CreateCompatibleBitmap(pWindowDC,m_nWidth,m_nHeight);
- //内存设备环境与内存位图关联,以便通过m_memDC在内存位图上作画
- m_memDC.SelectObject(&m_memBmp);
- //2.存储方块位图的内存资源
- //内存设备环境与屏幕设备环境关联(兼容)
- m_memRectDC.CreateCompatibleDC(pWindowDC);
- //相当于将外部位图rect.bmp动态载入m_hMemRectBmp中
- m_hMemRectBmp=(HBITMAP
)LoadImage(NULL,
"rect.bmp"
,IMAGE_BITMAP,150,30,LR_LOADFROMFILE);
- //内存设备环境与内存位图关联,以便通过m_memDC在内存位图上作画
- SelectObject(m_memRectDC.m_hDC, m_hMemRectBmp);
- //黑色的黑笔
- m_pBlackPen = new
CPen(PS_SOLID,1,BLACK);
- //画刷,
- m_pGrayBrush = new
CBrush(RGB(0,60,0));
- m_pBlackBrush = new
CBrush(BLACK);
- }
- }
- void
CSkyjuly_RecTTView::DCEnvClear()
- {
- //设备环境
- m_memDC.DeleteDC();
- m_memRectDC.DeleteDC();
- //位图资源
- DeleteObject(m_memBmp);
- DeleteObject(m_hMemRectBmp);
- delete
(m_pBlackPen);
- delete
(m_pGrayBrush);
- delete
(m_pBlackBrush);
- }
- int
CSkyjuly_RecTTView::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if
(CView::OnCreate(lpCreateStruct) == -1)
- return
-1;
- //决定第一次掉下来的方块的样式
- m_inextStatus = Random(7);
- return
0;
- }
- int
CSkyjuly_RecTTView::Random(
int
MaxNumber)
- {
- //部下随机种子
- srand( (unsigned)time( NULL ) );
- //产生随机数
- int
random = rand() % MaxNumber;
- //保证非0
- if
(random == 0 )
- random++;
- return
random;
- }
- void
CSkyjuly_RecTTView::RectDown()
- {
- IsBottom();
- if
(!m_isBottom)
- {
- //清除以前的方块
- int
x1,x2,x3,x4,y1,y2,y3,y4;
- x1 = ActiveStatus[0][0];
- x2 = ActiveStatus[1][0];
- x3 = ActiveStatus[2][0];
- x4 = ActiveStatus[3][0];
- y1 = ActiveStatus[0][1];
- y2 = ActiveStatus[1][1];
- y3 = ActiveStatus[2][1];
- y4 = ActiveStatus[3][1];
- GameStatus[x1][y1]=MAP_STATE_EMPTY;
- GameStatus[x2][y2]=MAP_STATE_EMPTY;
- GameStatus[x3][y3]=MAP_STATE_EMPTY;
- GameStatus[x4][y4]=MAP_STATE_EMPTY;
- InvalidateCurrent();
- //方块下落
- ActiveStatus[0][0] += 1;
- ActiveStatus[1][0] += 1;
- ActiveStatus[2][0] += 1;
- ActiveStatus[3][0] += 1;
- GameStatus[x1+1][y1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x2+1][y2]=MAP_STATE_NOT_EMPTY;
- GameStatus[x3+1][y3]=MAP_STATE_NOT_EMPTY;
- GameStatus[x4+1][y4]=MAP_STATE_NOT_EMPTY;
- InvalidateCurrent();
- }
- }
- void
CSkyjuly_RecTTView::InvalidateCurrent()
- {
- int
i;
- for
(i=0;i<4;i++)
- {
- CRect rect(m_iStartX+ActiveStatus[i][1]*m_iLarge,
- m_iStartY+ActiveStatus[i][0]*m_iLarge,
- m_iStartX+(ActiveStatus[i][1]+1)*m_iLarge+5,
- m_iStartY+(ActiveStatus[i][0]+1)*m_iLarge);
- //InvalidateRect(&rect);
- Invalidate(FALSE);
- }
- }
- void
CSkyjuly_RecTTView::IsBottom()
- {
- //到底有两种概念:1是已到底部,2是下面碰到了另外的方块
- int
x1,x2,x3,x4;
- int
x,xx,yy,i;
- x1 = ActiveStatus[0][0];
- x2 = ActiveStatus[1][0];
- x3 = ActiveStatus[2][0];
- x4 = ActiveStatus[3][0];
- //是否为底部的判断
- //1。到达游戏区域的底部
- //2。与接触面正下方的小方块区域为被占用状态
- if
(x1>=m_iRow-1 || x2>=m_iRow-1 || x3>=m_iRow-1 || x4>=m_iRow-1)
- m_isBottom = TRUE;
- else
- {
- for
(i=0;i<4;i++)
- {
- if
(InterFace[m_currentRect][i] > -1)
- {//取当前下坠物有接触面的方块
- //获取有接触面的小方块的编号
- x=InterFace[m_currentRect][i];
- //根据编号获取ActiveStatus中该小方块的整下方的坐标
- xx=ActiveStatus[x][0]+1;
- yy=ActiveStatus[x][1];
- //判断该接触面整下方的小方块区域是否为被占用状态
- if
(GameStatus[xx][yy]==MAP_STATE_NOT_EMPTY)
- m_isBottom = TRUE;
- }
- }
- }
- BOOL
m_bIsSucced;
- int
k,j;
- int
m_iMuch=0;
//本次销掉的行数
- //计分规则:一次销掉一行,加100分,一次销掉两行,加400分,三行,900分
- //例如销掉x行,则分数为:x*(x*100)
- if
(m_isBottom)
- {
- //判断是否已得分
- for
(i=0;i<m_iRow;i++)
- {
- m_bIsSucced = TRUE;
- for
(j=0;j<m_iCol;j++)
- if
(GameStatus[i][j]==MAP_STATE_EMPTY)
- m_bIsSucced = FALSE;
- //如果得分,则销掉此行
- if
(m_bIsSucced)
- {
- for
(k=i;k>0;k--)
- for
(j=0;j<m_iCol;j++)
- GameStatus[k][j] = GameStatus[k-1][j];
- //第1行清零
- for
(j=0;j<m_iCol;j++)
- GameStatus[0][j]=MAP_STATE_EMPTY;
- m_iMuch += 1;
- }
- }
- if
(m_iMuch>0)
- {
- m_iPerformance += m_iMuch * m_iMuch * 100;
- //刷新游戏区域
- CRect rect1(m_iStartY, m_iStartX, m_iStartY+300, m_iStartX+360);
- //InvalidateRect(&rect1);
- //刷新分数区域
- CRect rect2(m_iStartY+320, m_iStartX+180, m_iStartY+440, m_iStartX+200);
- //InvalidateRect(&rect2);
- Invalidate(FALSE);
- }
- }
- }
- //映射下一个方快,显示下一个降落的方块
- void
CSkyjuly_RecTTView::RectStatusToActiveStatus(
int
m_which)
- {
- switch
(m_which)
- {
- case
1:
- ActiveStatus[0][0] = 0; ActiveStatus[0][1] = 5; ActiveStatus[1][0] = 1; ActiveStatus[1][1] = 5;
- ActiveStatus[2][0] = 2; ActiveStatus[2][1] = 5; ActiveStatus[3][0] = 3; ActiveStatus[3][1] = 5;
- break
;
- case
2:
- ActiveStatus[0][0] = 0; ActiveStatus[0][1] = 5; ActiveStatus[1][0] = 1; ActiveStatus[1][1] = 5;
- ActiveStatus[2][0] = 0; ActiveStatus[2][1] = 6; ActiveStatus[3][0] = 1; ActiveStatus[3][1] = 6;
- break
;
- case
3:
- ActiveStatus[0][0] = 1; ActiveStatus[0][1] = 4; ActiveStatus[1][0] = 0; ActiveStatus[1][1] = 5;
- ActiveStatus[2][0] = 1; ActiveStatus[2][1] = 5; ActiveStatus[3][0] = 1; ActiveStatus[3][1] = 6;
- break
;
- case
4:
- ActiveStatus[0][0] = 0; ActiveStatus[0][1] = 5; ActiveStatus[1][0] = 1; ActiveStatus[1][1] = 5;
- ActiveStatus[2][0] = 1; ActiveStatus[2][1] = 6; ActiveStatus[3][0] = 2; ActiveStatus[3][1] = 6;
- break
;
- case
5:
- ActiveStatus[0][0] = 1; ActiveStatus[0][1] = 5; ActiveStatus[1][0] = 2; ActiveStatus[1][1] = 5;
- ActiveStatus[2][0] = 0; ActiveStatus[2][1] = 6; ActiveStatus[3][0] = 1; ActiveStatus[3][1] = 6;
- break
;
- case
6:
- ActiveStatus[0][0] = 0; ActiveStatus[0][1] = 5; ActiveStatus[1][0] = 0; ActiveStatus[1][1] = 6;
- ActiveStatus[2][0] = 1; ActiveStatus[2][1] = 6; ActiveStatus[3][0] = 2; ActiveStatus[3][1] = 6;
- break
;
- case
7:
- ActiveStatus[0][0] = 0; ActiveStatus[0][1] = 5; ActiveStatus[1][0] = 1; ActiveStatus[1][1] = 5;
- ActiveStatus[2][0] = 2; ActiveStatus[2][1] = 5; ActiveStatus[3][0] = 0; ActiveStatus[3][1] = 6;
- break
;
- }
- }
- void
CSkyjuly_RecTTView::OnTimer(
UINT
nIDEvent)
- {
- //如果原来的方块已到底或游戏刚开始,则掉下一个新的方块
- int
i,j,k;
- if
(m_isBottom)
- {
- //1.产生下一个随机下坠物
- m_icurrentStatus = m_inextStatus;
- m_inextStatus = Random(7); //得到下一次的方块样式
- // if (m_inextStatus==0) m_inextStatus++;
- //2.修改新的“下一下坠物”
- RectStatusToNextStatus( m_inextStatus );
- // CRect rect(m_iStartY+320, m_iStartX, m_iStartY+440, m_iStartX+160);
- // InvalidateRect(&rect);
- // Invalidate(FALSE);
- //3.将旧的“下一下坠物”用作当前使用
- m_currentRect = m_icurrentStatus;
- //根据当前下坠物的形状去初始化激活状态下的下坠物坐标
- RectStatusToActiveStatus( m_icurrentStatus );
- //将当前动态数组中的数据反映到大数组中
- ActiveStatusToGameStatus();
- m_isBottom = FALSE;
- //4.判断当前方块是否已到底
- IsBottom();
- //5.判断游戏是否已结束: 碰了底,且第1行有小方块
- if
(m_isBottom)
- for
(i=0;i<m_iCol;i++)
- if
(GameStatus[0][i])
- {
- KillTimer(1);
- AfxMessageBox("游戏已结束!"
);
- for
(j=0;j<m_iRow;j++)
- for
(k=0;k<m_iCol;k++)
- GameStatus[j][k]=0;
- Invalidate(FALSE);
- m_bGameEnd = TRUE;
- break
;
- }
- }
- else
//当前方块下降
- {
- RectDown();
- }
- CView::OnTimer(nIDEvent);
- }
- void
CSkyjuly_RecTTView::ActiveStatusToGameStatus()
- {
- int
x1,x2,x3,x4,y1,y2,y3,y4;
- x1 = ActiveStatus[0][0];
- x2 = ActiveStatus[1][0];
- x3 = ActiveStatus[2][0];
- x4 = ActiveStatus[3][0];
- y1 = ActiveStatus[0][1];
- y2 = ActiveStatus[1][1];
- y3 = ActiveStatus[2][1];
- y4 = ActiveStatus[3][1];
- GameStatus[x1][y1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x2][y2]=MAP_STATE_NOT_EMPTY;
- GameStatus[x3][y3]=MAP_STATE_NOT_EMPTY;
- GameStatus[x4][y4]=MAP_STATE_NOT_EMPTY;
- }
- void
CSkyjuly_RecTTView::RectStatusToNextStatus(
int
m_which)
- {
- switch
(m_which)
- {
- case
1:
- NextStatus[0][0] = 0; NextStatus[0][1] = 1; NextStatus[1][0] = 1; NextStatus[1][1] = 1;
- NextStatus[2][0] = 2; NextStatus[2][1] = 1; NextStatus[3][0] = 3; NextStatus[3][1] = 1;
- break
;
- case
2:
- NextStatus[0][0] = 0; NextStatus[0][1] = 1; NextStatus[1][0] = 1; NextStatus[1][1] = 1;
- NextStatus[2][0] = 0; NextStatus[2][1] = 2; NextStatus[3][0] = 1; NextStatus[3][1] = 2;
- break
;
- case
3:
- NextStatus[0][0] = 1; NextStatus[0][1] = 0; NextStatus[1][0] = 0; NextStatus[1][1] = 1;
- NextStatus[2][0] = 1; NextStatus[2][1] = 1; NextStatus[3][0] = 1; NextStatus[3][1] = 2;
- break
;
- case
4:
- NextStatus[0][0] = 0; NextStatus[0][1] = 1; NextStatus[1][0] = 1; NextStatus[1][1] = 1;
- NextStatus[2][0] = 1; NextStatus[2][1] = 2; NextStatus[3][0] = 2; NextStatus[3][1] = 2;
- break
;
- case
5:
- NextStatus[0][0] = 1; NextStatus[0][1] = 1; NextStatus[1][0] = 2; NextStatus[1][1] = 1;
- NextStatus[2][0] = 0; NextStatus[2][1] = 2; NextStatus[3][0] = 1; NextStatus[3][1] = 2;
- break
;
- case
6:
- NextStatus[0][0] = 0; NextStatus[0][1] = 1; NextStatus[1][0] = 0; NextStatus[1][1] = 2;
- NextStatus[2][0] = 1; NextStatus[2][1] = 2; NextStatus[3][0] = 2; NextStatus[3][1] = 2;
- break
;
- case
7:
- NextStatus[0][0] = 0; NextStatus[0][1] = 1; NextStatus[1][0] = 1; NextStatus[1][1] = 1;
- NextStatus[2][0] = 2; NextStatus[2][1] = 1; NextStatus[3][0] = 0; NextStatus[3][1] = 2;
- break
;
- }
- }
- void
CSkyjuly_RecTTView::RectArrow(
int
m_Type)
- {
- //获取当前下坠物4个小方块的位置坐标
- int
x1,x2,x3,x4,y1,y2,y3,y4;
- x1 = ActiveStatus[0][0];
- x2 = ActiveStatus[1][0];
- x3 = ActiveStatus[2][0];
- x4 = ActiveStatus[3][0];
- y1 = ActiveStatus[0][1];
- y2 = ActiveStatus[1][1];
- y3 = ActiveStatus[2][1];
- y4 = ActiveStatus[3][1];
- //对不同的移动命令指示进行分类实现
- switch
(m_Type)
- {
- case
LEFT:
- //对每种不同的移动命令指示特性作相应的可移动分析
- if
( (ActiveStatus[0][1]>0) && IsLeftLimit() && !m_isBottom)
- {
- //清原来的方块
- GameStatus[x1][y1]=MAP_STATE_EMPTY;
- GameStatus[x2][y2]=MAP_STATE_EMPTY;
- GameStatus[x3][y3]=MAP_STATE_EMPTY;
- GameStatus[x4][y4]=MAP_STATE_EMPTY;
- // InvalidateCurrent();
- //添加新的移动后数据状态
- ActiveStatus[0][1] -= 1;
- ActiveStatus[1][1] -= 1;
- ActiveStatus[2][1] -= 1;
- ActiveStatus[3][1] -= 1;
- GameStatus[x1][y1-1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x2][y2-1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x3][y3-1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x4][y4-1]=MAP_STATE_NOT_EMPTY;
- InvalidateCurrent();
- }
- break
;
- case
RIGHT:
- if
( (ActiveStatus[3][1]< m_iCol-1) && IsRightLimit() && !m_isBottom)
- {
- //清原来的方块
- GameStatus[x1][y1]=MAP_STATE_EMPTY;
- GameStatus[x2][y2]=MAP_STATE_EMPTY;
- GameStatus[x3][y3]=MAP_STATE_EMPTY;
- GameStatus[x4][y4]=MAP_STATE_EMPTY;
- // InvalidateCurrent();
- //添加新的移动后数据状态
- ActiveStatus[0][1] += 1;
- ActiveStatus[1][1] += 1;
- ActiveStatus[2][1] += 1;
- ActiveStatus[3][1] += 1;
- GameStatus[x1][y1+1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x2][y2+1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x3][y3+1]=MAP_STATE_NOT_EMPTY;
- GameStatus[x4][y4+1]=MAP_STATE_NOT_EMPTY;
- InvalidateCurrent();
- }
- break
;
- case
DOWN:
- RectDown();
- break
;
- }
- }
- void
CSkyjuly_RecTTView::OnKeyDown(
UINT
nChar,
UINT
nRepCnt,
UINT
nFlags)
- {
- switch
(nChar)
- {
- case
VK_LEFT:
- RectArrow(LEFT);
- break
;
- case
VK_RIGHT:
- RectArrow(RIGHT);
- break
;
- case
VK_UP:
- RectChange();
- break
;
- case
VK_DOWN:
- RectArrow(DOWN);
- break
;
- }
- CView::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- BOOL
CSkyjuly_RecTTView::IsLeftLimit()
- {
- int
x1,x2,x3,x4,y1,y2,y3,y4;
- x1 = ActiveStatus[0][0];
- x2 = ActiveStatus[1][0];
- x3 = ActiveStatus[2][0];
- x4 = ActiveStatus[3][0];
- y1 = ActiveStatus[0][1];
- y2 = ActiveStatus[1][1];
- y3 = ActiveStatus[2][1];
- y4 = ActiveStatus[3][1];
- //根据当前下坠物的具体形态,分析判断其是否有向左移动的空间
- switch
(m_currentRect)
- {
- // "1"字形形态类型,判断其四个方块的正左边都没有任何物件(空间没有被占据)
- case
1:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1] || GameStatus[x4][y4-1])
- return
FALSE;
- break
;
- case
11:
- if
(GameStatus[x1][y1-1])
- return
FALSE;
- break
;
- case
2:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
- return
FALSE;
- break
;
- case
3:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
- return
FALSE;
- break
;
- case
31:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
32:
- if
(GameStatus[x1][y1-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
33:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x4][y4-1])
- return
FALSE;
- break
;
- case
4:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x4][y4-1])
- return
FALSE;
- break
;
- case
41:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
- return
FALSE;
- break
;
- case
5:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
51:
- if
(GameStatus[x1][y1-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
6:
- if
(GameStatus[x1][y1-1] || GameStatus[x3][y3-1] || GameStatus[x4][y4-1])
- return
FALSE;
- break
;
- case
61:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
- return
FALSE;
- break
;
- case
62:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
63:
- if
(GameStatus[x1][y1-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
7:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
71:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1])
- return
FALSE;
- break
;
- case
72:
- if
(GameStatus[x1][y1-1] || GameStatus[x2][y2-1] || GameStatus[x3][y3-1])
- return
FALSE;
- break
;
- case
73:
- if
(GameStatus[x1][y1-1] || GameStatus[x4][y4-1])
- return
FALSE;
- break
;
- }
- return
TRUE;
- }
- BOOL
CSkyjuly_RecTTView::IsRightLimit()
- {
- int
x1,x2,x3,x4,y1,y2,y3,y4;
- x1 = ActiveStatus[0][0];
- x2 = ActiveStatus[1][0];
- x3 = ActiveStatus[2][0];
- x4 = ActiveStatus[3][0];
- y1 = ActiveStatus[0][1];
- y2 = ActiveStatus[1][1];
- y3 = ActiveStatus[2][1];
- y4 = ActiveStatus[3][1];
- switch
(m_currentRect)
- {
- case
1:
- if
(GameStatus[x1][y1+1] || GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
11:
- if
(GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
2:
- if
(GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
3:
- if
(GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
31:
- if
(GameStatus[x1][y1+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
32:
- if
(GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
33:
- if
(GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
4:
- if
(GameStatus[x1][y1+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
41:
- if
(GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
5:
- if
(GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
51:
- if
(GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
6:
- if
(GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
61:
- if
(GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
62:
- if
(GameStatus[x1][y1+1] || GameStatus[x2][y2+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
63:
- if
(GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
7:
- if
(GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
71:
- if
(GameStatus[x1][y1+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
72:
- if
(GameStatus[x2][y2+1] || GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- case
73:
- if
(GameStatus[x3][y3+1] || GameStatus[x4][y4+1])
- return
FALSE;
- break
;
- }
- return
TRUE;
- }
- void
CSkyjuly_RecTTView::RectChange()
- {
- //先预先变形,然后判断变形后的方块是否有空间,如有足够空间,则进行实际变形,否则不变
- int
xx1,xx2,xx3,xx4,yy1,yy2,yy3,yy4;
- int
m_lscurrentRect;
- CString lsStr;
- int
x1,x2,x3,x4,y1,y2,y3,y4;
- x1 = ActiveStatus[0][0];
- x2 = ActiveStatus[1][0];
- x3 = ActiveStatus[2][0];
- x4 = ActiveStatus[3][0];
- y1 = ActiveStatus[0][1];
- y2 = ActiveStatus[1][1];
- y3 = ActiveStatus[2][1];
- y4 = ActiveStatus[3][1];
- //变形后位置在数组中的存放顺序仍需遵循先左后右,在同一列中先上后下
- xx1=x1; xx2=x2; xx3=x3; xx4=x4; yy1=y1; yy2=y2; yy3=y3; yy4=y4;
- switch
(m_currentRect)
- {
- case
1:
- xx1=x1+1; yy1=y1-1; xx3=x3-1; yy3=y3+1; xx4=x4-2; yy4=y4+2;
- m_lscurrentRect = 11;
- break
;
- case
11:
- xx1=x1-1; yy1=y1+1; xx3=x3+1; yy3=y3-1; xx4=x4+2; yy4=y4-2;
- m_lscurrentRect = 1;
- break
;
- case
2:
- m_lscurrentRect=2;
- break
;
- case
3:
- xx1=x1-2; yy1=y1+1; xx4=x4-1; yy4=y4;
- m_lscurrentRect = 31;
- break
;
- case
31:
- xx1=x1+1; yy1=y1-1;
- m_lscurrentRect = 32;
- break
;
- case
32:
- xx1=x1+1; yy1=y1; xx4=x4+2; yy4=y4-1;
- m_lscurrentRect=33;
- break
;
- case
33:
- xx4=x4-1; yy4=y4+1;
- m_lscurrentRect=3;
- break
;
- case
4:
- xx1=x1+2; yy1=y1-1; xx3=x3+1; yy3=y3-1; xx4=x4-1;
- m_lscurrentRect = 41;
- break
;
- case
41:
- xx1=x1-2; yy1=y1+1; xx3=x3-1; yy3=y3+1; xx4=x4+1;
- m_lscurrentRect = 4;
- break
;
- case
5:
- xx1=x1-1; xx2=x2-2; yy2=y2+1; xx3=x3+1; yy4=y4+1;
- m_lscurrentRect = 51;
- break
;
- case
51:
- xx1=x1+1; xx2=x2+2; yy2=y2-1; xx3=x3-1; yy4=y4-1;
- m_lscurrentRect = 5;
- break
;
- case
6:
- xx2=x1+1; yy2=y2-1; xx3=x3-1; xx4=x4-2; yy4 = yy4+1;
- m_lscurrentRect = 61;
- break
;
- case
61:
- xx3=x3+2; yy3=y3-1; xx4=x4+2; yy4=y4-1;
- m_lscurrentRect = 62;
- break
;
- case
62:
- xx1=x1+1; yy1=y1-1; xx3=x3-2; yy3=y3+1; xx4=x4-1;
- m_lscurrentRect = 63;
- break
;
- case
63:
- xx1=x1-2; yy1=y1+1; xx2=x2-2; yy2=y2+1;
- m_lscurrentRect = 6;
- break
;
- case
7:
- xx3=x3-1; yy3=y3+1; xx4=x4+1; yy4=y4+1;
- m_lscurrentRect = 71;
- break
;
- case
71:
- xx1=x1+2; xx2=x2-1; yy2=y2+1; xx4=x4+1; yy4=y4-1;
- m_lscurrentRect = 72;
- break
;
- case
72:
- xx1=x1-2; xx3=x3-1; yy3=y3+1; xx4=x4-1; yy4=y4+1;
- m_lscurrentRect = 73;
- break
;
- case
73:
- xx2=x2+1; yy2=y2-1; xx3=x3+2; yy3=y3-2; xx4=x4-1; yy4=y4-1;
- m_lscurrentRect = 7;
- break
;
- }
- //如果变形后所在的区域内无其他方块,则表示有足够空间,可以变形
- //且不能超越边界
- GameStatus[x1][y1] = MAP_STATE_EMPTY;
- GameStatus[x2][y2] = MAP_STATE_EMPTY;
- GameStatus[x3][y3] = MAP_STATE_EMPTY;
- GameStatus[x4][y4] = MAP_STATE_EMPTY;
- if
(GameStatus[xx1][yy1]==MAP_STATE_EMPTY &&
- GameStatus[xx2][yy2]==MAP_STATE_EMPTY &&
- GameStatus[xx3][yy3]==MAP_STATE_EMPTY &&
- GameStatus[xx4][yy4]==MAP_STATE_EMPTY
- && yy1>=0 && yy4<=m_iCol-1
- && !(xx1<0 || xx2<0 || xx3<0 || xx4<0)
- && !(xx1>m_iRow-1 || xx2>m_iRow-1 || xx3>m_iRow-1 || xx4>m_iRow-1) )
- {
- InvalidateCurrent();
- ActiveStatus[0][0]=xx1;
- ActiveStatus[1][0]=xx2;
- ActiveStatus[2][0]=xx3;
- ActiveStatus[3][0]=xx4;
- ActiveStatus[0][1]=yy1;
- ActiveStatus[1][1]=yy2;
- ActiveStatus[2][1]=yy3;
- ActiveStatus[3][1]=yy4;
- GameStatus[xx1][yy1] = MAP_STATE_NOT_EMPTY;
- GameStatus[xx2][yy2] = MAP_STATE_NOT_EMPTY;
- GameStatus[xx3][yy3] = MAP_STATE_NOT_EMPTY;
- GameStatus[xx4][yy4] = MAP_STATE_NOT_EMPTY;
- InvalidateCurrent();
- //改变形状代码
- m_currentRect = m_lscurrentRect;
- }
- else
- {//恢复原来状态
- GameStatus[x1][y1] = MAP_STATE_NOT_EMPTY;
- GameStatus[x2][y2] = MAP_STATE_NOT_EMPTY;
- GameStatus[x3][y3] = MAP_STATE_NOT_EMPTY;
- GameStatus[x4][y4] = MAP_STATE_NOT_EMPTY;
- }
- //判断是否已到底
- IsBottom();
- }
//给的注释已经够详尽了,我就不再写多余的分析了。
//July、2010/10月。
Dlg.h文件。
- #if !defined(AFX_OPTIONDLG_H__570435A5_9237_4DE0_8215_48D075E106AD__INCLUDED_)
- #define AFX_OPTIONDLG_H__570435A5_9237_4DE0_8215_48D075E106AD__INCLUDED_
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- // OptionDlg.h : header file
- //
- /////////////////////////////////////////////////////////////////////////////
- // COptionDlg dialog
- class
COptionDlg :
public
CDialog
- {
- // Construction
- public
:
- int
m_iBlockStyle;
- int
m_iLevel;
- int
m_iArea;
- COptionDlg(int
m_iArea,
int
m_iLevel,
int
m_iBlockStyle,
BOOL
m_bMusic,
BOOL
m_bDrawGrid, CWnd* pParent = NULL);
- // Dialog Data
- //{{AFX_DATA(COptionDlg)
- enum
{ IDD = IDD_DLG_OPTION };
- BOOL
m_bDrawGrid;
- BOOL
m_bMusic;
- //}}AFX_DATA
- // Overrides
- // ClassWizard generated virtual function overrides
- //{{AFX_VIRTUAL(COptionDlg)
- protected
:
- virtual
void
DoDataExchange(CDataExchange* pDX);
// DDX/DDV support
- //}}AFX_VIRTUAL
- // Implementation
- protected
:
- int
m_oldArea;
- int
m_oldLevel;
- int
m_oldBlockSytle;
- BOOL
m_oldMusic;
- BOOL
m_oldDrawGrid;
- // Generated message map functions
- //{{AFX_MSG(COptionDlg)
- afx_msg void
OnCheckGrid();
- virtual
void
OnOK();
- virtual
BOOL
OnInitDialog();
- afx_msg int
OnCreate(LPCREATESTRUCT lpCreateStruct);
- afx_msg void
OnGameOption();
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- //{{AFX_INSERT_LOCATION}}
- // Microsoft Visual C++ will insert additional declarations immediately before the previous line.
- #endif // !defined(AFX_OPTIONDLG_H__570435A5_9237_4DE0_8215_48D075E106AD__INCLUDED_)
/////////////////////////////////////////////////////////////////////////////
// COptionDlg dialog
class COptionDlg : public CDialog
{
// Construction
public:
int m_iBlockStyle;
int m_iLevel;
int m_iArea;
COptionDlg(int m_iArea, int m_iLevel,int m_iBlockStyle, BOOL m_bMusic,BOOL m_bDrawGrid, CWnd* pParent = NULL);
// Dialog Data
//{{AFX_DATA(COptionDlg)
enum { IDD = IDD_DLG_OPTION };
BOOL m_bDrawGrid;
BOOL m_bMusic;
//}}AFX_DATA
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(COptionDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
int m_oldArea;
int m_oldLevel;
int m_oldBlockSytle;
BOOL m_oldMusic;
BOOL m_oldDrawGrid;
// Generated message map functions
//{{AFX_MSG(COptionDlg)
afx_msg void OnCheckGrid();
virtual void OnOK();
virtual BOOL OnInitDialog();
afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct);
afx_msg void OnGameOption();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_OPTIONDLG_H__570435A5_9237_4DE0_8215_48D075E106AD__INCLUDED_)
Dlg.cpp文件。
- // OptionDlg.cpp : implementation file
- //
- #include "stdafx.h"
- #include "skyjuly_RecTT.h"
- #include "OptionDlg.h"
- #ifdef _DEBUG
- #define new DEBUG_NEW
- #undef THIS_FILE
- static
char
THIS_FILE[] = __FILE__;
- #endif
- /////////////////////////////////////////////////////////////////////////////
- // COptionDlg dialog
- COptionDlg::COptionDlg(int
m_iArea,
int
m_iLevel,
int
m_iBlockStyle,
BOOL
m_bMusic,
BOOL
m_bDrawGrid, CWnd* pParent
/*=NULL*/
)
- : CDialog(COptionDlg::IDD, pParent)
- {
- //{{AFX_DATA_INIT(COptionDlg)
- m_bDrawGrid = FALSE;
- m_bMusic = FALSE;
- //}}AFX_DATA_INIT
- }
- void
COptionDlg::DoDataExchange(CDataExchange* pDX)
- {
- CDialog::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(COptionDlg)
- DDX_Check(pDX, IDC_CHECK_GRID, m_bDrawGrid);
- DDX_Check(pDX, IDC_CHECK_MUSIC, m_bMusic);
- //}}AFX_DATA_MAP
- }
- BEGIN_MESSAGE_MAP(COptionDlg, CDialog)
- //{{AFX_MSG_MAP(COptionDlg)
- ON_BN_CLICKED(IDC_CHECK_GRID, OnCheckGrid)
- ON_WM_CREATE()
- ON_COMMAND(ID_GAME_OPTION, OnGameOption)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- /////////////////////////////////////////////////////////////////////////////
- // COptionDlg message handlers
- void
COptionDlg::OnCheckGrid()
- {
- // TODO: Add your control notification handler code here
- }
- void
COptionDlg::OnOK()
- {
- // TODO: Add extra validation here
- CDialog::OnOK();
- }
- BOOL
COptionDlg::OnInitDialog()
- {
- CDialog::OnInitDialog();
- // TODO: Add extra initialization here
- return
TRUE;
// return TRUE unless you set the focus to a control
- // EXCEPTION: OCX Property Pages should return FALSE
- }
- int
COptionDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
- {
- if
(CDialog::OnCreate(lpCreateStruct) == -1)
- return
-1;
- // TODO: Add your specialized creation code here
- return
0;
- }
- void
COptionDlg::OnGameOption()
- {
- // TODO: Add your command handler code here
- }
COptionDlg::COptionDlg(int m_iArea, int m_iLevel, int m_iBlockStyle,BOOL m_bMusic, BOOL m_bDrawGrid, CWnd* pParent /*=NULL*/)
: CDialog(COptionDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(COptionDlg)
m_bDrawGrid = FALSE;
m_bMusic = FALSE;
//}}AFX_DATA_INIT
}
void COptionDlg::DoDataExchange(CDataExchange* pDX)
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(COptionDlg)
DDX_Check(pDX, IDC_CHECK_GRID, m_bDrawGrid);
DDX_Check(pDX, IDC_CHECK_MUSIC, m_bMusic);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(COptionDlg, CDialog)
//{{AFX_MSG_MAP(COptionDlg)
ON_BN_CLICKED(IDC_CHECK_GRID, OnCheckGrid)
ON_WM_CREATE()
ON_COMMAND(ID_GAME_OPTION, OnGameOption)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// COptionDlg message handlers
void COptionDlg::OnCheckGrid()
{
// TODO: Add your control notification handler code here
}
void COptionDlg::OnOK()
{
// TODO: Add extra validation here
CDialog::OnOK();
}
BOOL COptionDlg::OnInitDialog()
{
CDialog::OnInitDialog();
// TODO: Add extra initialization here
return TRUE; // return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
int COptionDlg::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CDialog::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
return 0;
}
void COptionDlg::OnGameOption()
{
// TODO: Add your command handler code here
}
//至此,大部分源码,已经贴出,欢迎各位 就俄罗斯方块算法交流指正。
//曾经 单单玩这个游戏,便 玩了好几个月。;-)。