当前位置: 首页 > news >正文

Easyx使用(小游戏开发)

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        easyx本身非常适合小游戏的开发。因为它可以画图,可以有键盘输入,可以有鼠标输入,也可以贴图,也可以做出各种效果,所以用来开发小游戏也是非常合适的。即使用来做大型游戏的demo,也是可以的。很多同学去学习easyx的api,本质上就是尝试开发游戏,当然这也无可厚非。今天我们可以简单开发一个贪吃蛇游戏。

1、贪吃蛇

        贪吃蛇是一个很经典的游戏。本身贪吃蛇的长度很短,但是它每吃一个食物之后,身体就会变长。这样随着蛇的身体越来越长,它的行动也越来越受限,比如它不能碰壁,也不能碰到自己。一旦出现这些问题,那么游戏就会结束。

2、功能分解

        要实现贪吃蛇也不难,整个功能可以切分成这几个部分。首先,初始化蛇的身体,比如分解成几个正方形。然后初始化食物的位置。接着就是绘制蛇的身体,绘制食物。这些都ok之后,就可以移动小蛇。如果无法移动,程序会结束;如果可以移动,则游戏继续。

3、初始化蛇的位置

        整个小蛇是按照正方形来进行设计的,所以可以设几个正方形就可以了,当然也要给出初始运动方向,

// basic function defined herevoid initSnake(Snake &snake)
{snake.length = 3; snake.x[0] = WIDTH / 2 / BLOCK_SIZE * BLOCK_SIZE;  snake.y[0] = HEIGHT / 2 / BLOCK_SIZE * BLOCK_SIZE;snake.x[1] = WIDTH / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE ;snake.y[1] = HEIGHT / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE;snake.x[2] = WIDTH / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE * 2;snake.y[2] = HEIGHT / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE * 2;snake.dir = RIGHT; 
}

4、设置食物的位置

        有两个时间点需要设置食物的位置。一个是初始化的时候,还有一个就是当小蛇吃掉食物的时候,需要更新一个食物位置。过程中,注意食物的位置不能在蛇的身上。

