lufy's legend

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 19936|回复: 1
打印 上一主题 下一主题

用HTML5来开发一款android本地化App游戏-宝石碰碰

  [复制链接]

37

主题

8

好友

9312

积分

诸侯王

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

跳转到指定楼层
楼主
发表于 2013-4-10 09:59:24 |显示全部楼层 |倒序浏览
本次来说一说如何利用lufylegend.js引擎制作一款HTML5游戏后,将其转换为android本地化的App应用,转换过程其实很简单,下面一步步来做说明。
首先来开发一个类似于对对碰的游戏,不过此游戏玩法为在下原创,如有雷同,纯属巧合,游戏界面如下。

游戏操作:上下左右划动屏幕,来操作宝石向不同的方向移动。
游戏规则:当有三个一样的宝石相邻则消除,被消除过一次的宝石会变成半透明,当所有宝石都被消除一次后,则进入下一关。
游戏测试连接:
制作开始
一,准备
首先,需要下载lufylegend.js引擎,下面是我在博客的lufylegend-1.7.0发布帖
二,游戏开发
引擎lufylegend1.7.0中扩展了LLoadManage静态类,可以读取图片,js文件以及文本文件,本次游戏开发就来体验一下这个新功能,首先看下面数组
代码清单1
  1. var loadData = [
  2. {path:"../jquery.js",type:"js"},
  3. {path:"./js/share.js",type:"js"},
  4. {path:"./js/Social.js",type:"js"},
  5. {path:"./js/GameRanking.js",type:"js"},
  6. {path:"./js/GameLogo.js",type:"js"},
  7. {path:"./js/GameClear.js",type:"js"},
  8. {path:"./js/Gem.js",type:"js"},
  9. {path:"./js/Stage.js",type:"js"},
  10. {path:"./js/Clock.js",type:"js"},
  11. {path:"./js/Point.js",type:"js"},
  12. {path:"./js/GetPoint.js",type:"js"},
  13. {path:"./js/Bullet.js",type:"js"},
  14. {path:"./js/Event.js",type:"js"},
  15. {path:"./js/function.js",type:"js"},
  16. {path:"./js/GameBody.js",type:"js"},
  17. {name:"num.+",path:"./images/plus.png"},
  18. {name:"num.0",path:"./images/0.png"},
  19. {name:"num.1",path:"./images/1.png"},
  20. {name:"num.2",path:"./images/2.png"},
  21. {name:"num.3",path:"./images/3.png"},
  22. {name:"num.4",path:"./images/4.png"},
  23. {name:"num.5",path:"./images/5.png"},
  24. {name:"num.6",path:"./images/6.png"},
  25. {name:"num.7",path:"./images/7.png"},
  26. {name:"num.8",path:"./images/8.png"},
  27. {name:"num.9",path:"./images/9.png"},
  28. {name:"back",path:"./images/back.png"},
  29. {name:"line",path:"./images/line.png"},
  30. {name:"clear",path:"./images/clear.png"},
  31. {name:"gem01",path:"./images/gem01.png"},
  32. {name:"gem02",path:"./images/gem02.png"},
  33. {name:"gem03",path:"./images/gem03.png"},
  34. {name:"gem04",path:"./images/gem04.png"},
  35. {name:"gem05",path:"./images/gem05.png"},
  36. {name:"gem06",path:"./images/gem06.png"},
  37. {name:"gem07",path:"./images/gem07.png"},
  38. {name:"gem08",path:"./images/gem08.png"},
  39. {name:"gem09",path:"./images/gem09.png"},
  40. {name:"ico_sina",path:"./images/ico_sina.gif"},
  41. {name:"ico_qq",path:"./images/ico_qq.gif"},
  42. {name:"ico_facebook",path:"./images/ico_facebook.png"},
  43. {name:"ico_twitter",path:"./images/ico_twitter.png"}
  44. ];
