转载博客 htm5l实现滚动播放

『HTML5梦幻之旅』-滚动播放的幻灯片效果

标签: Html5JavaScriptlufylegend幻灯片效果
12347人阅读 评论(21) 收藏 举报
本文章已收录于:
分类:

目录(?)[+]

很久又没写博客了,一者是因为要上课,平时没有什么零碎的时间研究新东西;二者最近在开发一款塔防游戏,有整块的时间都拿去开发这个项目了。因此最近没有什么好的东西和大家分享。这周末看在游戏快完工的份上,抽出了半天的时间研究了一下html5幻灯片制作,效果还不错,展示如下:

首先是一张《真三国无双7》关云长的头像


其次是《真三国无双7》貂蝉的头像


切换时的效果


怎么样?效果还是很不错,对吧~

测试链接:http://www.cnblogs.com/yorhom/articles/html5_dream_trip_slideshowsample1.html

接下来就来讲一讲制作过程。


一,准备工作

首先,需要下载html5开源引擎lufylegend.js,它是完全免费+开源的,可以下载下来学习一下。

下载地址:http://lufylegend.com/lufylegend

API文档:http://lufylegend.com/lufylegend/api


二,设计原理

要搞清楚本次开发的原理,我们不妨先画一张示意图:


假设绿色方框内的区域为显示区域,那么,我们可以用到lufylegend中的mask的方法来将整个红色方框裁减为绿色方框的大小,这时,我们只能看到A区域,而B,C被遮盖住了。然后如果我们要显示B区域,我们可以直接将红框区域往左移动一格的距离,绿色区域不动,就能将B显示出来了,就像放映机一样。

但是如果一直播放下去,那么我们播放到C区域时,红色区域再往左移动,那就会显示为空白。解决措施是又移回A区域,但是出现的问题又在于红色区域如果要移到A处,那应该右移动才能到达,但是我们要的是红色区域往左移动,因此就不能直接移回。那该怎么办呢?我想的解决措施就是把最前面的那个区域移动到最后的那个区域的右边。如果是刚才那种情况,那就让A接到C后方,这时候,A变成了最后一个。这时红色区域又往左移动时,取到的就是B,然后将B移动到A后面。

当然,上面我们只提到了向左移动时的处理方式,其实向右也是一样的,只是取的是最后一个区域,然后把这个区域移动到第一个区域的前面罢了。

光说原理只能算是纸上谈兵,接下来就来看看代码。


三,代码讲解

首先我们为了方便起见,建立一个LSlideshowSample1类,因为以后万一要拓展别的幻灯片效果,所以就在这个类的名字后面写上了"Sample1”,名字只是一种代号,我们主要看代码,构造器如下:

[javascript] view plain copy
  1. function LSlideshowSample1(width,height,isLoop,loopData){  
  2.     var self = this;  
  3.     base(self,LSprite,[]);  
  4.       
  5.     self._slideshowList = new Array();  
  6.     self._slideshowIndex = 0;  
  7.     self._currentIndex = self._slideshowIndex;  
  8.       
  9.     self.rangeWidth = width;  
  10.     self.rangeHeight = height;  
  11.     self.isLoop = isLoop;  
  12.       
  13.     self._toX = 0;  
  14.       
  15.     self.nextChildList = new Array();  
  16.     self.previousChildList = new Array();  
  17.       
  18.     self.borderLayer = new LSprite();  
  19.     self.borderLayer.graphics.drawRect(0,"",[0,0,width,height],true,"transparent");  
  20.       
  21.     self.contentLayer = new LSprite();  
  22.     self.contentLayer.mask = self.borderLayer;  
  23.     self.addChild(self.contentLayer);  
  24.       
  25.     if(self.isLoop == true){  
  26.         self.loopData = loopData;  
  27.         self.frameIndex = 0;  
  28.         self.maxFrame = Math.floor(self.loopData.delay*1000/LGlobal.speed);  
  29.         self.addEventListener(LEvent.ENTER_FRAME,self.loopPlay);  
  30.     }  
  31. }  

这个类有4个参数,意思分别是:[显示宽度,显示高度,是否自动播放,自动播放方式],如果第三个参数填false,就可以不用添第4个参数。

接下来解释一下构造器中的代码:
self._slideshowList原先是用来装每一帧的数据的,后来直接在LSprite的childList中取了,所以它没有什么用,直接忽略掉。

