EasyX 是针对 C++ 的图形库,可以帮助 C/C++ 初学者快速上手图形和游戏编程。通过查阅Easyx的官方文档我们可以很快速的上手并编写一些小游戏,如贪吃蛇、连连看等。本文章实现用C语言基于Easyx库,编写一个简单的连连看小游戏。

代码部分

先是一些头文件、宏定义等,方便后续修改游戏相关设置

#include<time.h>
#define MAP_SIZE 10 //每一行有多少张图片
#define IMG_SIZE 39 //每张图片的宽度
#define WIDTH (MAP_SIZE +2) * IMG_SIZE //窗口的宽度
#define ANIMAL_NUM 42 //图片的总个数int map[MAP_SIZE + 2][MAP_SIZE + 2];
int way[MAP_SIZE + 2][MAP_SIZE + 2];
IMAGE img_bk;
IMAGE img_Animal[ANIMAL_NUM][2];
struct Index
{int row;int col;
}begin = { 1, -1 }, end = { -1, -1 };
enum Cur
{BEGIN,END
};
int step = 0;
Cur state = BEGIN;

这部分是游戏初始化的函数

void gameInit()
{//设置随机数种子srand((unsigned)time(NULL));//用不同的数据表示不同的图片,每种图片来10个,一共需要10种图片for (int i = 1; i <= MAP_SIZE; i++){for (int k = 1; k <= MAP_SIZE; k++){map[i][k] = i; //10个i}}//加载图片loadimage(&img_bk,"./ref/bk.jpg",WIDTH+80,WIDTH+50);   //后两个参数用来调整背景图片的位置IMAGE animal;loadimage(&animal, "./ref/animal.bmp"); //bmp//如何切割图片SetWorkingImage(&animal);  //设置工作区for (int i = 0; i < ANIMAL_NUM; i++){for (int k = 0; k < 2; k++){getimage(&img_Animal[i][k], k * IMG_SIZE, i * IMG_SIZE, IMG_SIZE, IMG_SIZE);}}SetWorkingImage();  //恢复默认工作区//打乱数组排列,让图片也随机排列for (int i = 1; i <= MAP_SIZE; i++){for (int k = 1; k <= MAP_SIZE; k++){//随即找到两个游戏区域的下标位置,然后交换值 随机函数 rand()int x = rand() % MAP_SIZE + 1;int y=  rand() % MAP_SIZE + 1;int _swap = map[i][k];map[i][k] = map[x][y];map[x][y] = _swap;}}
}

我们使用一个二维数组来存储图片的位置信息,为了使每次运行程序时图片的排列方式不同,因此设置了一个随机数种子。

游戏图形的绘制

