运用c++与easyx图形库实现消灭星星最基本的消除功能、掉落功能以及判断死锁的方式

写在前面的话

此程序只实现了游戏的小部分内容,没有华丽的外观与消除特效

消灭星星是一款前些年十分流行的手机游戏,玩法简单却非常容易让人上瘾。

《消灭星星》是由Brian Baek公司开发的一款消除类休闲娱乐手机游戏,于2014年发行,游戏大小为3.8M。本作特点是易上手,点击两个或两个以上颜色相同的方块即可消除,没有时间限制。
                                                                                                                       ----百度百科

  1. 实现游戏的初始状态:

游戏的初始状态如图:

游戏关卡结束

再附上我们程序最终实现的效果

游戏的初始状态

游戏的关卡结束状态:

由图可知:游戏区域为一个10*10的正方形区域,区域中分布着红,紫,蓝,绿,黄5中颜色的方块。
我们可以简单的使用一个二维数组来存储每个不同颜色的方块,在初始化游戏是用以下代码来生成游戏的初始状态:

//准备工作
#define pointWidth 30  //每个方块的宽度//为了是二维数组和游戏界面上的小方块对应起来定义一个point结构体
typedef struct point {int x;  //点的横坐标int y; //点的纵坐标point() {};point(int _x, int _y) {x = _x;y = _y;}
}point;//绘制出方块,80和120是整个10*10区域在窗口中的位置,可视情况而改之
void drawPoint(point p, int color = GREEN) {setlinecolor(BLACK);setfillcolor(color);//+1,-1是的实际小正方形的边长为pointWidth-2int sx, sy, ex, ey;sx = 80 + pointWidth * p.x + 1;sy = 120 + pointWidth * p.y + 1;ex = sx + pointWidth - 1;ey = sy + pointWidth - 1;fillroundrect(sx, sy, ex, ey, 5, 5);
}
//定义二维数组
int item[10][10] = {0};
//方块的颜色,colors[0]是黑色(背景色),代表该处无方块(已被消除)
int colors[] = {BLACK,RED,YELLOW,BLUE,GREEN,RGB(128,0,128)};
srand(unsigned(clock()));
for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {item[i][j] = rand() % 5+ 1;}
}
//绘制游戏界面
void gameinterface() {point p;for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {p.x = i;p.y = j;drawPoint(p, colors[item[i][j]]);}}
}
  1. 方块的消除;
    我们可以通过下面代码获取鼠标点击的位置坐标,通过简单的计算得到对应二维数组中对应位置的存储的数字(颜色),从而进一步判断其能否被删除。
