第一次开发小游戏,用的是Hilo框架。由于项目开发时间比较紧张,对游戏和CANVAS都没有了解过。代码虽然写的很烂,但是还是记录下踩过的坑吧!本文为碎碎念模式,并不深入,写错的地方希望多多指点。

一、CANVAS横屏适配处理

游戏是微信内的一款横屏游戏。如果强制横屏,提示用户去控制横竖屏开关并不友好。

解决方案,游戏场景做成如下图紫色部分结构,游戏宽高和手机屏幕调换。如果手机为竖屏,那么将游戏旋转90°即可。

注:所述【横屏】为用户打开了允许横屏的开关并横屏,真正的横屏。

代码如下所示:

let width = document.documentElement.clientWidth;
let height =  document.documentElement.clientHeight;
let box =  document.getElementsByTagName('canvas');
let style = '';
// 竖屏
if (width < height) {style += `width:${height}px;`;style += `height:${width}px;`;style += '-webkit-transform: rotate(90deg); transform: rotate(90deg);';// 注意旋转中点的处理style += `-webkit-transform-origin: ${width / 2}px ${width / 2}px;`;style += `transform-origin: ${width / 2}px ${width / 2}px;`;
}if (box.length) {box[0].style.cssText = style;
}
复制代码

当用户开启了横屏开关,如果用户横屏,那就将游戏场景旋转0°即可,也就是恢复最初的样子。如下:

// 横屏
if (width > height) {style += `width:${width}px;`; // 注意旋转后的宽高切换style += `height:${height}px;`;style += '-webkit-transform: rotate(0); transform: rotate(0);';style += '-webkit-transform-origin: 0 0;';style += 'transform-origin: 0 0;';
}if (box.length) {box[0].style.cssText = style;
}
复制代码

横屏没想象那么顺利,我们的游戏是在微信场景。当用户开启横屏开关并横屏后,微信内置浏览器头也会占一大部分区域。这样我们的游戏场景旋转后明显是显示不全的。

解决方案就是利用Hilo的api resize下舞台

// 解决微信横屏浏览器头部 导致高度变化的问题
this.stage.resize(height, width, true);
复制代码

最后有几个注意点:

1、注意旋转过程中的宽高切换2、注意单位适配问题3、注意微信浏览器头,就因为这个头的变化。整个游戏都需要处理,所以还是尽量不要自己处理。。。
复制代码

参考文章

二、点击事件失效

如下图所示,游戏结束场景的2个按钮。

左侧旋转90°后变成右侧横屏,但是竖屏下的横屏(也就是旋转90°得来的)【再来一次】按钮点击事件会失效,但是点击红色区域(没有按钮,大致绘制并不精准)部分这个时间会被触发。

而用户横屏(开启了横屏开关,自然横屏)【再来一次】按钮点击事件不会失效。

绘制时坐标以游戏场景左上角为(0,0),而旋转90°后坐标以游戏场景左下角为(0,0)。因为旋转90°后游戏场景左下角变成了视觉上的左上角。因此竖屏下的横屏点击红色区域生效就是因为,Hilo的点击事件是绑定在元素绘制时坐标区域上(猜测,没有看源码)。旋转后,按钮的点击事件生效区间就变成了根据绘制的x、y也就是红色区域。

那么如何解决这个问题,如上图所示,旋转后的x、y如图中蓝色字所示。可以算出

// 再玩一次按钮
const start = this.gameOverScene.getChildById('start');
// 再玩一次按钮 新的x = 游戏画布宽度 - 绘制的y - 按钮的高度
const startNewX = this.width - start.y - start.height ;
// 再玩一次按钮 新的y = 绘制的x
const startNewY = start.x;
// 监听舞台点击事件
this.stage.on(Hilo.event.POINTER_START, (e) => {// 利用新的x、y 和按钮自身的高度和宽度 判断是否点击在按钮区域if ((e.stageX > startNewX && e.stageX < startNewX + start.height) &&(e.stageY > startNewY && e.stageY < startNewY + start.width)) {// 在玩一次逻辑处理}
)};
复制代码

【再玩一次】按钮点击事件解决了,但是事情没有那么简单。

给另一个【分享】按钮加上事件,what?无论横屏还是竖屏点击事件都不生效。至少【再玩一次】按钮事件还是生效的,只是不准罢了。

原因,观察上述图。【分享】按钮在初始化的过程中是在游戏画布右侧,也就是手机屏幕外部。经过测试发现,发现绘制时在手机屏幕外的区域点击事件都不会生效。解决方法如【再玩一次】,无论横屏还是竖屏都计算坐标判断。

三、音乐播放兼容

Hilo的HTMLAudio声音播放模块,官方文档表示【使用限制:iOS平台需用户事件触发才能播放,很多Android浏览器仅能同时播放一个音频。】但是目前使用来看,浏览器测试OK,绝大部分手机都不能正常播放。解决方案,采用DOM的audio,但是同样iOS平台需用户事件触发才能播放。因此最终的解决方案就是进入游戏之前或者某个合适的环节获取所有的音乐,先播放再暂停。用户不会感知,可以完美解决。如下:

