(part 1)用C/C++实现简单游戏开发:easyx实现"2048"

我花了两天学习EASYX图形库,想实现一个2048小游戏。接下来是我的实现步骤:

一、编译开发环境:Microsoft Visual Studio 以及其 windows控制台插件、easyx图形库插件

软件以及插件的安装,就不在此表述了,傻瓜式安装。

二、开始实现2048项目:

1.首先新建一个名为2048的windows控制台项目,其中包括一个pch.h头文件和一个2048.cpp源文件

2.设计分析:为了实现2048需要实现一些小的功能模块,也就是一些功能函数。(因为我最近在学C++所以就实现中主要运用了C++的知识,涉及到简单的继承、封装以及多态原理)就具体而言,需要 下列功能模块:

         a.一个游戏开始前的界面,包含一些游戏信息,如游戏名称,游戏完成设计时间,游戏作者等信息;

         b.一个游戏内的界面,包括游戏的4*4宫格、游戏得分等信息;

         c.宫格的数字变动的逻辑设计实现

         d.宫格的数字显示在游戏内界面的模块(此条可以与 b. 一同实现)

         e.游戏的终点设计,即所有数字无法移动合并就表示游戏结束,显示游戏结束的相关信息。

3.代码实现:

         (1).首先实现游戏开始前的界面:

                    分别在头文件和源文件中添加新建一个Game.h和Game,cpp文件,Game.h用来写实现的类的代码,Game.cpp用来写类中成员函数的定义的代码。(新手注意,开始写任何源文件之前,都要加上#include“pch.h”,避免出错)。  接下来,就是Game.h的代码编写。在Game.h中定义一个Game类,用来实现游戏大部分的功能的集合,这里就包括需要用到宫格元素的矩阵内容,因为后面需要使用矩阵的一些类内成员函数,因此这里将Game类继承矩阵类Array比较方便,故先写矩阵类Array。同样建立一个Array.h和Array.cpp,在Array中编写矩阵类:

#pragma once

#ifndef ARRAY_H
#define ARRAY_H

struct point {/*点结构体,方便对矩阵元素位置进行分析与操作*/
	int i;
	int j;
};

class Array {
private:
	int array[4][4];/*4阶矩阵用这个二维数组表示*/
public :
	Array();/*构造函数*/
	~Array() {};/*析构函数*/
	void TestShowArray();/*打印矩阵*/
	int CreatNewElem();/*创造随机2048数:2或4*/
	bool IfNullElem(point *p);
	/*是否存在非0实数已经占据该位置,存在则返回false,否则返回true*/
	point* CreateNewLocate();/*生成新的随机点*/
	void SetNewPoint();/*将随机点设置新数*/
	bool IfFullArray();/*是否为满矩阵,即无法重叠和移动元素的矩阵*/
	int GetArray(int i,int j);/*取出下标为i,j的元素*/
};

#endif //ARRAY_H

接下来是对这个类中的函数成员进行定义,代码写在Array.cpp中:

#include "pch.h"
#include "Array.h"//指明定义所指
#include <iostream>
#include <stdlib.h>
#include <ctime>
using namespace std;

Array::Array()/*构造函数,将4阶矩阵所有元素都初始化为0*/
{
	int i, j;
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
			array[i][j] = 0;
	}
}

void Array::TestShowArray()/*用于测试的输出函数,观察矩阵内部元素的值*/
{
	int i, j;
	SetNewPoint();
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
			cout << array[i][j] << "\t";
		cout << "\n";
	}
}

int Array::CreatNewElem()/*创建新的元素值:2或者4*/
{
	int *r = new int();
	return (int)r%2 == 0 ? 2 : 4;
}

bool Array::IfNullElem(point *p)/*判断点p所指的位置是否有非零元素*/
{
	return array[p->i][p->j] ? false : true;
}
/*一维随机数转换二位随机点*/
point * Array::CreateNewLocate()
{
	point *x = new point();
	x->i = 1;
	x->j = 1;
	while (!IfNullElem(x)){
		int rL;
		srand(time(NULL));
		rL = rand() % 16;
		x->j = rL % 4;
		x->i = (rL - x->j) / 4;
	}
	return x;
}

void Array::SetNewPoint()/*创建一个位置点,包含了位置的横纵坐标*/
{
	int NewEle;
	point *p;
	NewEle = CreatNewElem();
	p = CreateNewLocate();
	array[p->i][p->j] = NewEle;
}

bool Array::IfFullArray()/*判断矩阵是否已经达到饱和,即无法继续下去*/
{
	int i, j;
	for (i = 0; i < 4; i++)
	{
		for (j = 0; j < 4; j++)
		{
			if(array[i][j])
				return false;
			if ((j <= 2 && array[i][j] == array[i][j + 1]) ||
				(j >= 1 && array[i][j] == array[i][j - 1]) ||
				(i <= 2 && array[i][j] == array[i + 1][j]) ||
				(i >= 1 && array[i][j] == array[i - 1][j]))
				return false;
		}
	}
	return true;
}

int Array::GetArray(int i, int j)/*获取位置i,j的元素值*/
{
	return array[i][j];
}

