如何通过可视化游戏编程发布H5游戏?

在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。
标签:至少1个,最多5个
闲来无事做了个H5的音乐可视化,下面上主要部分的代码。包含部分AudioContext api的注释。
AudioContext api部分,相当于房子的原材料。
musicVisualizer.ac = new(window.AudioContext || window.webkitAudioContext)();
//实例化一个音频类型window.AudioContext,后面是为了兼容Chrome浏览器
function musicVisualizer(obj) {
this.source = //初始化音频资源变量
this.analyser = musicVisualizer.ac.createAnalyser(); //这一步是非常重要的,createAnalyser()可以创建一个/AnalyserNode/用来获取音频的各项数据,实现音乐可视化
this.size = obj. //这里是 index.js里面实例化原型的参数obj中的大小属性
this.analyser.fftSize = this.size * 2;//fftsize(AnalyserNode的一个属性)是一个无符号长整型的值, 用于确定频域的 FFT (快速傅里叶变换) 的大小.fftSize 属性的值必须是从32到32768范围内的2的非零幂; 其默认值为2048.总之最后获取到的数组长度应该是fftSize值的一半,还应该保证它是以2为底的幂。
this.xhr = new XMLHttpRequest();//这个就很熟悉了对于大家而言,创建ajax对象
this.analyser.connect(musicVisualizer.ac.destination);//musicVisualizer.ac.destination是音频要最终输出的目标,所有节点中的最后一个节点应该再连接到musicVisualizer.ac.destination播放声音
this.visualizer = obj.//这里是 index.js里面实例化原型的参数obj中的canvas绘画音乐节点实现节奏可视化
this.visualize();
musicVisualizer.prototype.load = function(url, fun) {
this.xhr.abort();//停止正在进行的ajax请求
this.xhr.open("GET", url);
this.xhr.responseType = "arraybuffer";
var self =
this.xhr.onload = function() {
fun(self.xhr.response);
this.xhr.send();
musicVisualizer.prototype.decode = function(arraybuffer, fun) {
musicVisualizer.ac.decodeAudioData(arraybuffer, function(buffer) {
//decodeAudioData用于异步解码音频文件中的arrayBuffer数据
fun(buffer);
}, function(err) {
console.log(err);
musicVisualizer.prototype.stop = function() {
this.source[this.source.stop ? "stop" : "noteOff"](0);
musicVisualizer.prototype.visualize = function() {
var arr = new Uint8Array(this.analyser.frequencyBinCount);
//frequencyBinCount通常是可视化数据值的数量,为fftSize的一半
requestAnimationFrame = window.requestAnimationFrame || webkitRequestAnimationFrame || mozRequestAnimationF//window.requestAnimationFrame() 方法告诉浏览器您希望执行动画,并请求浏览器调用指定的函数在下一次重绘之前更新动画。该方法将在重绘之前调用的回调作为参数。
var self =
function v() {
self.analyser.getByteFrequencyData(arr);
//getByteFrequmencyData把当前频率数据复制到传入其中的Uint8Array
self.visualizer(arr);
requestAnimationFrame(v);
requestAnimationFrame(v);
musicVisualizer.prototype.play = function(url) {
var self =
this.source && this.stop();
this.load(url, function(arraybuffer) {
self.decode(arraybuffer, function(buffer) {
var bs = musicVisualizer.ac.createBufferSource();
//createBufferSource() 方法用于创建一个新的AudioBufferSourceNode接口, 该接口可以通过AudioBuffer 对象来播放音频数据. AudioBuffer对象可以通过AudioContext.createBuffer 来创建或者通过 AudioContext.decodeAudioData成功解码音轨后获取.
bs.connect(self.analyser);
bs.buffer =
bs[bs.start ? "start" : "noteOn"](0);
self.source =
H5 canvas可视化部分。原材料的粘合剂
var size = 64;
var box = $("#box")[0];
var height,
var canvas = document.createElement('canvas');
var ctx = canvas.getContext("2d");
box.appendChild(canvas);
var Dots = [];
draw.type = "column";
window.onresize =
var mv = new musicVisualizer({
size: size,
visualizer: draw
var clickMusic = (function () {
var lis = $(".music li");
lis.click(function() {
var i = $(this).index();
lis.css('color', 'white');
lis.eq(i).css('color', 'grey');
mv.play('./musics/' + lis.eq(i).html());
function random(m, n) {
return Math.round(Math.random() * (n - m) + m);
function getDots() {
Dots = [];
for (var i = 0; i & i++) {
var x = random(0, width);
var y = random(0, height);
var color = "rgba(" + random(0, 255) + "," + random(0, 255) + "," + random(0, 255) + ",0)";
Dots.push({
color: color,
dx: random(1, 4)
var resize = (function () {
height = box.clientH
width = box.clientW
canvas.height =
canvas.width =
line = ctx.createLinearGradient(0, 0, 0, height);
line.addColorStop(0, "pink");
line.addColorStop(0.5, "grey");
line.addColorStop(1, "lightblue");
getDots();
function draw(arr) {
ctx.clearRect(0, 0, width, height);
var w = width /
var cw = w * 0.6;
ctx.fillStyle =
for (var i = 0; i & i++) {
var o = Dots[i];
if (draw.type == "column") {
var h = arr[i] / 256 *
ctx.fillRect(w * i, height - h, cw, h);
ctx.fillRect(w * i, height - (o.cap + ch), cw, ch);
if (o.cap & 0) {
o.cap = 0;
if (h & 0 && o.cap & h + 30) {
o.cap = h + 30 & height - ch ? height - ch : h + 30;
} else if (draw.type == "dot") {
ctx.beginPath();
var r = 10 + arr[i] / 256 * (height & width ? width : height) / 10;
ctx.arc(o.x, o.y, r, 0, Math.PI * 2, true);
var circle = ctx.createRadialGradient(o.x, o.y, 0, o.x, o.y, r);
circle.addColorStop(0, "white");
circle.addColorStop(1, o.color);
ctx.fillStyle =
ctx.fill();
o.x = o.x & width ? 0 : o.x;
var changeStyle = (function () {
var spans = $(".musicList span");
spans.click(function() {
var i = $(this).index();
spans.removeClass('selected')
.eq(i).addClass('selected');
draw.type = spans.eq(i).attr('type');
完整源码在这里
0 收藏&&|&&3
你可能感兴趣的文章
22 收藏,3.2k
5 收藏,938
3 收藏,1.3k
本作品采用 署名-非商业性使用-禁止演绎 4.0 国际许可协议 进行许可
分享到微博?
我要该,理由是:
在 SegmentFault,学习技能、解决问题
每个月,我们帮助 1000 万的开发者解决各种各样的技术问题。并助力他们在技术能力、职业生涯、影响力上获得提升。17:50 304412
本帖最后由 xsstomy 于
14:53 编辑
这个是本人踩过很多坑,也看过很多例子,再实践出来的一套可行性方案,主要是用于解决在Egret_Wing游戏项目中直接进行界面可视化设计,并且支持精灵表单的可视化设计. !!!本教程是基于Egret_wing2.1.3 ,EgretEngine2.5.4,不知道如何更新到这个版本的,可以直接在EgretEngine里面打开社区体验版.好了,废话不多说了,直接开始正题吧.
一:由于用Egret开发游戏,我们一般都是新建Egret游戏项目,但是新建游戏项目后,你会发现里面再新建EXML皮肤是毫无反应的,那怎么办?不可能开两个工程,一个Egret游戏项目,一个Egret_EUI项目吧。当然不是,不过EgretIDE真心还有很大的进步空间。
01.png (10.66 KB, 下载次数: 0)
17:15 上传
,新建的Egret游戏项目是没有eui这个模块的,所以我们要手动添加下,具体怎么添加,这个可以自己摸索或者百度一下Egret添加外部库
&&2:eui库添加完毕后应该是这个样子的 & &
02.png (32.32 KB, 下载次数: 0)
17:18 上传
,在我们的egretProperties.json里面添加eui引用,再编译下就会自动在module下面添加eui库了。
3.你以为添加了eui库就可以新建EXML皮肤了吗?那你错了。。。接着来
3.png (15.53 KB, 下载次数: 0)
17:35 上传
拷贝EUI项目中的assets和eui_skins文件夹(可以新建一个EUI项目,然后拷贝这两项就可以了)到你对应的游戏项目的resource的文件夹
4:拷贝EUI项目中resource的一个主题文件default.thm.json到对应的游戏项目resource目录下。
04.png (24.88 KB, 下载次数: 0)
17:38 上传
内容大概是这样
5:接着配置你这个项目的项目属性,如图
05.png (14.09 KB, 下载次数: 0)
17:40 上传
06.png (20.35 KB, 下载次数: 0)
17:40 上传
配置好资源和主题以后,你已经成功2/3了
6:我们需要在Main.ts(主程序入口,当然也可以是你自己设置的一个入口)中,当resource配置加载完毕后面加上这句话 new eui.Theme(&resource/default.thm.json&,this.stage);
好了,你已经成功了,不过这只是初级的,来个高级的拓展,为了能在设计界面的时候直接应用sheet里面某个小图,实现可拖拽,那你还需要继续往下看。
7:拷贝两个文件到你项目目录中(具体位置可以自己定,文件是在附件中)
(2.67 KB, 下载次数: 15)
17:45 上传 点击文件名下载附件 下载积分: 银子 -1
& &然后修改你的Main.ts如下
07.png (28.51 KB, 下载次数: 3)
17:46 上传
,为什么要这么搞,在你进行可视化界面设计的时候就明白了,比如你用TextMeger打包了一个纹理图集叫icon的,然后里面有两个图片,一个叫start,一个叫end。如果你不做第7步,那在你的EXML界面里面引用资源的时候需要填写全路径,比如icon.start,但是加了以后,你只需要引用start就可以了。
好了,这样你就可以在Egret游戏项目里面使用eui项目里面的设计功能了。
最后说一句,如果发现按照这些步骤做了都不能新建皮肤文件,建议关掉Egret_wing再打开下,我的就遇到这个情况了,希望官方团队积极改进了
& | <em id="authorposton8-11-4 18:22:00
我记得之前GUI的时候,WING有一个功能叫做导入项目,导入以后,会自动配置好GUI相关的东西,可以直接用gui了,eui还没用,不知道还可以不可以
& | <em id="authorposton8-11-4 18:34:32
为什么不直接创建eui项目= =,eui项目是包含game项目内容另外还有eui相关内容。不过写的还是写的挺好的。
& | <em id="authorposton8-11-4 21:47:41
这种皮肤的方式做应用还挺方便,做游戏的话,就显示麻烦和臃肿了
& | <em id="authorposton8-11-5 10:04:57
怎么创建eui项目呀?
& | <em id="authorposton8-11-5 10:09:37
然并卵,直接点一个建EUI项目全解决了
& | <em id="authorposton8-11-6 10:18:33
为什么不直接创建eui项目= =,eui项目是包含game项目内容另外还有eui相关内容。不过写的还是写的挺好的。 ... 这不是坑么。。。创建一个EUI项目的权限比创建一个Game项目的权限还要大,你让我们普通人怎么理解。。。早点说明嘛。
& | <em id="authorposton8-11-6 10:22:51
怎么创建eui项目呀? 升级引擎到2.5之后,同时Wing 升级到2.1.3.然后在Wing 中就可以创建eui项目了。
升级方法,在引擎面板和工具面板,都打开界面右上角的社区体验版本按钮,就可以更新了。
& | <em id="authorposton8-11-6 10:30:24
这不是坑么。。。创建一个EUI项目的权限比创建一个Game项目的权限还要大,你让我们普通人怎么理解。。。 ... 要不然难道创建一个三方库eui,然后让你拷贝么= =多麻烦。
& | <em id="authorposton8-11-11 11:52:10
浏览过的版块
活跃会员 经常参与各类话题的讨论,发帖内容较有主见
优秀版主 活跃且尽责职守的版主
热心会员 经常帮助其他会员答疑
论坛元老 为论坛做出突出贡献的会员
积分: 472 帖子: 578 精华: 0
function mw_syntaxhighlighter_show_editor_codebox(editortype) { var tag = 'code'; var mw_syntaxhighlighter_tag = 'mw_shl_code'; var str = '请输入要插入的代码选择语言:'; str += '';str += 'AppleScript'; str += 'Actionscript3'; str += 'Bash shell'; str += 'ColdFusion'; str += 'C'; str += 'C++'; str += 'C#'; str += 'CSS'; str += 'Delphi'; str += 'Diff'; str += 'Erlang'; str += 'Groovy'; str += 'HTML'; str += 'Java'; str += 'JavaFX'; str += 'JavaScript'; str += 'Pascal'; str += 'Patch'; str += 'Perl'; str += 'PHP'; str += 'Plain Text'; str += 'PowerShell'; str += 'Python'; str += 'Ruby'; str += 'Ruby on Rails'; str += 'Sass'; str += 'Scala'; str += 'Scss'; str += 'Shell'; str += 'SQL'; str += 'Visual Basic'; str += 'Visual Basic .NET'; str += 'XHTML'; str += 'XML'; str += 'XSLT'; str += 'Objective-C'; str += 'Asm'; str += 'AAuto'; str += 'Golang'; str += ''; str += '显示行号:'; str += ''; if(editortype == 'newthread') { var sel, var str1 = '', strdialog = 0, stitle = ''; var ctrlid = editorid + '_' + var menu = $(ctrlid + '_menu'); var pos = [0, 0]; var menuwidth = 270; var menupos = '43!'; var menutype = 'menu'; str += '你的代码:'; str += ''; if(BROWSER.ie) { if(wysiwyg) { editdoc.body.focus(); sel = editdoc.selection.createRange(); } else { sel = document.selection.createRange(); } pos = getCaret(); } selection = sel ? (wysiwyg ? sel.text : sel.text) : mw_highlighter_getSel(); if(menu) { if($(ctrlid).getAttribute('menupos') !== null) { menupos = $(ctrlid).getAttribute('menupos'); } if($(ctrlid).getAttribute('menuwidth') !== null) { menu.style.width = $(ctrlid).getAttribute('menuwidth') + 'px'; } if(selection) { $('mw_codearea').style.display = 'none'; } showMenu({'ctrlid':ctrlid,'evt':'click','pos':menupos,'timeout':250,'duration':in_array(tag, ['fontname', 'fontsize', 'sml']) ? 2 : 3,'drag':1}); } else { var menu = document.createElement('div'); menu.id = ctrlid + '_menu'; menu.style.display = 'none'; menu.className = 'p_pof upf'; menu.style.width = menuwidth + 'px'; s = '' + str + '提交'; menu.innerHTML = $(editorid + '_editortoolbar').appendChild(menu); if(selection) { $('mw_codearea').style.display = 'none'; } showMenu({'ctrlid':ctrlid,'mtype':menutype,'evt':'click','duration':3,'cache':0,'drag':1,'pos':menupos}); } try { if($(ctrlid + '_param_1')) { $(ctrlid + '_param_1').focus(); } } catch(e) {} var objs = menu.getElementsByTagName('*'); for(var i = 0; i < objs. i++) { _attachEvent(objs[i], 'keydown', function(e) { e = e ? e : obj = BROWSER.ie ? event.srcElement : e. if((obj.type == 'text' && e.keyCode == 13) || (obj.type == 'textarea' && e.ctrlKey && e.keyCode == 13)) { if($(ctrlid + '_submit') && tag != 'image') $(ctrlid + '_submit').click(); doane(e); } else if(e.keyCode == 27) { hideMenu(); doane(e); } }); } if($(ctrlid + '_submit')) $(ctrlid + '_submit').onclick = function() { checkFocus(); if(BROWSER.ie && wysiwyg) { setCaret(pos[0]); } if(wysiwyg) { if(!BROWSER.ie) { selection = selection ? selection : ''; } } str1 = $(ctrlid + '_param_1') && $(ctrlid + '_param_1').value ? $(ctrlid + '_param_1').value : (selection ? selection : ''); var opentag = '[' + mw_syntaxhighlighter_tag + '=' + $('brush_lang').value + ',' + (($('show_gutter') && $('show_gutter').checked) ? 'true' : 'false') + ']'; var closetag = '[/' + mw_syntaxhighlighter_tag + ']'; if(wysiwyg) { str1 = preg_replace([''], ['&', '&'], str1); str1 = str1.replace(/\r?\n/g, ''); } str1 = opentag + str1 + insertText(str1, strlen(opentag), strlen(closetag), false, sel); hideMenu(); }; } else if(editortype == 'fastpost' || editortype == 'post') { var sel = var seditorkey = if(!isUndefined($(seditorkey + 'message').selectionStart)) { sel = $(seditorkey + 'message').selectionEnd - $(seditorkey + 'message').selectionS } else if(document.selection && document.selection.createRange) { $(seditorkey + 'message').focus(); var sel = document.selection.createRange(); $(seditorkey + 'message').sel = sel = sel.text ? true : } var ctrlid = seditorkey + var menuid = ctrlid + '_menu'; str += '你的代码:'; str += ''; if(!$(menuid)) { v}

我要回帖

更多关于 可视化游戏开发 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信