// html
<audio id="audio"  src="xxx.mp3" preload="auto"></audio>
// dom为获取
const dom = document.getElementById('audio');
dom.play();
dom.pause();
复制代码

四、部分机型游戏场景显示不全

游戏中可能有某些元素是经常复用的,因此会单独切出来。如下图左侧

如上图右侧所示效果,最开始的实现方式如下。在初始化的时候就将公用元素Y轴截断展示,这个效果看似OK,但是在测试阶段发现某些iPhone手机不能显示这2个元素。

new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect: [0, 100, 50, 300],y: 0,
});
new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect:[0, 150, 50, 300],y: 0,
});复制代码

查看Hilo源码绘制图片是用CanvasRenderingContext2D.drawImage方法。

CanvasRenderingContext2D.drawImage() 是浏览器原生提供的在 canvas 上绘制图片的方法。

其有以下三种参数形式(详细用法说明及演示可见 MDN):

  1. ctx.drawImage(image, dx, dy);
    ctx.drawImage(image, dx, dy, dWidth, dHeight);
    ctx.drawImage(image, sx, sy, sWidth, sHeight, dx, dy, dWidth, dHeight);
    复制代码
参数 意义
sx, sy 源图像的选择区域的偏移量
sWidth, sHeight 源图像的选择区域的宽高
dx, dy 目标canvas的选择区域的偏移量
dWidth, dHeight 目标canvas的选择区域的宽高

注:

  1. 在 Chrome 和 Firefox 下,最终的选择区域超出源图像的部分不会被绘制。
  2. 在 IE 和 Edge 下,最终的选择区域超出源图像的部分会用图像的边界像素来填充。
  3. Safari 7.1 额外要求 sx + sWidthsy + sHeight 不超过源图像的宽高,否则 drawImage() 函数不会绘制任何图像。(未在更高版本的 Safari 上测试)
  4. 在支持 canvas 的老版本的 Firefox 上,有着和 IE 等浏览器类似的对 sx, sy, sWidth, sHeight 的限制,在新版本中,这些限制已经被移除。

而我们的元素在部分机型上不能显示就是因为触发了第3点坑。修复代码如下,通过完整的绘制图片,然后通过元素的坐标来达到目标样式。

new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect: [0, 0, 50, 300],y: -100,
});
new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect:[0, 0, 50, 300],y: -150,
});
复制代码

参考文章

五、碰撞检测,撞击坐标不准确

用Hilo最开始开心的一点也是碰撞检测不需要自己写,hitTestObject检测object参数指定的对象是否与其相交。因此撞击区域可以书写撞击坐标。

// 给如下图中的一个多边形实行撞击坐标
new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect: [0, 0, 50, 300],y: -100,boundsArea: [// 测试坐标,非精准坐标,图中红点的坐标,从左到右{x: 0, y: 0},{x: 0, y: 100},{x: 100, y: 100},{x: 100, y: 200},{x: 200, y: 200},{x: 200, y: 100},{x: 300, y: 100},{x: 300, y: 0},]
});
复制代码

理想中应该是如下黄色区域构成的碰撞检测区域。

而实际却是如下黄色区域,空气墙???用户反馈为什么没撞到就死翘翘了。(看了Hilo碰撞检测这部分的实现源码,没太看懂多边形的处理。。)

解决办法,类似雪碧图使用,恩...主要是懒得切图

new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect: [0, 0, 100, 100],y: 0,boundsArea: [// 测试坐标,非精准坐标,图中红点的坐标,从左到右{x: 0, y: 0},{x: 0, y: 100},{x: 100, y: 100},{x: 100, y: 0},]
});
new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect: [100, 0, 100, 200],y: 0,boundsArea: [// 测试坐标,非精准坐标,图中红点的坐标,从左到右{x: 0, y: 0},{x: 0, y: 200},{x: 100, y: 200},{x: 100, y: 0},]
});
new Hilo.Bitmap({// 绘制的图片image: 'imgurl', // 测试坐标,非精准坐标rect: [200, 0, 100, 100],y: 0,boundsArea: [// 测试坐标,非精准坐标,图中红点的坐标,从左到右{x: 0, y: 0},{x: 0, y: 100},{x: 100, y: 100},{x: 100, y: 0},]
});
复制代码

其实就是将1张图裁剪成了3张图,裁剪出来的区域撞击坐标都中规中矩。过于不规则的图形只能尽量写的粗糙一些。

这么轻松就解决了吗???当然NO!!!回顾下第四点,部分机型游戏场景显示不全。上面裁剪的3张图里,最后一张图又触发了safari的bug。o(╥﹏╥)o,所以还是乖乖切图,或者雪碧图留一点安全区域吧!

而且后来我才知道雪碧图对于CANVAS来说更耗性能,还不如多切点图呢~

转载于:https://juejin.im/post/5ba0dea5f265da0aa3591f8d

