开言:

在RPG游戏中,如果有地图切换的地方,通常就会使用幕布效果。所谓的幕布其实就是将两个矩形合拢,直到把屏幕遮住,然后再展开直到两个矩形全部移出屏幕。

为了大家做游戏方便,于是我给这个引擎加了这么一个类。

本系列文章目录:

如何制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现

http://blog.csdn.net/yorhomwang/article/details/8892305

如何制作一款HTML5 RPG游戏引擎——第二篇,烟雨+飞雪效果

http://blog.csdn.net/yorhomwang/article/details/8915020

该引擎是基于lufylegend开发的,学习时请先了解lufylegend。

官方网站地址:http://lufylegend.com/lufylegend

API地址:http://lufylegend.com/lufylegend/api

今天我们先看实现后的代码:

var curtain = new LCurtainSample3();
addChild(curtain);

就两行,已经达到最简单了。那么接下来就来看看是如何实现它的。

由于有很多种幕布效果,因此我只为大家实现常用的3种作为sample,大家可以借鉴一下,写出更美观的幕布。

1,LCurtainSample1

这个是一个基础幕布,效果是左右合拢。

看看构造器中的代码:

function LCurtainSample1(speed,onClosing,onComplete){
var s = this;
base(s,LSprite,[]);
if(!speed)speed = LStage.width/100;
if(!onClosing){
s.onClosing = function(){};
}else{
s.onClosing = onClosing;
}
if(!onComplete){
s.onComplete = function(){};
}else{
s.onComplete = onComplete;
}
s.mode = "close";
s.width1 = 0;
s.width2 = 0;
s.isDoClosing = false;
s.speed = speed;
s.addEventListener(LEvent.ENTER_FRAME,s.onshow);
}

这个类是继承自LSprite类,有三个参数,分别是:幕布合拢/展开的速度,幕布合拢后调用此函数,幕布展开后调用此函数。

mode 属性顾名思义,它是用来表示接下来的工作的。当为close时说明要合拢。
我们在其中定义两个属性:width1,width2,它们分别表示两块幕布显示的宽度,通过调节宽度来实现合拢。另外定义了isDoClosing来判断是否已经合拢。用speed来保存幕布移动速度,方便以后使用。

然后我们给自身加一个时间轴事件,在时间轴事件中调用onshow方法绘画幕布。

onshow中的完整代码:

LCurtainSample1.prototype.onshow = function(s){
s.graphics.clear();
s.graphics.drawRect(1,"black",[0,0,s.width1,LStage.height],true,"black");
s.graphics.drawRect(1,"black",[LStage.width-s.width2,0,s.width2,LStage.height],true,"black");
if(s.width1 >= LStage.width/2){
s.mode = "open";
if(s.isDoClosing == false){
s.onClosing();
s.isDoClosing = true;
}
}
if(s.mode == "close"){
s.width1 += s.speed;
s.width2 += s.speed;
}else if(s.mode == "open"){
s.width1 -= s.speed;
s.width2 -= s.speed;
if(s.width1 < 0){
s.mode = "stop";
}
}else if(s.mode == "stop"){
s.graphics.clear();
s.removeEventListener(LEvent.ENTER_FRAME,s.onshow);
s.onComplete();
}
}

首先我们将我们的绘图区清空,然后画一个高为画布的高度,宽为width1的矩型。由于它是从x坐标为0,y坐标为0的地方画起,所以不需要任何处理。

接着用同样的办法画出高为画布的高度,宽为width2的矩形。但是由于是在屏幕最右边开始画,所以我们就得计算出它的x坐标,然后再来画。计算方法很简单,就是用屏幕宽度减去width2的长度就可以得到画笔起始的x坐标。

接着我们判断第一块幕布是否已经到达中点,如果是,就将mode设为"open",表示接下来要open,判断isDoClosing是否为false,是则设为true,并且调用合拢时调用的函数。

接下来我们为了使幕布增长或缩短,我用到了判断mode的值的方法来实现。当为close时,就将宽度变大,当为open时就变小。如果移动完毕就将mode设置为stop,然后接着判断如果为stop就清屏,然后移除时间轴事件,达到停止的效果。效果如下:

虽然单独看有点丑,但是如果放在游戏中还是很不错的

2,LCurtainSample2

LCurtainSample2和LCurtainSample1差不多,只是一个是横着的,一个竖着的。

直接上代码:

/**
*LCurtainSample2.js
*/
function LCurtainSample2(speed,onClosing,onComplete){
var s = this;
base(s,LSprite,[]);
if(!speed)speed = LStage.height/100;
if(!onClosing){
s.onClosing = function(){};
}else{
s.onClosing = onClosing;
}
if(!onComplete){
s.onComplete = function(){};
}else{
s.onComplete = onComplete;
}
s.mode = "close";
s.height1 = 0;
s.height2 = 0;
s.isDoClosing = false;
s.speed = speed;
s.addEventListener(LEvent.ENTER_FRAME,s.onshow);
}
LCurtainSample2.prototype.onshow = function(s){
s.graphics.clear();
s.graphics.drawRect(1,"black",[0,0,LStage.width,s.height1],true,"black");
s.graphics.drawRect(1,"black",[0,LStage.height-s.height2,LStage.width,s.height2],true,"black");
if(s.height1 >= LStage.height/2){
s.mode = "open";
if(s.isDoClosing == false){
s.onClosing();
s.isDoClosing = true;
}
}
if(s.mode == "close"){
s.height1 += s.speed;
s.height2 += s.speed;
}else if(s.mode == "open"){
s.height1 -= s.speed;
s.height2 -= s.speed;
if(s.height1 < 0){
s.mode = "stop";
}
}else if(s.mode == "stop"){
s.graphics.clear();
s.removeEventListener(LEvent.ENTER_FRAME,s.onshow);
s.onComplete();
}
}

效果如下:

3,LCurtainSample3

LCurtainSample3是LCurtainSample1和LCurtainSample2的结合体,效果就是一起合拢展开。实现方法差不多,大家可以看看:

/**
*LCurtainSample3.js
*/
function LCurtainSample3(speed,onClosing,onComplete){
var s = this;
base(s,LSprite,[]);
if(!speed)speed = LStage.width/100;
if(!onClosing){
s.onClosing = function(){};
}else{
s.onClosing = onClosing;
}
if(!onComplete){
s.onComplete = function(){};
}else{
s.onComplete = onComplete;
}
s.mode = "close";
s.height1 = 0;
s.height2 = 0;
s.width1 = 0;
s.width2 = 0;
s.isDoClosing = false;
s.speed = speed;
s.addEventListener(LEvent.ENTER_FRAME,s.onshow);
}
LCurtainSample3.prototype.onshow = function(s){
s.graphics.clear();
s.graphics.drawRect(1,"black",[0,0,LStage.width,s.height1],true,"black");
s.graphics.drawRect(1,"black",[0,LStage.height-s.height2,LStage.width,s.height2],true,"black");
s.graphics.drawRect(1,"black",[0,0,s.width1,LStage.height],true,"black");
s.graphics.drawRect(1,"black",[LStage.width-s.width2,0,s.width2,LStage.height],true,"black");
if(s.height1 >= LStage.height/2 ){
s.mode = "open";
if(s.isDoClosing == false){
s.onClosing();
s.isDoClosing = true;
}
}
if(s.mode == "close"){
s.height1 += s.speed;
s.height2 += s.speed;
s.width1 += s.speed;
s.width2 += s.speed;
}else if(s.mode == "open"){
s.height1 -= s.speed;
s.height2 -= s.speed;
s.width1 -= s.speed;
s.width2 -= s.speed;
if(s.height1 < 0){
s.mode = "stop";
}
}else if(s.mode == "stop"){
s.graphics.clear();
s.removeEventListener(LEvent.ENTER_FRAME,s.onshow);
s.onComplete();
}
}

效果如下:

4,切换场景

上面我们实现了幕布类,接下来就要实战一下了。

首先我们找几张图片:

还有一张