//将鼠标点击的坐标转换为二维数组的下标
m = GetMouseMsg();if (m.mkLButton&&m.x >= 80 && m.x < (80 + pointWidth * 10) && m.y >= 120 && m.y <= (120 + pointWidth * 10)) {cnt = 0;p.x = (m.x - 80) / pointWidth;p.y = (m.y - 120) / pointWidth;
//判断其能否被消除,当与被点击方块相邻(上、下、左、右,不包括对角)的方块中有与之相同颜色的方块时,该被点击方块可被消除
bool ifCanPop(point p) {for (int i = p.x - 1; i <= p.x + 1; i++) {for (int j = p.y - 1; j <= p.y + 1; j++) {if (item[i][j]!=0&&item[i][j] == item[p.x][p.y] && ((p.x == i && p.y != j) || (p.x != i && p.y == j))) {return true;}}}return false;
}
//方块的消除,将二维数组对应位置的值设为0;
void popstar(point p) {drawPoint(p, BLACK);item[p.x][p.y] = 0;
}

由于消除方块不单单是消除被点击的方块,连同与其相邻的同色方块都需要一并消除,我们可以使用队列,类似与图的广度优先搜索,先将第一个可以被消除的点入队列,再将队头的方块相邻且同色的方块压入队列,再pop对头的方块,直到队列为空时,说明消除完毕


if (item[p.x][p.y] != 0 && ifCanPop(p)) {a.push(p);//放入第一个可消除的方块while (!a.empty()) {point temp = a.front();//取的队头元素,下面的两层循环就是找与之相邻且同色的方块,并入队列for (int i = temp.x - 1; i <= (temp.x + 1) && i < 10; i++) {for (int j = temp.y - 1; j <= (temp.y + 1) && j < 10; j++) {//判断item[i][j]!=0避免重复访问if (item[i][j] != 0 && item[i][j] == item[temp.x][temp.y] && ((temp.x == i && temp.y != j) || (temp.x != i && temp.y == j))) {point pp(i, j);a.push(pp);}}}a.pop();弹出队头元素popstar(temp);//消除对头对应位置的方块cnt++;//记录消除的个数,方便计算得分}
  1. 方块的掉落与左移;
//当方块下方为空时,方块位置下移
void down() {for (int i = 0; i < 10; i++) {int d = 0;for (int j = 9; j >= 0; j--) {if (item[i][j] == 0)d++;elseitem[i][j + d] = item[i][j];}for (int k = 0; k < d; k++) {item[i][k] = 0;}}
}//当有一列中的小方块均为空时,右边不为空的方块左移
void left() {bool isBlankCol;int count = 0;for (int i = 0; i < 10; i++) {isBlankCol = true;for (int j = 0; j < 10; j++) {if (item[i][j] != 0)isBlankCol = false;}if (isBlankCol) { count++; }else {for (int jj = 0; jj < 10; jj++) {item[i - count][jj] = item[i][jj];}}}for (int k = 10 - count; k < 10; k++) {for (int j = 0; j < 10; j++) {item[k][j] = 0;}}
}
  1. 判断死锁(没有可以消除的方块了);

简单思考可知,我们只需间隔的判断小方格是否可以被消除就可以判断所有的方块是否存在可以被消除的方块。

bool isDeadlock() {for (int i = 0; i < 10; i++) {for (int j = i % 2; j < 10; j += 2) {point p(i, j);if (ifCanPop(p)) return false;}}return true;
}

6.所有代码(包括一些没有说明的代码)

#include<iostream>
#include<graphics.h>
#include<conio.h>
#include<time.h>
#include<queue>
using namespace std;#define pointWidth 30int item[10][10] = {0};
int colors[] = {BLACK,RED,YELLOW,BLUE,GREEN,RGB(128,0,128)};
int score;
IMAGE startbkimage;
//定义结构体点   这个点为游戏地图上的点,并非像素点
typedef struct point {int x;  //点的横坐标int y; //点的纵坐标point() {};point(int _x, int _y) {x = _x;y = _y;}
}point;void drawPoint(point p, int color = GREEN) {setlinecolor(BLACK);setfillcolor(color);int sx, sy, ex, ey;sx = 80 + pointWidth * p.x + 1;sy = 120 + pointWidth * p.y + 1;ex = sx + pointWidth - 1;ey = sy + pointWidth - 1;fillroundrect(sx, sy, ex, ey, 5, 5);
}void initgame() {score = 0;srand(unsigned(clock()));for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {item[i][j] = rand() % 5+ 1;}}
}void startinterface(){putimage(0, 0, &startbkimage);MOUSEMSG m;while (1) {m = GetMouseMsg();if (m.mkLButton)break;}}void gameinterface() {point p;for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {p.x = i;p.y = j;drawPoint(p, colors[item[i][j]]);}}
}bool ifCanPop(point p) {for (int i = p.x - 1; i <= p.x + 1; i++) {for (int j = p.y - 1; j <= p.y + 1; j++) {if (item[i][j]!=0&&item[i][j] == item[p.x][p.y] && ((p.x == i && p.y != j) || (p.x != i && p.y == j))) {return true;}}}return false;
}//更新分数,cnt为每次消除的个数
void updateScore(int cnt) {score += (cnt*cnt * 5);_TCHAR S[20];_stprintf_s(S,L"%d",score);settextstyle(40, 0, 0);outtextxy(400,600,S);
}
bool isDeadlock() {for (int i = 0; i < 10; i++) {for (int j = i % 2; j < 10; j += 2) {point p(i, j);if (ifCanPop(p)) return false;}}return true;
}
void game(){initgraph(480, 720);startinterface();
}void popstar(point p) {drawPoint(p, BLACK);item[p.x][p.y] = 0;
}void left() {bool isBlankCol;int count = 0;for (int i = 0; i < 10; i++) {isBlankCol = true;for (int j = 0; j < 10; j++) {if (item[i][j] != 0)isBlankCol = false;}if (isBlankCol) { count++; }else {for (int jj = 0; jj < 10; jj++) {item[i - count][jj] = item[i][jj];}}}for (int k = 10 - count; k < 10; k++) {for (int j = 0; j < 10; j++) {item[k][j] = 0;}}
}
void down() {for (int i = 0; i < 10; i++) {int d = 0;for (int j = 9; j >= 0; j--) {if (item[i][j] == 0)d++;elseitem[i][j + d] = item[i][j];}for (int k = 0; k < d; k++) {item[i][k] = 0;}}
}void play() {MOUSEMSG m;queue<point> a;point p;int cnt;              //用于记录每次消除方块的个数,由此计算得分while (true){m = GetMouseMsg();if (m.mkLButton&&m.x >= 80 && m.x < (80 + pointWidth * 10) && m.y >= 120 && m.y <= (120 + pointWidth * 10)) {cnt = 0;p.x = (m.x - 80) / pointWidth;p.y = (m.y - 120) / pointWidth;if (item[p.x][p.y] != 0 && ifCanPop(p)) {a.push(p);while (!a.empty()) {point temp = a.front();for (int i = temp.x - 1; i <= (temp.x + 1) && i < 10; i++) {for (int j = temp.y - 1; j <= (temp.y + 1) && j < 10; j++) {if (item[i][j] != 0 && item[i][j] == item[temp.x][temp.y] && ((temp.x == i && temp.y != j) || (temp.x != i && temp.y == j))) {point pp(i, j);a.push(pp);}}}a.pop();popstar(temp);cnt++;}updateScore(cnt);down();left();gameinterface();if (isDeadlock()) {int leftStar = 0;for (int i = 0; i < 10; i++) {for (int j = 0; j < 10; j++) {if (item[i][j] != 0) leftStar++;}}if (leftStar <= 10)score = 2000 - leftStar * 5;updateScore(0);outtextxy(400, 700, _T("死锁"));}}}}
}int main(){initgame();initgraph(480, 720);startinterface();gameinterface();play();_getch();
}

