分享
 
 
 

第一次真正意义上的用VC++实现的一个完整的Win32程序—俄罗斯方块

王朝vc·作者佚名  2006-01-09
窄屏简体版  字體: |||超大  

第一次真正意义上的用VC++实现的一个完整的Win32程序。

//Block.h

//-------------------------------------------------------------------------------------------------

/*

定义每个方块的结构

*/

#if !defined _BLOCK_H_

#define _BLOCK_H_

#define BLOCK_VERSION &H01000000 //主版本号、辅版本、附加版本、附加2

#define BLOCK_SIZE 6 //存储到文件时占用的字节数

#define BLOCK_HEADER_SIZE 8 //存储文件头信息的大小

struct _Block

{//注意:这些字段对于存储文件来说是有先后之分的。

unsigned int ID:8;

unsigned int NextID:8;

int Width:4;

int Height:4;

int OffsetY:4;

int OffsetX:4;

unsigned int Elements; //方块的各位是否为实体

};

typedef _Block BLOCK;

#endif

//-------------------------------------------------------------------------------------------------

//CustomGDI.h

//-------------------------------------------------------------------------------------------------

#pragma once

#include "windows.h"

//#include "d3d9.h"

#define BORDER_STYLE_NONE 0

#define BORDER_STYLE_FLAT 1

//为简单起见,目前只提供FLAT

//#define BORDER_STYLE_FIXED3D 2

//#define BORDER_STYLE_INNER3D 4

#define BORDER_STYLE_DEFAULT BORDER_STYLE_NONE

#define INNER_STYLE_EMPTY 0

#define INNER_STYLE_SOLID 1

#define INNER_STYLE_DEFAULT INNER_STYLE_EMPTY

#define TRANSPARENT_COLOR RGB(0,0,0)

#define BACKGROUND_DEFAULT_COLOR RGB(0,0,0)

typedef int INNER_STYLE;

typedef int BORDER_STYLE;

typedef DWORD GDI_COLOR;

class CCustomGDI

{

public:

//CCustomGDI(void);

CCustomGDI(HWND hWnd);

~CCustomGDI(void);

void TextOut(int x, int y,const char* lpString, int cbString);

void Drawbox(PRECT prect, BORDER_STYLE bstyle=BORDER_STYLE_DEFAULT, INNER_STYLE istyle=INNER_STYLE_DEFAULT);

void Drawbox(int x, int y, int height, int width, BORDER_STYLE bstyle=BORDER_STYLE_DEFAULT, INNER_STYLE istyle=INNER_STYLE_DEFAULT);

void DrawPic(int x, int y, int height, int width, const char* file);

void DrawPic(PRECT prect, const char* file);

void Clear(void);

void Clear(PRECT prect);

void Clear(GDI_COLOR color);

void Clear(PRECT prect, GDI_COLOR color);

void Clear(int x, int y, int height, int width, GDI_COLOR color);

void SetBkColor(GDI_COLOR color); //设置背景色

void SetColor(GDI_COLOR color); //设置前景色

void Set3DColor(GDI_COLOR ul_color, GDI_COLOR rb_color); //设置绘制3D时左上角与右下角的颜色

void SetBorderColor(GDI_COLOR color);

void SetBorderSize(int size);

protected:

//LPDIRECT3D9 m_pD3D;

//LPDIRECT3DDEVICE9 m_pd3dDevice;

//HDC m_hdc;

HWND m_hwnd;

//HBRUSH m_hbrBkgnd;

GDI_COLOR m_background;

int m_bordersize;

GDI_COLOR m_bordercolor;

GDI_COLOR m_color;

};

//-------------------------------------------------------------------------------------------------

//CustomGDI.cpp

//-------------------------------------------------------------------------------------------------

#include ".\customgdi.h"

//

//CCustomGDI::CCustomGDI(void)

//{

//}

//

CCustomGDI::CCustomGDI(HWND hWnd)

{

//初始化图形设备

m_hwnd=hWnd;

//m_hdc=GetDC(hWnd);

m_background=BACKGROUND_DEFAULT_COLOR;

m_bordersize=1;

m_bordercolor=RGB(0x80,0x80,0x80); //gray

m_color=RGB(0xFF,0xFF,0xFF); //white

}

CCustomGDI::~CCustomGDI(void)

{

//ReleaseDC(m_hwnd, m_hdc);

}

void CCustomGDI::TextOut(int x, int y,const char* lpString, int cbString)

{

HDC hdc=GetDC(m_hwnd);

::TextOut(hdc,x,y,lpString,cbString);

ReleaseDC(m_hwnd,hdc);

}

void CCustomGDI::Drawbox(PRECT prect, BORDER_STYLE bstyle, INNER_STYLE istyle)

