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

虚拟机主机网站建设的几个步骤怎么自己创建网站免费

虚拟机主机网站建设的几个步骤,怎么自己创建网站免费,网站优化目录,网站手机采集个人主页#xff1a;北海 #x1f390;CSDN新晋作者 #x1f389;欢迎 #x1f44d;点赞✍评论⭐收藏✨收录专栏#xff1a;C/C#x1f91d;希望作者的文章能对你有所帮助#xff0c;有不足的地方请在评论区留言指正#xff0c;大家一起学习交流#xff01;#x1f9…  个人主页北·海 CSDN新晋作者 欢迎 点赞✍评论⭐收藏✨收录专栏C/C希望作者的文章能对你有所帮助有不足的地方请在评论区留言指正大家一起学习交流 天天酷跑,一款童年游戏,主要是进行跳跃操作,和躲避障碍物,中篇主要实现人物的下蹲,随机障碍物的生成以及优化main函数里面的sleep(30) 一. 游戏的展示效果 二.本节开发日志 上篇已更新 : 天天酷跑上篇 优化main函数里面的sleep(30); 1.利用接口getDelay()函数 2.更新窗口标志update; 3.优化来自用户点击时候的消息 实现玩家的下蹲 1利用计数器 随机障碍物的实现   1.障碍物池子 2.随机数取类型 三.优化上篇中main函数里的sleep(30) 首先为什么要优化这个呢? 了解sleep的都知道,这个是让程序休眠30ms也就是当程序执行到这里的时候,会在这里呆30ms,因为这款游戏需要接收玩家的按键消息,所以有时候玩家在这30ms内有键盘响应的时候,由于程序休眠,无法接收到消息,会降低游戏的体验性 要解决的问题: 在按跳跃键的时候不受sleep的影响 解决方法 : 利用时间戳,定义一个计时器,当达到该计时器的设定的时间就可以打开刷新窗口的按钮,或者当跳跃时候打开该按钮,代码如下: int main() {init();while (1) {keyEvent();timer getDelay();if (timer 30) {timer 0;update true;}if (update) {update false;BeginBatchDraw();//渲染背景updataBg();//实现人物的奔跑putimagePNG2(heroX, heroY, imgHero[heroIndex]);//渲染障碍物updateEnemy();EndBatchDraw();fly();}}system(pause);return 0; } 代码解释 : timer是一个全局变量,用于累加两次函数执行的时间,当达到30ms就会将update标志设置为true进行刷新界面 时间戳 : 一个用于表示特定时刻的数值通常是一个整数或浮点数。在上述代码中时间戳用于记录函数调用的时间点 这样优化的话,感觉和sleep(30)的效果一样,此时还需要在跳跃的时候将其update设为true,在以后只要接受玩家键盘消息的时候都要加上 void jump() {//跳跃只需要改变y值即可,在底层数据管理函数实现,此时只需要给出可以改数据的信号即可heroJump true;update true; } 这样的话就解决了玩家按跳跃键程序休眠的问题 ,此时提高了游戏的体验性 开发之前,先回顾一下上篇中的开发流程,将开发分为两层,一个是渲染层(update)一个是数据层(fly),渲染层是将游戏的图片呈现出来,数据层是控制渲染层的,实现游戏的控制,其他的功能根据可封装为函数围绕这两层进行展开,将游戏的资源加载放在初始化函数(init) 四.实现玩家的下蹲功能 天天酷跑主要就是跳跃和下蹲,下蹲可躲避障碍物柱子,给障碍物的创建先奠定基础,实现下蹲和实现跳跃的流程大致相似,分析可知,下蹲时玩家发出的信号,那么我们就可用从用户点击函数开始开发,当玩家按下a的时候执行下蹲操作 资源必须先加载进来,因为下蹲有两张图片,所以在全局定义一个存放该图片的数组,然后再初始化中进行加载 //下蹲 IMAGE imgDown[2]; bool heroDown;//下蹲标志void init(){ ...//人物的下蹲 loadimage(imgDown[0], res/d1.png); loadimage(imgDown[1], res/d2.png); heroIndex 0; heroDown false; } 由于下蹲是个动态的,所以要用到帧序列,也要将其初始化为0 用户点击  void keyEvent() {//获取玩家键盘事件char ch 0;if (_kbhit()) {ch _getch();if (ch ) {//空格为跳跃jump();}else if (ch a) {//a为下蹲down();}} }  当程序收到下蹲的消息时,就会执行该下蹲操作,将下蹲功能封装为一个函数 实现下蹲  void down() { //下蹲只需要改变y值即可, 在底层数据更新函数实现, 此时只需要给出可以改数据的信号即可heroDown true;update true;heroIndex 0 ; } 此时定义一个下蹲的标志,如果时true的话,就可以在数据层进行修改数据,然后打开更新界面的按钮 现在就可以在数据层实现数据的更新了 数据更新 //实现跳跃if (heroJump) {//跳跃状态if (heroY jumpHeightMax) {heroJumpOff 4;// (-4)等于向上走,4等于向下走}heroY heroJumpOff;if (heroY 345 - imgHero[0].getheight()) {//达到地面heroJump false;heroJumpOff -4;}}else {//改变人物帧序列heroIndex (heroIndex 1) % 12;} 这里是上篇中的人物跳跃和人物跑步,此时只需给该状态添加一个下蹲的状态即可 else if (heroDown) {//下蹲状态heroIndex;if (heroIndex 2) {heroDown false;heroIndex 0;}} 我只贴出了下蹲部分的代码,当heroDown为true说明执行下蹲,就改图片帧,当帧数大于等于2的时候,说明一次下蹲操作结束了,此时就可以将下蹲标志设置为false,将图片帧也得归零 这个下蹲的速度非常快,不到1s就结束了,所以没有截图到,除了速度块基本上这个下蹲操作就已经实现了,现在来优化一下这个下蹲的速度 下蹲速度优化 为什么速度会这么快呢? 因为这个下蹲的图片只有两张,循环一次的时间也就几十毫秒,所以速度很快,解决这个问题有两种方法,第一个就是,将这个下蹲过程的图片设置很多张,例如下蹲的图片有50张,将其全部渲染出来,这就加长了时间,当然也是很费内存的,第二种就是用计数器,利用空循环当达到计数器设定的值的时候在进行执行下蹲,由于下蹲第二张渲染呈现时间比第一张的长,这也显得下蹲才逼真,解决这一问题,需要定义一个数组,存储两张图片的计数,以下为代码: else if(heroDown){static int count 0;int dalays[2] { 4,10 };count;if (count dalays[heroIndex]) {count 0;heroIndex;if (heroIndex 2) {heroIndex 0;heroDown false;}}} 利用static记录循环执行的次数,dalays保存两张图片的计数,heroIndex序列帧循环两个图片,如果满足的话,就将count设为0,执行下蹲操作 渲染下蹲操作 人物跳跃的渲染在main函数里面通过一行代码实现了,但是现在人物的状态有两种,跳跃与下蹲,此时就需要封装为函数了,创建updateHero函数 在main函数里用updateHero函数代替人物奔跑的代码  void updateHero() {//实现人物的奔跑if (!heroDown) {putimagePNG2(heroX, heroY, imgHero[heroIndex]);}else {int y 345 - imgDown[heroIndex].getheight();putimagePNG2(heroX, y, imgDown[heroIndex]);} } 如果处于非下蹲操作,由于人物都是一个高度,当处于下蹲时候,两张图片的高度不一样,所以需要利用图片序列帧计算y的坐标 此时的下蹲代码算是写完了,下面时运行结果此时就很容易的截图到该英雄的下蹲操作了,接下来实现随机障碍物 看看上面几个小标题就是开发这个模块的流程 五.随机障碍物的实现 如何实现随机障碍物呢? 此时就会涉及到枚举的应用,障碍物的封装,障碍物的池子和随机数 枚举 : 可用提高代码的可读性,简化程序,一般一定个数的东西可定义为枚举类型,枚举里的元素,也就是整数类型 首先定义枚举类型,就将障碍物设置为乌龟,狮子,四种柱子 typedef enum {TORTOISE,//乌龟 0LION,//狮子 1HOOK1,//柱子 2HOO2,HOO3,HOOK4,OBSTACLE_TYPE_COUNT // 总数 }obstacle_type; 在这里用到的OBSTACLE_TYPE_COUNT 很是巧妙,枚举里的值从0开始,到了OBSTACLE_TYPE_COUNT 刚好时前面障碍物的总数,此时就将枚举定义好了,然后就可以封装结构体了 首先应该知道封装的属性都有什么,一个障碍物,他得有类型,坐标,速度,伤害,使用状态,此时我们可用再添加一个图片的帧序列,因为每个障碍物有的是动态的,都有序列,此时就可以将初始化加载图片进行优化,要用到一个大小可变的容器vector来存储,声明为二维的,每一维存储该组图片 vector的使用需要导入头文件vector  #includevector 代码中 obstacleImgs为定义在全局的二维数组,在初始化时候,创建个一维数组,最后再将其一维数组添加到该二维数组里 vectorvectorIMAGEobstacleImgs;//存放所有障碍物的各个图片 此时所有障碍物的图片存在于二维数组obstacleImgs中了 封装结构体 typedef struct obstacle {int type;//类型,由于类型定义在枚举种,枚举里的变量就相当于整数类型,所以可用int代替int x, y;//坐标int imgIndex;//帧序列int speed;//速度int power;//伤害bool exist;//是否可用}obstacle_t; 创建障碍物池子 也就是定义一个结构体数组,OBSTACLE_COUNT是定义的宏,池子的大小 obstacle_t obstacles[OBSTACLE_COUNT];//障碍物池子 在封装了障碍物之后,那么之前小乌龟所定义的地方都需要优化了 小乌龟的定义 创建小乌龟 fly函数中小乌龟的运动 障碍物的渲染层 此时可用依据上面删除的部分进行开发,定义我们已经做了但是应该将池子里的exist属性进行初始化,以保证能够正确的知道哪个障碍物可用 void init(){...//初始化障碍物池子for (int i 0; i OBSTACLE_COUNT; i) {obstacles[i].exist false;} } 接下来需要创建小乌龟,此时应该重写creatObstacle函数, 开发思路 : 先用for循环在池子里面找到一个可用使用的障碍物,也就是exist为false的,然后再设定他的各属性 void creatObstacle() {int i 0;//找到一个可以用的障碍物for (i 0; i OBSTACLE_COUNT; i) {if (obstacles[i].exist false) break;}obstacles[i].exist true;obstacles[i].imgIndex 0;obstacles[i].type rand() % 6;//取0-5的随机数obstacles[i].x WIN_WIDTH;obstacles[i].y 345 5 - obstacleImgs[obstacles[i].type][0].getheight();if (obstacles[i].type TORTOISE) {//小乌龟obstacles[i].power 5;obstacles[i].speed 0;}else if (obstacles[i].type LION) {//狮子obstacles[i].power 20;obstacles[i].speed 5;}else if (obstacles[i].type HOOK1 obstacles[i].type HOOK4) {//四个柱子obstacles[i].power 20;obstacles[i].speed 0;//静态的obstacles[i].y 0;//由于柱子是在填上挂着,所以将其y设置为0} } 这个初始化看着比较多,但是难度不大,就找到一个可以用的障碍物,然后将其封装的属性进行初始化,实现随机就是再枚举里面取随机数,只有狮子是跑过来的,所以要和第三层草坪背景图的速度不能保持一致,其他障碍物的速度设置为0即可实现初始化 fly中更新障碍物的数据 更新x坐标使其运动,更新图片帧序列使其处于动态 void init(){...//更新各障碍物的状态 for (int i 0; i OBSTACLE_COUNT; i) {if (obstacles[i].exist) {obstacles[i].x - (obstacles[i].speed bgSpeed[2]);if (obstacles[i].x -obstacleImgs[obstacles[i].type][0].getwidth() * 2) {//已经从左边跑出了屏幕obstacles[i].exist false;}//更新该障碍物的帧序列int len obstacleImgs[obstacles[i].type].size();obstacles[i].imgIndex (obstacles[i].imgIndex 1) % len;}}} 代码解释 : 从障碍物池子里面找正字使用的障碍物,找到之后,再改变他的x坐标,bgSpeed[2]为草坪的速度,当减去他的时候,和草坪是相对速度为0,再减去该障碍物的速度,就是和草坪的相对速度,若不为0,此时就能显示出运动的状态,若为0,就和草坪相对静止 渲染障碍物 void updateEnemy() {for (int i 0; i OBSTACLE_COUNT; i) {if (obstacles[i].exist) {putimagePNG2(obstacles[i].x, obstacles[i].y, WIN_WIDTH,obstacleImgs[obstacles[i].type][obstacles[i].imgIndex]);}}} 渲染的图片的第一维是该图片的类型,第二维是该图片的帧数,很巧妙 这样就设计完了,看看成果 我跑了半分钟,感觉这个柱子出现的频率还是太大了,因为当初随机数是对6取余的,二柱子就占了四个,所以这里可用优化 此时类型的这里就化解了,取两次随机数,让其柱子出现的几率降低 此时就能看到这几个障碍物同框了,但是碰撞这里还没有做,现在随机障碍物也实现了 六.实现英雄与障碍物的碰撞检测 从图可以看出,障碍物的碰撞检测就是在检测两个矩形是否相交,这种判断矩形相交的代码在网上开源的有很多 如果以白边的坐标来检测的话,可能会有误差,则加上偏移量,使判断更加准确, 分析 : 碰撞检测实在数据层进行的,但是这个功能可封装为函数,所以在fly函数里面定义一个checkHit函数用于检测碰撞 一下是判断是否碰撞的代码,主要是找到这四个点的坐标,加上偏移量即可 开源代码,判断矩形是否相交 //设A[x01,y01,x02,y02] B[x11,y11,x12,y12]. bool rectIntersect(int x01, int y01, int x02, int y02,int x11, int y11, int x12, int y12) {int zx abs(x01 x02 - x11 - x12);int x abs(x01 - x02) abs(x11 - x12);int zy abs(y01 y02 - y11 - y12);int y abs(y01 - y02) abs(y11 - y12);return (zx x zy y); } 找四个点的坐标,调用rectIntersect函数进行判断是否相交 void checkHit() { //实现碰撞检测for (int i 0; i OBSTACLE_COUNT; i) {if (obstacles[i].exist) {int a1x, a1y,a2x,a2y;int off 30;if (!heroDown) {//非下蹲状态a1x heroX off;a1y heroY off;a2x heroX imgHero[heroIndex].getwidth() - off;a2y heroY imgHero[heroIndex].getheight();}else {//下蹲状态a1x heroXoff;a1y 345 - imgDown[heroIndex].getheight();a2x heroX imgDown[heroIndex].getwidth()-off;a2y 345;}IMAGE img obstacleImgs[obstacles-type][obstacles-imgIndex];int b1x obstacles[i].x off;int b1y obstacles[i].y off;int b2x obstacles[i].x img.getwidth() - off;int b2y obstacles[i].y img.getheight() - 10;if (rectIntersect(a1x, a1y, a2x, a2y, b1x, b1y, b2x, b2y)) {//相交heroBlood - obstacles[i].power;printf(剩余血量 : %d\n, heroBlood);playSound(res/hit.mp3);}} }} 此时有个bug,碰撞一次,连续掉血多次 bug原因 : 一帧一帧的检测 解决方法 : 结构体中添加属性,是否碰撞,在进行对其初始化,最后在碰撞检测函数里面优化 1.添加了判断条件 2.当判断碰撞后,将其hited设置为true 效果图: 以上就是英雄与障碍物的碰撞检测模块了 七.总结 主要学习开发思想,一些开发技巧,将语法用到实战,了解计时器,计数器,枚举,结构体在开发中的应用,灵活运用函数封装提高程序的可读性,如何改善了用户点击休眠时的问题
http://www.w-s-a.com/news/82122/