接下来就可以测试当前的所有代码是否有一个好的效果,在主函数中:

#include "pch.h"
#include "Array.h"
#include <iostream>
using namespace std;

int main(){
    Array ar;
    ar.TestShowArray();
    return 0;
}

现在就可以进行运行了,结果会显示如下:

其中有一个随机生成的数 2 。

这样,第一小部分就完成了。下一部分会通过类的继承实现Game类,并设计游戏界面,如下:(我设计的比较简陋)

写的很简陋(不好看),毕竟我也是新手,相信慢慢会变强的。下次有时间我会补上后面的实现。

  • 2
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
好的,下面我给你讲一下如何使用EASYX库设计井字棋游戏的思路。 首先,我们需要在程序中引入EASYX库,然后通过 `initgraph` 函数初始化窗口。接着,我们需要设计界面,可以使用 `rectangle` 函数绘制出棋盘和棋子。其中,棋盘可以用一个 3x3 的矩形数组来表示,每个矩形代表一个棋子的位置,初始时可以将数组中的值全部设为 0。 然后,我们需要设计游戏逻辑。每当玩家点击某个位置时,程序需要判断该位置是否已经被占据。如果已经被占据,则提示玩家重新选择;否则,将该位置设置为当前玩家的棋子(可以用 1 表示玩家 1 的棋子,用 2 表示玩家 2 的棋子),然后判断是否满足胜利条件(即同一行、同一列或同一对角线上有三个相同的棋子)。如果满足胜利条件,则游戏结束,否则交换玩家并进入下一轮。 最后,我们需要在程序中加入音效和背景音乐,可以使用 `mciSendString` 函数来实现。 下面是一份简单的代码示例,帮助你更好地理解上述思路: ```c #include <graphics.h> #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <windows.h> #include <mmsystem.h> #pragma comment(lib,"Winmm.lib") #define ROW 3 #define COL 3 int chessboard[ROW][COL] = {0}; // 棋盘数组 int player = 1; // 当前玩家 void drawChessboard() // 绘制棋盘 { for(int i = 0; i < ROW; i++) { for(int j = 0; j < COL; j++) { rectangle(j * 50 + 50, i * 50 + 50, j * 50 + 100, i * 50 + 100); } } } void drawChessman(int x, int y) // 绘制棋子 { if(chessboard[x][y] == 1) { setfillcolor(BLACK); fillellipse(y * 50 + 75, x * 50 + 75, 20, 20); } else if(chessboard[x][y] == 2) { setfillcolor(WHITE); fillellipse(y * 50 + 75, x * 50 + 75, 20, 20); } } int checkWin() // 判断胜利条件 { for(int i = 0; i < ROW; i++) { if(chessboard[i][0] == chessboard[i][1] && chessboard[i][1] == chessboard[i][2] && chessboard[i][0] != 0) { return chessboard[i][0]; } } for(int j = 0; j < COL; j++) { if(chessboard[0][j] == chessboard[1][j] && chessboard[1][j] == chessboard[2][j] && chessboard[0][j] != 0) { return chessboard[0][j]; } } if(chessboard[0][0] == chessboard[1][1] && chessboard[1][1] == chessboard[2][2] && chessboard[0][0] != 0) { return chessboard[0][0]; } if(chessboard[0][2] == chessboard[1][1] && chessboard[1][1] == chessboard[2][0] && chessboard[0][2] != 0) { return chessboard[0][2]; } return 0; } int main() { initgraph(400, 400); // 初始化窗口 drawChessboard(); // 绘制棋盘 PlaySound(TEXT("bgm.wav"), NULL, SND_FILENAME | SND_ASYNC | SND_LOOP); // 播放背景音乐 int x, y; while(1) { if(player == 1) { settextcolor(BLACK); outtextxy(250, 100, "Black's turn"); } else { settextcolor(WHITE); outtextxy(250, 100, "White's turn"); } if(kbhit()) // 判断是否有键盘输入 { int key = getch(); if(key == 27) // 按下 ESC 键退出游戏 { break; } else if(key == 32) // 按下空格键重新开始游戏 { cleardevice(); drawChessboard(); memset(chessboard, 0, sizeof(chessboard)); player = 1; continue; } x = (GetCursorPos().y - 50) / 50; y = (GetCursorPos().x - 50) / 50; if(x >= 0 && x < ROW && y >= 0 && y < COL && chessboard[x][y] == 0) // 判断是否是有效位置 { chessboard[x][y] = player; drawChessman(x, y); int result = checkWin(); if(result != 0) // 判断游戏是否结束 { if(result == 1) { settextcolor(BLACK); outtextxy(250, 200, "Black wins!"); } else { settextcolor(WHITE); outtextxy(250, 200, "White wins!"); } Sleep(1000); cleardevice(); drawChessboard(); memset(chessboard, 0, sizeof(chessboard)); player = 1; continue; } player = 3 - player; // 交换玩家 } } } closegraph(); // 关闭窗口 return 0; } ``` 上述代码仅供参考,你可以根据自己的需求进行修改和优化。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

尼卡尼卡尼

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值