{

HBRUSH hbr;

HDC hdc;

hdc=GetDC(m_hwnd);

RECT rect;

rect.top=prect->top;

rect.bottom=prect->bottom;

rect.left=prect->left;

rect.right=prect->right;

if(bstyle==BORDER_STYLE_FLAT)

{

//如果为BORDER_STYLE_FLAT

hbr=CreateSolidBrush(m_bordercolor);

FrameRect(hdc, &rect, hbr); //这里不知道如何画线,呵呵。

DeleteObject(hbr);

rect.left+=m_bordersize;

rect.right-=m_bordersize;

rect.top+=m_bordersize;

rect.bottom-=m_bordersize;

}

if(istyle==INNER_STYLE_SOLID) {

hbr=CreateSolidBrush(m_color);

FillRect(hdc, &rect, hbr);

DeleteObject(hbr);

}

ReleaseDC(m_hwnd,hdc);

}

void CCustomGDI::Drawbox(int x, int y, int height, int width, BORDER_STYLE bstyle, INNER_STYLE istyle)

{

RECT rect;

rect.top=y;

rect.left=x;

rect.bottom=y+height-1;

rect.right=x+width-1;

Drawbox(&rect,bstyle,istyle);

}

void CCustomGDI::DrawPic(int x, int y, int height, int width, const char* file)

{

}

void CCustomGDI::DrawPic(PRECT prect, const char* file)

{

}

void CCustomGDI::Clear(void)

{

//清除屏幕

RECT rect;

GetClientRect(m_hwnd,&rect);

Clear(&rect, m_background);

}

void CCustomGDI::Clear(PRECT prect)

{

Clear(prect, m_background);

}

void CCustomGDI::Clear(GDI_COLOR color)

{

RECT rect;

GetClientRect(m_hwnd,&rect);

Clear(&rect, color);

}

void CCustomGDI::Clear(PRECT prect, GDI_COLOR color)

{

HDC hdc;

hdc=GetDC(m_hwnd);

HBRUSH hbr=CreateSolidBrush(color);

FillRect(hdc, prect, hbr);

DeleteObject(hbr);

ReleaseDC(m_hwnd,hdc);

}

void CCustomGDI::Clear(int x, int y, int height, int width, GDI_COLOR color)

{

RECT rect;

rect.left=x;

rect.top=y;

rect.right=x+height-1;

rect.bottom=y+width-1;

Clear(&rect,color);

}

void CCustomGDI::SetBkColor(GDI_COLOR color)

{

m_background=color;

}

void CCustomGDI::SetColor(GDI_COLOR color)

{

m_color=color;

}

void CCustomGDI::Set3DColor(GDI_COLOR ul_color, GDI_COLOR rb_color)

{

}

void CCustomGDI::SetBorderSize(int size)

{

}

void CCustomGDI::SetBorderColor(GDI_COLOR color)

{

}

//--------------------------------------------------------------------------------------------------

//Els.h

//-------------------------------------------------------------------------------------------------

#include <windows.h>

//#include <d3d9.h>

#include <stdio.h>

#include <direct.h>

#include <time.h>

#include "Block.h"

#include "CustomGDI.h"

#define PLAYAREA_HEIGHT 24

#define PLAYAREA_WIDTH 12

#define PLAYAREA_EMPTY_COLOR RGB(0,0,0)

#define IDT_PLAY 2005

#define GAME_STATUS_STOPPED 0

#define GAME_STATUS_RUNNING 1

#define GAME_STATUS_PAUSED -1

#define PLAYER_DEFAULT_NAME "<Player>"

#define PLAYER_MAX_LEVEL 12

#define PLAYER_MAX_SCORE 999999999

struct _PLAYER

{

char Name[50];

int Power; //爆了几次

int Score; //得分,最大为999999999

};

struct _ELSSYS

{

int Level; //当前游戏级别

int ClientHeight; //当前客户区域高度

int ClientWidth; //当前客户区域宽度

int PlayAreaX; //游戏区域X坐标(注意:不包含游戏区域外的边框等)

int PlayAreaY; //游戏区域Y坐标(注意:不包含游戏区域外的边框等)

int SingleHeight; //单个格的高度

int SingleWidth; //单个格的宽度

int BorderSize; //边框大小

int Spacing; //格与格之间的间隔

int NextX; //下一个方块显示区域的X坐标

int NextY; //下一个方块显示区域的Y坐标

bool IsNextShown; //下一个方块是否显示

};

typedef _PLAYER PLAYER;

typedef _ELSSYS EVIRONMENT;

//---------------------------------------------------------------------------------------------------

//Els.cpp

//---------------------------------------------------------------------------------------------------

#include "Els.h"

//Direct3D Object

//LPDIRECT3D9 g_pD3D = NULL;

//Direct3D Device

//LPDIRECT3DDEVICE9 g_pd3dDevice = NULL;

//窗体的HWND

HWND g_hwnd;

int g_Status=GAME_STATUS_STOPPED; //存储游戏的状态

//当前的时间间隔

//int g_Interval=1000;

//游戏区域,存放每个格的颜色值,如果为0,表示当前格没有占用,否则已占用。

GDI_COLOR g_PlayArea[PLAYAREA_HEIGHT][PLAYAREA_WIDTH];

