按教程做了个俄罗斯方块,运行后无法游戏。求助!!
按着一份教程做了个俄罗斯方块……可是运行后没法正常游戏……开始后连一个方块都没掉下来…………我把代码贴出来……求高手帮帮忙看看哪里出问题了……
下面是新建的一个游戏类……
///////////////////////////////////////////////////////////////////Russia.h://////////////////////////////////////////////////////////////////////
// Russia.h: interface for the CRussia class.
//
//////////////////////////////////////////////////////////////////////
#if !defined(AFX_RUSSIA_H__8CEDC523_1202_4CAB_876D_E19BC3BA49FF__INCLUDED_)
#define AFX_RUSSIA_H__8CEDC523_1202_4CAB_876D_E19BC3BA49FF__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CRussia
{
public:
CRussia();
virtual ~CRussia();
////////////////////////////////////////////////
//游戏数组
int Russia[100][100];
//当前图形
int Now[4][4];
//上一图形
int Will[4][4];
//变化后图形
int After[4][4];
//当前图形左上角位置
CPoint NowPosition;
//当前可能出现的图形形状数
int Count;
//游戏结束
bool end;
//级别
int m_Level;
//速度
int m_Speed;
//分数
int m_Score;
//行列数
int m_RowCount,m_ColCount;
//方块
CBitmap fangkuai;
//界面
CBitmap jiemian;
//显示分数等内容
void DrawScore(CDC*pDC);
//消行
void LineDelete();
//方块移动
void Move(int direction);
//方块变化,既方向键上键操作
bool Change(int a[][4],CPoint p,int b[][100]);
//是否与原来方块接触,或与边界接触
bool Meet(int a[][4],int direction,CPoint p);
//显示下一个方块
void DrawWill();
//显示界面
void DrawJiemian(CDC*pDC);
//开始
void Start();
///////////////////////////////////////////////////////
};
#endif // !defined(AFX_RUSSIA_H__8CEDC523_1202_4CAB_876D_E19BC3BA49FF__INCLUDED_)
///////////////////////////////////////////////////////////////////Russia.cpp://////////////////////////////////////////////////////////////////////
// Russia1.cpp: implementation of the CRussia class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#include "ELSFK.h"
#include "Russia.h"
////////////////////////////////////
#include"cstdlib"
#include"ctime"
////////////////////////////////////
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CRussia::CRussia()
{
////////////////////////////////////
jiemian.LoadBitmap(IDB_BITMAP2);
fangkuai.LoadBitmap(IDB_BITMAP4);
///////////////////////////////////////
}
CRussia::~CRussia()
{
}
///////////////////////////////
void CRussia::DrawJiemian(CDC*pDC)
{
CDC Dc;
if(Dc.CreateCompatibleDC(pDC)==FALSE)
AfxMessageBox("Can't create DC");
//画背景
Dc.SelectObject(jiemian);
pDC->BitBlt(0,0,500,550,&Dc,0,0,SRCCOPY);
//画分数,速度,难度
DrawScore(pDC);
//如果有方块,显示方块?????????????
//////////////////////
//游戏区
for(int i=0;i<m_RowCount;i++)
{
for(int j=0;j<m_ColCount;j++)
if(Russia[i][j]==1)
{
Dc.SelectObject(fangkuai);
pDC->BitBlt(j*30,i*30,30,30,&Dc,0,0,SRCCOPY);
}
}
//预先图形方块
for(int n=0;n<4;n++)
{
for(int m=0;m<4;m++)
if(Will[n][m]==1)
{
Dc.SelectObject(fangkuai);
pDC->BitBlt(365+m*30,240+n*30,30,30,&Dc,0,0,SRCCOPY);
}
}
}
void CRussia::DrawScore(CDC*pDC)
{
int nOldDC=pDC->SaveDC();
//设置字体
CFont font;
if(0==font.CreatePointFont(300,"Comic Sans MS"))
{
AfxMessageBox("Can't Create Font");
}
pDC->SelectObject(&font);
//设置字体颜色及其背景颜色
CString str;
pDC->SetTextColor(RGB(39,244,10));
pDC->SetBkColor(RGB(255,255,0));
//输出数字
str.Format("%d",m_Level);
if(m_Level>=0)
pDC->TextOut(440,120,str);
str.Format("%d",m_Speed);
if(m_Speed>=0)
pDC->TextOut(440,64,str);
str.Format("%d",m_Score);
if(m_Score>=0)
pDC->TextOut(440,2,str);
pDC->RestoreDC(nOldDC);
}
void CRussia::Start()
{
end=false;//运行结束标志
m_Score=0; //初始分数
m_Speed=0; //初始速度
m_Level=1; //初始难度
m_RowCount=18; //行数
m_ColCount=12; //列数
Count=7; //方块种类
//清空背景数组
for(int i=0;i<m_RowCount;i++)
{
for(int j=0;j<m_ColCount;j++)
{
Russia[i][j]=0;
}
}
//清空方块数组Now[ ][ ] Will[ ][ ]
for(i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
Now[i][j]=0;
Will[i][j]=0;
}
}
//先画Will[][]
DrawWill();
//再画Now[][]&Will[][]
DrawWill();
}
void CRussia::DrawWill()
{
int i,j;
int k=4,l=4;
//把将要出现的方块给当前数组,并把将要出现数组赋值为零
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
{
Now[i][j]=Will[i][j];
Will[i][j]=0;
}
}
//初始化随即数种子
srand(GetTickCount());
int nTemp=rand()%Count;
//各种图形
switch(nTemp)
{
case 0:
Will[0][0]=1;
Will[0][1]=1;
Will[1][0]=1;
Will[1][1]=1;
break;
case 1:
Will[0][0]=1;
Will[0][1]=1;
Will[1][0]=1;
Will[2][0]=1;
break;
case 2:
Will[0][0]=1;
Will[0][1]=1;
Will[1][1]=1;
Will[2][1]=1;
break;
case 3:
Will[0][1]=1;
Will[1][0]=1;
Will[1][1]=1;
Will[2][0]=1;
break;
case 4:
Will[0][0]=1;
Will[1][0]=1;
Will[1][1]=1;
Will[2][1]=1;
break;
case 5:
Will[0][0]=1;
Will[1][0]=1;
Will[1][1]=1;
Will[2][0]=1;
break;
case 6:
Will[0][0]=1;
Will[1][0]=1;
Will[2][0]=1;
Will[3][0]=1;
break;
//适应于难度扩展
/* case 7:
Will[0][0]=1;
Will[1][0]=1;
Will[1][1]=1;
Will[1][2]=1;
Will[0][2]=1;
break;
case 8:
Will[0][0]=1;
Will[1][0]=1;
Will[2][0]=1;
Will[1][1]=1;
Will[1][2]=1;
break;
*/
}
//转换
int tmp[4][4];
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
tmp[i][j]=Will[j][3-i];
}
//整理,为了移动的需要
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
if(tmp[i][j]==1)
{
if(k>i) k=i;
if(l>j) l=j;
}
}
for(i=0;i<4;i++)
{ for(j=0;j<4;j++)
Will[i][j]=0;
}
//把变换后的矩阵移到左上角
for(i=k;i<4;i++)
{
for(j=l;j<4;j++)
Will[i-k][j-l]=tmp[i][j];
}
// Now[][]的开始位置
NowPosition.x=0;
NowPosition.y=m_ColCount/2;
}
void CRussia::Move(int direction)
{
if(end)
return;
switch(direction)
{
//左
case 1:
if (Meet(Now,1,NowPosition)) break;
NowPosition.y--;
break;
//右
case 2:
if (Meet(Now,2,NowPosition)) break;
NowPosition.y++;
break;
//上
case 4:
Meet(Now,3,NowPosition);
break;
//下
case 3:
if(Meet(Now,4,NowPosition))
{
LineDelete();
break;
}
NowPosition.x++;
break;
default:
break;
}
}
//消去行
void CRussia::LineDelete()
{
int m = 0; //本次共消去的行数
bool flag = 0;
for(int i=0;i<m_RowCount;i++)
{
//检查要不要消行
flag = true;
for(int j=0;j<m_ColCount;j++)
{
if(Russia[i][j] == 0)
{
flag = false;
}
}
if(flag==true)
{
m++;
for(int k=i;k>0;k--)
{
//上行给下行
for(int l=0;l<m_ColCount;l++)
{
Russia[k][l] = Russia[k-1][l];
}
}
//第一行为零
for(int l=0;l<m_ColCount;l++)
{
Russia[0][1] =0;
}
}
}
//消行,表示运动方块已停止
//必须生成新的运动方块
DrawWill();
//加分
switch(m)
{
case 1:
m_Score++;
break;
case 2:
m_Score+=3;
break;
case 3:
m_Score+=6;
case 4:
m_Score+=10;
default:
break;
}
//速度赋值
m_Speed=m_Score/100;
for(i=0;i<4;i++)
for(int j=0;j<4;j++)
if(Now[i][j]==1)
//到了顶点
if(Russia[i+NowPosition.x][j+NowPosition.y]==1)
{
end = true;
AfxMessageBox("游戏结束!");
return;
}
}
//是否遇到了边界或者有其他方块档住了
bool CRussia::Meet(int a[][4],int direction,CPoint p)
{
int i,j;
//先把原位置清零
for(i=0;i<4;i++)
{
for(j=0;j<4;j++)
if(a[i][j]==1)
Russia[p.x+i][p.y+j]=0;
}
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(a[i][j]==1)
{
switch(direction)
{
case 1: //左移
if((p.y+j-1)<0) goto exit;
if(Russia[p.x+i][p.y+j-1]==1) goto exit;
break;
case 2://右移
if((p.y+j+1)>=m_ColCount) goto exit;
if(Russia[p.x+i][p.y+j+1]==1) goto exit;
break;
case 3://下移
if((p.x+i+1)>=m_RowCount) goto exit;
if(Russia[p.x+i+1][p.y+j]==1) goto exit;
break;
case 4://变换
if(!Change(a,p,Russia)) goto exit;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
Now[i][j]=After[i][j];
a[i][j]=Now[i][j];
}
return false;
break;
}
}
int x,y;
x=p.x;
y=p.y;
//移动位置,重新给数组赋值
switch(direction)
{
case 1:
y--;break;
case 2:
y++;break;
case 3:
x++;break;
case 4:
break;
}
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(a[i][j] == 1)
Russia[x+i][y+j]=1;
return false;
exit:
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(a[i][j]==1)
Russia[p.x+i][p.y+j]=1;
return true;
}
//转换
bool CRussia::Change(int a[][4], CPoint p,int b[][100])
{
int tmp[4][4];
int i,j;
int k=4,l=4;
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
tmp[i][j] = a[j][3-i];
After[i][j] = 0; // 存放变换后的方块矩阵
}
for(i=0;i<4;i++)
for(j=0;j<4;j++)
if(tmp[i][j] == 1)
{
if(k > i) k = i;
if(l > j) l = j;
}
for(i=k;i<4;i++)
for(j=1;j<4;j++)
{
After[i-k][j-l] = tmp[i][j];
//把变换后的矩阵移到座上角
}
//判断是否接触,是:返回失败
for(i=0;i<4;i++)
for(j=0;j<4;j++)
{
if(After[i][j] == 0) continue;
if(((p.x+i)>=m_RowCount)||((p.y+j)<0)||((p.y+j)>=m_ColCount)) return false;
if(b[p.x+i][p.y+j]==1)
return false;
}
return true;
}
///////////////////////////////
///////////////////////////////////////////////////////////////////下面是View类//////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////ELSFKView.h://////////////////////////////////////////////////////////////////////
// ELSFKView.h : interface of the CELSFKView class
//
/////////////////////////////////////////////////////////////////////////////
///////////////////////////////
#include"Russia.h"
//////////////////////////////
#if !defined(AFX_ELSFKVIEW_H__4860EB69_0AAE_43A8_8EB9_8EF2FD85ED71__INCLUDED_)
#define AFX_ELSFKVIEW_H__4860EB69_0AAE_43A8_8EB9_8EF2FD85ED71__INCLUDED_
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CELSFKView : public CView
{
protected: // create from serialization only
CELSFKView();
DECLARE_DYNCREATE(CELSFKView)
// Attributes
public:
CELSFKDoc* GetDocument();
//////////////////////////////////
//俄罗斯类
CRussia russia;
//开始标志
bool start;
//封面
CBitmap fenmian;
//暂停
BOOL m_bPause;
//开始菜单
//afx_msg void OnMenuStart(); /*建立类向导中重复*/
//计时器
//afx_msg void OnTimer(UINT nIDEvent); /*建立类向导中重复*/
//键盘操作
//afx_msg void OnKeyDown(UINT nChar,UINT nRepCnt,UINT nFlags); /*建立类向导中重复*/
///////////////////////////////////
// Operations
public:
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CELSFKView)
public:
virtual void OnDraw(CDC* pDC); // overridden to draw this view
virtual BOOL PreCreateWindow(CREATESTRUCT& cs);
protected:
virtual BOOL OnPreparePrinting(CPrintInfo* pInfo);
virtual void OnBeginPrinting(CDC* pDC, CPrintInfo* pInfo);
virtual void OnEndPrinting(CDC* pDC, CPrintInfo* pInfo);
//}}AFX_VIRTUAL
// Implementation
public:
virtual ~CELSFKView();
#ifdef _DEBUG
virtual void AssertValid() const;
virtual void Dump(CDumpContext& dc) const;
#endif
protected:
// Generated message map functions
protected:
//{{AFX_MSG(CELSFKView)
afx_msg void OnMenuStart(); /*重复*/
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 ELSFKView.cpp
inline CELSFKDoc* CELSFKView::GetDocument()
{ return (CELSFKDoc*)m_pDocument; }
#endif
/////////////////////////////////////////////////////////////////////////////
//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.
#endif // !defined(AFX_ELSFKVIEW_H__4860EB69_0AAE_43A8_8EB9_8EF2FD85ED71__INCLUDED_)
///////////////////////////////////////////////////////////////////ELSFKView.cpp://////////////////////////////////////////////////////////////////////
// ELSFKView.cpp : implementation of the CELSFKView class
//
#include "stdafx.h"
#include "ELSFK.h"
#include "ELSFKDoc.h"
#include "ELSFKView.h"
///////////////////////////////
#include"Russia.h"
#include"windows.h"
//////////////////////////////
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
/////////////////////////////////////////////////////////////////////////////
// CELSFKView
IMPLEMENT_DYNCREATE(CELSFKView, CView)
BEGIN_MESSAGE_MAP(CELSFKView, CView)
//{{AFX_MSG_MAP(CELSFKView)
ON_COMMAND(ID_MENU_START, OnMenuStart)
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()
/////////////////////////////////////////////////////////////////////////////
// CELSFKView construction/destruction
CELSFKView::CELSFKView()
{
// TODO: add construction code here
/////////////////////////////////
fenmian.LoadBitmap(IDB_BITMAP1);
start = false;
m_bPause = false;
/////////////////////////////////
}
CELSFKView::~CELSFKView()
{
}
BOOL CELSFKView::PreCreateWindow(CREATESTRUCT& cs)
{
// TODO: Modify the Window class or styles here by modifying
// the CREATESTRUCT cs
return CView::PreCreateWindow(cs);
}
/////////////////////////////////////////////////////////////////////////////
// CELSFKView drawing
void CELSFKView::OnDraw(CDC* pDC)
{
CELSFKDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
// TODO: add draw code for native data here
//////////////////////////////////
CDC Dc;
if(Dc.CreateCompatibleDC(pDC) == FALSE)
{
AfxMessageBox("Can't create DC");
}
//没有开始,显示封面
if(!start)
{
Dc.SelectObject(fenmian);
pDC->BitBlt(0,0,500,500,&Dc,0,0,SRCCOPY);
}
//显示背景
else
russia.DrawJiemian(pDC);
//////////////////////////////////
}
/////////////////////////////////////////////////////////////////////////////
// CELSFKView printing
BOOL CELSFKView::OnPreparePrinting(CPrintInfo* pInfo)
{
// default preparation
return DoPreparePrinting(pInfo);
}
void CELSFKView::OnBeginPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add extra initialization before printing
}
void CELSFKView::OnEndPrinting(CDC* /*pDC*/, CPrintInfo* /*pInfo*/)
{
// TODO: add cleanup after printing
}
/////////////////////////////////////////////////////////////////////////////
// CELSFKView diagnostics
#ifdef _DEBUG
void CELSFKView::AssertValid() const
{
CView::AssertValid();
}
void CELSFKView::Dump(CDumpContext& dc) const
{
CView::Dump(dc);
}
CELSFKDoc* CELSFKView::GetDocument() // non-debug version is inline
{
ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CELSFKDoc)));
return (CELSFKDoc*)m_pDocument;
}
#endif //_DEBUG
/////////////////////////////////////////////////////////////////////////////
// CELSFKView message handlers
void CELSFKView::OnMenuStart()
{
// TODO: Add your command handler code here
///////////////////////////////
start = true;
russia.Start();
SetTimer(1,50*(11-russia.m_Speed ) , NULL);
///////////////////////////////
}
void CELSFKView::OnTimer(UINT nIDEvent)
{
// TODO: Add your message handler code here and/or call default
///////////////////////////////
//下移
russia.Move(3);
//重画
russia.DrawJiemian(GetDC());
///////////////////////////////
CView::OnTimer(nIDEvent);
}
void CELSFKView::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
{
// TODO: Add your message handler code here and/or call default
///////////////////////////////
//没有开始
if(!start)
return;
//暂停
if(m_bPause == true)
return;
//按下方向键
switch(nChar)
{
case VK_LEFT:russia.Move(1);break;
case VK_RIGHT:russia.Move(2);break;
case VK_UP:russia.Move(4);break;
case VK_DOWN:russia.Move(3);break;
}
//重画
CDC* pDC=GetDC();
russia.DrawJiemian(pDC);
ReleaseDC(pDC);
///////////////////////////////
CView::OnKeyDown(nChar, nRepCnt, nFlags);
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////