相关推荐

  • 用c++和easyx图形库做一个低配版扫雷游戏
  • Easyx图形库+C++做一个贪吃蛇小游戏 数据结构课程设计

符加说明:本程序使用了简单好用的easyx图形库:可以Easyx官网中下载安装,且Easyx官网提供的文档详细的介绍了各种函数的用法,很容易上手。

运用c++与easyx图形库实现消灭星星最基本的消除功能、掉落功能以及判断死锁的方式相关推荐

  1. easyx图形库-----贴图技巧之双缓冲消除闪屏(BeginBatchDraw 与 EndBatchDraw)

    目录 前言: 案例1:作图时闪屏 案例2:贴图时闪屏 双缓冲解决闪屏问题 原理: 前言: 学了easyx图形库的朋友们都知道,我们可以在easyx图形库上面画出连续运动的图片,或者通过贴图的方式把每一 ...

  2. 消灭星星最大得分c语言算法,消灭星星分数算法简易分析

    1分数计算方法  >>>进入消灭星星专区 1.1 消除分数计算大家可能都注意到了,一次性消除同种相邻色块越多,本次分数越多.那么究竟多多少呢? 如左图可以看出,分数随着数目的增加而暴 ...

  3. 使用C语言+EasyX完成消灭星星游戏(2)

    使用C语言+EasyX完成消灭星星游戏(2) 上一篇简单介绍一下项目和创建游戏界面 本篇介绍如何达到消除方块的功能.具体思路,代码都有详细注释. 下一篇消除同色方块后其他方块的下落. #include ...

  4. 使用C语言+EasyX完成消灭星星游戏(1)

    使用C语言+EasyX完成消灭星星游戏(1) 给大家介绍一个自己做的消灭星星小游戏项目,主要是基于C语言+EasyX实现,我使用的是vs2017编写.项目实现登陆,注册,游戏基本的玩法等功能. 项目展 ...

  5. 使用C语言+EasyX完成消灭星星游戏(3)

    使用C语言+EasyX完成消灭星星游戏(3) 本篇介绍方块消除后,方块下落移动. #include<stdio.h> #include<graphics.h> #include ...

  6. 2021级C语言大作业 - 消灭星星

    分享21级同学大一上学期用C语言(及少量C++)实现的消灭星星游戏.由于同学们刚学了三个月的编程,实现还不够完善,工程代码.图片音乐素材可以从百度网盘下载: 链接:https://pan.baidu. ...

  7. Cocos2d JS 之消灭星星(九) 处理星星类之——移动和消灭星星

    1 /* 2 * 本层拥有处理星星的实例化以及对星星的操作 3 * 1/排列星星 4 * 2/移动和删除星星 5 */ 6 var GAMESTARLAYOUT; 7 var GameStarLayo ...

  8. 弟子规python编程游戏_《Python游戏趣味编程》 第11章 消灭星星

    知乎视频​www.zhihu.com 图书简介可以看这里: 童晶:<Python游戏趣味编程>新书上架了​zhuanlan.zhihu.com 消灭星星是一款非常容易上瘾的消除类游戏,只需 ...

  9. PopStar(消灭星星)游戏源代码下载、分析及跨平台移植---第四篇(关卡)

    背景: 本来打算把第三篇和第四篇合并都一起,但以前计划分开,就还是分来吧:一般的游戏涉及到关卡的话,一般都会建立一个数组来存放各种定义参数,消灭星星关卡比较容易,不需要建立数组,只有两个参数level ...