//当前行、列

int g_CurRow=0;

int g_CurCol=0;

//当前方块的索引

int g_CurBlock;

//当前方块的颜色

GDI_COLOR g_CurBlockColor;

//下一个方块的索引

int g_NextBlock;

GDI_COLOR g_NextBlockColor;

//存放所有的方块

BLOCK* Blocks=NULL;

//方块的个数

int g_BlockCount=0;

//当前级别

int g_Level=0;

int g_NextLevelPower=0;

int g_NextLevelScore=1000;

//环境信息

EVIRONMENT g_Env;

//用户的信息

PLAYER g_Player={"Player",0,0};

//声明自己的GDI对象

CCustomGDI* g_GDI;

//所有函数定义

extern void CaculateEnv(void); //计算界面环境信息

extern void Render(void); //绘制界面

extern HRESULT LoadBlocks(void); //载入方块

extern void ClearBlocks(void); //清除所有方块所占内存

extern void _Bottom(void); //方块置底后的处理过程

extern void Bottom(void); //方块置底的处理过程

extern void Down(void); //方块下落

extern void MapCurBlockToPlayArea(void); //把当前方块影射到游戏区域

//

//void ShowDebugMsg(const char* sMsg, int x=100, int y=100)

//{

// HDC hdc;

// hdc=GetDC(g_hwnd);

// TextOut(hdc,x,y, sMsg, (int)strlen(sMsg));

//}

//

//清除释放所有方块所占内存

void ClearBlocks()

{

if(Blocks!=NULL)

{

free(Blocks);

}

}

//从文件中调入所有的方块

HRESULT LoadBlocks()

{

int i;

FILE* fp;

char sPath[_MAX_PATH];

char Header[BLOCK_HEADER_SIZE];

//char sMsg[255];

if(Blocks!=NULL)

{

ClearBlocks();

}

_getcwd(sPath, _MAX_PATH); //这里不判断了

strcat(sPath, "\Turn.Right.blk");

fp=fopen(sPath, "rb");

if(fp==NULL) {

//存在错误。

return E_FAIL;

}

fread(Header,1,BLOCK_HEADER_SIZE,fp);

//这里不再判断这个文件是否正确了,同时没有判断版本信息。

//0-2字节为:BLK

//3-6字节为:版本信息

//7字节为方块个数。

g_BlockCount=(unsigned int)Header[BLOCK_HEADER_SIZE-1];

//然后申请g_BlockCount大小的方块数组

Blocks=(BLOCK *)malloc(sizeof(BLOCK)*g_BlockCount);

for(i=0;i<g_BlockCount;i++)

{

fread(&Blocks[i], sizeof(BLOCK), 1, fp);

//测试载入的小片段

//sprintf(sMsg, "ID:%d;Next:%d.",Blocks[i].ID,Blocks[i].NextID);

//ShowDebugMsg(sMsg, 0, 24*i);

//MessageBox(g_hwnd, sMsg, "test",MB_OK);

}

fclose(fp);

return S_OK;

}

//_Drawbox:

//在俄罗斯方块区域以颜色color绘制第r行,第c列的单元格方块。

void _Drawbox(int r, int c, GDI_COLOR color)

{

int x,y;

x=g_Env.PlayAreaX + g_Env.BorderSize + (c+1)*g_Env.Spacing + c*g_Env.SingleWidth;

y=g_Env.PlayAreaY + g_Env.BorderSize + (r+1)*g_Env.Spacing + r*g_Env.SingleHeight;

g_GDI->SetColor(color);

//g_GDI->Set3DColor(WHITE,BLACK);

if(color==PLAYAREA_EMPTY_COLOR)

{

g_GDI->Drawbox(x,y,g_Env.SingleHeight,g_Env.SingleWidth,BORDER_STYLE_NONE,INNER_STYLE_SOLID);

}

else

{

g_GDI->Drawbox(x,y,g_Env.SingleHeight,g_Env.SingleWidth,BORDER_STYLE_FLAT,INNER_STYLE_SOLID);

}

}

void HideCurBlock()

{

//清除屏幕上当前方块的显示

int row,col;

for(row=0;row<=Blocks[g_CurBlock].Height;row++)

{

if(g_CurRow+row<0) continue;

for(col=0;col<=Blocks[g_CurBlock].Width;col++)

{

if(((Blocks[g_CurBlock].Elements) & (1<<(row*(Blocks[g_CurBlock].Width+1)+col)))!=0)

{

_Drawbox(g_CurRow+row,g_CurCol+col,PLAYAREA_EMPTY_COLOR);

}

}

}

}

void ShowCurBlock()

