您的位置:首页 > 移动开发 > Android开发

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

2014-10-13 16:40 435 查看
本次来说一说如何利用lufylegend.js引擎制作一款HTML5游戏后,将其转换为android本地化的App应用,转换过程其实很简单,下面一步步来做说明。

首先来开发一个类似于对对碰的游戏,不过此游戏玩法为在下原创,如有雷同,纯属巧合,游戏界面如下。

游戏操作:上下左右划动屏幕,来操作宝石向不同的方向移动。

游戏规则:当有三个一样的宝石相邻则消除,被消除过一次的宝石会变成半透明,当所有宝石都被消除一次后,则进入下一关。

制作开始



一,准备

首先,需要下载lufylegend.js引擎,下面是我在博客的lufylegend-1.7.0发布帖

/article/1360473.html



二,游戏开发

引擎lufylegend1.7.0中扩展了LLoadManage静态类,可以读取图片,js文件以及文本文件,本次游戏开发就来体验一下这个新功能,首先看下面数组

代码清单1

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
1. backLayer.addEventListener(LMouseEvent.MOUSE_DOWN,onDown);

2. backLayer.addEventListener(LMouseEvent.MOUSE_UP,onUp);
再来看看具体做法,先是onDown函数。

代码清单8

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
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

[javascript] view plaincopy
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,如下

[html] view plaincopy
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网页,如下

[java] view plaincopy
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文件。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