转自:http://www.apkbus.com/android-58408-1-1.html
SDK版本源码下载(是我们移植的素材):
Tetris_slide.rar(537.04 KB, 下载次数: 113)
接着实战篇的第一讲,我们开始新建上面提到的这些类,便于从SDK版本中移植。
- public class TetrisGame extends Game {
- Screen screen;
- @Override
- public void create() {
- // TODO Auto-generated method stub
- setScreen(screen);
- }
- public TetrisGame(Screen screen) {
- super();
- // TODO Auto-generated constructor stub
- this.screen=screen;
- }
- }
我们在构造这个Game的时候,同时传入了一个Screen,内部有一个变量保存这个引用,并在这个Game被AndroidApplication调用initialize()方法的时候(Game则调用create())的时候将Game的默认屏幕变为这个传入的Screen。
目前这两个类也是空的,什么都没有。很简单,直接实现Screen接口就可以了,所以就不贴代码了。
UiActivity.java:
- public class UiActivity extends AndroidApplication {
- TetrisGame tg;
- UiScreen us;
- GameScreen gs;
- @Override
- public void onCreate(Bundle savedInstanceState) {
- super.onCreate(savedInstanceState);
- requestWindowFeature(Window.FEATURE_NO_TITLE);
- getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
- WindowManager.LayoutParams.FLAG_FULLSCREEN);
- gs=new GameScreen();
- us=new UiScreen();
- tg=new TetrisGame(us);
- initialize(tg, true);
- }
- }
然后我们修改UiScreen,画出基本图像,不过我们这里先不加入难度设置,并且游戏开始用一个按钮表示,最后我们会尝试将用SDK实现的滑动开始的效果和RatingBar的效果用自定义Libgdx实现。
还记得SDK版本的主界面是怎样的吗?我们回忆一下,哈哈,贴张图,然后好做对比。
当然现在我们要用Libgdx来实现它。
我们将需要的素材从SDK版本中拿过来…放心,这两个版本都是我自己写的所以没有版权问题哈=。=
将三张背景图片放在asset文件夹下,这里我们为了追求简单,只对320*240,480*320,800*480的分辨率进行适配。所以其他机型可以显示,但可能有显示的问题,比如图片拉伸的问题。
我们先修改UiScreen,这个界面修改好后将成为游戏的开始界面。
注意,这里有一个非常 非常 非常 非常 非常 非常 非常 非常 非常 非常重要的问题。 libgdx中的图片的边长只能是2的幂次,如2*4,32*64等等,但是图片不满足这个要求怎么办呢?我们可以用libgdx中的工具TextruePacker,具体使用方法可以看:
android游戏开发框架libgdx的使用(十六)
http://www.apkbus.com/android-44510-1-1.html
也可以使用将图片修改成2的幂次的边长(多余的部分可以是白色或者任意颜色)我们在绘制的时候用TextureRegion封装Textrue并且只将有用的部分绘制出来就可以了。下面我用的就是这种方法。
我们将图片做一些调整,让边长满足2的幂次的条件。多余的部分我们在绘制的时候不画出就可以了。修改后的图片如下,我们可以很清楚的看见有红色的部分,这都是不会被画出的。
这些图我改成了边长为2的幂次的:
为了醒目,让大家明白多余的部分是不会被画出的,我用了醒目的红色。
UiScreen.java(接下来还会修改,一步步来嘛)
请大家务必看一下注释,很多问题就不便一一讲,但是又非常重要,所以我在注释中都写出来了。
- public class UiScreen implements Screen {
- Texture texture;
- TextureRegion background;
- boolean hasini;
- SpriteBatch batch;
- Stage stage;
- Button start;
- int width;
- int height;
- //边长的最大值和最小值
- int max;
- int min;
- Texture tx1;
- Texture tx2;
- Texture tx3;
- @Override
- public void dispose() {
- // TODO Auto-generated method stub
- }
- @Override
- public void hide() {
- // TODO Auto-generated method stub
- }
- @Override
- public void pause() {
- // TODO Auto-generated method stub
- }
- @Override
- public void render(float arg0) {
- // TODO Auto-generated method stub
- Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
- Gdx.gl.glClearColor(0f,0f,0f,0f);
- batch.begin();
- batch.draw(background,0,0,min,max);
- batch.end();
- //舞台绘制要在背景绘制之后,不然背景会覆盖在按钮表面,我们就看不到按钮了
- stage.act(Gdx.graphics.getDeltaTime());
- stage.draw();
- }
- @Override
- public void resize(int arg0, int arg1) {
- // TODO Auto-generated method stub
- }
- @Override
- public void resume() {
- // TODO Auto-generated method stub
- }
- @Override
- public void show() {
- // TODO Auto-generated method stub
- //做一个简单的适配。这里解释一下为什么不直接令max=height,原因在于有时候我们从锁屏回到游戏,
- //从横屏切换到竖屏或者从竖屏切换到横屏的时候,libGdx有时候会来不及切换,也就是说我们可能
- //getWidth得到的是实际的height值,getHeight得到的是实际的width值,所以这里增加一个长宽哪一个
- //更大的语句,这样就不会出错了
- width=Gdx.graphics.getWidth();
- height=Gdx.graphics.getHeight();
- max=width>height?width:height;
- min=width>height?height:width;
- //再做一个简单的适配
- if(max>=320&&max<480)
- max=320;
- if(max>=480&&max<800)
- max=480;
- if(max>=800)
- max=800;
- if(!hasini){
- batch=new SpriteBatch();
- stage=new Stage(min,max,true);
- texture=new Texture(Gdx.files.internal("background"+max+".jpg"));
- //新建一个Button
- tx2 = new Texture(Gdx.files.internal("button1.png"));
- tx1 = new Texture(Gdx.files.internal("button2.png"));
- tx3 = new Texture(Gdx.files.internal("button3.png"));
- NinePatch n1 = new NinePatch(tx1, 14, 14, 18, 18);
- NinePatch n2 = new NinePatch(tx2, 14, 14, 18, 18);
- NinePatch n3 = new NinePatch(tx3, 14, 14, 18, 18);
- start= new Button( new ButtonStyle(n1, n2, n3, 0f, 0f, 0f, 0f), "Start");
- //让按钮的位置处在正中间
- start.x=(min-tx2.getWidth())/2;
- stage.addActor(start);
- //重点在这条语句,我们只取了texture的一部分,红色的多余部分我们没有取
- background=new TextureRegion(texture, 0, 0, min, max);
- hasini=true;
- }
- //这句话是必须的,而且在if(hasini)之外,无论资源是否加载完成,每次显示的时候我们都养将当前屏幕
- //设置能够接受用户输入
- Gdx.input.setInputProcessor(stage);
- }
- }
咩哈哈,老样子,我胆子比较小,学习Mars老师的,写一点就运行一下,一是可以看看小效果给自己一点信心,二是防止错误往下面积累,后面出错不好锁定错误的位置。运行一下,显示效果应该是这样的,按钮按下没有任何变化..
然后我们就开始移植最重要的部分,游戏界面,GameScreen,我们将需要移植的工程的GameView里面的一些变量都复制过来,并做一些相应的修改,比如SDK中用来保存方块图片的Bitmap数组我们用libgdx中的Textrue来代替之类的。
这次的教程写的实在是太长了...我还是放在下一讲继续写...word文档摆了50页...伤不起啊