复制代码
将需要的js文件和图片文件都加到数组内,如果需要加载文件为js文件时,需要指定type为js,如果加载的文件为图片,则type可以不设定。
读取过程与之前用法完全一样
代码清单2
  1. function main(){
  2.         loadingLayer = new LoadingSample3();
  3.         addChild(loadingLayer);       
  4.         LLoadManage.load(
  5.                 loadData,
  6.                 function(progress){
  7.                         loadingLayer.setProgress(progress);
  8.                 },
  9.                 function(result){
  10.                         LGlobal.setDebug(true);
  11.                         datalist = result;
  12.                         removeChild(loadingLayer);
  13.                         loadingLayer = null;
  14.                         gameInit();
  15.                 }
  16.         );
  17. }
复制代码
下面来向游戏中添加8行8列64块宝石,具体做法如下
代码清单3
  1. function addGem(){
  2.         stage.setStage(stage.num + 1);
  3.         gemLayer.removeAllChild();
  4.         list = [];
  5.         //添加宝石
  6.         for(i=0;i<8;i++){
  7.                 list.push([]);
  8.                 for(var j=0;j<8;j++){
  9.                         num = (Math.random()*9 >>> 0)+1;
  10.                         g = new Gem(num);
  11.                         g.x = j*60;
  12.                         g.y = i*60+120;
  13.                         gemLayer.addChild(g);
  14.                         list[i].push(g);
  15.                 }
  16.         }
  17.         //检验可消除宝石
  18.         do{
  19.                 clearList = checkClear();
  20.                 if(clearList.length > 0){
  21.                         for(i=0;i<clearList.length;i++){
  22.                                 g = clearList[i];
  23.                                 num = (Math.random()*9 >>> 0)+1;
  24.                                 g.change(num);
  25.                         }
  26.                 }
  27.         }while(clearList.length > 0);
  28. }
复制代码
上面代码中的Gem对象是一个宝石类,完整代码如下
代码清单4
  1. function Gem(num){
  2.         var self = this;
  3.         base(self,LSprite,[]);
  4.         self.num = num;
  5.         self.bitmap = new LBitmap(new LBitmapData(datalist["gem0"+num]));
  6.         self.bitmap.x=self.bitmap.y=10;
  7.         self.addChild(self.bitmap);
  8.        
  9. }
  10. Gem.prototype.change = function (num){
  11.         var self = this;
  12.         self.num = num;
  13.         self.bitmap.bitmapData = new LBitmapData(datalist["gem0"+num]);
  14. }
复制代码
Gem类继承自LSprite,内部包含一个LBitmap对象来显示宝石图片。
代码清单3中调用了checkClear函数,来检验是否有可消除宝石,检测方法为先进行横向检索,然后进行纵向检索。
代码清单5
  1. clearList = [];
  2.         //横向检索
  3.         for(i=0;i<8;i++){
  4.                 checkList = [list[i][0]];
  5.                 for(j=1;j<8;j++){
  6.                         if(checkList[checkList.length - 1].num == list[i][j].num){
  7.                                 checkList.push(list[i][j]);
  8.                         }else{
  9.                                 clearList = addClearList(clearList,checkList);
  10.                                 checkList = [list[i][j]];
  11.                         }
  12.                 }
  13.                 clearList = addClearList(clearList,checkList);
  14.         }
  15.         //纵向检索
  16.         for(i=0;i<8;i++){
  17.                 checkList = [list[0][i]];
  18.                 for(j=1;j<8;j++){
  19.                         if(checkList[checkList.length - 1].num == list[j][i].num){
  20.                                 checkList.push(list[j][i]);
  21.                         }else{
  22.                                 clearList = addClearList(clearList,checkList);
  23.                                 checkList = [list[j][i]];
  24.                         }
  25.                 }
  26.                 clearList = addClearList(clearList,checkList);
  27.         }
复制代码
addClearList函数作用是将可消除宝石压入clearList数组,做法如下
代码清单6
  1. function addClearList(clearList,checkList){
  2.         if(checkList.length >= 3){
  3.                 clearList = clearList.concat(checkList)
  4.         }
  5.         return clearList;
  6. }
