转自:http://www.apkbus.com/android-58414-1-1.html
我们接着实战篇的第二讲继续我们的移植工作。我们开始移植最重要的部分,游戏界面,GameScreen,我们将需要移植的工程的GameView里面的一些变量都复制过来,并做一些相应的修改,比如SDK中用来保存方块图片的Bitmap数组我们用libgdx中的Textrue来代替之类的。
- public boolean checkfull()
- public boolean checkcollide(int x,int y,int[][]bricks,int[][]frame)
- public void copy()
- public void roll()
- public void toLeft()
- public void toRight()
- public void toBelow()
未移植前,也就是SDK版本中的GameView.java这部分用来产生新方块的代码是这样的:
- public void run() {
- // TODO Auto-generated method stub
- try{
- while(isplaying==1){
- if(isflying==0){
- switch((int) Math.round(Math.random() * 7)){
- case 0:brick=new COBrick((int) rand.nextInt(6));System.out.print("O!"+brick.color);break;
- case 1:brick=new CLBrick((int) rand.nextInt(6));System.out.print("L!"+brick.color);break;
- case 2:brick=new CLLBrick((int) rand.nextInt(6));System.out.print("LL!"+brick.color);break;
- case 3:brick=new CSBrick((int) rand.nextInt(6));System.out.print("S!"+brick.color);break;
- case 4:brick=new CSSBrick((int) rand.nextInt(6));System.out.print("SS!"+brick.color);break;
- case 5:brick=new CIBrick((int) rand.nextInt(6));System.out.print("I!"+brick.color);break;
- case 6:brick=new CCBrick((int) rand.nextInt(6));System.out.print("C!"+brick.color);break;
- }
- x=0;
- y=3;
- isflying=1;
- try{
- bricks=brick.checkori(brick.ori);
- }catch(NullPointerException e){
- brick=new CSSBrick((int) rand.nextInt(6));
- bricks=brick.checkori(brick.ori);
- }
- }
- toBelow();
- Draw();
- Thread.sleep(speed);
- }
- }catch (InterruptedException e){
- }
- }
其中我加入了适当的打印代码便于发现问题的时候追踪。
下面这段代码是加在libgdx版本GameScreen.java的show()方法里的:
- new Thread(new Runnable() {
- @Override
- public void run() {
- // TODO Auto-generated method stub
- try{
- while(isplaying==true){
- if(!isflying){
- switch((int) Math.round(Math.random() * 7)){
- case 0:brick=new COBrick((int) rand.nextInt(6));System.out.print("O!"+brick.color);break;
- case 1:brick=new CLBrick((int) rand.nextInt(6));System.out.print("L!"+brick.color);break;
- case 2:brick=new CLLBrick((int) rand.nextInt(6));System.out.print("LL!"+brick.color);break;
- case 3:brick=new CSBrick((int) rand.nextInt(6));System.out.print("S!"+brick.color);break;
- case 4:brick=new CSSBrick((int) rand.nextInt(6));System.out.print("SS!"+brick.color);break;
- case 5:brick=new CIBrick((int) rand.nextInt(6));System.out.print("I!"+brick.color);break;
- case 6:brick=new CCBrick((int) rand.nextInt(6));System.out.print("C!"+brick.color);break;
- }
- x=0;
- y=3;
- isflying=true;
- try{
- bricks=brick.checkori(brick.ori);
- }catch(NullPointerException e){
- brick=new CSSBrick((int) rand.nextInt(6));
- bricks=brick.checkori(brick.ori);
- }
- }
- toBelow();
- Thread.sleep(speed);
- }
- }catch (InterruptedException e){
- }
- }
- }).start();
和原来的对照一下,基本没有任何变化。还有一个重要的问题,怎么关闭一个线程呢?很简单,我们在hide()和pause()方法内令isplaying为false就可以了,再每次show的时候重新置为true,就像下面显示的那样:
- @Override
- public void hide() {
- // TODO Auto-generated method stub
- isplaying=false;
- }
- @Override
- public void pause() {
- // TODO Auto-generated method stub
- isplaying=false;
- }
继续下面的工作。
- batch.begin();
- for(int i=0;i<21;i++)
- for(int j=0;j<10;j++)
- //根据屏幕大小做了一个简单的适配,只适配了QVGA,HVGA,WVGA
- if(temframe[i][j]!=0){
- if(max>=320&&max<480){
- batch.draw(image[temframe[i][j]-1], (float)(50+14*j), max-(float)(25+14*i),14,14);
- }
- if(max>=480&&max<800){
- batch.draw(image[temframe[i][j]-1], (float)(80+16*j), max- (float)(70+16*i),16,16);
- }
- if(max>=800){
- batch.draw(image[temframe[i][j]-1], (float)(100+28*j),max-(float)(120+28*i),28,28);
- }
- }
- //结束时要调用end()方法
这里又有一点要再次强调!!!!!!libgdx中的坐标和SDK中是不一样的!!!SDK中以左上角为原点,libgdx的是笛卡尔坐标系,以左下角为原点!!!上面这段代码是从SDK版本的ViewActivity的OnDraw()函数中移植过来的,大家可以对照一下看看有什么不同的地方。
另外,我们还要把SDK版本中的ViewActivity.java里面除了上面用到的OnDraw()方法外的一些方法也复制过来,因为我们现在用一个GameScreen直接作为一个界面,因此我们实际是在一个GameScreen里面做了GameView.java和ViewActivity两部分的工作,因此我们也需要将ViewActivity里面的一些方法给移植进去。如save(),read(),savedata()等方法,当然都要做少量的调整。由于read()方法中需要取到当前设备上下文Context,而GameScreen中是无法取得的,我们就可以修改GameScreen的构造函数传入UiActivity来获得这个Context。修改后的GameScreen构造函数:
- public GameScreen(UiActivity activity) {
- super();
- this.activity=activity;
- // TODO Auto-generated constructor stub
- }
其中需要的用来保存UiActivity引用的变量activity我们自行添加。
- //空中方块向左移动
- public void toLeft(){
- if(checkcollide(x,((int)(y-1)),bricks,frame)){
- System.out.print("Left");
- y-=1;
- copy();
- Draw();
- }
- }
- //向右移动
- public void toRight(){
- if(checkcollide(x,((int)(y+1)),bricks,frame)){
- y+=1;
- copy();
- Draw();
- }
- }
- //向下移动
- public void toBelow(){
- System.out.println("In below!");
- try{
- if(bricks!=null){
- if(checkcollide(((int)(x+1)),y,bricks,frame)){
- x+=1;
- copy();
- Draw();
- }
- else {
- if(checkfull()){
- UiActivity.gameover=true;
- }
- for(int i=0;i<4;i++)
- for(int j=0;j<4;j++){
- if(bricks[i][j]!=0)
- frame[x+i][y+j]=bricks[i][j];
- }
- isflying=false;
- bricks=null;
- for(int i=0;i<21;i++){
- int flag=1;
- for(int j=0;j<10;j++){
- if(frame[i][j]==0)
- flag=0;
- }
- if(flag==1){
- for(int k=i;k>0;k--)
- frame[k]=frame[k-1].clone();
- for(int p=0;p<10;p++)
- frame[0][p]=0;
- score+=100;
- }
- }
- }
- }
- }catch(NullPointerException e){
- e.printStackTrace();
- }
- }
- //旋转
- public void roll(){
- if(checkcollide(x,y,brick.checkori((int)(brick.ori+1)),frame)){
- brick.ori+=1;
- bricks=brick.checkori(brick.ori);
- copy();
- Draw();
- }
- }
- //更新temframe里的内容,用于实时绘图
- public void copy(){
- for(int k=0;k<21;k++)
- temframe[k]=frame[k].clone();
- for(int i=0;i<4;i++)
- for(int j=0;j<4;j++)
- if(bricks[i][j]!=0&&temframe[x+i][y+j]==0)
- temframe[x+i][y+j]=bricks[i][j];
- }
- public boolean checkcollide(int x,int y,int[][]bricks,int[][]frame){
- if(bricks!=null)
- {
- int max_x=0,min_x=3,max_y=0,min_y=3;
- boolean collide=true;
- for(int i=0;i<4;i++)
- for(int j=0;j<4;j++)
- if(bricks[i][j]!=0){
- if(j<min_y)
- min_y=j;
- if(j>max_y)
- max_y=j;
- if(i>max_x)
- max_x=i;
- if(i<min_x)
- min_x=i;
- }
- if((max_x+x)>20||(max_y+y)>10||y+min_y<0)
- collide=false;
- try{
- int i;
- int j;
- for(i=0;i<=max_x;i++)
- for(j=min_y;j<=max_y;j++)
- if(bricks[i][j]!=0&&frame[x+i][y+j]!=0){
- collide=false;
- }
- }catch(ArrayIndexOutOfBoundsException e){
- return false;
- }
- return collide;
- }
- return false;
- }
- //判断是否方块到顶,游戏结束
- public boolean checkfull(){
- for(int i=0;i<21;i++)
- for(int j=0;j<10;j++){
- if(temframe[i][j]!=frame[i][j])
- return false;
- }
- return true;
- }
- public void save(String fileName, String fileContent) throws Exception {
- FileOutputStream fileOutputStream = activity.openFileOutput(
- fileName, Context.MODE_PRIVATE);
- fileOutputStream.write(fileContent.getBytes());
- }
- public String read(String fileName) throws Exception {
- FileInputStream fileInputStream = activity.openFileInput(fileName);
- ByteArrayOutputStream byteArray = new ByteArrayOutputStream();
- byte[] buffer = new byte[1024];
- int len = 0;
- while ((len = fileInputStream.read(buffer)) > 0) {
- byteArray.write(buffer, 0, len);
- };
- return byteArray.toString();
- }
- public void savedata(){
- String framedata="";
- for(int i=0;i<21;i++)
- for(int j=0;j<10;j++){
- framedata+=Integer.toString(frame[i][j])+",";
- }
- framedata+=Integer.toString(score);
- try {
- save("Tetris_slide.txt",framedata);
- } catch (Exception e) {
- // TODO Auto-generated catch block
- e.printStackTrace();
- }
- }