接着就用到了我们的幕布类实现切换场景,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>Curtain幕布</title>
<script type="text/javascript" src="./js/lufylegend-1.7.6.min.js"></script>
<script type="text/javascript" src="./js/lufylegendrpg-1.0.0.js"></script>
<script>
init(30,"legend",600,400,main);
var backindex = 1;
var loadlist = [
{name:"back1",path:"./back1.jpg"},
{name:"back2",path:"./back2.jpg"}
];
var datalist = [];
LRPGStage.setShortcuts(true);
LGlobal.setDebug(true);
var backLayer;
var loadingLayer;
function main(){
LEvent.addEventListener(LGlobal.window,LKeyboardEvent.KEY_DOWN,onkeydown);
loadingLayer = new LoadingSample1();
addChild(loadingLayer);
LLoadManage.load(
loadlist,
function(progress){
loadingLayer.setProgress(progress);
},
gameInit
);
}
function gameInit(result){
datalist = result;
backLayer = new LSprite();
addChild(backLayer);
addImg();
}
function addImg(){
backLayer.removeAllChild();
var bitmapdata = new LBitmapData(datalist["back"+backindex]);
var bitmap = new LBitmap(bitmapdata);
backLayer.addChild(bitmap);
}
function onkeydown(){
var curtain = new LCurtainSample3(20,function(){
if(backindex == 1){
backindex = 2;
}else if(backindex == 2){
backindex = 1;
}
addImg();
},function(){
trace("已经切换为back"+backindex);
});
addChild(curtain);
}
</script>
</head>
<body>
<div id="legend"></div>
</body>
</html>

截图如下:

合拢时

展开完成后

嘻嘻~不错吧

5,源代码

本次开发代码虽然比较多,但都有些类似,放在下面,大家可以拿下去测试:

/**
*LCurtainSample1.js
*/
function LCurtainSample1(speed,onClosing,onComplete){
var s = this;
base(s,LSprite,[]);
if(!speed)speed = LStage.width/100;
if(!onClosing){
s.onClosing = function(){};
}else{
s.onClosing = onClosing;
}
if(!onComplete){
s.onComplete = function(){};
}else{
s.onComplete = onComplete;
}
s.mode = "close";
s.width1 = 0;
s.width2 = 0;
s.isDoClosing = false;
s.speed = speed;
s.addEventListener(LEvent.ENTER_FRAME,s.onshow);
}
LCurtainSample1.prototype.onshow = function(s){
s.graphics.clear();
s.graphics.drawRect(1,"black",[0,0,s.width1,LStage.height],true,"black");
s.graphics.drawRect(1,"black",[LStage.width-s.width2,0,s.width2,LStage.height],true,"black");
if(s.width1 >= LStage.width/2){
s.mode = "open";
if(s.isDoClosing == false){
s.onClosing();
s.isDoClosing = true;
}
}
if(s.mode == "close"){
s.width1 += s.speed;
s.width2 += s.speed;
}else if(s.mode == "open"){
s.width1 -= s.speed;
s.width2 -= s.speed;
if(s.width1 < 0){
s.mode = "stop";
}
}else if(s.mode == "stop"){
s.graphics.clear();
s.removeEventListener(LEvent.ENTER_FRAME,s.onshow);
s.onComplete();
}
}
/**
*LCurtainSample2.js
*/
function LCurtainSample2(speed,onClosing,onComplete){
var s = this;
base(s,LSprite,[]);
if(!speed)speed = LStage.height/100;
if(!onClosing){
s.onClosing = function(){};
}else{
s.onClosing = onClosing;
}
if(!onComplete){
s.onComplete = function(){};
}else{
s.onComplete = onComplete;
}
s.mode = "close";
s.height1 = 0;
s.height2 = 0;
s.isDoClosing = false;
s.speed = speed;
s.addEventListener(LEvent.ENTER_FRAME,s.onshow);
}
LCurtainSample2.prototype.onshow = function(s){
s.graphics.clear();
s.graphics.drawRect(1,"black",[0,0,LStage.width,s.height1],true,"black");
s.graphics.drawRect(1,"black",[0,LStage.height-s.height2,LStage.width,s.height2],true,"black");
if(s.height1 >= LStage.height/2){
s.mode = "open";
if(s.isDoClosing == false){
s.onClosing();
s.isDoClosing = true;
}
}
if(s.mode == "close"){
s.height1 += s.speed;
s.height2 += s.speed;
}else if(s.mode == "open"){
s.height1 -= s.speed;
s.height2 -= s.speed;
if(s.height1 < 0){
s.mode = "stop";
}
}else if(s.mode == "stop"){
s.graphics.clear();
s.removeEventListener(LEvent.ENTER_FRAME,s.onshow);
s.onComplete();
}
}
/**
*LCurtainSample3.js
*/
function LCurtainSample3(speed,onClosing,onComplete){
var s = this;
base(s,LSprite,[]);
if(!speed)speed = LStage.width/100;
if(!onClosing){
s.onClosing = function(){};
}else{
s.onClosing = onClosing;
}
if(!onComplete){
s.onComplete = function(){};
}else{
s.onComplete = onComplete;
}
s.mode = "close";
s.height1 = 0;
s.height2 = 0;
s.width1 = 0;
s.width2 = 0;
s.isDoClosing = false;
s.speed = speed;
s.addEventListener(LEvent.ENTER_FRAME,s.onshow);
}
LCurtainSample3.prototype.onshow = function(s){
s.graphics.clear();
s.graphics.drawRect(1,"black",[0,0,LStage.width,s.height1],true,"black");
s.graphics.drawRect(1,"black",[0,LStage.height-s.height2,LStage.width,s.height2],true,"black");
s.graphics.drawRect(1,"black",[0,0,s.width1,LStage.height],true,"black");
s.graphics.drawRect(1,"black",[LStage.width-s.width2,0,s.width2,LStage.height],true,"black");
if(s.height1 >= LStage.height/2 ){
s.mode = "open";
if(s.isDoClosing == false){
s.onClosing();
s.isDoClosing = true;
}
}
if(s.mode == "close"){
s.height1 += s.speed;
s.height2 += s.speed;
s.width1 += s.speed;
s.width2 += s.speed;
}else if(s.mode == "open"){
s.height1 -= s.speed;
s.height2 -= s.speed;
s.width1 -= s.speed;
s.width2 -= s.speed;
if(s.height1 < 0){
s.mode = "stop";
}
}else if(s.mode == "stop"){
s.graphics.clear();
s.removeEventListener(LEvent.ENTER_FRAME,s.onshow);
s.onComplete();
}
}