复制代码
游戏操作需要划动屏幕,但是在lufylegend.js引擎中,是没有划动屏幕的事件的,所以我通过下面MOUSE_DOWN,MOUSE_UP获取点击时和点击后的位置,来模拟一下划动事件。
代码清单7
  1.         backLayer.addEventListener(LMouseEvent.MOUSE_DOWN,onDown);
  2.         backLayer.addEventListener(LMouseEvent.MOUSE_UP,onUp);
复制代码
再来看看具体做法,先是onDown函数。
代码清单8
  1. function onDown(e){
  2.         if(mouse_down_obj.isMouseDown)return;
  3.         continuous = 0;
  4.         mouse_down_obj.x = e.offsetX;
  5.         mouse_down_obj.y = e.offsetY;
  6.         mouse_down_obj.time = new Date().getTime();
  7.         mouse_down_obj.cx = e.offsetX/60 >>> 0;
  8.         mouse_down_obj.cy = (e.offsetY - 120)/60 >>> 0;
  9.         mouse_down_obj.isMouseDown = true;
  10.         list[mouse_down_obj.cy][mouse_down_obj.cx].graphics.drawRect(1,"black",[0, 0, 60, 60],true,"#000000");
  11. }
复制代码
通过e.offsetX和e.offsetY来获取点击位置,通过getTime()来获取点击时刻的时间。
在来看看onUp函数。
代码清单9
  1. function onUp(e){
  2.         list[mouse_down_obj.cy][mouse_down_obj.cx].graphics.clear();
  3.         if(new Date().getTime() - mouse_down_obj.time > 500){
  4.                 mouse_down_obj.isMouseDown = false;
  5.                 return;
  6.         }
  7.         var mx = e.offsetX - mouse_down_obj.x;
  8.         var my = e.offsetY - mouse_down_obj.y;
  9.         if(Math.abs(mx) > Math.abs(my)){
  10.                 if(mx > 50){
  11.                         move("right");
  12.                         return;
  13.                 }else if(mx < -50){
  14.                         move("left");
  15.                         return;
  16.                 }
  17.         }else{
  18.                 if(my > 50){
  19.                         move("down");       
  20.                         return;
  21.                 }else if(my < -50){
  22.                         move("up");
  23.                         return;
  24.                 }
  25.         }
  26.         mouse_down_obj.isMouseDown = false;
  27. }
复制代码
函数中通过同样的方法得到点击结束时的位置和时间,然后与点击时刻做比较,最后计算划动的方向,然后根据划动的方向来调用move函数,让宝石移动。
move函数如下:

代码清单10
  1. function move(dir){
  2.         direction = dir;
  3.         var m = moveGem(dir,8);
  4.         var mx = m[0],my = m[1];
  5.         var obj,fun;
  6.         for(var i=0;i<8;i++){
  7.                 if(mx == 0){
  8.                         obj = list[i][mouse_down_obj.cx];
  9.                 }else{
  10.                         obj = list[mouse_down_obj.cy][i];
  11.                 }
  12.                 if(i < 7){
  13.                         fun = null;
  14.                 }else{
  15.                         fun = function(){
  16.                                 hiddenObj.visible = true;
  17.                                 checkClear();
  18.                         };
  19.                 }
  20.                 LTweenLite.to(obj,0.3,
  21.                 {
  22.                         x:obj.x+mx,
  23.                         y:obj.y+my,
  24.                         onComplete:fun,
  25.                         ease:Strong.easeOut
  26.                 });
  27.        
  28.         }
  29. }
复制代码
下面以向右移动为例来说明一下move函数的处理过程,如下


先将最左边的一个宝石H移到最左边,然后再利用LTweenLite缓动类将整个一行8个宝石,向右缓动一个单位。向左的话正好相反,向上向下也是同样的原理。
每次缓动结束,要调用一次checkClear函数,来判断一下是否有可消除的宝石,如果有则开始消除宝石,如何来消除宝石呢?
我依然以向右划动来举例说明,看下面图片,假设D1,D2,D3可消除,E4,F4,G4可消除