接下来看_slideshowIndex属性,这个属性很怪异,主要用于取出要显示的帧,以后慢慢解释。_currentIndex是用来表示显示位置的,如果往左移动,表示显示位置增加1格,往右移动,表示显示位置减少1格。

self.rangeWidth,self.rangeHeight,self.isLoop是将参数存放起来的属性,后面会用到的。

然后是self._toX,这个表示要移动到的位置,和_currentIndex联用,以后也会提到,到时候慢慢讲。接下来是self.nextChildList和self.previousChildList属性,这两个属性和_slideshowIndex联用,_slideshowIndex主要负责作为这两个数组的取值下标。接下来,我们初始化显示层:

[javascript] view plain copy
  1. self.borderLayer = new LSprite();  
  2. self.borderLayer.graphics.drawRect(0,"",[0,0,width,height],true,"transparent");  
  3.       
  4. self.contentLayer = new LSprite();  
  5. self.contentLayer.mask = self.borderLayer;  
  6. self.addChild(self.contentLayer);  

borderLayer等于上面我们讲解原理时的绿色区域,contentLayer代表红色区域。borderLayer要作为contentLayer的遮罩,因此在contentLayer中写道:

[javascript] view plain copy
  1. self.contentLayer.mask = self.borderLayer;  
然后进入判断是否自动播放:
[javascript] view plain copy
  1. if(self.isLoop == true){  
  2.     self.loopData = loopData;  
  3.     self.frameIndex = 0;  
  4.     self.maxFrame = Math.floor(self.loopData.delay*1000/LGlobal.speed);  
  5.     self.addEventListener(LEvent.ENTER_FRAME,self.loopPlay);  
  6. }  
代码很简单,值得注意的是,我们实例化构造器时,第4个参数是一个json对象,如下格式:
[javascript] view plain copy
  1. {delay:每帧停留时间(单位s),order:出现时滚动的样式(向右或者向左)}  
ok,构造器就讲完了,接下来看看设置帧的setFrame:
[javascript] view plain copy
  1. LSlideshowSample1.prototype.setFrame = function(o){  
  2.     var self = this;  
  3.     var cl = self.contentLayer.childList;  
  4.     o.x = self.contentLayer.childList.length * self.rangeWidth;  
  5.     o.y = 0;  
  6.     self.contentLayer.addChild(o);  
  7.       
  8.     self._sortChild();  
  9. };  
这个函数也有一个参数,是一个LDisplayObject对象。其中代码很简单,就是将加入的这一帧放到最后面。其中调用到一个_sortChild函数,这个函数十分重要,如下:
[javascript] view plain copy
  1. LSlideshowSample1.prototype._sortChild = function(){  
  2.     var self = this;  
  3.       
  4.     self.nextChildList = new Array();  
  5.     self.previousChildList = new Array();  
  6.     var duplicate = new Array();  
  7.     for(var i=0; i<self.contentLayer.childList.length; i++){  
  8.         self.nextChildList.push(i);  
  9.         duplicate.push(i);  
  10.     }  
  11.     self.nextChildList = self.nextChildList.sort();  
  12.     duplicate.splice(0,1);  
  13.     var sortedList = duplicate.sort(function(a,b){  
  14.         return b - a;  
  15.     });  
  16.     self.previousChildList.push(0);  
  17.     for(var key in sortedList){  
  18.         self.previousChildList.push(sortedList[key]);  
  19.     }  
  20. };  
我们能看到,主要是对self.nextChildList和self.previousChildList两个属性进行操作。也许有朋友不理解为什么要将他们排续,这个就设计到显示时的原理,还是用刚才那张图来讲解:


我们加入ABC后,A在contentLayer中的成员序号是0,B是1,C是2。在self.nextChildList我们将其加入先后顺序排列为[0,1,2],如果我们要显示B区域,那我们就要在contentLayer中取B对象,B对象的序号是1,因此我们要将显示位置往后调一格,于是self._slideshowIndex+=1; self._currentIndex += 1; 然后通过self._slideshowIndex的值来取出contentLayer的成员列表中对应的对象,正好self._slideshowIndex初始值是0,+1后变为1,取出的刚好是B对象。