{

//在屏幕上显示当前方块

int row,col;

for(row=0;row<=Blocks[g_CurBlock].Height;row++)

{

if(g_CurRow+row<0) continue;

for(col=0;col<=Blocks[g_CurBlock].Width;col++)

{

if(((Blocks[g_CurBlock].Elements) & (1<<(row*(Blocks[g_CurBlock].Width+1)+col)))!=0)

{

_Drawbox(g_CurRow+row,g_CurCol+col,g_CurBlockColor); //注意g_CurBlockColor值是否设置

}

}

}

//char s[200];

//sprintf(s,"Block:%d,%2x;SIZE:%d.",g_CurBlock, Blocks[g_CurBlock].Elements,sizeof(BLOCK));

//g_GDI->Drawbox(0,g_Env.ClientHeight-35,30,g_Env.ClientWidth*3/10-10,BORDER_STYLE_FLAT,INNER_STYLE_SOLID);

//g_GDI->TextOut(10,g_Env.ClientHeight-30,s,(int)strlen(s));

}

void ShowNextBlock()

{

//在下一个方块的显示框中显示下一个方块

int row,col;

int blkRow,blkCol;

blkRow=(3-Blocks[g_NextBlock].Height)/2;

blkCol=(3-Blocks[g_NextBlock].Width)/2;

g_GDI->SetColor(PLAYAREA_EMPTY_COLOR);

g_GDI->Drawbox(g_Env.NextX,g_Env.NextY,((g_Env.SingleHeight+g_Env.Spacing)<<2)+g_Env.Spacing+(g_Env.BorderSize<<1),((g_Env.SingleWidth+g_Env.Spacing)<<2)+g_Env.Spacing+(g_Env.BorderSize<<1),BORDER_STYLE_FLAT,INNER_STYLE_SOLID);

for(row=0;row<4;row++)

{

for(col=0;col<4;col++)

{

if(row>=blkRow && row<=blkRow+Blocks[g_NextBlock].Height && col>=blkCol && col<=blkCol+Blocks[g_NextBlock].Width)

{

if((Blocks[g_NextBlock].Elements & (1<<((row-blkRow)*(Blocks[g_NextBlock].Width+1)+(col-blkCol))))!=0)

{

g_GDI->SetColor(g_NextBlockColor);

g_GDI->Drawbox(g_Env.NextX+g_Env.BorderSize+g_Env.Spacing+(g_Env.SingleWidth+g_Env.Spacing)*col, g_Env.NextY+g_Env.BorderSize+g_Env.Spacing+(g_Env.SingleHeight+g_Env.Spacing)*row,g_Env.SingleHeight,g_Env.SingleWidth,BORDER_STYLE_FLAT,INNER_STYLE_SOLID);

continue;

}

}

g_GDI->SetColor(PLAYAREA_EMPTY_COLOR);

g_GDI->Drawbox(g_Env.NextX+g_Env.BorderSize+g_Env.Spacing+(g_Env.SingleWidth+g_Env.Spacing)*col, g_Env.NextY+g_Env.BorderSize+g_Env.Spacing+(g_Env.SingleHeight+g_Env.Spacing)*row,g_Env.SingleHeight,g_Env.SingleWidth,BORDER_STYLE_FLAT,INNER_STYLE_SOLID);

}

}

}

void ShowGameInfo()

{

char s[200];

//显示游戏数据信息

if(g_Status==GAME_STATUS_STOPPED)

{

strcpy(s,"Game Status: Stopped.");

}

if(g_Status==GAME_STATUS_RUNNING)

{

strcpy(s,"Game Status: Running.");

}

if(g_Status==GAME_STATUS_PAUSED)

{

strcpy(s,"GameStatus: Paused.");

}

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight-30," ",30);

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight-30,s,(int)strlen(s));

//用户得分、当前级别

sprintf(s,"Score: %d",g_Player.Score);

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2-50," ",30);

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2-50,s,(int)strlen(s));

sprintf(s,"Level: %d",g_Level);

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2-30," ",30);

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2-30,s,(int)strlen(s));

}

BOOL CanMoveDown()

{

int row,col;

if(Blocks==NULL) return FALSE;

if(g_BlockCount<=0) return FALSE;

if(g_CurBlock<0||g_CurBlock>=g_BlockCount) return FALSE;

//如果已经到达最下面一行,不能再向下移了。

if((g_CurRow+Blocks[g_CurBlock].Height+1)>=PLAYAREA_HEIGHT) return FALSE;

for(col=0;col<=Blocks[g_CurBlock].Width;col++)

{

for(row=Blocks[g_CurBlock].Height;row>=0;row--)

{

//找到最下的非空

if(((Blocks[g_CurBlock].Elements) & (1<<(row*(Blocks[g_CurBlock].Width+1)+col)))!=0)

{

//如果游戏区域的下一行相应位置不空,则也不能再向下移动了。

if(g_PlayArea[g_CurRow+row+1][g_CurCol+col]!=PLAYAREA_EMPTY_COLOR)

{

return FALSE;

}

}

}

}

return TRUE;

}

BOOL CanMoveLeft()

