学习Android的基本开发也有一段时间了,但是因为没有经常使用Android渐渐的也就忘记了。Android编程学的不深,仅仅是为了对付逆向,但是有时还是会感到力不从心的。毕竟不是一个计算机专业毕业的Coder,相对来说编程的基础对于以后很多方面的学习都是很重要的,特别是想在软件安全或软件的企业开发的过程中有所进步,必须要计算机专业知识扎实。

不多说了,发个Android版的俄罗斯方块,当然基本框架是参照之前的学的C语言版的俄罗斯方块的。俄罗斯方块程序的开发方法比较多,感觉使用数组的方法去实现还是很方便的,下面看代码的具体实现。


俄罗斯方块界面显示代码的实现:

//俄罗斯方块界面的显示package com.example.mytetris;import android.content.Context;import android.graphics.Canvas;import android.graphics.Color;import android.graphics.Paint;import android.util.AttributeSet;import android.util.DisplayMetrics;import android.view.View;import android.view.WindowManager;public class GameUI extends View{public Game m_Game = null;    private byte[][] m_Groundback = null;        private Paint m_Paint = new Paint(); //画刷    private final int PADDING = 2;       private int m_TetrisWidth = 0;        @Override    protected void onDraw(Canvas canvas)     { //设置背景颜色setBackgroundColor(Color.BLACK);//画背景drawGoundback(canvas);//画方块int nX = m_Game.m_nX;int nY = m_Game.m_nY;if (m_Game.m_CurrBlock == null)return;byte[][] data = m_Game.m_CurrBlock;for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){if (data[i][j] == Game.ISWALL){int nLeft = nX * m_TetrisWidth  + j * m_TetrisWidth;int nTop = nY * m_TetrisWidth +  i * m_TetrisWidth;//外框m_Paint.setColor(Color.WHITE);canvas.drawRect(nLeft, nTop, nLeft + m_TetrisWidth, nTop + m_TetrisWidth, m_Paint);//内框m_Paint.setColor(Color.GREEN);canvas.drawRect(nLeft + PADDING, nTop + PADDING, nLeft + m_TetrisWidth - PADDING, nTop +m_TetrisWidth - PADDING, m_Paint);}}}    }    private void drawGoundback(Canvas canvas)    {    //获取背景m_Groundback = m_Game.getGroundback();for (int i = 0; i < Game.NROWS; i++) {    for (int j = 0; j < Game.NCOLS; j++)     {if (m_Groundback[i][j] == Game.ISWALL){    //画白色的方块--外框    m_Paint.setColor(Color.WHITE);    canvas.drawRect(j*m_TetrisWidth, i*m_TetrisWidth,        (j+1)*m_TetrisWidth, (i+1)*m_TetrisWidth, m_Paint);        //画绿色的方块--内框    m_Paint.setColor(Color.GREEN);    canvas.drawRect(j*m_TetrisWidth + PADDING, i*m_TetrisWidth + PADDING,           (j+1)*m_TetrisWidth - PADDING, (i+1)*m_TetrisWidth - PADDING, m_Paint);}    }}    }        public GameUI(Context context, AttributeSet attrs, int defStyleAttr)    {    super(context, attrs, defStyleAttr);        }        //自定义view组件,构造调用该函数    public GameUI(Context context, AttributeSet attrs)    {    super(context, attrs);        //创建Game    m_Game = new Game();        //获取手机分辨率    WindowManager wmgr = (WindowManager)context.getSystemService(Context.WINDOW_SERVICE);DisplayMetrics outMetrics = new DisplayMetrics();wmgr.getDefaultDisplay().getMetrics(outMetrics);//手机屏幕宽度int nTetrisWidth = outMetrics.widthPixels;        //根据手机分辨率,设置方块宽度    m_TetrisWidth = nTetrisWidth/Game.NCOLS*3/4;        }        public GameUI(Context context)    {    super(context);        }}


俄罗斯方块具体的逻辑的实现:

package com.example.mytetris;import java.util.Arrays;import java.util.Random;import android.R.integer;public class Game {public static final byte ISWALL = 1; //墙public static final int NROWS = 20;  //18行public static final int NCOLS = 12;  //12列public byte[][] m_Groundback = null;public int m_nX = 0;   //方块x坐标public int m_nY = 0;   //方块y坐标private Random m_Random = new Random(); //产生随机对象private byte[][][] m_Tetris = null;  //方块的各种变化public byte[][] m_CurrBlock = new  byte[4][4]; //当前方块private byte[][] m_NextBlock = new  byte[4][4]; //下一个方块public Game(){m_Groundback = new byte[NROWS][NCOLS];initGroundback();initTetris();}//初始化背景public void initGroundback(){for (int i = 0; i < NROWS; i++){for (int j = 0; j < NCOLS; j++){if (i == NROWS - 1 || j == 0 || j == NCOLS - 1){    //设置墙    m_Groundback[i][j] = ISWALL;}}}}//初始化变换方块的类型public void initTetris(){//这种初始化不能给维数    m_Tetris = new byte [][][]{    /*1*/{{1, 1, 1, 1},{0, 0, 0, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},/*2*/{{1, 0, 0, 0},{1, 0, 0, 0}, {1, 0, 0, 0},{1, 0, 0, 0}},/*3*/{{1, 0, 0, 0},{1, 1, 0, 0}, {0, 1, 0, 0},{0, 0, 0, 0}},/*4*/{{0, 1, 0, 0},{1, 1, 0, 0}, {1, 0, 0, 0},{0, 0, 0, 0}},/*5*/{{1, 1, 0, 0},{0, 1, 1, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},/*6*/{{0, 1, 1, 0},{1, 1, 0, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},/*7*/{{0, 1, 0, 0},{1, 1, 1, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},/*8*/{{1, 1, 1, 0},{0, 1, 0, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},/*9*/{{1, 0, 0, 0},{1, 1, 0, 0}, {1, 0, 0, 0},{0, 0, 0, 0}},/*10*/{{0, 1, 0, 0},{1, 1, 0, 0}, {0, 1, 0, 0},{0, 0, 0, 0}},/*11*/{{1, 1, 0, 0},{0, 1, 0, 0}, {0, 1, 0, 0},{0, 0, 0, 0}},/*12*/{{1, 1, 0, 0},{1, 0, 0, 0}, {1, 0, 0, 0},{0, 0, 0, 0}},    /*13*/{{1, 0, 0, 0},{1, 1, 1, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},/*14*/{{1, 1, 1, 0},{0, 0, 1, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},    /*15*/{{1, 1, 0, 0},{1, 1, 0, 0}, {0, 0, 0, 0},{0, 0, 0, 0}},    };    }//获取背景public byte[][] getGroundback(){    return m_Groundback;}//开始游戏public void startGame(){m_nX = NCOLS / 2 - 2;m_nY = 0;// 产生方块m_CurrBlock = RandomBlock();m_NextBlock = RandomBlock();}//结束游戏public void stopGame(){    }//左移public void moveLeft(){if (IsCanMove(m_nX - 1, m_nY)){m_nX--;}}//右移public void moveRight(){if (IsCanMove(m_nX + 1, m_nY)){m_nX++;}}//方块变换时,变换方块--这个产生的问题还没解决?public byte[][] getNextBlock(){//产生一个随机数    int nLen = m_Tetris.length;    //右移高位补0--去掉符号位    int nIndex = (m_Random.nextInt() >>> 1) % nLen;    return m_Tetris[(nIndex+2)%15];}//变换public void moveChange(){byte[][] oldBlock = m_CurrBlock;m_CurrBlock = getNextBlock();if (!IsCanMove(m_nX, m_nY)){m_CurrBlock = oldBlock;}}//下移public void moveDown(){if (IsCanMove(m_nX, m_nY + 1)){m_nY++;} else{Fixbircks();}}//随机产生方块public byte[][] RandomBlock(){ //产生一个随机数  int nLen = m_Tetris.length;  //右移高位补0--去掉符号位  int nIndex = (m_Random.nextInt() >>> 1) % nLen;    return m_Tetris[nIndex];}//产生方块private void CreateBircks(){m_nX = NCOLS / 2 - 2;m_nY = 0;// 产生方块m_CurrBlock = m_NextBlock;m_NextBlock = RandomBlock();}//下移到底public void MoveFix(){while (IsCanMove(m_nX, m_nY + 1)){m_nY++;}Fixbircks();}//判断方块能否移动private boolean IsCanMove(int x, int y){byte[][] data = m_CurrBlock;for (int i = 0; i < 4; i++){for (int j = 0; j < 4; j++){if (data[i][j] == ISWALL&& m_Groundback[y + i][x + j] == ISWALL){return false;}}}return true;}//固定方块private  void Fixbircks(){  byte[][] data = m_CurrBlock;  for (int i = 0; i < 4; i++)  {    for (int j = 0; j < 4; j++)    {      //填充背景      if (data[i][j] == ISWALL)      {        m_Groundback[m_nY + i][m_nX + j] = ISWALL;      }    }  }  int nRows = ReleaseRows();  //产生新方块  CreateBircks();  //新方块不能移动,结束游戏}//消除方块private int ReleaseRows(){  int nReleaseRows = 0;  for (int nRow = NROWS - 2; nRow > 0; nRow--)  {    if (IsCanRelease(nRow))    {      //消除方块      nReleaseRows++;      //调整方块--下移      MoveRows(nRow);          //重新判断本行是否可以消行      nRow++;     }  }  return nReleaseRows;}//能否消除方块private boolean IsCanRelease(int nRow){  for (int nCol = 1; nCol < NCOLS - 1; nCol++)  {    if (m_Groundback[nRow][nCol] == 0)    {      return false;    }  }  return true;}//消除方块以后,下移方块private void MoveRows(int nRow){  for (int i = nRow; i > 0; i--)  {    for (int j = 1; j < NCOLS - 1; j++)    {      m_Groundback[i][j] = m_Groundback[i - 1][j];    }  }}}


俄罗斯方块主体的控制流程的代码实现:


package com.example.mytetris;import java.util.Timer;import java.util.TimerTask;import android.media.MediaPlayer;import android.os.Bundle;import android.app.Activity;import android.util.DisplayMetrics;import android.view.Menu;import android.view.MenuItem;import android.view.View;import android.view.View.OnClickListener;import android.view.Window;import android.view.WindowManager;import android.widget.Button;public class MainActivity extends Activity implements OnClickListener{private GameUI m_GameUi = null;private Game   m_Game   = null;private Button btnLeft = null;private Button btnRight = null;private Button btnDown = null;private Button btnChange = null;private MediaPlayer mp2 = null;@Overrideprotected void onCreate(Bundle savedInstanceState){//设置全屏无标题显示this.requestWindowFeature(Window.FEATURE_NO_TITLE);getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,     WindowManager.LayoutParams.FLAG_FULLSCREEN);super.onCreate(savedInstanceState);setContentView(R.layout.linearlayout);//获取组件m_GameUi = (GameUI)findViewById(R.id.GameUI);m_Game   = m_GameUi.m_Game;btnLeft = (Button)findViewById(R.id.button1_left);btnRight = (Button)findViewById(R.id.button2_right);btnDown = (Button)findViewById(R.id.button3_down);btnChange = (Button)findViewById(R.id.button4_change);//设置监听btnLeft.setOnClickListener(this);btnRight.setOnClickListener(this);btnDown.setOnClickListener(this);btnChange.setOnClickListener(this);//mp2 = MediaPlayer.create(this, R.raw.action);}@Overridepublic boolean onCreateOptionsMenu(Menu menu) {getMenuInflater().inflate(R.menu.gamemenu, menu);return true;}@Overridepublic boolean onOptionsItemSelected(MenuItem item){int nIndex = item.getItemId();switch (nIndex) {case R.id.item1_startgame:{//开始游戏m_Game.startGame();m_GameUi.invalidate();//播放音效MediaPlayer mp = MediaPlayer.create(this, R.raw.ready_go);mp.start();//mp.release();//定时器new Timer().schedule(new TimerTask(){@Overridepublic void run() {m_GameUi.m_Game.moveDown();m_GameUi.invalidate();mp2.start();}}, 0, 2000);//线程//new Thread(new Runnable()//{//@Override//public void run()//{//try//{//Thread.sleep(1000);//} //catch (InterruptedException e)//{//e.printStackTrace();//}////m_GameUi.m_Game.moveDown();//m_GameUi.invalidate();////}//}).start();}break;case R.id.item2_restartgame:{}break;case R.id.item3_stopgame:{}break;default:break;}return super.onOptionsItemSelected(item);}@Overridepublic void onClick(View v) {int nId = v.getId();switch (nId){case R.id.button1_left:{m_Game.moveLeft();}break;case R.id.button2_right:{m_Game.moveRight();}break;case R.id.button3_down:{m_Game.MoveFix();}break;case R.id.button4_change:{m_Game.moveChange();}break;default:break;}//重绘m_GameUi.invalidate();}}



运行效果图,界面做的比较挫:






Android俄罗斯方块的代码实现还不全,有兴趣的Coder可以完善一下。网上Android版俄罗斯方块代码到处都是,但是我觉得这份代码给出了俄罗斯方块编写的基本框架,按照这个框架,可以写出很多语言版本的俄罗斯方块。



代码下载地址:http://download.csdn.net/detail/qq1084283172/9037683



更多相关文章

  1. Android团队成员间的代码共享!(Git+Github版)
  2. Android: 记一次Android内存泄露
  3. Android(安卓)必知必会-Android(安卓)Splash 页秒开之细节处理
  4. 使用vs2010查看android原生代码
  5. Android延时启动效果+轮播图+点击进入+沉浸式状态栏+按钮点击颜
  6. 分享开发 Android(安卓)手机应用的开发经验——QR生成器
  7. 在Android系统使用socket在Java层和native之间数据通信
  8. Android(安卓)内置群组,联系人
  9. android -- sim/usim卡导联系人

随机推荐

  1. 修改状态栏(StatusBar)图标(icon)(定制自
  2. Android实现双模(CDMA/GSM)手机短信监听
  3. ViewFlipper 左右滑动效果
  4. Android游戏开发菜鸟之路(三)
  5. android自定义view控件
  6. android按键映射
  7. Linux,maven,redis,android,java,yum,ant
  8. Android(安卓)富文本
  9. Android获取SD卡上图片和视频缩略图的几
  10. Android购物车全选功能实现·