但是,我们的红色区域如果往右移动时,按理说要显示最后的那一个对象C,C的序号是2,但是self._slideshowIndex - 1 != 2,因此我们要在新建self.previousChildList这个属性来确保往右移动时,能正常地取出对象的序号,因此我们对self.previousChildList里的成员排列做了特殊处理,将其变成了[0,2,1]。但是还是不对啊,self._slideshowIndex - 1 = -1时,应该显示C对象,但是C对象序号在self.previousChildList中对应的下标是1不是-1,怎么办呢?其实很简单,取的时候用self._slideshowIndex的绝对值就ok啦。

比如说我们F5一下界面,回到第一格的位置,然后,我们将红色部分向有移动一格,self._slideshowIndex -= 1; self._currentIndex -= 1; 现在按理说要显示C,这时我们在self.previousChildList中用self._slideshowIndex的绝对值取出要找的对象,self._slideshowIndex这时的值是-1,绝对值就是1,在[0,2,1]中对应的值正好是2,也就是C在contentLayer的成员列表中对应的序号,然后用这个序号取出contentLayer的成员列表中对应的成员,位置移动到响应的地方,然后将其通过LTweenLite缓动类缓缓地显示出来,达到想要的效果。

有了上面的介绍,我们就来看看显示部分的代码next()和previous():

[javascript] view plain copy
  1. LSlideshowSample1.prototype.next = function(){  
  2.     var self = this;  
  3.       
  4.     self._currentIndex += 1;  
  5.     self._slideshowIndex += 1;  
  6.       
  7.     if(self._slideshowIndex >= self.contentLayer.childList.length){  
  8.         self._slideshowIndex = 0;  
  9.     }  
  10.       
  11.     if(self._slideshowIndex < 0){  
  12.         var obj = self.contentLayer.getChildAt(self.previousChildList[Math.abs(self._slideshowIndex)]);  
  13.     }else{  
  14.         var obj = self.contentLayer.getChildAt(self.nextChildList[Math.abs(self._slideshowIndex)]);  
  15.     }  
  16.     obj.x = self.rangeWidth*self._currentIndex;  
  17.               
  18.     self._toX = -(self._currentIndex*self.rangeWidth);  
  19.       
  20.     var tweenObj = LTweenLite.to(self.contentLayer,1,{  
  21.         x:self._toX  
  22.     });  
  23. };  
  24. LSlideshowSample1.prototype.previous = function(){  
  25.     var self = this;  
  26.       
  27.     self._currentIndex -= 1;  
  28.     self._slideshowIndex -= 1;  
  29.       
  30.     if(self._slideshowIndex < -(self.contentLayer.childList.length-1)){  
  31.         self._slideshowIndex = 0;  
  32.     }  
  33.       
  34.     if(self._slideshowIndex < 0){  
  35.         var obj = self.contentLayer.getChildAt(self.previousChildList[Math.abs(self._slideshowIndex)]);  
  36.     }else{  
  37.         var obj = self.contentLayer.getChildAt(self.nextChildList[Math.abs(self._slideshowIndex)]);  
  38.     }  
  39.     obj.x = self.rangeWidth*self._currentIndex;  
  40.           
  41.     self._toX = -(self._currentIndex*self.rangeWidth);  
  42.       
  43.     var tweenObj = LTweenLite.to(self.contentLayer,1,{  
  44.         x:self._toX  
  45.     });  
  46. };  
其中用到了LTweenLite,这个是Lufylegend中给的一个用于实现缓动的类,具体方法请移步API文档。

还有一个getChildAt,这是lufylegend中LSprite类的一个成员函数,用于取出参数值在LSprite成员列表中相应的对象。

这个类在设计时为了方便大家使用,还提供了showFrameAt函数,可以直接跳到播放某一帧:

