libgdx游戏引擎教程实战篇(二)移植俄罗斯方块(附源码)

转自:http://www.apkbus.com/android-58408-1-1.html

 

SDK版本源码下载(是我们移植的素材):

Tetris_slide.rar(537.04 KB, 下载次数: 113)

2012-7-10 20:54 上传
点击文件名下载附件
下载积分: 下载豆 -2



 

既然我们是要用 libgdx移植这个游戏,我们很显然要让UiActvity从直接继承Activity改成继承AndrodApplication,并且我们用到了多界面,那么按照我在第五,第六,第七讲三讲中讲的,我们要有两个继承自Screen的界面,分别叫UiScreen,GameScreen,并且有一个管理这两个Screen的继承自Game类的类,我们叫它TetrisGame好了。


接着实战篇的第一讲,我们开始新建上面提到的这些类,便于从SDK版本中移植。

先创建一个新类 TetrisGame,继承自Game:
  1. public class TetrisGame extends Game {
  2. Screen screen;
  3. @Override
  4. public void create() {
  5. // TODO Auto-generated method stub
  6. setScreen(screen);
  7. }
  8. public TetrisGame(Screen screen) {
  9. super();
  10. // TODO Auto-generated constructor stub
  11. this.screen=screen;
  12. }


  13. }
复制代码

我们在构造这个Game的时候,同时传入了一个Screen,内部有一个变量保存这个引用,并在这个Game被AndroidApplication调用initialize()方法的时候(Game则调用create())的时候将Game的默认屏幕变为这个传入的Screen。

10.jpg

2012-7-10 20:58 上传
下载附件(119.29 KB)



这个类其实就算写完了,传入一个Screen,并在创建的时候将这个Screen设置为当前界面。


 

然后是新建两个 Screen, UiScreenGameScreen,分别代表主界面和游戏界面。


 

11.jpg
2012-7-10 20:59 上传
下载附件(130.28 KB)



 

12.jpg
2012-7-10 20:59 上传
下载附件(130.6 KB)


目前这两个类也是空的,什么都没有。很简单,直接实现Screen接口就可以了,所以就不贴代码了。

然后我们进行一个初始阶段比较重要的操作。修改UiActivity让其继承自AndroidApplication



UiActivity.java:

  1. public class UiActivity extends AndroidApplication {
  2. TetrisGame tg;
  3. UiScreen us;
  4. GameScreen gs;
  5. @Override
  6. public void onCreate(Bundle savedInstanceState) {
  7. super.onCreate(savedInstanceState);
  8. requestWindowFeature(Window.FEATURE_NO_TITLE);
  9. getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
  10. WindowManager.LayoutParams.FLAG_FULLSCREEN);
  11. gs=new GameScreen();
  12. us=new UiScreen();
  13. tg=new TetrisGame(us);
  14. initialize(tg, true);
  15. }
  16. }
复制代码
然后我们运行一下,程序能正常启动,不过是是一个全黑的屏幕,这很正常,因为我们没有做任何操作。


然后我们修改UiScreen,画出基本图像,不过我们这里先不加入难度设置,并且游戏开始用一个按钮表示,最后我们会尝试将用SDK实现的滑动开始的效果和RatingBar的效果用自定义Libgdx实现

还记得SDK版本的主界面是怎样的吗?我们回忆一下,哈哈,贴张图,然后好做对比。




当然现在我们要用Libgdx来实现它。

我们将需要的素材从SDK版本中拿过来放心,这两个版本都是我自己写的所以没有版权问题哈==

将三张背景图片放在asset文件夹下,这里我们为了追求简单,只对320*240480*320800*480的分辨率进行适配。所以其他机型可以显示,但可能有显示的问题,比如图片拉伸的问题。

我们先修改UiScreen,这个界面修改好后将成为游戏的开始界面。

注意,这里有一个非常 非常 非常 非常 非常 非常 非常 非常 非常 非常重要的问题。 libgdx中的图片的边长只能是2的幂次,如2*432*64等等,但是图片不满足这个要求怎么办呢?我们可以用libgdx中的工具TextruePacker,具体使用方法可以看:

android游戏开发框架libgdx的使用(十六)

http://www.apkbus.com/android-44510-1-1.html

也可以使用将图片修改成2的幂次的边长(多余的部分可以是白色或者任意颜色)我们在绘制的时候用TextureRegion封装Textrue并且只将有用的部分绘制出来就可以了。下面我用的就是这种方法。

我们将图片做一些调整,让边长满足2的幂次的条件。多余的部分我们在绘制的时候不画出就可以了。修改后的图片如下,我们可以很清楚的看见有红色的部分,这都是不会被画出的。

这些图我改成了边长为2的幂次的:

background320.jpg

2012-7-10 21:12 上传
下载附件(27.09 KB)

background800.jpg

2012-7-10 21:12 上传
下载附件(71.77 KB)

