- 浏览: 13316 次
- 性别:
- 来自: 成都
文章分类
最新评论
如何制作一款HTML5 RPG游戏引擎——第三篇,利用幕布切换场景
开言:
在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(); } }
这次讲解就到这里,下一次我们就来实现必不可少的对话类,不容错过哦!!!
谢谢大家阅读本文。支持就是最大的鼓励。
----------------------------------------------------------------
欢迎大家转载我的文章。
转载请注明:转自Yorhom's Game Box
http://blog.csdn.net/yorhomwang
欢迎继续关注我的博客
相关推荐
制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏制作RPG游戏...
D游戏算法——RPG游戏初步.ppt
D5rpg网页游戏引擎D5rpg网页游戏引擎D5rpg网页游戏引擎
RPG游戏引擎的设计原理,可以让读者了解RPG游戏引擎,以便于制作或者参考
RPG游戏——征途(附代码).rar RPG游戏——征途(附代码).rar
在玩过许多游戏后 许多玩家都不再仅仅满足于一个游戏玩家的身份 而会思考游戏是如何制作的 并且打算制作一个自己的游戏 网上的各种游戏制作小组更是如雨后春笋般涌现 下面我就给大家介绍一下角色扮演游戏引擎的原理...
RPG JS是一个2D RPG游戏制作引擎,目前版本基于Ease|JS游戏引擎,基于Canvas Engine的新版本即将发布。 RPG JS是免费且开源的。 RPG JS有着完善的文档支持。 RPG JS 100%使用HTML5和JAVASCRIPT书写,因而是跨平台...
这款游戏是成都金点工作组的《圣剑英雄传-英雄救美》的续作,和前作相比,《圣II》更加成熟,更加强调了开放性。图片、声音甚至是脚本都是开放的,只要你稍微花一点时间来熟悉,那么你就可以利用《圣II》制作出你...
使用J2ME技术开发RPG游戏(一)——程序框架.doc
该源码仅供学习使用,欢迎访问我的博客:http://blog.csdn.net/crow_html5
2D RPG游戏引擎_Envision_的源码,使用BitBlt,速度快
RPG游戏制作教程RPG游戏制作教程RPG游戏制作教程作教程
客户端服务端齐全,并带有工具,仅做学习交流使用!!
自己写的原创RPG游戏策划书,可用于课程设计,开发团队为小组4人,用RPGMAKER开发周期为全职1星期
一款简单的RPG游戏制作软件,不用太精通各种语言就能制作出自己喜欢的RPG游戏,脚本编辑简单用RGSS代码编辑 分别解压两个压缩文件 这个是part1
Rpg网络 服务器战斗引擎简单实现 欢迎大家 学习学习
一款简单的RPG游戏制作软件,不用太精通各种语言就能制作出自己喜欢的RPG游戏,脚本编辑简单用RGSS代码编辑 分别解压两个压缩文件 这个是part2
2D回合制游戏,win32平台实现。拥有完整的游戏引擎,简易的...通过学习本例程,可以独立开发一个回合制RPG游戏。例程中没有备注,需要自行研究。本例程适合初窥游戏开发的朋友进阶学习(初学者请搜索我另外一个资源)。
狼RPG游戏制作,致力于制作RPG类型的游戏,但是又区别RPG Maker。尝试才知道。
Python下Pygame引擎制作经典小游戏魔塔