[javascript] view plain copy
  1. LSlideshowSample1.prototype.showFrameAt = function(index,order){  
  2.     var self = this;  
  3.     if(self._slideshowIndex < 0){  
  4.         if(self.previousChildList[Math.abs(self._slideshowIndex)] == index)return;  
  5.     }else{  
  6.         if(self.nextChildList[Math.abs(self._slideshowIndex)] == index)return;  
  7.     }  
  8.     if(order == LSlideshow.LEFTWARD){  
  9.         self._currentIndex -= 1;  
  10.     }else if(order == LSlideshow.RIGHTWARD){  
  11.         self._currentIndex += 1;  
  12.     }else{  
  13.         self._currentIndex += 1;  
  14.     }  
  15.     self._slideshowIndex = index;  
  16.       
  17.     var obj = self.contentLayer.getChildAt(index);  
  18.     obj.x = self.rangeWidth*self._currentIndex;  
  19.       
  20.     self._toX = -(self._currentIndex*self.rangeWidth);  
  21.       
  22.     var tweenObj = LTweenLite.to(self.contentLayer,1,{  
  23.         x:self._toX  
  24.     });  
  25. };  
在上面也提到过自动播放这个功能,我们不妨温习一下调用自动播放的地方:
[javascript] view plain copy
  1. if(self.isLoop == true){  
  2.     self.loopData = loopData;  
  3.     self.frameIndex = 0;  
  4.     self.maxFrame = Math.floor(self.loopData.delay*1000/LGlobal.speed);  
  5.     self.addEventListener(LEvent.ENTER_FRAME,self.loopPlay);  
  6. }  
在时间轴事件ENTER_FRAME中,我们调用了loopPlay函数,这个函数的代码如下:
[javascript] view plain copy
  1. LSlideshowSample1.prototype.loopPlay = function(self){  
  2.     if(self.contentLayer.childList.length == 0)return;  
  3.     if(self.frameIndex++ < self.maxFrame)return;  
  4.     self.frameIndex = 0;  
  5.     if(self.loopData.order == LSlideshow.RIGHTWARD){  
  6.         self.next();  
  7.     }else if(self.loopData.order == LSlideshow.LEFTWARD){  
  8.         self.previous();  
  9.     }else if(self.loopData.order == LSlideshow.RANDOM){  
  10.         var index = Math.floor(Math.random()*(self.contentLayer.childList.length-1));  
  11.         var order = Math.random() > 0.5 ? LSlideshow.LEFTWARD : LSlideshow.RIGHTWARD;  
  12.         self.showFrameAt(index,order);  
  13.     }  
  14. };  
其中我们能看到了LSlideshow.RIGHTWAR,LSlideshow.LEFTWARD,LSlideshow.RANDOM这几种播放方式,它们分别是在LSlideshow静态类中得到定义的。如下:
[javascript] view plain copy
  1. var LSlideshow = function(){throw "LSlideshow cannot be instantiated";};  
  2. LSlideshow.type = "LSlideshow";  
  3. LSlideshow.RIGHTWARD = "rightward";  
  4. LSlideshow.LEFTWARD = "leftward";  
  5. LSlideshow.RANDOM = "random";  
LSlideshow.RIGHTWAR代表向右滚动,LSlideshow.LEFTWARD代表向左滚动,LSlideshow.RANDOM代表随机滚动。

最后还加了一个getFrameIndex的函数,是用于取当前帧的序号的:

[javascript] view plain copy
  1. LSlideshowSample1.prototype.getFrameIndex = function(){  
  2.     var self = this;  
  3.     if(self._slideshowIndex < 0){  
  4.         var v = self.previousChildList[Math.abs(self._slideshowIndex)];  
  5.     }else{  
  6.         var v = self.nextChildList[Math.abs(self._slideshowIndex)];  
  7.     }  
  8.     return v;  
  9. };  