Hilo开发H5小游戏踩坑笔记相关推荐

  1. mpvue开发微信小程序踩坑笔记

    在列表page点击进入详情页面时,用mounted()方法 去获取数据去展示数据,但是有些数据需要在onShow()方法中调用,因为mpvue框架问题,所以在返回的时候如果不将data中定义的数据清除 ...

  2. 使用cocoscreator打包vivo小游戏踩坑

    使用cocoscreator打包vivo小游戏踩坑 首先打开cocos creator的官方文档 首先打开cocos creator官网 然后打开文档打开cocoscreator的文档下面是图片 打开 ...

  3. 小游戏开发 小程序app游戏开发 H5小游戏开发

    目前有很多人对小游戏的理解都不同,有的人认为小游戏是H5嵌入形式的,也有的人认为小游戏是就几兆的程序 其实大家认为的都是正确的,没有任何问题.那么今天给大家讲下小游戏之间的区别 1.H5小游戏嵌入:这 ...

  4. Egret 生成 自带EUI 的微信小游戏 踩坑!

    1. 首先,再次被网上一大堆屎一样的资料搞得浪费了我一天时间.各种坑. 2. 本文先讲一种正确的方式,然后再列举坑. 去www.egret.com下载最新的引擎,我的最新版本是5.2.2. 然后就会被 ...

  5. 微信小游戏踩坑记录(二)

    2019独角兽企业重金招聘Python工程师标准>>> 微信视频组件 这次是关于视频组件的,creator的视频组件在小游戏中是没有用的,只能使用小游戏自带的组件.使用小游戏Vide ...

  6. 疫情在家游戏玩腻了?那就一起来开发H5小游戏吧

    前提:游戏玩腻了?作为一名合格的程序员,应该自己开发小游戏来玩,玩腻了,自己就再去开发个游戏,利用这一特点实现永动机.既可以学习,也可以娱乐. 本次开发的是贪吃蛇小游戏.使用技术:html.css.原 ...

  7. uniapp 开发微信小程序踩坑:TypeError: Cannot read property ‘FormData‘ of undefined

    需求: UniApp 的 H5 端已经正常使用,现在打算兼容微信小程序. 1. 问题分析 本以为应该很顺利,但是一上来就直接报错了,心里很慌呀,报错信息如下: 页面[components/major/ ...

  8. Egret 开发H5小游戏

    Egret Wing 代码编辑器 ResDepot 静态资源加载器 项目目录主要构成:resource文件夹下的新建的游戏文件(用于存放图片,音频和json文件等资源).新建游戏同名的 .ts 文件( ...

  9. h5小游戏制作开发大概要多久,微信h5的游戏开发成本有多少?

    国内有很多商家在用h5的游戏做营销,诸如TOM游戏等出色的开发商也脱颖而出,成为了H5小游戏定制领域的翘楚,本期我们借助TOM游戏,分析一款h5小游戏制作开发大概要多久,微信h5的游戏开发成本有多少, ...

最新文章

  1. php连接mysql数据库测试_php连接mysql数据库连接测试文件
  2. html5网站测试工具,基于HTML5网页的前端技术测试技巧
  3. linux centos 下载rpm源码包
  4. spring boot中servlet启动原理
  5. ubuntu同时装有MXNet和Caffe框架
  6. java 各组件单击总数_java 获取面板上有多少个组件
  7. little w and Sum(思维)
  8. iOS研发助手DoraemonKit技术实现(一)
  9. SQL查询数据以及排序
  10. 2022年Java面试题---中科创达
  11. c语言课程设计--打飞碟源代码,c语言课程设计_打飞碟提高篇.doc
  12. ubuntu 开机后 按键 鼠标不能用
  13. python输入三个数形成各种三角形
  14. Google战略的深远意义
  15. element-ui table表格。数组对应的一组数据占有两行怎么处理?
  16. uni-app 数据上拉加载更多功能
  17. 【计算机网络】路由器和交换机的基本配置
  18. 【NOIP2014】提高组初赛答案加解析
  19. 有趣的兔子(斐波那契数列)
  20. java module和model_Java9-Modularity 初探

热门文章

  1. 2017.4.7 e.toString() 与 e.getMessage()的区别
  2. FreeSwitch安装和配置记录
  3. ie不支持getElementsByName的解决办法
  4. SQL FOREIGN KEY 约束
  5. http默认超时时间_Bof 是一个HTTP客户端,旨在尽可能方便用户使用
  6. 神经网络与机器学习 笔记—基本知识点(下)
  7. 【错误记录】GitHub 提交报错 ( OpenSSL SSL_connect: SSL_ERROR_SYSCALL in connection to github.com:443 )
  8. 【Android 逆向】启动 DEX 字节码中的 Activity 组件 ( 在 PathClassLoader 和 BootClassLoader 之间插入 DexClassLoader )
  9. 【C 语言】数组与指针操作 ( 数组符号 [] 与 指针 * 符号 的 联系 与 区别 | 数组符号 [] 与 指针 * 符号 使用效果 基本等价 | 数组首地址 与 指针 本质区别 )
  10. 【错误记录】Tinker 热修复示例运行报错 ( Execution failed for task ‘:app:tinkerProcessD‘ . tinkerId is not set!!! )