void generateFood(Food &food, const Snake &snake)
{bool valid = false;while (!valid){valid = true;food.x = (rand() % (WIDTH / BLOCK_SIZE)) * BLOCK_SIZE;food.y = (rand() % (HEIGHT / BLOCK_SIZE)) * BLOCK_SIZE;// check food in snake bodyfor (int i = 0; i < snake.length; ++i){if (food.x == snake.x[i] && food.y == snake.y[i]) {valid = false;break;}}}
}

5、绘制小蛇

        小蛇的绘制其实不复杂,主要就是绘制几个正方形即可,

// draw snakevoid drawSnake(const Snake &snake) 
{for (int i = 0; i < snake.length; ++i) {setfillcolor(i == 0 ? BLUE : GREEN);  fillrectangle(snake.x[i], snake.y[i], snake.x[i] + BLOCK_SIZE, snake.y[i] + BLOCK_SIZE);}
}

6、食物的绘制

        相对而言,食物的绘制则更加简单,就是绘制一个正方形,注意颜色的区分,

// draw foodvoid drawFood(const Food &food)
{setfillcolor(RED);fillrectangle(food.x, food.y, food.x + BLOCK_SIZE, food.y + BLOCK_SIZE);
}

7、小蛇的移动

        小蛇的移动稍微复杂一点。这里面有一个小诀窍。首先把所有的小蛇身体,往后移动一格。再根据当前运动方向,确定第一个小格中的x和y怎么修改。修改的时候判断有没有食物,有实物的话,反而简单,直接长度+1,重新生成食物,退出继续循环。

        如果不是食物,需要判断有没有出界,或者碰到自己。前面两个没遇到,就继续行走,遇到的话,就程序退出了。

// move snakebool moveSnake(Snake &snake, Food &food) 
{// update snakefor (int i = snake.length - 1; i > 0; --i) {snake.x[i] = snake.x[i - 1];snake.y[i] = snake.y[i - 1];}// adjust position of headerswitch (snake.dir) {case UP:snake.y[0] -= BLOCK_SIZE;break;case DOWN:snake.y[0] += BLOCK_SIZE;break;case LEFT:snake.x[0] -= BLOCK_SIZE;break;case RIGHT:snake.x[0] += BLOCK_SIZE;break;default:break;}// check food whether being eatenif (snake.x[0] == food.x && snake.y[0] == food.y){snake.length++;generateFood(food, snake);  // re-generate foodreturn true;  //already eat food}// hit wallif (snake.x[0] < 0 || snake.x[0] >= WIDTH || snake.y[0] < 0 || snake.y[0] >= HEIGHT) {return false;  }// hit snake itselffor (int i = 1; i < snake.length; ++i) {if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]) {return false;  }}return true;  
}

8、键盘输入

        整个小蛇的控制是通过键盘进行的。控制的按键是a、w、s、d,玩过cs的同学应该不会陌生。每一次按键确认之后,都要设置下小蛇的前进方向,根据小蛇是否正常运行,对小蛇和食物进行重新绘制,这样整个游戏就可以慢慢做好了。

        当然实际开发的时候,我们也会显示当前的得分,以及提示用户,什么时候程序已经结束了。最后这里给出完整的代码,有兴趣的同学可以好好看一下代码,

#define _CRT_SECURE_NO_WARNINGS
#include <graphics.h>
#include <conio.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctime>static const int WIDTH = 640;  
static const int HEIGHT = 480; 
static const int BLOCK_SIZE = 20; 
static const int SNAKE_MAX_LENGTH = 100; enum Direction { UP, DOWN, LEFT, RIGHT };// struct of Snakestruct Snake 
{int x[SNAKE_MAX_LENGTH];  int y[SNAKE_MAX_LENGTH]; int length; Direction dir; 
};// struct of Foodstruct Food 
{int x;int y;
};// basic function defined herevoid initSnake(Snake &snake)
{snake.length = 3; snake.x[0] = WIDTH / 2 / BLOCK_SIZE * BLOCK_SIZE;  snake.y[0] = HEIGHT / 2 / BLOCK_SIZE * BLOCK_SIZE;snake.x[1] = WIDTH / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE ;snake.y[1] = HEIGHT / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE;snake.x[2] = WIDTH / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE * 2;snake.y[2] = HEIGHT / 2 / BLOCK_SIZE * BLOCK_SIZE + BLOCK_SIZE * 2;snake.dir = RIGHT; 
}void generateFood(Food &food, const Snake &snake)
{bool valid = false;while (!valid){valid = true;food.x = (rand() % (WIDTH / BLOCK_SIZE)) * BLOCK_SIZE;food.y = (rand() % (HEIGHT / BLOCK_SIZE)) * BLOCK_SIZE;// check food in snake bodyfor (int i = 0; i < snake.length; ++i){if (food.x == snake.x[i] && food.y == snake.y[i]) {valid = false;break;}}}
}// draw snakevoid drawSnake(const Snake &snake) 
{for (int i = 0; i < snake.length; ++i) {setfillcolor(i == 0 ? BLUE : GREEN);  fillrectangle(snake.x[i], snake.y[i], snake.x[i] + BLOCK_SIZE, snake.y[i] + BLOCK_SIZE);}
}// draw foodvoid drawFood(const Food &food)
{setfillcolor(RED);fillrectangle(food.x, food.y, food.x + BLOCK_SIZE, food.y + BLOCK_SIZE);
}// move snakebool moveSnake(Snake &snake, Food &food) 
{// update snakefor (int i = snake.length - 1; i > 0; --i) {snake.x[i] = snake.x[i - 1];snake.y[i] = snake.y[i - 1];}// adjust position of headerswitch (snake.dir) {case UP:snake.y[0] -= BLOCK_SIZE;break;case DOWN:snake.y[0] += BLOCK_SIZE;break;case LEFT:snake.x[0] -= BLOCK_SIZE;break;case RIGHT:snake.x[0] += BLOCK_SIZE;break;default:break;}// check food whether being eatenif (snake.x[0] == food.x && snake.y[0] == food.y){snake.length++;generateFood(food, snake);  // re-generate foodreturn true;  //already eat food}// hit wallif (snake.x[0] < 0 || snake.x[0] >= WIDTH || snake.y[0] < 0 || snake.y[0] >= HEIGHT) {return false;  }// hit snake itselffor (int i = 1; i < snake.length; ++i) {if (snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]) {return false;  }}return true;  
}int main(int argc, char* argv) 
{Snake snake; Food food; char buf[32] = {0};bool gameOver = false;srand((unsigned int)time(0));  // random seedinitgraph(WIDTH, HEIGHT); setbkmode(TRANSPARENT);BeginBatchDraw();initSnake(snake);generateFood(food, snake);while (!gameOver) {if (_kbhit()) // non-block function{ // check keyboardchar ch = _getch();switch (ch) {case 'w':  // upif (snake.dir != DOWN) snake.dir = UP;break;case 's':  // downif (snake.dir != UP) snake.dir = DOWN;break;case 'a':  // leftif (snake.dir != RIGHT) snake.dir = LEFT;break;case 'd':  // rightif (snake.dir != LEFT) snake.dir = RIGHT;break;default:break;}}// logical checkgameOver = !moveSnake(snake, food); if (gameOver){break;}// re-draw picturecleardevice(); drawSnake(snake);  drawFood(food);  memset(buf, 0, 32); // draw score heresprintf(buf, "Score: %d", snake.length -3);outtextxy(500, 50, buf);EndBatchDraw();Sleep(250); // left some time to gamerBeginBatchDraw();}// update to clear screencleardevice();outtextxy(260, 220,"Game Over!!!");EndBatchDraw();_getch();closegraph();  //close windowreturn 0;
}

http://www.dtcms.com/a/454203.html

相关文章:

  • C++面经|小林coding|(2)
  • 前端学习day01
  • 怎样攻击网站设计师素材网站e
  • 13-verilog实现LED呼吸灯效果
  • 哪里有做网站设计查网站权重
  • 可以做围棋题的网站厂家招商
  • 利用ps制作网站的设计查企企官网
  • 大型地方门户网站源码网页平面设计教程
  • 网站建设600分站优缺点网站开发 群
  • 行业网站联盟wordpress响应式视频
  • 建设网站要多少页面销售网站html源码
  • C++类和对象(3)6个类的默认成员函数之构造函数和析构函数
  • 英文网站建设szjijie山东省和城乡建设厅网站首页
  • 计算机视觉(opencv)——疲劳检测
  • 网站建设与运营的预算方案模板做图骂人的图片网站
  • 网站开发报告参考文献安卓优化大师最新版
  • 【代码随想录算法训练营——Day28】贪心算法——452.用最少数量的箭引爆气球、435.无重叠区间、763.划分字母区间
  • 企业在建设自己网站时哪个网站可以免费做推广
  • 数据备份-从策略到实战
  • 598网站建设推广渠道有哪些
  • 一文畅览 Qt 控件类
  • 高校网站建设招标公告企业网站模板推荐
  • 网站建设所需域名百度推广优化是什么?
  • 网站的颜色搭配专业营销网站开发
  • 第八个实验——浮动路由
  • 西安网站建设云阔网络熊掌号网站建设骗
  • 爱唐山做贡献月评十佳投票网站网站空间稳定性
  • 江苏省城乡建设网站玉溪做网站的公司
  • 专业柳州网站建设多少钱中卫网站推广营销
  • 付网站首期合同款怎么做分录彩票网站wordpress模板