{

int row,col;

if(Blocks==NULL) return FALSE;

if(g_BlockCount<=0) return FALSE;

if(g_CurBlock<0||g_CurBlock>=g_BlockCount) return FALSE;

//如果已经到达最左一列,不能再左移了。

if(g_CurCol<=0) return FALSE;

for(row=0;row<=Blocks[g_CurBlock].Height;row++)

{

for(col=0;col<=Blocks[g_CurBlock].Width;col++)

{

//找到最左的非空

if(((Blocks[g_CurBlock].Elements) & (1<<(row*(Blocks[g_CurBlock].Width+1)+col)))!=0)

{

//如果游戏区域的左位置不空,则也不能再左移动了。

if(g_PlayArea[g_CurRow+row][g_CurCol+col-1]!=PLAYAREA_EMPTY_COLOR)

{

return FALSE;

}

}

}

}

return TRUE;

}

BOOL CanMoveRight()

{

if(Blocks==NULL) return FALSE;

if(g_BlockCount<=0) return FALSE;

if(g_CurBlock<0||g_CurBlock>=g_BlockCount) return FALSE;

//如果已经到达最右一列,不能再右移了。

if(g_CurCol+Blocks[g_CurBlock].Width+1>=PLAYAREA_WIDTH) return FALSE;

int row,col;

for(row=0;row<=Blocks[g_CurBlock].Height;row++)

{

for(col=Blocks[g_CurBlock].Width;col>=0;col--)

{

//找到最右的非空

if(((Blocks[g_CurBlock].Elements) & (1<<(row*(Blocks[g_CurBlock].Width+1)+col)))!=0)

{

//如果游戏区域的右位置不空,则也不能再右移动了。

if(g_PlayArea[g_CurRow+row][g_CurCol+col+1]!=PLAYAREA_EMPTY_COLOR)

{

return FALSE;

}

}

}

}

return TRUE;

}

BOOL CanTurn()

{

int row,col;

int ARow,ACol;

BLOCK* next;

if(Blocks==NULL) return FALSE;

if(g_BlockCount<=0) return FALSE;

if(g_CurBlock<0||g_CurBlock>=g_BlockCount) return FALSE;

if(Blocks[g_CurBlock].NextID<0||Blocks[g_CurBlock].NextID>=(unsigned int)g_BlockCount) return FALSE; //说明原数据文件有错误,需更正

next=&Blocks[Blocks[g_CurBlock].NextID];

//这里的OffsetY、OffsetX,应该是由当前Block提供。

ARow=g_CurRow + Blocks[g_CurBlock].OffsetY;

ACol=g_CurCol + Blocks[g_CurBlock].OffsetX;

//如果超过高度了,应该不允许变换了,要不,一直按变换键,可能就永远落不了地了。

if(ARow+next->Height+1>PLAYAREA_HEIGHT) return FALSE;

//如果列超出游戏区域,可以处理一下。

if(ACol<0) ACol=0;

if(ACol+next->Width+1>=PLAYAREA_WIDTH)

{

ACol=PLAYAREA_WIDTH-next->Width-1;

}

//实现CanTurn时,突然想到,当前方块所占的空,不要在g_PlayArea中记录

for(row=0;row<=next->Height;row++)

{

for(col=0;col<=next->Width;col++)

{

if(((next->Elements) & (1<<(row*next->Width+col+1)))!=0)

{

//如果下一个变换的相应位置非空的话

if(g_PlayArea[ARow+row][ACol+col]!=PLAYAREA_EMPTY_COLOR)

{

//如果游戏区域也非空

return FALSE;

}

}

}

}

return TRUE;

}

void _Turn()

{

g_CurRow = g_CurRow + Blocks[g_CurBlock].OffsetY;

g_CurCol = g_CurCol + Blocks[g_CurBlock].OffsetX;

g_CurBlock = Blocks[g_CurBlock].NextID;

//关于列的超范围值,变换应该同CanTurn中的算法相同。

if(g_CurCol<0) g_CurCol=0;

if(g_CurCol + Blocks[g_CurBlock].Width+1>=PLAYAREA_WIDTH)

{

g_CurCol = PLAYAREA_WIDTH-Blocks[g_CurBlock].Width-1;

}

//变换完毕

}

void Turn()

{

if(g_Status!=GAME_STATUS_RUNNING) return;

if(CanTurn()==TRUE)

{

HideCurBlock();

_Turn();

ShowCurBlock();

}

}

void _MoveLeft()

{

g_CurCol--;

}

void MoveLeft()

{

if(g_Status!=GAME_STATUS_RUNNING) return;

if(CanMoveLeft()==TRUE)

{

HideCurBlock();

_MoveLeft();

ShowCurBlock();

}

}

void _MoveRight()

{

g_CurCol++;

}

void MoveRight()

{

if(g_Status!=GAME_STATUS_RUNNING) return;

if(CanMoveRight()==TRUE)

{

HideCurBlock();

_MoveRight();

ShowCurBlock();

}

}

void _Down()

{

g_CurRow++;

}

void MapCurBlockToPlayArea()

