今天来介绍一下,怎么用Phaser来实现一个高仿微信对话界面的效果,有了这个效果之后,我们可以做很多事情,比如,把网上的一些段子,用微信对话的形式表现出来,我这里有一个例子,有兴趣的可以看一看。线上地址:http://game.webxinxin.com/?game=weiduan。
其实要实现这个功能并不是很难,只需要用到一些Phaser里面的图形、text、tween动画等等知识。
这里一个难点是要让文字不超出区域的边界,要实现这一点,可以设置text的style中wordWrap为true,然后设置一个wordWrapWidth,这样,文本就会在wordWrapWidth所限定的范围内折行了。但是,这仅仅是对于英文来说的,谁让Phaser是老外做的呢?那中文怎么办?中文需要在需要折行的地方加上一个空格,对了,就是空格!加上空格之后,就会被当成两个英文单词啦,这样就能够折行啦!
this.textStyle = { font: "14px Arial", fill: '#000000', wordWrap: true, wordWrapWidth: game.width - 80 };
另外一个难点就是,要让白色或者绿色的框框正好包含文本,这就需要提前知道文本的长度,才能确定框框的宽度。但是文本的长度怎么知道呢?这里,我们使用一个临时文本来解决这个问题。步骤是这样的,我们申明一个tmp的临时文本,使用设定好的style,将它add进game里,然后将它的width和height得到,这样,我们就可以根据这个width和height做后面的事情了。
// 虚拟一个text来计算宽高 var tmp = game.add.text(0, 0, text, this.textStyle); tmp.lineSpacing = -3; var width = tmp.width; var height = tmp.height; tmp.kill();
得到文本的宽度和高度之后,接下来,当产生一条新的消息之后,我们需要让前面的所有消息都往上移动一个距离,而这个距离就取决于之前得到的高度。当然,在这个过程中,如果有某一条消息移出了屏幕区域,我们需要将它kill掉。接下来,就是让新的消息出现,我们通过drawRoundedRect来绘制圆角矩形,然后把文本、矩形等等元素都作为head的子sprite,相对于head来定位,也和head一起移动。
// 都上移一个高度 for(var i=0; i<this.words.length; i++) { var newpos = this.words[i].pos - height - this.ellipse; if(newpos < 0 - this.words[i].height) { this.words[i].sprite.kill(); this.words.splice(0, 1); i--; } else { game.add.tween(this.words[i].sprite).to({y: newpos}, 100, Phaser.Easing.Linear.None, true); this.words[i].pos = newpos; } } // 创建一个sprite if(me) { var sprite = game.add.sprite(game.width - 40, game.height, head); } else { var sprite = game.add.sprite(10, game.height, head); } // 背景 var rounded = game.make.graphics(0, 0); if(me) { rounded.beginFill(0xa0e75a); rounded.drawRoundedRect(-width-29, 0, width+17, height+7, 4); } else { rounded.beginFill(0xffffff); rounded.drawRoundedRect(42, 0, width+17, height+7, 4); } rounded.endFill(); sprite.addChild(rounded); // 尖尖 if(me) { var jian = game.make.sprite(-12, 10, 'greenjian'); } else { var jian = game.make.sprite(37, 10, 'whitejian'); } sprite.addChild(jian); // 文本 if(me) { var txt = game.make.text(-width-19, 7, text, this.textStyle); } else { var txt = game.make.text(52, 7, text, this.textStyle); } txt.lineSpacing = -3; sprite.addChild(txt); game.add.tween(sprite).to({y: game.height - height - this.ellipse}, 100, Phaser.Easing.Linear.None, true);
接下来,就是用一些数据结构去保存一些必要的数据啦,比较简单,这里就不细讲了,需要了解的同学,可以查看源码!
有了这个技能,只要脑洞够大,很多东西都能够实现了!