用 HTML5 Canvas 写一个下落音游模拟器!

Posted by XTXTMTXTX on 2018-11-29
Web


越忙越给自己找点感兴趣的事儿做有时候也能改善下心情(拖延)
  前几天整了下js,不得不说这东西坑是真的多,对我这种之前写C++(其实写出来像C)的人来说有点不友好。

一开始听说js是弱类型,觉得很方便,就开始放飞自我,完全没考虑数据类型,字符串乘数字、字符串当数字加导致数字溢出之类的操作满.html起飞,好在debug了一万次之后终于慢慢改过来了,最终虽然也有点小问题不过已经和osu!mania的感觉差不多了。

好了,我们先来看怎么玩这个东西(推销),网站在这里 当然 这里也可以,不过那个是放在国外的php免费空间上,可能会导致因加载过慢而卡住的坑。 具体就是读取osu!mania谱面,分析谱面,得出结论,然后只支持4K,因为我懒得根据Key数搞一大堆特判,不过以后说不定会加入7k(咕咕咕)。
  Bug还有点,也没任何处理错误的语句,不过比较懒,玩起来效果还不错了就这样吧(之前不小心打开了张主模式的图导致我一直以为js写错了又耗了好久,错误处理真的有点必要)。最后还加了个成绩图,不过就不要想和osu是一样的计分规则了,也没有什么缓动动画,然而能玩,能看变速特效,OK了。

然后我们来看看写这么个东西过程中遇到的坑。

首先是变量的类型,因为我不注意写着写着变量变字符串类型了我还以为还是数字,一旦a+b就会越来越长,最后出现奇奇怪怪的问题,debug到死才发现不对劲。
  然后<script></script>的地方也有讲究,放在文档前面就会先于HTML加载出来之前执行,嗯,比较基础,但我就是被坑了会儿
  canvas绘制过程中需要反复调用draw(),然而如果你在draw()最后requestAnimationFrame (draw()),那就可能递归下去,最终导致浏览器越来越卡(还可能卡爆系统)。
  在程序块里用var声明的变量在块外都还在,和我以前接触到的实在不一样,比如

1
2
3
4
5
var a=1;
for(var i=0;i<1;i++){
var a="a";
}
alert(a);

就会弹出"a"。好在没被坑到,想要像c一样的话用let而不是var。
  removeEventListener的参数要和addEventListener的参数完全一致才可以移除,而且不可以用匿名函数。
  canvas.height改的是canvas的画布的高度,而canvas.setAttribute(“style”,“height: xxxpx;”);改的是最终显示大小,和canvas.height不一致将会导致canvas画布被缩放。
  html5的audio.play()有肉眼可见延迟,导致不方便倒计时时间的预判,另外iOS不允许音频自动播放,但我懒得再处理了(本来还想拿ipad试试)。
  监听触控事件最好在回调函数里开头加上e.preventDefault();不然肯导致移动设备的屏幕缩放之类的事发生。
  监听触控事件返回的X,Y是相对页面而不是你所监听的对象的坐标,因此处理之前要先吧得到的坐标减掉那个对象的坐标,比方说我关注相对canvas的水平距离,那就e.changedTouches[0].clientX-c.offsetLeft。
  利用ajax访问本域上的.osu谱面文件时发现404了,可是我明明传上去了,然而直接用浏览器也404。实在没办法就把后缀名改txt,结果成了。不过目前还没什么头绪为什么会这样,可能是php空间的文件处理机制导致的。
  
  另外别的想不出来什么了,那就放一下我之前推的根据间隔时间求屏幕像素距离的公式
  间隔时间*屏幕Y像素/(下落整屏所需时间*当前小节拍子时长*绿线百分比/基准拍子时长)
  这样的话要求当前时间某个物体相对判定线的距离,只要先找到在当前时间之前的最近的一个TimingPoint作为基准TimingPoint,先将基准TimingPoint时间到物件时间之间的所有TimingPoint分割出来的完整的时间区域用上述公式计算距离并累加,再计算最后一小段的时间的距离。同理求当前时间相对基准TimingPoint的距离,减一下就是要求的物件的距离了。
  
  完整代码在github,目前支持移动设备的触控操作,不过iOS因为各种各样的原因玩不了。然后玩在线谱面可能会因为缓冲块不够而卡住或重放,目前还不知道怎么让它先把整个音频文件加载完。
  
  目测会有一段时间不碰js了,打算抽时间恶补写软件时的一些规范,之前搞习惯了oi习惯了那一套格式,现在写大的程序都debug无力(,而且辅导员看了我的github都说我的程序怎么看怎么像C)
  
  最后放一张osu!mania的判定时间图吧,说不定你们也想写呢(笑)。
这是图


当你在凝视深渊的时候 深渊也正在凝视着你