ok,幻灯片类就搞定了~只要搞清楚原理,其实还是挺简单的,不是吗?接下来是使用举例:

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>幻灯片效果</title>  
  6. </head>  
  7. <body>  
  8. <div id="mylegend">loading......</div>  
  9. <script type="text/javascript" src="./lufylegend-1.8.0.min.js"></script>  
  10. <script type="text/javascript" src="./lufylegend.ui-0.2.0.min.js"></script>  
  11. <script type="text/javascript" src="./LSlideshow.js"></script>  
  12. <script type="text/javascript" src="./LSlideshowSample1.js"></script>  
  13. <script>  
  14. init(50,"mylegend",980,609,main);  
  15. var backLayer,slideshowObj;  
  16. var loadData = [  
  17.     {name:"caocao",path:"./images/cao_cao.jpg"},  
  18.     {name:"diaochan",path:"./images/diao_chan.jpg"},  
  19.     {name:"guanyu",path:"./images/guan_yu.jpg"},  
  20.     {name:"zhaoyun",path:"./images/zhao_yun.jpg"},  
  21.     {name:"sunshangxiang",path:"./images/sun_shang_xiang.jpg"}  
  22. ];  
  23. var datalist = {};  
  24. function main(){  
  25.     LStage.setDebug(true);  
  26.     if(LGlobal.canTouch){  
  27.         LGlobal.stageScale = LStageScaleMode.EXACT_FIT;  
  28.         LSystem.screen(LStage.FULL_SCREEN);  
  29.     }  
  30.       
  31.     var loadingLayer = new LoadingSample5();  
  32.     addChild(loadingLayer);  
  33.       
  34.     LLoadManage.load(  
  35.         loadData,  
  36.         function(p){  
  37.             loadingLayer.setProgress(p);  
  38.         },  
  39.         function(r){  
  40.             datalist = r;  
  41.             removeChild(loadingLayer);  
  42.             initPage();  
  43.         }  
  44.     );  
  45. }     
  46. function initPage(){  
  47.     backLayer = new LSprite();  
  48.     addChild(backLayer);  
  49.       
  50.     slideshowObj = new LSlideshowSample1(971,609,true,{delay:3,order:LSlideshow.RANDOM});  
  51.     backLayer.addChild(slideshowObj);  
  52.       
  53.     slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["caocao"])));  
  54.     slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["diaochan"])));  
  55.     slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["guanyu"])));  
  56.     slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["zhaoyun"])));  
  57.     slideshowObj.setFrame(new LBitmap(new LBitmapData(datalist["sunshangxiang"])));  
  58.       
  59.     addButton();  
  60. }  
  61. function addButton(){  
  62.     var next_btn = new LButtonSample2(">",20,"黑体","white");  
  63.     next_btn.backgroundCorl = "#008800";  
  64.     next_btn.x = LStage.width-next_btn.getWidth()-40;  
  65.     next_btn.y = (LStage.height-next_btn.getHeight())*0.5;  
  66.     backLayer.addChild(next_btn);  
  67.     next_btn.addEventListener(LMouseEvent.MOUSE_DOWN,function(){  
  68.         slideshowObj.next();  
  69.     });  
  70.       
  71.     var last_btn = new LButtonSample2("<",20,"黑体","white");  
  72.     last_btn.backgroundCorl = "#008800";  
  73.     last_btn.x = 20;  
  74.     last_btn.y = (LStage.height-last_btn.getHeight())*0.5;  
  75.     backLayer.addChild(last_btn);  
  76.     last_btn.addEventListener(LMouseEvent.MOUSE_DOWN,function(){  
  77.         slideshowObj.previous();  
  78.     });  
  79.       
  80.     for(var i=0; i<5; i++){  
  81.         var page_btn = new LButtonSample2(i+1,20,"黑体","white");  
  82.         page_btn.backgroundCorl = "#008800";  
  83.         page_btn.x = 50*i+600;  
  84.         page_btn.y = LStage.height-page_btn.getHeight()-40;  
  85.         backLayer.addChild(page_btn);  
  86.         page_btn.addEventListener(LMouseEvent.MOUSE_DOWN,function(event,o){  
  87.             var textObj = o.getChildAt(1).getChildAt(0);  
  88.             var toIndex = parseInt(textObj.text)-1;  
  89.             slideshowObj.showFrameAt(toIndex,LSlideshow.LEFTWARD);  
  90.         });  
  91.     }  
  92. }  
  93. function ondown(event){  
  94.     if(event.offsetX <= 100){  
  95.         slideshowObj.previous();  
  96.     }else if(event.offsetX >= LStage.width-100){  
  97.         slideshowObj.next();  
  98.     }  
  99. }  
  100. </script>   
  101. </body>  
  102. </html>  

运行代码后,就得到了本文最上面展示的效果。


四,源代码

上面讲解得有些乱,大家可以把源代码下载下来看看。

最后,奉上源代码:http://files.cnblogs.com/yorhom/Slideshow_source.zip



本章就到此为止,以上就是本篇所有内容,欢迎大家交流。

----------------------------------------------------------------

欢迎大家转载我的文章。

转载请注明:转自Yorhom's Game Box

http://blog.csdn.net/yorhomwang

欢迎继续关注我的博客