{

int row,col;

row=0;

col=0;

for(row=0;row<=Blocks[g_CurBlock].Height;row++)

{

for(col=0;col<=Blocks[g_CurBlock].Width;col++)

{

if((Blocks[g_CurBlock].Elements & (1<<(row*(Blocks[g_CurBlock].Width+1)+col)))!=0)

{

g_PlayArea[g_CurRow+row][g_CurCol+col]=g_CurBlockColor;

}

}

}

}

void Gain()

{

int row,col;

int gain=0;

BOOL full; //当前行是否全部填满

for(row=0;row<=Blocks[g_CurBlock].Height;row++)

{

full=TRUE;

for(col=0;col<PLAYAREA_WIDTH;col++)

{

if(g_PlayArea[g_CurRow+row][col]==PLAYAREA_EMPTY_COLOR)

{

full=FALSE;

break;

}

}

if(full==TRUE)

{

//消当前行的动画效果

//消当前行

int tmpRow,tmpCol;

for(tmpRow=g_CurRow+row;tmpRow>0;tmpRow--)

{

for(tmpCol=0;tmpCol<PLAYAREA_WIDTH;tmpCol++)

{

g_PlayArea[tmpRow][tmpCol]=g_PlayArea[tmpRow-1][tmpCol];

_Drawbox(tmpRow,tmpCol,g_PlayArea[tmpRow][tmpCol]);

}

}

for(tmpCol=0;tmpCol<PLAYAREA_WIDTH;tmpCol++)

{

g_PlayArea[0][tmpCol]=PLAYAREA_EMPTY_COLOR;

_Drawbox(tmpRow,tmpCol,PLAYAREA_EMPTY_COLOR);

}

gain++;

}

}

//变更用户的相关情况

if(gain>0)

{

g_Player.Score+=(100*(gain*gain-gain+1)); //1:100;2:300;3:700;4:1300;

if(g_Player.Score>PLAYER_MAX_SCORE)

{

g_Player.Power++;

g_Player.Score %= (PLAYER_MAX_SCORE+1);

}

ShowGameInfo();

}

}

void UpdateSys()

{

//变更系统相关情况

if(g_Player.Power==g_NextLevelPower)

{

if(g_Player.Score>=g_NextLevelScore)

{

//变更级别

g_Level++;

g_Level %= PLAYER_MAX_LEVEL;

g_NextLevelScore+=(100*(g_Level*g_Level)+1000);

if(g_NextLevelScore>PLAYER_MAX_SCORE)

{

g_NextLevelPower++;

g_NextLevelScore%=(PLAYER_MAX_SCORE+1);

}

//变更系统速度

KillTimer(g_hwnd,IDT_PLAY);

SetTimer(g_hwnd, IDT_PLAY,1000/(g_Level+1),NULL);

}

}

}

BOOL NextBlock()

{

g_CurBlock=g_NextBlock;

g_CurBlockColor=g_NextBlockColor;

g_CurRow=0;

g_CurCol=(PLAYAREA_WIDTH-Blocks[g_CurBlock].Width)/2;

srand((unsigned)time(NULL));

g_NextBlock=rand()%g_BlockCount;

g_NextBlockColor=RGB((rand()%4)*64+63,(rand()%4)*64+63,(rand()%4)*64+63);

ShowNextBlock();

ShowCurBlock();

int row,col;

for(row=0;row<=Blocks[g_CurBlock].Height;row++)

{

for(col=0;col<=Blocks[g_CurBlock].Width;col++)

{

if((Blocks[g_CurBlock].Elements & (1<<(row*(Blocks[g_CurBlock].Width+1)+col)))!=0)

{

if(g_PlayArea[g_CurRow+row][g_CurCol+col]!=PLAYAREA_EMPTY_COLOR) //如果所在位置已经不为空则Game Over。

{

return FALSE;

}

}

}

}

return TRUE;

}

void Stop()

{

if(g_Status!=GAME_STATUS_RUNNING) return;

KillTimer(g_hwnd,IDT_PLAY);

g_Status=GAME_STATUS_STOPPED;

ShowGameInfo();

}

void Down()

{

if(g_Status!=GAME_STATUS_RUNNING) return;

//g_GDI->Drawbox(0,g_Env.ClientHeight,60,20,BORDER_STYLE_FLAT,INNER_STYLE_SOLID);

//g_GDI->TextOut(10, g_Env.ClientHeight-30,"Downning!",9);

if(CanMoveDown()==TRUE)

{

//BeginPaint(g_hwnd,NULL);

HideCurBlock();

_Down();

ShowCurBlock();

//ValidateRect(g_hwnd,NULL);

//UpdateWindow(g_hwnd);

}

else

{

_Bottom();

}

}

void _Bottom()

{

//把当前方块映射到游戏区域中

MapCurBlockToPlayArea();

//检查是否有可消行,变更用户得分

Gain();

//检查游戏级别是否需要提高

UpdateSys();

//设置当前方块为下一个方块,并重新产生一个下一方块

if(NextBlock()==FALSE)

{

//如果下一个方块顶死应该Game Over。

Stop(); //首先停止游戏。

//然后检查最高分,记录到排行榜。

}

ShowGameInfo();

}