那么首先将D1,D2,D3移到左边边界外,E4,F4,G4也移到边界外,表示被消除,之后对每一行的宝石进行位置判定,如每行的第一个宝石的x坐标应该是60,第二个为120,以此类推。如果他们不在自己的相应位置上,那么将其向左移动到规定位置就可以了,写成代码的话,如下。
代码清单11
  1. function moveList(){
  2.         var gem,time,maxTime,mx,my,fun;
  3.         maxTime = 0;
  4.         switch(direction){
  5.                 case "left":
  6.                         for(i=0;i<8;i++){
  7.                                 for(j=0;j<8;j++){
  8.                                         gem = list[i][j];
  9.                                         mx = 60*j;
  10.                                         if(gem.x > mx){
  11.                                                 time = 0.3*((gem.x-mx) / 60 >>> 0);
  12.                                                 if(maxTime < time)maxTime = time;
  13.                                                 fun = null;
  14.                                                 if(gem.x > 420){
  15.                                                         fun = function(gem){
  16.                                                                 if(gem.x <= 420)gem.visible = true;
  17.                                                         }
  18.                                                 }
  19.                                                 LTweenLite.to(gem,time,
  20.                                                 {
  21.                                                         x:mx,
  22.                                                         onUpdate:fun,
  23.                                                         onComplete:fun,
  24.                                                         ease:Strong.easeOut
  25.                                                 });
  26.                                         }
  27.                                 }
  28.                         }
  29.                         break;
  30.                 case "right":
  31.                         for(i=0;i<8;i++){
  32.                                 for(j=0;j<8;j++){
  33.                                         gem = list[i][j];
  34.                                         mx = 60*j;
  35.                                         if(gem.x < mx){
  36.                                                 time = 0.3*((mx-gem.x) / 60 >>> 0);
  37.                                                 if(maxTime < time)maxTime = time;
  38.                                                 fun = null;
  39.                                                 if(gem.x < 0){
  40.                                                         fun = function(gem){
  41.                                                                 if(gem.x >= 0)gem.visible = true;
  42.                                                         }
  43.                                                 }
  44.                                                 LTweenLite.to(gem,time,
  45.                                                 {
  46.                                                         x:mx,
  47.                                                         onUpdate:fun,
  48.                                                         onComplete:fun,
  49.                                                         ease:Strong.easeOut
  50.                                                 });
  51.                                         }
  52.                                 }
  53.                         }
  54.                         break;
  55.                 case "up":
  56.                         for(i=0;i<8;i++){
  57.                                 for(j=0;j<8;j++){
  58.                                         gem = list[j][i];
  59.                                         my = 120+60*j;
  60.                                         if(gem.y > my){
  61.                                                 time = 0.3*((gem.y-my) / 60 >>> 0);
  62.                                                 if(maxTime < time)maxTime = time;
  63.                                                 fun = null;
  64.                                                 if(gem.y > 560){
  65.                                                         fun = function(gem){
  66.                                                                 if(gem.y <= 560)gem.visible = true;
  67.                                                         }
  68.                                                 }
  69.                                                 LTweenLite.to(gem,time,
  70.                                                 {
  71.                                                         y:my,
  72.                                                         onUpdate:fun,
  73.                                                         onComplete:fun,
  74.                                                         ease:Strong.easeOut
  75.                                                 });
  76.                                         }
  77.                                 }
  78.                         }
  79.                         break;
  80.                 case "down":
  81.                         for(i=0;i<8;i++){
  82.                                 for(j=0;j<8;j++){
  83.                                         gem = list[j][i];
  84.                                         my = 120+60*j;
  85.                                         if(gem.y < my){
  86.                                                 time = 0.3*((my-gem.y) / 60 >>> 0);
  87.                                                 if(maxTime < time)maxTime = time;
  88.                                                 fun = null;
  89.                                                 if(gem.y < 120){
  90.                                                         fun = function(gem){
  91.                                                                 if(gem.y >= 120)gem.visible = true;
  92.                                                         }
  93.                                                 }
  94.                                                 LTweenLite.to(gem,time,
  95.                                                 {
  96.                                                         y:my,
  97.                                                         onUpdate:fun,
  98.                                                         onComplete:fun,
  99.                                                         ease:Strong.easeOut
  100.                                                 });
  101.                                         }
  102.                                 }
  103.                         }
  104.                         break;
  105.         }
  106.         LTweenLite.to({},maxTime*1.5,
  107.         {
  108.                 onComplete:checkStageClear,
  109.                 ease:Strong.easeOut
  110.         });
  111. }
