lufy's legend

 找回密码
 立即注册
搜索
热搜: 活动 交友 discuz
查看: 19771|回复: 5

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

  [复制链接]

37

主题

8

好友

9309

积分

诸侯王

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引擎请自己到官网下载
不回答与技术和引擎不相关的问题
回复

使用道具 举报

0

主题

0

好友

10

积分

士兵

Rank: 1

发表于 2014-5-9 17:25:57 |显示全部楼层
看帖子的要发表下看法
回复

使用道具 举报

9

主题

0

好友

133

积分

士兵

Rank: 1

发表于 2014-5-10 19:49:53 |显示全部楼层
嘿嘿  跟站长一伙的啊
回复

使用道具 举报

10

主题

0

好友

176

积分

士兵

Rank: 1

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

使用道具 举报

37

主题

8

好友

9309

积分

诸侯王

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

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

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

使用道具 举报

0

主题

0

好友

4

积分

士兵

Rank: 1

发表于 2024-3-18 15:22:18 |显示全部楼层
本帖最后由 serajes 于 2024-3-18 15:29 编辑

Textfree is available for both iOS and Android devices and free text and call app without phone number. offers both free and paid versions with additional features.

回复

使用道具 举报

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

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

Archiver|lufy's legend

GMT+8, 2024-4-19 10:14 , Processed in 0.060237 second(s), 24 queries .

Powered by Discuz! X2.5

© 2001-2012 Comsenz Inc.

回顶部