void Bottom()

{

if(g_Status!=GAME_STATUS_RUNNING) return;

while(CanMoveDown()==TRUE)

{

HideCurBlock();

_Down();

ShowCurBlock();

}

_Bottom();

}

void Pause()

{

if(g_Status!=GAME_STATUS_RUNNING) return;

//clear timer.

KillTimer(g_hwnd, IDT_PLAY);

g_Status=GAME_STATUS_PAUSED;

ShowGameInfo();

}

//写到Resume,觉得应该引入一个变量,用来标识游戏是否已经开始,是否是继续游戏,而Start()只能算作重新从头开始。

void Resume()

{

if(g_Status!=GAME_STATUS_PAUSED) return;

SetTimer(g_hwnd, IDT_PLAY,1000/(g_Level+1),NULL);

g_Status=GAME_STATUS_RUNNING;

ShowGameInfo();

}

void Start()

{

if(g_Status!=GAME_STATUS_STOPPED) return;

int row,col;

for(row=0;row<PLAYAREA_HEIGHT;row++)

{

for(col=0;col<PLAYAREA_WIDTH;col++)

{

g_PlayArea[row][col]=PLAYAREA_EMPTY_COLOR;

}

}

//产生当前方块及下一个方块

srand((unsigned)time(NULL));

g_CurBlock=rand()%g_BlockCount;

g_CurBlockColor=RGB((rand()%4)*64+63,(rand()%4)*64+63,(rand()%4)*64+63);

g_NextBlock=rand()%g_BlockCount;

g_NextBlockColor=RGB((rand()%4)*64+63,(rand()%4)*64+63,(rand()%4)*64+63);

//决定当前方块的位置

g_CurRow=0;

g_CurCol=(PLAYAREA_WIDTH-Blocks[g_CurBlock].Width)/2;

//初始化系统信息

g_Level=0; //将来可以通过用户定制现在级别

g_NextLevelPower=0;

g_NextLevelScore=1000;

//初始化用户信息

strcpy(g_Player.Name, PLAYER_DEFAULT_NAME);

g_Player.Power=0;

g_Player.Score=0;

//然后开始游戏

Render(); //重新绘制界面

g_Status=GAME_STATUS_RUNNING;

SetTimer(g_hwnd, IDT_PLAY,(10-g_Level)*100,NULL);

ShowNextBlock();

ShowCurBlock();

ShowGameInfo();

}

void CaculateEnv()

{

RECT rect;

GetClientRect(g_hwnd, &rect); //得到当前窗口的大小

//更改环境变量

g_Env.ClientHeight=rect.bottom-rect.top+1;

g_Env.ClientWidth=rect.right-rect.left+1;

g_Env.BorderSize=3;

g_Env.Spacing=1;

g_Env.IsNextShown=true;

//得到各区域坐标

//游戏区域

g_Env.PlayAreaX=g_Env.ClientWidth*3/10+g_Env.BorderSize;

g_Env.PlayAreaY=g_Env.BorderSize;

g_Env.SingleHeight = (g_Env.ClientHeight-g_Env.PlayAreaY*2-g_Env.BorderSize*2-g_Env.Spacing)/PLAYAREA_HEIGHT-g_Env.Spacing;

g_Env.SingleWidth = (g_Env.ClientWidth - g_Env.PlayAreaX*2-g_Env.BorderSize*2-g_Env.Spacing)/PLAYAREA_WIDTH-g_Env.Spacing;

//下一个区域

g_Env.NextX = g_Env.ClientWidth*17/20-g_Env.BorderSize-g_Env.Spacing*5/2-g_Env.SingleWidth*2;

g_Env.NextY = g_Env.BorderSize*2;

//UpdateWindow(g_hwnd);

}

VOID Render()

{ //绘制整个界面

char s[200];

//清除所有

g_GDI->Clear(RGB(0x80,0x80,0x80));

//绘制图片

//g_GDI->DrawPic(g_Env.BorderSize*2,g_Env.BorderSize*2, g_Env.ClientWidth/5-g_Env.BorderSize*5,g_Env.ClientWidth/5-g_Env.BorderSize*5, "mydaughter.bmp");

//绘制Logo

//g_GDI->DrawPic(g_Env.BorderSize*2,rect.bottom-g_Env.BorderSize*2,100,100, "logo.bmp");

//绘制游戏区域

g_GDI->SetColor(0);

g_GDI->Drawbox(g_Env.PlayAreaX,g_Env.PlayAreaY,(g_Env.SingleHeight+g_Env.Spacing)*PLAYAREA_HEIGHT+g_Env.Spacing+g_Env.BorderSize*2,(g_Env.SingleWidth+g_Env.Spacing)*PLAYAREA_WIDTH+g_Env.Spacing+g_Env.BorderSize*2,BORDER_STYLE_FLAT,INNER_STYLE_SOLID);

int row,col;

for(row=0;row<PLAYAREA_HEIGHT;row++)

{

for(col=0;col<PLAYAREA_WIDTH;col++)

{

if(g_PlayArea[row][col]!=PLAYAREA_EMPTY_COLOR)

{

_Drawbox(row,col,g_PlayArea[row][col]);

}

}

}

//绘制当前方块

if(g_Status!=GAME_STATUS_STOPPED)

{

ShowNextBlock();

ShowCurBlock();

}

//绘制Next

//绘制各按钮

strcpy(s,"[Enter]: Start/Resume");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2,s,(int)strlen(s));