最新文章

  1. 序数是什么意思_序数与基数
  2. java虚拟机 函数表_java虚拟机的基本结构如图
  3. php yii2 路径问题,yii2常用路径获取
  4. Ansroid系统(262)---MTK安卓sim卡相关源码分析
  5. 使用ConcurrentLinkedQueue惨痛的教训
  6. 你的计算机usb管理策略,您的计算机已经实施了USB存储设备管理策略,系统发现你使用了USB存储设备,该设备已被阻止,如有疑问请与...
  7. Linux之Keepalived实现服务器集群高可用
  8. 计算机合计功能,Javascript自动求和,Javascript自动合计
  9. 以软件开发周期来说明不同的测试的使用情况
  10. android ResideMenu使用
  11. andriod搭建自己的轮询框架
  12. 伍德里奇计量经济学第六版第七章计算机答案,伍德里奇计量经济学第六版答案Appendix-E...
  13. 修了一天的kali外置网卡,重装了n遍系统后..
  14. 胡阳pyhton作业题--20150725
  15. 汽车侧向动力学模型简介(动力学建模入门知识)
  16. ZOJ 1655 Transport Goods
  17. Java毕业设计-外卖点餐管理系统
  18. 齐次Markov链的遍历性判定
  19. 【QTdesigner】课时52.绘制各种图形(paintEevnt()))【pyqt5+QTdesigner模式】
  20. python数字推盘游戏怎么显示步数_Python游戏开发:数字华容道

热门文章

  1. 【DIY】基于OpenMV的STM32追球小车
  2. 光伏风电混合并网系统simulink仿真模型 有光伏发电系统、风力发电系统、负载
  3. 【集思广益】关于手机3D APP
  4. 【手写 Vue2.x 源码】第二十二篇 - dep 和 watcher 关联
  5. 解密word找回打开密码
  6. 计算机工作原理可以概括,计算机工作流程
  7. http://show.ku6.com/app.html,恶意软件分析 URL链接扫描 免费在线病毒分析平台 | 魔盾安全分析...
  8. Ubutun搭建集群遇到的一些问题
  9. 20-1.系统启动和内核管理centos6(grub,chkconfig,proc,lsmod)
  10. Java爬虫更新mysql数据库(简单事例)