📄 mainform.cpp
字号:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include <Registry.hpp>
#include <stdlib.h>
#include <MMSystem.h>
#include "Mainform.h"
#include "CustomizeForm.h"
#include "Hero.h"
#include "HeroName.h"
#include "About.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
/***************************************************************************/
#define _Index(X,Y,COL) ((Y)*(COL) + (X))
const char g_RegistryPath[] = "MyMine";
const char g_Lost_SoundPath[] = "resource\\GameLost.wav";
const char g_Win_SoundPath[] = "resource\\GameWin.wav";
const char g_Second_SoundPath[] = "resource\\Second.wav";
const char g_ChmFile_Path[] = "resource\\mine.chm";
const char g_SysHelpFile_Path[] = "resource\\SysHelp.chm";
TImage *Image_Block, *Image_Number, *Image_Face;
int Xpos,Ypos;
int GridCol,GridRow,BombCount,GameLevel = l_Easy;
bool isHaveColor = true, isHaveQuestionMark = true, isHaveSound = false;
int UsedTime,BlockOpenCount,LeftBombCount,CurrentFace;
int GameStatus = g_Waiting;
bool isLeftBtnDown, isRightBtnDown, isLeftAndRightBtnDown;
TPoint CurrentPosition;
struct {
int value;
int view;
int status;
}GridArray[g_MaxRow*g_MaxCol];
struct _hero hero[4];
/***************************************************************************/
void InitGridArray(int col,int row,int count, TPoint first)
{
for (int i=0; i<row*col; ++i)
{
GridArray[i].value = 0;
GridArray[i].view = b_Blank;
GridArray[i].status = s_Default;
}
GridArray[first.y*col + first.x].value = -1;
for (int i=0; i<count; ++i)
{
int pos;
do {
pos = random(row*col);
} while (GridArray[pos].value == -1);
GridArray[pos].value = -1;
}
GridArray[first.y*col + first.x].value = 0;
for (int i=0; i<col; ++i)
{
for (int j=0; j<row; ++j)
{
int & value = GridArray[_Index(i,j,col)].value;
int x, y;
if (value) continue;
for (int k=0; k<8; ++k)
{
x = i + DIR[k].x;
y = j + DIR[k].y;
if (x<0 || x>=col || y<0 || y>=row) continue;
if (GridArray[y*col + x].value == -1) GridArray[j*col + i].value += 1;
}
}
}
}
/***************************************************************************/
TPoint ChangePixelToBlock(TPoint pixel)
{
return Point(pixel.x / g_BlockWidth, pixel.y / g_BlockHeight);
}
/***************************************************************************/
void ReadRegister()
{
TRegistry *reg = new TRegistry();
reg->RootKey = HKEY_CURRENT_USER;
if ( !reg->OpenKey(g_RegistryPath, false) ) {
delete reg;
return;
}
try {
isHaveColor = reg->ReadBool("Color");
isHaveQuestionMark = reg->ReadBool("Mark");
isHaveSound = reg->ReadBool("Sound");
Xpos = reg->ReadInteger("Xpos");
Ypos = reg->ReadInteger("Ypos");
GridCol = reg->ReadInteger("Width");
GridRow = reg->ReadInteger("Height");
GameLevel = reg->ReadInteger("Difficulty");
BombCount = reg->ReadInteger("Mines");
hero[0].time = reg->ReadInteger("Time1");
hero[0].name = reg->ReadString("Name1");
hero[1].time = reg->ReadInteger("Time2");
hero[1].name = reg->ReadString("Name2");
hero[2].time = reg->ReadInteger("Time3");
hero[2].name = reg->ReadString("Name3");
hero[3].time = reg->ReadInteger("Time4");
hero[3].name = reg->ReadString("Name4");
}
catch(...)
{
delete reg;
reg = NULL;
}
delete reg;
}
/***************************************************************************/
void WriteRegister()
{
TRegistry *reg = new TRegistry();
reg->RootKey = HKEY_CURRENT_USER;
if ( !reg->KeyExists(g_RegistryPath) )
{
reg->CreateKey(g_RegistryPath);
}
if ( !reg->OpenKey(g_RegistryPath,false) )
{
delete reg;
return;
}
try {
reg->WriteBool("Color", isHaveColor);
reg->WriteBool("Sound", isHaveSound);
reg->WriteBool("Mark", isHaveQuestionMark);
reg->WriteInteger("Width", GridCol);
reg->WriteInteger("Height", GridRow);
reg->WriteInteger("Difficulty", GameLevel);
reg->WriteInteger("Mines", BombCount);
reg->WriteInteger("Xpos", Xpos);
reg->WriteInteger("Ypos", Ypos);
reg->WriteInteger("Time1", hero[0].time);
reg->WriteString("Name1", hero[0].name);
reg->WriteInteger("Time2", hero[1].time);
reg->WriteString("Name2", hero[1].name);
reg->WriteInteger("Time3", hero[2].time);
reg->WriteString("Name3", hero[2].name);
reg->WriteInteger("Time4", hero[3].time);
reg->WriteString("Name4", hero[3].name);
}
catch(...)
{
delete reg;
reg = NULL;
}
delete reg;
}
/***************************************************************************/
TMainWin *MainWin;
//###########################################################################
void TMainWin::SetGameLevel(int level, int col, int row, int count)
{
N_Level_Easy->Checked = false;
N_Level_Middle->Checked = false;
N_Level_Expert->Checked = false;
N_Level_Professional->Checked = false;
N_Level_Customize->Checked = false;
GameLevel = level;
BlockOpenCount = 0;
switch (level)
{
case l_Easy:
N_Level_Easy->Checked = true;
GridRow = g_Level_1_Row;
GridCol = g_Level_1_Col;
BombCount = g_Level_1_Count;
break;
case l_Middle:
N_Level_Middle->Checked = true;
GridRow = g_Level_2_Row;
GridCol = g_Level_2_Col;
BombCount = g_Level_2_Count;
break;
case l_Expert:
N_Level_Expert->Checked = true;
GridRow = g_Level_3_Row;
GridCol = g_Level_3_Col;
BombCount = g_Level_3_Count;
break;
case l_Professional:
N_Level_Professional->Checked = true;
GridRow = g_Level_4_Row;
GridCol = g_Level_4_Col;
BombCount = g_Level_4_Count;
break;
case l_Customize:
N_Level_Customize->Checked = true;
GridRow = row;
GridCol = col;
BombCount = count;
break;
default:
break;
}
SetControlSize(GridCol, GridRow);
LeftBombCount = BombCount;
CurrentFace = f_Smile;
DrawGame(GridCol, GridRow);
}
//###########################################################################
void TMainWin::SetControlSize(int col, int row)
{
Panel_Top->Top = 0;
Panel_Top->Left = 0;
Panel_Top->Width = col * g_BlockWidth + 16;
Panel_Top->Height = g_FaceHeight + 16 + 8;
Panel_Bottom->Left = 0;
Panel_Bottom->Top = Panel_Top->Top + Panel_Top->Height;
Panel_Bottom->Width = Panel_Top->Width;
Panel_Bottom->Height = row * g_BlockHeight + 16;
MainWin->Width = Panel_Top->Width + 6;
MainWin->Height = Panel_Bottom->Top + Panel_Bottom->Height + 52;
Panel_Left->Left = 10;
Panel_Left->Top = 12;
Panel_Right->Left = Panel_Top->Width - Panel_Right->Width - 10;
Panel_Right->Top = 12;
Image_Middle->Left = (Panel_Top->Width -Image_Middle->Width)/2;
Image_Middle->Top = 12;
}
//###########################################################################
void TMainWin::DrawNumber(TImage *image, int num)
{
int digit[4] = {0};
if (num < 0) digit[3] = -10;
num = abs(num);
for (int i=2; i>=0; --i)
{
digit[i] = num % 10;
num /= 10;
}
digit[0] += digit[3];
for (int i=0; i<3; i++)
{
if (digit[i]<10 && digit[i]>=0)
{
num = 11-digit[i];
}
else
{
num = 0;
}
image->Canvas->CopyRect(TRect(g_NumberWidth*i, 0, g_NumberWidth*(i+1), g_NumberHeight),
Image_Number->Canvas,
TRect(0, g_NumberHeight*num, g_NumberWidth, g_NumberHeight*(num+1)));
}
return;
}
//###########################################################################
void TMainWin::DrawBlock(int col,int row,int block)
{
if (block>15 || block<0) return;
Image_Main->Canvas->CopyRect(TRect(col*g_BlockWidth, row*g_BlockHeight, (col+1)*g_BlockWidth, (row+1)*g_BlockHeight),
Image_Block->Canvas,
TRect(0, block*g_BlockHeight, g_BlockWidth, (block+1)*g_BlockHeight));
}
//###########################################################################
void TMainWin::DrawGame(int col, int row)
{
DrawNumber(Image_Left,LeftBombCount);
DrawNumber(Image_Right,UsedTime);
ChangeFace(CurrentFace);
for (int j=0; j<row; ++j)
{
for (int i=0; i<col; i++)
{
DrawBlock(i,j,GridArray[_Index(i,j,col)].view);
}
}
}
//###########################################################################
void TMainWin::ChangeFace(int face)
{
if (CurrentFace != face) {
CurrentFace = face;
}
if (face>4 || face<0) return;
Image_Middle->Canvas->CopyRect(TRect(0, 0, g_FaceWidth, g_FaceHeight),
Image_Face->Canvas,
TRect(0, face*g_FaceHeight, g_FaceWidth, (face+1)*g_FaceHeight));
}
//###########################################################################
void TMainWin::SearchBlankBlock(int col, int row)
{
#define ARRAY_SIZE (g_MaxCol * g_MaxRow)
TPoint queue[ARRAY_SIZE] = {Point(0,0)};
int first=0,len=1;
queue[0] = Point(col,row);
for (;len > 0;)
{
int index; // GridArray index
TPoint point;
int x, y;
point = queue[first % ARRAY_SIZE];
--len; first = (first+1)%ARRAY_SIZE;
index = _Index(point.x,point.y,GridCol);
GridArray[index].view = b_Blank_Down;
if (GridArray[index].status != s_Opened) {
GridArray[index].status = s_Opened;
++BlockOpenCount;////////////////////
}
DrawBlock(point.x,point.y,b_Blank_Down);
for (int i=0; i<8; ++i)
{
x = point.x + DIR[i].x; y = point.y + DIR[i].y;
if (x<0 || x>=GridCol || y<0 || y>=GridRow) continue;
int j = _Index(x,y,GridCol);
if (GridArray[j].value == -1)
{
}
else if (GridArray[j].value==0)
{
if (GridArray[j].status==s_Default)
{
++len;
queue[(first+len-1)%ARRAY_SIZE] = Point(x,y);
GridArray[j].status = s_Listed;
}
}
else if (GridArray[j].view==b_Blank || GridArray[j].view==b_Blank_Down ||
GridArray[j].view==b_QuestionMark || GridArray[j].view==b_QuestionMark_Down )
{
GridArray[j].view = 15 - GridArray[j].value;
if (GridArray[j].status != s_Opened) {
GridArray[j].status = s_Opened;
++BlockOpenCount;///////////////////////////
}
DrawBlock(x,y,GridArray[j].view);
}
}
}
#undef ARRAY_SIZE
}
//###########################################################################
void TMainWin::GameLost()
{
if (isHaveSound) {
sndPlaySound(g_Lost_SoundPath, SND_ASYNC );
}
ChangeFace(f_Sad);
GameStatus = g_Gameover;
GameTimer->Enabled = false;
for (int i=0; i<GridCol; ++i)
{
for (int j=0; j<GridRow; ++j)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -