18910140161

Hilo开发H5小游戏踩坑笔记

顺晟科技

2021-06-16 10:38:29

271

次用Hilo框架开发了一个小游戏。因为项目开发时间短,不了解游戏和CANVAS。虽然代码写的很烂,但是记录下你踩过的坑!本文是一种断想模式,不深入。希望写错了能多指点指点。

I . CAVEN水平屏幕适配处理

游戏是微信里的横屏游戏。如果强制水平屏幕,提示用户控制水平和垂直屏幕开关是不友好的。

解决方案:游戏场景做成如下图紫色部分结构,游戏宽度和高度随手机屏幕变化。如果手机是垂直屏幕,将游戏旋转90度。

注意:【横屏】为用户打开允许横屏的开关,做出横屏,这才是真正的横屏。

垂直屏蔽

代码如下所示:

let width=document . document element . client width;

let height=document . document element . client height;

let box=document . getelementsbytagname(' canvas ');

let style=

//垂直屏幕

if(宽度高度){

style=`width: $ { height } px`;

style=`height: $ { width } px`;

style='-web kit-transform : rotate(90 deg);变压器:旋转(90度);';

//注意旋转中点的处理

style=`- web kit-transform-origin : $ { width/2 } px $ { width/2 } px;`;

style=` transform-origin : $ { width/2 } px $ { width/2 } px;`;

}

if (box.length) {

box[0]. style . CSS text=style;

}

当用户打开横屏开关,如果用户是横屏,游戏场景可以旋转0,也就是恢复原来的样子。以下:

水平屏幕

//水平屏幕

if(宽度高度){

style=`width: $ { width } px`;//注意旋转后的宽高切换

style=`height: $ { height } px`;

style='-web kit-transform : rotate(0);transform : rotate(0);';

style='-web kit-transform-origin : 0;0 ';

style=' transform-origin : 0 0;';

}

if (box.length) {

box[0]. style . CSS text=style;

}

横屏没有我想象的那么顺利。我们的游戏在微信场景。当用户打开横屏开关,横屏时,微信内置的浏览器头也会占据很大一部分面积。这样,我们的游戏场景旋转后明显不完整。

解决办法是使用Hilo的api resize来走下舞台

//解决微信横屏浏览器头部引起的高度变化问题

this.stage.resize(高度,宽度,true);

最后有几点注意:

1、旋转过程中注意宽度和高度的切换

2.注意单位适应问题

3.关注微信浏览器的页眉,因为这个页眉的变化。整个游戏都需要处理,尽量不要自己处理。

参考文章

第二,点击事件无效

如下图,游戏结束场景有两个按钮。

左侧旋转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 start newx e . stagex start newx start . height)

(e . stagey start new y e . stagey start new y start . width)){

//播放逻辑处理一次

}

)};

【再次播放】按钮点击事件解决了,但没那么简单。

将事件添加到另一个共享按钮,什么?无论横屏还是竖屏点击事件都会生效。至少[再次播放]按钮事件仍然有效,但这是不允许的。

原因,观察上图。初始化时[Share]按钮在游戏画布的右边,也就是手机屏幕外面。经过测试,发现手机屏幕外区域的点击事件在绘制时不会生效。《再玩一次》等解决方案,不管横屏还是竖屏,计算坐标判断。

第三,音乐播放兼容

Hilo的HTMLAudio声音播放模块,官方文件说【使用限制:iOS平台只能在用户事件触发的情况下播放,很多Android浏览器一次只能播放一个音频。但是目前浏览器测试还可以,大部分手机都不能正常播放。解决方案使用DOM的音频,但同样的iOS平台需要用户事件触发才能播放。所以,最终的解决办法是在进入游戏之前或者在一个合适的链接上获取所有的音乐,然后先播放再暂停。用户不会察觉,可以完美解决。以下:

//html

audio id=' audio ' src=' XXX . MP3 ' preload=' auto '/audio

//dom是获取

const DOM=document . getelementbyid(' audio ');

DOM . play();

DOM . pause();

第四,部分机型的游戏场景没有充分展现

游戏中可能有一些元素经常被重复使用,所以会单独裁剪掉。下图左侧

上图右侧所示效果的初步实现如下。初始化时,公共元素的Y轴被截断并显示。这个效果看起来还可以,但是发现有些iPhone在测试阶段无法显示这两个元素。

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect: [0,100,50,300],

y: 0,

});

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect:[0,150,50,300],

y: 0,

});

看一下Hilo源代码,用canvasrenderingcontext2d画图。drawimage方法。

Canvasrenderingcontext2d。drawimage()是浏览器本身提供的在画布上绘制图片的方法。

它有以下三种参数形式(详细说明和演示见MDN):

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 |源图像选定区域的偏移量|

源图像选定区域的宽度和高度

| dx,dy |目标画布选定区域的偏移量|

|宽度、深度|目标画布选定区域的宽度和高度|

注意:

在chrome _ 6494 _ 1 . html ' target=' _ blank ' chrome和Firefox下,不会绘制源图像以外的最终选择区域部分。

在IE和Edge下,最终选择区域超出源图像的部分将被图像的边界像素填充。

Safari 7.1另外要求sx sWidth和sy sHeight不能超过源图像的宽度和高度,否则drawImage()函数不会绘制任何图像。(未在更高版本的Safari上测试)

在老版本支持canvas的Firefox上,sx sx,sy,sWidth,sHeight to IE等浏览器也有类似的限制。在新版本中,这些限制已被删除。

我们的元素不能在一些模型上显示,因为第三个坑被触发了。修复代码如下:把画面画完整,然后通过元素的坐标达到目标风格。

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect: [0,0,50,300],

y: -100,

});

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect:[0,0,50,300],

y: -150,

});

参考文章

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

使用Hilo个开心的事情就是碰撞检测不需要自己写,hitTestObject检测对象参数指定的对象是否与它相交。所以撞击区可以写撞击坐标。

//给下图中的多边形一个碰撞坐标

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect: [0,0,50,300],

y: -100,

边界区域: [

//测试坐标,不坐标,图中红点坐标,从左到右

{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碰撞检测的源代码,不太懂多边形处理。)

解决方案,类似于雪碧的使用,是,嗯.主要是懒得剪图。

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect: [0,0,100,100],

y: 0,

边界区域: [

//测试坐标,不坐标,图中红点坐标,从左到右

{x: 0,y: 0},

{x: 0,y: 100},

{x: 100,y: 100},

{x: 100,y: 0},

]

});

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect: [100,0,100,200],

y: 0,

边界区域: [

//测试坐标,不坐标,图中红点坐标,从左到右

{x: 0,y: 0},

{x: 0,y: 200},

{x: 100,y: 200},

{x: 100,y: 0},

]

});

新希洛。位图({

//画的图

image: 'imgurl ',

//测试坐标,不坐标

rect: [200,0,100,100],

y: 0,

边界区域: [

//测试坐标,不坐标,图中红点坐标,从左到右

{x: 0,y: 0},

{x: 0,y: 100},

{x: 100,y: 100},

{x: 100,y: 0},

]

});

其实一张图切三张图,切出来的区域冲击坐标都还算满意。太不规则的图形只能尽量粗略的写。

这么容易解决吗?当然没有!回过头来看第四点,有些机型的游戏场景并没有完全展现出来。上面剪的三张图片,最后一张又触发了safari bug。O ( ) o,所以更好切地图,或者给雪碧留个安全区!

而且后来我了解到Sprite对于CANVAS来说性能更密集,所以切点多一点比较好~

相关文章
我们已经准备好了,你呢?
2024我们与您携手共赢,为您的企业形象保驾护航