22
0
 
 
我的同类文章
猜你在找
ArcGIS for JavaScript
HTML 5移动开发从入门到精通
iOS8-Swift开发教程
零基础学HTML 5实战开发(第一季)
数据结构和算法
查看评论
11楼 shanyishan12 2014-10-03 01:55发表 [回复]
请问你是用什么工具来编写代码的呢
Re: Yorhom 2014-10-03 19:19发表 [回复]
回复shanyishan12:html5和js开发用不着什么好的编辑器吧,记事本也行的。不过针对web开发这一类型的编辑器还挺多的,比如说Aptana studio,WebStorm,H5Builder。这些大型IDE虽然使用起来方便,但是如果是作为初学者,用这些工具反而会使自己纠结于IDE的功能,而不是去学习如何写程序。
目前我使用的是Sublime Text2,感觉还行吧,界面很美观,而且属于轻量级软件,不过貌似要收费。免费的文本编辑器有Notepad++。
总之写代码的话就不必要过分追究用什么工具,何况还是html5/js的开发。自己用起来顺手的工具就是好工具吧
10楼 风吹夏天 2013-11-13 22:37发表 [回复]
非常不错呀,而且你的详解写的也非常好。虽然我用的都是C++.这种新技术不常见到源码
Re: Yorhom 2013-11-14 20:37发表 [回复]
回复bluecol:多谢朋友支持啦~
9楼 lori0801 2013-10-30 08:59发表 [回复]
看明白了,精神值得学习
Re: Yorhom 2013-10-30 20:13发表 [回复]
回复lori_xj:O(∩_∩)O~~
8楼 会飞De琥珀 2013-10-25 09:40发表 [回复]
真起不明白,为啥那么多人对XP,对IE6那么不舍,
Re: Yorhom 2013-10-25 19:04发表 [回复]
回复u010953901:存在及合理~
7楼 奋斗的松树苗 2013-10-24 13:50发表 [回复]
初学者一枚,愿跟着大神学习HTML5,加油!
Re: Yorhom 2013-10-24 20:06发表 [回复]
回复u010020611:在下也算不了什么大神啊!一起加油吧!
6楼 siank 2013-10-22 23:18发表 [回复]
挺好的作品
5楼 程序员的家园 2013-10-22 11:04发表 [回复]
不错
4楼 coedears 2013-10-21 22:38发表 [回复]
半天就把html5搞懂了? 太厉害了
Re: Yorhom 2013-10-22 13:34发表 [回复]
回复u011803182:木有啊...我只是说把幻灯片效果搞懂了啊……
3楼 i_like_cpp 2013-10-21 22:26发表 [回复]
写得好。
Re: Yorhom 2013-10-22 13:34发表 [回复]
回复i_like_cpp:多谢支持O(∩_∩)O~~
2楼 鹳狸媛 2013-10-21 13:49发表 [回复]
您的文章已被推荐到CSDN首页,感谢您的分享。
Re: Yorhom 2013-10-21 20:45发表 [回复]
回复suannai0314:多谢~
1楼 月影晃荡 2013-10-20 22:56发表 [回复]
一直在关注HTML5可是我们的项目基本上都是政府类的,内网的浏览器还都是IE6,IE8.暂时可能还用不到。
Re: Yorhom 2013-10-21 20:47发表 [回复]
回复yueyinghuangdang:学习一些新技术对未来的发展是有好处滴~
发表评论
  • 用 户 名:
  • szcsun5
  • 评论内容:
  • 插入代码
  • 个人资料
    • 访问:590651次
    • 积分:7249
    • 等级:
    • 排名:第1827名
    • 原创:63篇
    • 转载:0篇
    • 译文:0篇
    • 评论:787条
  • 联系我
  • 我的微博
  • lufylegend.js游戏引擎
  • 我开发的游戏
    • Greedy Bug
    基于HTML5和lufylegend.js开源引擎的一款类似于贪吃蛇的游戏。相信这款游戏能给你带来欲速则不达、近在咫尺却无法接触地虐心体验!
    • 翻三国
    本游戏基于开源HTML5引擎lufylegend.js开发,是一款跨平台休闲类翻牌游戏。本游戏一共有五个关卡,随着关卡难度的增加会有更多卡牌出现。快来考验一下自己的记忆力吧~

    More >>
  • 博客专栏
  • 最新评论
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值