这次讲解就到这里,下一次我们就来实现必不可少的对话类,不容错过哦!!!

如何制作一款HTML5 RPG游戏引擎——第三篇,利用幕布切换场景的更多相关文章

  1. 如何制作一款HTML5 RPG游戏引擎——第五篇,人物&人物特效

    上一次,我们实现了对话类,今天就来做一个游戏中必不可少的——人物类. 当然,你完全是可以自己写一个人物类,但是为了方便起见,还是决定把人物类封装到这个引擎里. 为了使这个类更有意义,我还给人物类加了几 ...

  2. 如何制作一款HTML5 RPG游戏引擎——第四篇,情景对话

    今天我们来实现情景对话.这是一个重要的功能,没有它,游戏将变得索然无味.所以我们不得不来完成它. 但是要知道,使用对话可不是一件简单的事,因为它内部的东西很多,比如说人物头像,人物名称,对话内容... ...

  3. 如何制作一款HTML5 RPG游戏引擎——第二篇,烟雨+飞雪效果

    今天我们来实现烟雨+飞雪效果.首先来说,一款经典的RPG游戏难免需要加入天气的变化.那么为了使我们的RPG游戏引擎更完美,我们就只好慢慢地实现它. 本文为该系列文章的第二篇,如果想了解以前的文章可以看 ...

  4. 如何制作一款HTML5 RPG游戏引擎——第一篇,地图类的实现

    一,话说天下大事 前不久看到lufy的博客上,有一位朋友想要一个RPG游戏引擎,出于兴趣准备动手做一做.由于我研究lufylegend有一段时间了,对它有一定的依赖性,因此就准备将这个引擎基于lufy ...

  5. HTML5 RPG游戏引擎 地图实现篇

    一,话说全国年夜事   前没有暂看到lufy的专客上,有一名伴侣念要一个RPG游戏引擎,出于兴趣筹办入手做一做.因为我研讨lufylegend有冶时间了,对它有必然的依赖性,因而便筹办将那个引擎基于 ...

  6. 用Html5结合Qt制作一款本地化EXE游戏-太空大战(Space War)

    本次来说一说如何利用lufylegend.js引擎制作一款html5游戏后将其通过Qt转换成EXE程序.步骤其实非常简单,接下来就一步步地做一下解释和说明. 首先我们来开发一个有点类似于太空大战的游戏 ...

  7. HTML5开源RPG游戏引擎lufylegendRPG 0.1发布

    一,小小开篇   首先不得不先介绍一下这个引擎: lufylegendRPG是lufylegend的拓展引擎,使用它时,需要引入lufylegend.同时您也需要了解lufylegend语法,这样才能 ...

  8. 推荐一些好用的 HTML5 & JavaScript 游戏引擎开发库

    推荐一些好用的 HTML5 & JavaScript 游戏引擎开发库 0. 引言 如果你是一个游戏开发者,并且正在寻找一个可以与 JavaScript 和 HTML5 无缝工作的游戏引擎.那么 ...

  9. 或许您还不知道的八款Android开源游戏引擎

    很多初学Android游戏开发的朋友,往往会显得有些无所适从,他们常常不知道该从何处入手,每当遇到自己无法解决的难题时,又往往会一边羡慕于iPhone下有诸如Cocos2d-iphone之类的免费游戏 ...