background48.jpg

2012-7-10 21:12 上传
下载附件(48.08 KB)




为了醒目,让大家明白多余的部分是不会被画出的,我用了醒目的红色。


UiScreen.java(接下来还会修改,一步步来嘛)

请大家务必看一下注释,很多问题就不便一一讲,但是又非常重要,所以我在注释中都写出来了。

  1. public class UiScreen implements Screen {
  2. Texture texture;
  3. TextureRegion background;
  4. boolean hasini;
  5. SpriteBatch batch;
  6. Stage stage;
  7. Button start;
  8. int width;
  9. int height;
  10. //边长的最大值和最小值
  11. int max;
  12. int min;
  13. Texture tx1;
  14. Texture tx2;
  15. Texture tx3;
  16. @Override
  17. public void dispose() {
  18. // TODO Auto-generated method stub

  19. }

  20. @Override
  21. public void hide() {
  22. // TODO Auto-generated method stub
  23. }

  24. @Override
  25. public void pause() {
  26. // TODO Auto-generated method stub

  27. }

  28. @Override
  29. public void render(float arg0) {
  30. // TODO Auto-generated method stub
  31. Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
  32. Gdx.gl.glClearColor(0f,0f,0f,0f);

  33. batch.begin();
  34. batch.draw(background,0,0,min,max);
  35. batch.end();

  36. //舞台绘制要在背景绘制之后,不然背景会覆盖在按钮表面,我们就看不到按钮了
  37. stage.act(Gdx.graphics.getDeltaTime());
  38. stage.draw();
  39. }

  40. @Override
  41. public void resize(int arg0, int arg1) {
  42. // TODO Auto-generated method stub

  43. }

  44. @Override
  45. public void resume() {
  46. // TODO Auto-generated method stub

  47. }


  48. @Override
  49. public void show() {
  50. // TODO Auto-generated method stub

  51. //做一个简单的适配。这里解释一下为什么不直接令max=height,原因在于有时候我们从锁屏回到游戏,
  52. //从横屏切换到竖屏或者从竖屏切换到横屏的时候,libGdx有时候会来不及切换,也就是说我们可能
  53. //getWidth得到的是实际的height值,getHeight得到的是实际的width值,所以这里增加一个长宽哪一个
  54. //更大的语句,这样就不会出错了
  55. width=Gdx.graphics.getWidth();
  56. height=Gdx.graphics.getHeight();
  57. max=width>height?width:height;
  58. min=width>height?height:width;
  59. //再做一个简单的适配
  60. if(max>=320&&max<480)
  61. max=320;
  62. if(max>=480&&max<800)
  63. max=480;
  64. if(max>=800)
  65. max=800;
  66. if(!hasini){
  67. batch=new SpriteBatch();
  68. stage=new Stage(min,max,true);
  69. texture=new Texture(Gdx.files.internal("background"+max+".jpg"));

  70. //新建一个Button

  71. tx2 = new Texture(Gdx.files.internal("button1.png"));
  72. tx1 = new Texture(Gdx.files.internal("button2.png"));
  73. tx3 = new Texture(Gdx.files.internal("button3.png"));
  74. NinePatch n1 = new NinePatch(tx1, 14, 14, 18, 18);
  75. NinePatch n2 = new NinePatch(tx2, 14, 14, 18, 18);
  76. NinePatch n3 = new NinePatch(tx3, 14, 14, 18, 18);
  77. start= new Button( new ButtonStyle(n1, n2, n3, 0f, 0f, 0f, 0f), "Start");

  78. //让按钮的位置处在正中间
  79. start.x=(min-tx2.getWidth())/2;
  80. stage.addActor(start);

  81. //重点在这条语句,我们只取了texture的一部分,红色的多余部分我们没有取
  82. background=new TextureRegion(texture, 0, 0, min, max);
  83. hasini=true;
  84. }
  85. //这句话是必须的,而且在if(hasini)之外,无论资源是否加载完成,每次显示的时候我们都养将当前屏幕
  86. //设置能够接受用户输入
  87. Gdx.input.setInputProcessor(stage);
  88. }
  89. }
复制代码


咩哈哈,老样子,我胆子比较小,学习Mars老师的,写一点就运行一下,一是可以看看小效果给自己一点信心,二是防止错误往下面积累,后面出错不好锁定错误的位置。运行一下,显示效果应该是这样的,按钮按下没有任何变化..
14.png

2012-7-10 21:17 上传
下载附件(138.64 KB)




然后我们就开始移植最重要的部分,游戏界面,GameScreen,我们将需要移植的工程的GameView里面的一些变量都复制过来,并做一些相应的修改,比如SDK中用来保存方块图片的Bitmap数组我们用libgdx中的Textrue来代替之类的。

这次的教程写的实在是太长了...我还是放在下一讲继续写...word文档摆了50页...伤不起啊

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值