//#define SHOW_CONSOLE
#include <graphics.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
void load(); //加载资源
void loadImage(); //加载图片
void loadRecord(); //读取游戏记录
void loadMusic(); //加载音乐
void gameSave(); //游戏保存
void releaseImage(); //释放图片资源
void releaseMusic(); //关闭音乐文件,释放资源
void draw(); //绘制画面
void drawGameInfo(); //绘制游戏信息
void addRandomNum(int n); //增加随机数字
bool move(int direct); //按方向移动格子
void drawBlocks(); //绘制格子
void restart(); //重新游戏
void gameOverCheck(); //游戏结束检测
//界面布局参数
const int AREA_LEFT = 20, AREA_TOP = 178, AREA_WIDTH = 500, AREA_HEIGHT = 500;
const int GRID_WIDTH = 106, DEVIDE = 15;
const int SCR_WIDTH = AREA_WIDTH + AREA_LEFT * 2, SCR_HEIGHT = AREA_HEIGHT + AREA_TOP + AREA_LEFT;
//颜色参数
#define COLOR_TEXT_SCORE EGERGB(241, 231, 214)
#define COLOR_BACKGROUD EGERGB(250,248, 239)
//动画参数
#define SPEED 25
#define FPS 60
//按钮点击判断
inline bool clickBtnRestart(int x, int y) {
return (20 < x && x < 20 + 222) && (110 < y && y < 110 + 50);
}
//图片
#define NUM_BLOCK 18
PIMAGE blockImgs[NUM_BLOCK];
#define NUM_IMG 5
PIMAGE pimgs[NUM_IMG];
const int ID_IMG_BACKGROUND = 0, ID_IMG_LOGO = 1, ID_IMG_SCORE_BG = 2, ID_IMG_RESTART = 3;
const int ID_IMG_GAMEOVER = 4;
//图片文件位置
const char* imgFiles[NUM_IMG] = {
"resource\\image\\background.png",
"resource\\image\\gamelogo.png",
"resource\\image\\scorebg.png",
"resource\\image\\restart.png",
"resource\\image\\gameOver.png",
};
//数据文件
const char* recordFile = "game2048Record.txt";
//音乐
MUSIC mergeMusic;
MUSIC startMusic;
const char* mergeMusicFile = "resource\\music\\merge.mp3";
const char* startMusicFile = "resource\\music\\start.mp3";
//方向偏移
const int LEFT = 0, UP = 1, RIGHT = 2, DOWN = 3;
const int dx[4] = { -1, 0, 1, 0 };
const int dy[4] = { 0, -1, 0, 1 };
struct GameInfo
{
int score;
int topScore;
int maxNum;
};
GameInfo gameInfo;
int grid[4][4]; //格子
int emptyBlock = 16; //空格子数
bool gameOver = false;
int main()
{
//注意要INIT_NOFORCEEXIT, 即关闭窗口不强制退出程序,以便进行游戏保存工作
setinitmode(INIT_RENDERMANUAL | INIT_NOFORCEEXIT, 100, 50);
initgraph(SCR_WIDTH, SCR_HEIGHT);
setcaption("2048");
setbkcolor(COLOR_BACKGROUD);
setbkmode(TRANSPARENT);
delay_ms(0); //刷新窗口
srand((unsigned int)time(0));
load();
startMusic.Play(0);
draw();
gameOverCheck();
int xClick, yClick;
for (; is_run(); delay_fps(FPS)) {
//按键检测
int direction = -1;
while (kbmsg()) {
key_msg keyMsg = getkey();
if (keyMsg.msg == key_msg_down) {
switch (keyMsg.key) {
case 'A': case key_left: direction = 0; break;
case 'W': case key_up: direction = 1; break;
case 'D': case key_right: direction = 2; break;
case 'S': case key_down: direction = 3; break;
}
}
}
//鼠标点击检测
bool leftClick = false;
while (mousemsg()) {
mouse_msg mouseMsg = getmouse();
if (mouseMsg.is_left() && mouseMsg.is_down()) { //左键按下
leftClick = true;
xClick = mouseMsg.x;
yClick = mouseMsg.y;
}
}
//移动
if (!gameOver && direction != -1 && move(direction)) {
addRandomNum(1);
cleardevice();
draw();
gameOverCheck();
}
//鼠标点击判断
if (leftClick && clickBtnRestart(xClick, yClick)) {
restart();
startMusic.Play(0);
cleardevice();
draw();
}
}
gameSave();
releaseImage();
releaseMusic();
closegraph();
return 0;
}
void drawGameInfo()
{
putimage_withalpha(NULL, pimgs[ID_IMG_LOGO], AREA_LEFT + 14, 30); //图标
putimage_withalpha(NULL, pimgs[ID_IMG_SCORE_BG], 260, 10); //游戏分数背景
putimage_withalpha(NULL, pimgs[ID_IMG_RESTART], 20, 110); //重新开始安妮
//游戏分数
setcolor(COLOR_TEXT_SCORE);
setfont(30, 0, "黑体");
xyprintf(370, 24, "%8d", gameInfo.topScore);
xyprintf(370, 72, "%8d", gameInfo.score);
xyprintf(370, 120, "%8d", gameInfo.maxNum);
}
void draw()
{
drawGameInfo();
drawBlocks();
}
void restart()
{
gameInfo.score = 0;
gameOver = false;
memset(grid, 0, sizeof(int) * 16);
emptyBlock = 16;
addRandomNum(2);
}
void drawBlocks()
{
putimage_withalpha(NULL, pimgs[ID_IMG_BACKGROUND], AREA_LEFT, AREA_TOP);
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
int x = AREA_LEFT + (j + 1) * DEVIDE + j * GRID_WIDTH;
int y = AREA_TOP + (i + 1) * DEVIDE + i * GRID_WIDTH;
if (grid[i][j] != 0)
putimage_withalpha(NULL, blockImgs[grid[i][j]], x, y);
}
}
}
void gameOverCheck()
{
if (emptyBlock != 0)
return;
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if ((j + 1 < 4 && grid[i][j] == grid[i][j + 1])
|| (i + 1 < 4 && grid[i][j] == grid[i + 1][j]))
return;
}
}
gameOver = true;
setfillcolor(EGEACOLOR(0x60, WHITE));
ege_fillrect(AREA_LEFT, AREA_TOP, AREA_WIDTH, AREA_HEIGHT);
putimage_withalpha(NULL, pimgs[ID_IMG_GAMEOVER], 120, 400);
}
void addRandomNum(int n)
{
while (n-- > 0) {
if (emptyBlock == 0)
break;
int r = rand() % emptyBlock--; //随机选取一个空位
int* p = &grid[0][0] - 1, i = 0;
do { //找到目标空位
while (*++p);
} while (i++ < r);
*p = (rand() % 10 == 0) + 1; //随机数字,0.9概率是1,0.1概率是2
}
}
bool move(int direction)
{
//0~3对应移动方向左上右下
//初始检测位置及检测偏移
static int x0[4] = {0, 0, 3, 0}, y0[4] = {0, 0, 0, 3};
static int firstOffset[4][2] = { {1, 0},{0, 1},{-1, 0}, {0, -1} };
static int secondOffset[4][2] = { {0, 1}, {1, 0}, {0, 1}, {1, 0} };
bool changed = false;
bool hasMoved[4] = { true, true, true, true };
bool merged[4][4] = { false }/*合并标记*/, mergeMusic_flag = false, move_flag;
for (int check = 3; check > 0; --check) {
int lastGrid[4][4]; //上次格子存储
bool moving[4][4] = { false }; //移动标记
memcpy(lastGrid, grid, sizeof(int) * 4 * 4);
int xLast = x0[direction], yLast = y0[direction];
move_flag = false;
//整体单格移动
for (int i = 0; i < 4; i++) {
if (!hasMoved[i])
continue;
hasMoved[i] = false;
int xCur = x0[direction] + i * secondOffset[direction][0];
int yCur = y0[direction] + i * secondOffset[direction][1];
for (int j = 1; j < 4; j++) {
xLast = xCur;
yLast = yCur;
xCur += firstOffset[direction][0];
yCur += firstOffset[direction][1];
if (grid[yCur][xCur] != 0) {
if (grid[yLast][xLast] == 0) {
grid[yLast][xLast] = grid[yCur][xCur];
grid[yCur][xCur] = 0;
moving[yCur][xCur] = hasMoved[i] = move_flag = true;
changed = true;
}
//合并
else if (grid[yCur][xCur] == grid[yLast][xLast]
&& (!merged[yLast][xLast] && !merged[yCur][xCur])) {
++grid[yLast][xLast];
grid[yCur][xCur] = 0;
moving[yCur][xCur] = merged[yLast][xLast] = hasMoved[i] = true;
changed = mergeMusic_flag = move_flag = true;
emptyBlock++;
int score = 1 << grid[yLast][xLast];
if (score > gameInfo.maxNum)
gameInfo.maxNum = score;
if ((gameInfo.score += score) > gameInfo.topScore)
gameInfo.topScore = gameInfo.score;
}
}
}
}
if (!move_flag)
break;
//移动动画
cleardevice();
drawGameInfo();
setfillcolor(getbkcolor());
for (int dist = SPEED; dist < GRID_WIDTH + DEVIDE ; delay_fps(FPS), dist += SPEED) {
bar(AREA_LEFT, AREA_TOP, AREA_LEFT + AREA_WIDTH, AREA_TOP + AREA_HEIGHT); //清除区域
putimage_withalpha(NULL, pimgs[ID_IMG_BACKGROUND], AREA_LEFT, AREA_TOP); //绘制背景
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (lastGrid[i][j] != 0){
int x = AREA_LEFT + (j + 1) * DEVIDE + j * GRID_WIDTH;
int y = AREA_TOP + (i + 1) * DEVIDE + i * GRID_WIDTH;
if (moving[i][j]) {
x
没有合适的资源?快使用搜索试试~ 我知道了~
示例二 2048.zip
共370个文件
png:301个
mp3:36个
xml:9个
1星 需积分: 0 232 下载量 179 浏览量
2020-02-13
20:28:23
上传
评论 1
收藏 5.65MB ZIP 举报
温馨提示
EGE专栏中的示例程序二 2048游戏, 包含所用素材,源代码和EXE文件,下载解压后,双击EXE文件即可直接运行。压缩包中有三个版本,分别是基础功能实现版,完整版和无音乐流畅完整版。 使用EGE图形库制作
资源推荐
资源详情
资源评论
收起资源包目录
示例二 2048.zip (370个子文件)
mimo_asset.apk 398KB
965fbaf0dd204712a41a1059c6f66cd2.config 1KB
773ce9c7a15542c6bbb4bf7fc6de87ee.config 1KB
main.cpp 10KB
main(无音乐流畅版).cpp 9KB
main.cpp 4KB
2048.exe 269KB
2048(无音乐流畅版).exe 268KB
2048.exe 261KB
zhadan.ExportJson 30KB
xuanzhongdaoju.ExportJson 4KB
xuanzhongfangkuai.ExportJson 3KB
goldfont.fnt 20KB
ac-2.fnt 12KB
scorefont.fnt 9KB
ceshi.fnt 6KB
ziti5.fnt 1KB
icon.ico 78KB
bgm.mp3 235KB
scoreroll.mp3 35KB
perfect.mp3 17KB
reliveLayer.mp3 13KB
pass.mp3 13KB
double.mp3 9KB
start.mp3 8KB
start.mp3 8KB
multishot.mp3 7KB
combo_sound12.mp3 7KB
relive.mp3 7KB
excellent.mp3 7KB
dead.mp3 7KB
amazing.mp3 6KB
great.mp3 6KB
cool.mp3 6KB
combo_sound6.mp3 6KB
combo_sound5.mp3 6KB
combo_sound2.mp3 6KB
combo_sound8.mp3 6KB
combo_sound7.mp3 6KB
combo_sound10.mp3 6KB
combo_sound1.mp3 6KB
combo_sound11.mp3 5KB
combo_sound3.mp3 5KB
combo_sound4.mp3 5KB
merge.mp3 5KB
merge.mp3 5KB
combo_sound9.mp3 5KB
exchange.mp3 4KB
backstep.mp3 3KB
coin.mp3 2KB
highscore.mp3 2KB
button.mp3 2KB
move.mp3 1KB
clik.mp3 288B
hecheng_1.plist 9KB
zhadan0.plist 2KB
xuanzhongfangkuai0.plist 1KB
xuanzhongdaoju0.plist 1KB
gamebg.png 511KB
ceshi_0.png 245KB
ac-2_0.png 218KB
shareImage.png 175KB
scorefont.png 174KB
menulogo.png 117KB
shopbigbg.png 102KB
icon.png 88KB
icon.png 88KB
icon.png 88KB
icon.png 88KB
loginbg.png 80KB
zhadan0.png 66KB
shopbg.png 55KB
selfinfobg.png 47KB
Default-@2x.png 44KB
goldfont_0.png 38KB
pausebg.png 37KB
spr_mode_describe.png 35KB
excellent.png 34KB
survivaloverbg.png 33KB
survivaloverbg_en.png 33KB
amazing.png 32KB
nodebg.png 32KB
propsoverbg_en.png 31KB
classicoverbg_en.png 31KB
propsoverbg.png 31KB
mode_2.png 30KB
overshare_en.png 30KB
overplayagain_en.png 30KB
gamelogo.png 30KB
gameLayer_top_en.png 30KB
splash.png 30KB
splash.png 30KB
splash.png 30KB
splash.png 30KB
boxno_en.png 30KB
overhome_en.png 30KB
startbtn.png 29KB
nodebg_2.png 29KB
mode_3.png 29KB
mode_1.png 29KB
共 370 条
- 1
- 2
- 3
- 4
资源评论
- 江河湖海2022-04-04好厉害 !!
依稀_yixy
- 粉丝: 3170
- 资源: 4
上传资源 快速赚钱
- 我的内容管理 展开
- 我的资源 快来上传第一个资源
- 我的收益 登录查看自己的收益
- 我的积分 登录查看自己的积分
- 我的C币 登录后查看C币余额
- 我的收藏
- 我的下载
- 下载帮助
安全验证
文档复制为VIP权益,开通VIP直接复制
信息提交成功