随机推荐

  1. Python高级编程之生成器(Generator)与coroutine(一):Generator

    转载请注明出处:点我 这是一系列的文章,会从基础开始一步步的介绍Python中的Generator以及coroutine(协程)(主要是介绍coroutine),并且详细的讲述了Python中coro ...

  2. CSS(六):盒子模型

    一.什么是盒子模型 盒子模型是css中一个重要的概念,理解了盒子模型才能更好的排版. 从上图可以看到标准的盒子模型范围包括margin(外边距).border(边框).padding(内边距).con ...

  3. Hadoop、Pig、Hive、NOSQL 学习资源收集

    转自:http://www.cnblogs.com/zzjhn/p/3855566.html (一)hadoop 相关安装部署 1.hadoop在windows cygwin下的部署: http:// ...

  4. 敏捷软件开发实践-Code Review Process(转)

    介绍: 在敏捷软件开发中,从代码的产生速度上来看,要比 传统Waterfall产生速度高很多.因为我们把时间安排的更加紧凑了.那么这么多的代码,如何能保证这些代码质量呢?很多人可能直接想到静态代码检测 ...

  5. 阿里Java开发手冊之编程规约

    对于程序猿来说,编程规范能够养成良好的编程习惯,提高代码质量,减少沟通成本.就在2月9号,阿里出了一份Java开发手冊(正式版),分为编程规约.异常日志.MySQL规约,project规约.安全规约五 ...

  6. Frameset 两页面互调控件技术案例

    总共包含三个页面(Html),分别为Parent.Html.ChildA.Html.ChildB.Html Parent.Html页面代码 <frameset cols="50%,*& ...

  7. 【Openwrt】刷

    设定你的电脑ip 为192.168.1.100 网线一头连接lan口,另外一头连接电脑.WAN口不能插线. 按住路由器的qss 键,开启路由器的电,灯灭掉,等6秒左右灯会再次闪几下就松开,用googl ...

  8. UIWindow小记

    If you choose to create a window in Interface Builder, be sure to select the Full Screen at Launch o ...

  9. 编程之美 set 3 最大公约数问题

    解法 1. f(x,y) = f(y, y%x) (y>0) 辗转相除法 2. 取模运算较为耗时, 将取模变成相减. 但对极端数据效果很差, 比如 gcd(1000,1) 3. 分析公约数的特点 ...

  10. WebStorm Cordova 环境搭建

    一.软件安装 1.nodejs 2.npm 3.Cordova 如果慢,可以修改镜像,再进行安装. npm config set registry http://registry.cnpmjs.org ...