strcpy(s,"[Pause]: Pause");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2+20,s,(int)strlen(s));

strcpy(s,"↑: 翻转方块");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2+40,s,(int)strlen(s));

strcpy(s,"↓: 向下落一格");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2+60,s,(int)strlen(s));

strcpy(s,"←: 左移");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2+80,s,(int)strlen(s));

strcpy(s,"→: 右移");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2+100,s,(int)strlen(s));

strcpy(s,"[Space]: 置底");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2+120,s,(int)strlen(s));

strcpy(s,"[ESC]: Stop Game");

g_GDI->TextOut(g_Env.ClientWidth*3/4,g_Env.ClientHeight/2+140,s,(int)strlen(s));

//绘制当前状态

ShowGameInfo();

//以下为调试信息

//sprintf(s,"ClientWidth:%d",g_Env.ClientWidth);

//g_GDI->TextOut(0,0,s,(int)strlen(s));

//sprintf(s,"ClientHeight:%d",g_Env.ClientHeight);

//g_GDI->TextOut(0,20,s,(int)strlen(s));

//sprintf(s,"PlayAreaX:%d",g_Env.PlayAreaX);

//g_GDI->TextOut(0,40,s,(int)strlen(s));

//sprintf(s,"PlayAreaY:%d",g_Env.PlayAreaY);

//g_GDI->TextOut(0,60,s,(int)strlen(s));

//sprintf(s,"SingleHeight:%d",g_Env.SingleHeight);

//g_GDI->TextOut(0,80,s,(int)strlen(s));

//sprintf(s,"SingleWidth:%d",g_Env.SingleWidth);

//g_GDI->TextOut(0,100,s,(int)strlen(s));

}

LRESULT WINAPI MsgProc(HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)

{

switch(msg)

{

case WM_TIMER:

Down();

return 0;

case WM_DESTROY:

PostQuitMessage(0);

return 0;

case WM_ACTIVATE:

if(wParam==WA_INACTIVE)

{

Pause();

}

break;

case WM_SIZE:

if(wParam!=SIZE_MINIMIZED)

{

CaculateEnv();

if(wParam==SIZE_RESTORED)

{

Render();

}

//UpdateWindow(hWnd);

}

return 0;

case WM_PAINT:

Render();

ValidateRect(hWnd, NULL); //呵呵,目前还不能去掉该行

return 0;

//case WM_SYSKEYDOWN:

case WM_KEYDOWN:

switch(wParam)

{

case VK_UP:

Turn();

break;

case VK_DOWN:

Down();

break;

case VK_LEFT:

MoveLeft();

break;

case VK_RIGHT:

MoveRight();

break;

case VK_SPACE:

Bottom();

break;

case VK_RETURN:

if(g_Status==GAME_STATUS_PAUSED)

{

Resume();

}

else

{

Start();

}

break;

case VK_PAUSE:

Pause();

break;

//case VK_END:

case VK_ESCAPE:

Stop();

break;

}

}

return DefWindowProc(hWnd,msg,wParam,lParam);

}

//系统初始化

HRESULT Initialize()

{

//绑定当前窗口到自己的GDI

g_GDI=new CCustomGDI(g_hwnd);

if(SUCCEEDED(LoadBlocks()))

{

return S_OK;

}

return E_FAIL;

}

//释放系统资源

void Cleanup()

{

//释放方块资源

ClearBlocks();

//释放GDI

delete g_GDI;

}

int WINAPI WinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPSTR lpCmdLine,

int nCmdShow)

{

//创建窗体

WNDCLASS wndclass={0, MsgProc, 0L, 0L, hInstance, NULL,NULL,NULL,NULL,"Els"};

RegisterClass(&wndclass);

g_hwnd=CreateWindow("Els","Els v1.0.0.0",

WS_OVERLAPPEDWINDOW,100,100,640,480,GetDesktopWindow(),NULL,wndclass.hInstance,NULL);

//初始化

if(SUCCEEDED(Initialize()))

{

ShowWindow(g_hwnd,SW_SHOWDEFAULT);

UpdateWindow(g_hwnd);

//进入Window消息循环

MSG msg;

while(GetMessage(&msg,NULL,0,0))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

Cleanup();

UnregisterClass("Els", wndclass.hInstance);

return 0;

}

//--------------------------------------------------------------------------------------------------------

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有