复制代码
当然,游戏是有时间限制的,看下面的Clock类。
代码清单12
  1. function Clock(){
  2.         var self = this;
  3.         base(self,LSprite,[]);
  4.         self.timer = 0;
  5.         self.addTimer = 0.05;
  6.         self.graphics.drawArc(5,"#333333",[0,0,70,0,2*Math.PI]);
  7.        
  8. }
  9. Clock.prototype.onframe = function (){
  10.         var self = this;
  11.         self.timer += self.addTimer;
  12.         self.graphics.clear();
  13.         self.graphics.drawArc(10,"#333333",[0,0,70,0,2*Math.PI]);
  14.         self.graphics.drawArc(5,"#ffffff",[0,0,70,-Math.PI*0.5,Math.PI*self.timer/180-Math.PI*0.5]);
  15. }
复制代码
首先将Clock加载到游戏中,然后再利用ENTER_FRAME时间轴事件,来不断调用Clock的onframe不断的绘制圆弧,当timer的数值大于等于360的时候代表画完了整个圆弧,那么游戏结束。
以上,游戏的主要原理都介绍完了,下面看看如何来把游戏转化为本地App
三,发布本地化App
首先,用Eclipse新建一个Android Project


注:如何搭建Android环境,我就不说了,网上教程多得是,随便百度一下吧。
然后,填写项目名称,并选择相应的sdk版本,这里我选了2.2

接着是填写相应数据,这个随自己心情就可以了。

接着,重点来了,在工程下的assets文件夹下,简历一个www文件夹(名字自己随意),然后把刚才开发好的游戏复制到这个文件夹下,当然,lufylegend引擎也必须复制过来。

接着修改res/layout/main.xml文件,添加webView,如下
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3.     android:layout_width="fill_parent"
  4.     android:layout_height="fill_parent"
  5.     android:orientation="vertical" >
  6.     <WebView
  7.         android:id="@+id/webView1"
  8.         android:layout_width="match_parent"
  9.         android:layout_height="match_parent" />
  10. </LinearLayout>
复制代码
最后,修改Main.java文件,利用webView来显示html网页,如下
  1. public class Main extends Activity {
  2.     /** Called when the activity is first created. */
  3.     @Override
  4.     public void onCreate(Bundle savedInstanceState) {
  5.         super.onCreate(savedInstanceState);
  6.         setContentView(R.layout.main);
  7.         WebView webview = (WebView )findViewById(R.id.webView1);
  8.         webview.getSettings().setJavaScriptEnabled(true);
  9.         webview.setVerticalScrollbarOverlay(true);
  10.         webview.loadUrl("file:///android_asset/www/index.html");
  11.     }
  12. }
复制代码
好了,运行程序吧。

画面如下:

最后,想要发布游戏为.apk文件的话,build一下就好了。
发布后的apk文件。

结束了,简单吧?
四,源码
最后给出本次游戏的源代码
注:只含游戏源码,lufylegend.js引擎请自己到官网下载
不回答与技术和引擎不相关的问题
回复

使用道具 举报

37

主题

8

好友

9312

积分

诸侯王

Rank: 15Rank: 15Rank: 15Rank: 15Rank: 15

沙发
发表于 2015-11-13 20:24:49 |显示全部楼层
731315163 发表于 2015-11-13 20:09
电脑浏览器玩不了

这个帖子的代码太久了,用最新版本引擎下的demo
不回答与技术和引擎不相关的问题
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

防止垃圾广告,请填写任意字符

Archiver|lufy's legend

GMT+8, 2024-5-7 18:53 , Processed in 0.049737 second(s), 20 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部