void gameDraw()
{putimage(0, 0, &img_bk);for (int i = 1; i <= MAP_SIZE; i++){for (int k = 1; k <= MAP_SIZE; k++){if (map[i][k] != 0){putimage(k * IMG_SIZE, i * IMG_SIZE, &img_Animal[map[i][k]][1], SRCAND);    //原图putimage(k * IMG_SIZE, i * IMG_SIZE, &img_Animal[map[i][k]][0], SRCPAINT);  //掩码图}}}
}

获取鼠标消息,获取点击的两个位置的下标

void mouseEvent()
{if (MouseHit()){MOUSEMSG msg = GetMouseMsg();//判断鼠标点击的位置(begin,end)if (msg.uMsg == WM_LBUTTONDOWN && state == BEGIN){//把鼠标的坐标转成对应的数组的下标begin.col = msg.x / IMG_SIZE;begin.row = msg.y / IMG_SIZE;end.col = -1;end.row = -1;state = END;  //改变状态}else if (msg.uMsg == WM_LBUTTONDOWN && state == END){end.col = msg.x / IMG_SIZE;end.row = msg.y / IMG_SIZE;state = BEGIN; //改变状态}if (msg.uMsg == WM_LBUTTONDOWN){printf("begin(%d,%d) end(%d,%d)\n", begin.col, begin.row, end.col, end.row);}}
}

判断某个位置是否有图片

bool isBlock(int row, int col)
{if (row < 0 || col < 0 || row >= MAP_SIZE + 2 || col >= MAP_SIZE + 2)return 1;return map[row][col] + way[row][col];
}

在控制台打印出二维数组(为了后续观察寻路器的运作)

void showMap()
{for (int i = 0; i < MAP_SIZE + 2; i++){for (int k = 0; k < MAP_SIZE + 2; k++){printf("%-2d ", map[i][k]);}printf("\n");}
}

判断鼠标点击的起点和终点是否一致

bool same(int begin_x, int begin_y, int end_x, int end_y)
{if (begin_x < 0 || begin_y < 0 || end_x < 0 || end_y < 0 || end_x >= MAP_SIZE + 2 || end_y >= MAP_SIZE + 2 || begin_x >= MAP_SIZE + 2 || begin_y >= MAP_SIZE + 2)return false;if (begin_x == end_x && begin_y == end_y)return true;return false;
}

判断是否满足消除条件

bool can_pass(int begin_x, int begin_y, int end_x, int end_y)
{if (state != BEGIN || begin_x < 0 || begin_y < 0 || end_x < 0 || end_y < 0 || end_x >= MAP_SIZE + 2 || end_y >= MAP_SIZE + 2 || begin_x >= MAP_SIZE + 2 || begin_y >= MAP_SIZE + 2)return false;if (begin_x == end_x && begin_y == end_y)return false;if (map[begin.row][begin.col] != map[end.row][end.col])return false;return true;
}

使用A*寻路算法进行递归寻路消除

bool can(int begin_x, int begin_y, int end_x, int end_y)
{printf("step:%d (%d,%d)->(%d,%d)\n", step, begin_x, begin_y, end_x, end_y);if (step++ > 2000) //当找路太多了return false;if (begin_x < 0 || begin_y < 0 || end_x < 0 || end_y < 0 || end_x >= MAP_SIZE + 2 || end_y >= MAP_SIZE + 2 || begin_x >= MAP_SIZE + 2 || begin_y >= MAP_SIZE + 2)return false;if (same(begin_x, begin_y, end_x, end_y) || same(begin_x - 1, begin_y, end_x, end_y) || same(begin_x + 1, begin_y, end_x, end_y) || same(begin_x, begin_y - 1, end_x, end_y) || same(begin_x, begin_y + 1, end_x, end_y))return true;if (!isBlock(begin_x - 1, begin_y)) //1{way[begin_x - 1][begin_y] = 1;if (can(begin_x - 1, begin_y, end_x, end_y))return true;way[begin_x - 1][begin_y] = 0;}if (!isBlock(begin_x, begin_y - 1)) //3{way[begin_x][begin_y - 1] = 1;if (can(begin_x, begin_y - 1, end_x, end_y))return true;way[begin_x][begin_y - 1] = 0;}if (!isBlock(begin_x + 1, begin_y)) //2{way[begin_x + 1][begin_y] = 1;if (can(begin_x + 1, begin_y, end_x, end_y))return true;way[begin_x + 1][begin_y] = 0;}if (!isBlock(begin_x, begin_y + 1)) //4{way[begin_x][begin_y + 1] = 1;if (can(begin_x, begin_y + 1, end_x, end_y))return true;way[begin_x][begin_y + 1] = 0;}return false;
}

主函数部分

int main()
{//首先需要我们自己创建一个图形窗口initgraph(WIDTH, WIDTH, SHOWCONSOLE);gameInit();showMap();while (1){//开始双缓冲绘图BeginBatchDraw();gameDraw();//结束双缓冲绘图EndBatchDraw();if (can_pass(begin.row, begin.col, end.row, end.col)){memset(way, 0, sizeof(way));way[begin.row][begin.col] = 1;step = 0;printf("inininininin");if (can(begin.row, begin.col, end.row, end.col)){map[begin.row][begin.col] = 0;map[end.row][end.col] = 0;begin.row = -1;begin.col = -1;end.row = -1;end.col = -1;}}mouseEvent();}getchar();return 0;
}

使用双缓冲绘图防止闪烁

运行结果

(背景图片和连连看内容图片可以自行更换,这里背景我随便放了一张球星照片,注意连连看图片要同时制作其掩码图以实现透明效果)

C语言:基于Easyx库实现连连看小游戏相关推荐

  1. c语言基于easyx库的 飞机大战游戏(鼠标控制飞机移动,武器升级,boss发射散弹,boss血条等功能)

    课设题目 实现功能: 飞机鼠标控制–飞机武器升级–敌机发射子弹–boss发射散弹–boss血条记录–我方多条生命 图片资源和源码在下面 链接:https://pan.baidu.com/s/1uTQV ...

  2. 【精选】基于EasyX的贪吃蛇小游戏

    文章目录 前言 一.项目环境 1.Visual Studio 2019 2.EasyX 20200902 二.运行效果展示 0.加载游戏 1.主菜单 2.游戏设置 3.游戏说明 4.生存模式 5.无尽 ...

  3. 基于easyX的颜色侵略小游戏

    是挺久以前做的一个东西,突然想到放上来分享一下俺的拙作,纯原创. 利用二维数组对齐进行划分,并讲状态分为被侵略与未被侵略两种状态来记录. 在旧版的easyX可以运行. 源码及exe下载 头文件: 1  ...

  4. 【Python黑科技】tkinter库实战“连连看”小游戏(保姆级图文+实现代码)

    目录 实现效果 实现思路 实现代码 总结 欢迎关注 『Python黑科技』 系列,持续更新中 欢迎关注 『Python黑科技』 系列,持续更新中 实现效果 实现思路 链接: https://pan.b ...

  5. 【基于Swing+Java的连连看小游戏的设计与实现(效果+源代码+论文 获取~~)】

    快速阅读目录 (一)效果 (1)初始化游戏 (2)游戏过程(静态截图) (3)动态游戏 示例: (二)源代码示例 (三)说明 (一)效果 (1)初始化游戏 (2)游戏过程(静态截图) 选择游戏难度:

  6. C/C++基于easyX库实现三星环绕小项目(C/C++)

    1,项目描述 功能1:使用图形化的方式描述地球围绕着太阳转动,月球围绕着地球转动 功能2:在转动的过程中当用户按下1,2,3,4,5,6,7时它可以变换出7种不同的颜色,当用户按下8时它可以变换从1- ...

  7. 基于easyx库的GUI扫雷项目

    基于easyx库的GUI扫雷项目 文章目录 基于easyx库的GUI扫雷项目 0.观前提醒 1.扫雷游戏项目效果展示 2.扫雷游戏项目基本信息 3.扫雷游戏项目设计思路 4.扫雷游戏实现原理 4.1 ...

  8. MacOS下使用C语言基于openssl库进行RSA加密解密

    MacOS下使用C语言基于openssl库进行RSA加密解密 1 安装openssl并生成密钥 首先当然要安装openssl(这里记得看一下安装路径,应该是/usr/local/Cellar/open ...

  9. 基于QT实现简单的连连看小游戏

    资源下载地址:https://download.csdn.net/download/sheziqiong/85788216 资源下载地址:https://download.csdn.net/downl ...

  10. html游戏代码_JS实现连连看小游戏,代码很简单,思路很清晰!

    前言:这是web前端源码交流QQ群:828036770领取素材资料开发工具和听课权限!每日仅限300名!!! 这是一款比较经典的连连看游戏源码,规则比较简单,基于html5实现的连连看网页游戏.游戏目 ...

最新文章

  1. 一文读懂机器学习“数据中毒”
  2. 探究oracle clob字段是怎样存储的
  3. python参数_python 参数
  4. 美国Thinkfun的“编程三剑客”少儿编程从入门到精通
  5. c++ 二维数组 排序_漫画:“排序算法” 大总结
  6. python函数和类的区别_Python中类中的方法还有区别?
  7. php中如何配置环境变量,如何配置phpstorm环境变量如何配置phpstorm环境变量
  8. 标题决胜武器:标题常用的14个套路
  9. php源码 乱码 通达oa_PHPOA源码中小企业OA办公系统流程ERP CRM HR微信钉钉泛微通达oa...
  10. 飞机航线的获取、配准、制作与统计距离
  11. 电子电路学习笔记(7)——LED发光二极管限流电阻计算
  12. 1.3.1 计算机的主要性能指标 (机器字长、数据通路带宽、主存容量、运算速度、吞吐量、响应时间、主频和时钟周期、CPI、CPU执行时间、MIPS、MFLOPS、GFLOPS、TFLOPS)
  13. 广东又将添新高校:香山大学来了
  14. Dyna中建立预紧力螺栓的两种方法
  15. AVCaptureDevice中通过调用VideoZoomFactor方法调整焦距实现拉近拉远镜头进行拍照录制视频(动画缩放画面,不闪屏)
  16. 深度学习机器学习面试问题准备
  17. 零基础数据挖掘入门系列(三) - 数据清洗和转换技巧
  18. 易语言写64位魔兽世界游戏 寻路call 教程
  19. 【ML】欠拟合(underfitting)和 过拟合(overfitting)实践(基于sklearn)
  20. CSDN网站勋章获取介绍

热门文章

  1. Leetcode804.Unique Morse Code Words唯一摩尔斯密码词
  2. Lunix git stash clear 或者 git stash drop后恢复的方法
  3. IOS客户端Coding项目记录导航
  4. Linux_数据段、代码段、堆栈段、BSS段的区别
  5. 分享一段飞天R502读卡器的JAVA读卡代码
  6. SpringCloud Alibaba之Nacos组件
  7. python中dir函数的作用_【Python】Python内置函数dir详解
  8. python卡尔曼滤波_卡尔曼滤波+单目标追踪+python-opencv
  9. css小球落地阴影,CSS3球体掉落动画带阴影效果
  10. MFC OpenCasCade – 实现View中的实体对象与右边属性窗口的关联