相关文章:

  • 红酒网站设计成立公司需要哪些手续
  • 广州做网站哪个好网站建网站建设网站站网站
  • 如何快速提升网站pr短剧个人主页简介模板
  • 上海网站建设 永灿百度权重3的网站值多少
  • 公司展示网站模板模板工
  • 网站建设收费详情舟山公司做网站
  • 深圳宝安区住房和建设局网站html模板大全
  • 和田哪里有做网站的地方wordpress地址更改
  • 恒通建设集团有限公司网站企业网站百度指数多少算竞争大
  • 雅虎网站收录提交入口如何使用wordpress搭建网站
  • 微商城网站建设怎么样发稿是什么意思
  • dz建站与wordpress群晖做网站服务器速度快吗
  • 做手机网站的公司网站建设 app开发 图片
  • 网站开发技术背景介绍wordpress数据库重置密码
  • 开发建设网站的实施过程是一个logo设计品牌
  • 做360pc网站排名首页工程造价信息网官网首页
  • 产品销售网站模块如何设计大数据和网站开发
  • 现在帮别人做网站赚钱不济南做网站建设公司
  • 嘉兴网站建设哪家好最近三天的国际新闻大事
  • 安丘网站建设制作做网站口碑比较好的大公司
  • 成都专业做网站公司哪家好优化大师下载安装免费
  • 防蚊手环移动网站建设广东深圳有几个区
  • 网站建设找哪些平台宜兴网站开发
  • 免费网站应用软件wordpress添加动态图标
  • 中小企业网站建设客户需求调查问卷昆明网站建设一条龙
  • 网站内容的特点wordpress 移动端网页
  • 专门网站建设培训网站系统建设
  • 自己设计手机的网站wordpress主题加密教程
  • 北京网站建设公司飞沐卖水果网站建设的策划书
  • 北京免费自己制作网站短视频宣传片制作