以前刚学安卓的时候花了大半天写出来的俄罗斯方块。
GitHub:GitHub - TTFlyzebra/Tetris
代码比较粗糙^-^,分享下代码:总共三个文件
1、TetriShape.java
package com.flyzebra.tetris;import java.util.Random;public class TetriShape {// 位置private int left, top, right, bottom;// 各种形状private int shapes[][][] = {{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },// 00 正方形{ { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } },// 01 长条1{ { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 } },// 02 L形1{ { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 } },// 03 反L形1{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 1 }, { 0, 0, 0, 0 } },// 04 Z形{ { 0, 0, 0, 0 }, { 0, 0, 1, 1 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },// 05 反Z形{ { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 1 }, { 0, 0, 0, 0 } },// 06 山形1{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },// 07 正方形2{ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } },// 08 长条2{ { 0, 0, 0, 0 }, { 0, 1, 1, 1 }, { 0, 1, 0, 0 }, { 0, 0, 0, 0 } },// 09 L形2{ { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 1 }, { 0, 0, 0, 0 } },// 10 反L形2{ { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 } },// 11 Z形2{ { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 } },// 12 反Z形2{ { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 1 }, { 0, 0, 1, 0 } },// 13 山形2{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },// 14 正方形3{ { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } },// 15 长条3{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } },// 16 L形3{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 } },// 17 反L形3{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 1 }, { 0, 0, 0, 0 } },// 18 Z形3{ { 0, 0, 0, 0 }, { 0, 0, 1, 1 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },// 19 反Z形3{ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 1, 1 }, { 0, 0, 1, 0 } },// 20 山形3{ { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 0, 0 } },// 21 正方形4{ { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 }, { 0, 0, 0, 0 } },// 22 长条4{ { 0, 0, 0, 0 }, { 0, 0, 0, 1 }, { 0, 1, 1, 1 }, { 0, 0, 0, 0 } },// 23 L形4{ { 0, 0, 0, 0 }, { 0, 1, 1, 1 }, { 0, 0, 0, 1 }, { 0, 0, 0, 0 } },// 24 反L形4{ { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 } },// 25 Z形4{ { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 } },// 26 反Z形4{ { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 } } // 27 山形4};private int shape[][] = new int[4][4];private int shape_cret, shape_rote;public TetriShape() {left = 3;top = -4;right = 6;bottom = -1;Random random = new Random();int i = random.nextInt();if (i < 0) {i = 0 - i;}shape_cret = i % 28;if(shape_cret==13){left=2;right=5;}shape = shapes[shape_cret].clone();}public int getShape_cret() {return shape_cret;}public int[][] getRotShape() {shape_rote = (shape_cret + 7) % 28;return shapes[shape_rote].clone();}public int getLeft() {return left;}public int getTop() {return top;}public int getRight() {return right;}public int getBottom() {return bottom;}public int[][] getShape() {return shape;}public synchronized void setShape(int[][] shape) {shape_cret = shape_rote;this.shape = shape;}public synchronized void setPosition(int left, int top, int right,int bottom) {this.left = left;this.top = top;this.right = right;this.bottom = bottom;}
}
2、TetrisView.java
package com.flyzebra.tetris;import java.util.HashMap;import android.annotation.SuppressLint;
import android.app.Activity;
import android.content.Context;
import android.content.SharedPreferences;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.media.AudioManager;
import android.media.SoundPool;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;@SuppressLint("UseSparseArrays")
public class TetrisView extends View implements OnTouchListener { public static final String TAG = "com.flyzebra";private Context context;// View测量获得的长和宽private int width;
// private int height;// 方块画笔//边框的画笔private Paint block_paint1;private Paint block_paint2;private Paint text_paint1;private Paint text_paint2;private Paint text_paint3;private Paint back_paint1;private Paint back_paint2;private Paint button_paint1;private Paint button_paint2;// 方块大小private int block_size;private int offset_x, offset_y;// 定义方块数组private int block_array[][] = new int[20][10];private Rect view_rect = new Rect();private TetriShape cret_tetrishape;private TetriShape next_tetrishape; private boolean gamepause = false;private boolean gamestop = true;private boolean gamemusic = true;// 按钮private float radius1, radius2, radius3;private float up_x;private float up_y;private float down_x;private float down_y;private float left_x;private float left_y;private float right_x;private float right_y;private float exit_x;private float exit_y;private float start_x;private float start_y;private float pause_x;private float pause_y;private float music_x;private float music_y;private float rotate_x;private float rotate_y;
// private ResetGameTask resetTask;private boolean isDownLeft = false, isDownRight = false, isDownUp = false,isDownDown = false, isDownExit = false, isDownStart = false,isDownPasue = false, isDownMusic = false, isDownRotate = false;// 声音SoundPool sp;HashMap<Integer, Integer> hm; int sound_1=0;int sound_2=0;int sound_3=0;private int cret_score = 0;private int base_score = 100;private int speed_score = 5000;private int speed = 1;private String ME_SHARE = "Tetri";private String H_SCORE = "h_score";private int high_score = 0;private String H_TIME = "h_time";private String high_time = "00:00:00";private int count_time = 0;//线程控制变量private boolean TC_CountTimeThread = true;private boolean TC_StartGameThread = true;private boolean TC_ResetGameThread = true;private Bitmap bt_bitmap01,bt_bitmap02,bk_bitmap03;private Rect bt_rect01,bt_rect02,bk_rect03;private Rect up_rect;private Rect down_rect;private Rect left_rect;private Rect right_rect;private Rect rotate_rect;private Rect exit_rect;private Rect start_rect;private Rect pause_rect;private Rect music_rect;@SuppressLint("ClickableViewAccessibility")public TetrisView(Context context) {super(context);this.context = context;block_paint1 = new Paint();block_paint1.setAntiAlias(true);block_paint1.setStyle(Paint.Style.FILL);block_paint1.setColor(Color.parseColor("#222222")); block_paint2 = new Paint();block_paint2.setAntiAlias(true);block_paint2.setStyle(Paint.Style.FILL);block_paint2.setColor(Color.parseColor("#00FF00"));text_paint1 = new Paint();text_paint1.setColor(Color.parseColor("#FFFFFF"));text_paint1.setAntiAlias(true);text_paint1.setStyle(Paint.Style.FILL);text_paint1.setTextAlign(Paint.Align.CENTER);text_paint2 = new Paint();text_paint2.setColor(Color.parseColor("#BFFF00"));text_paint2.setAntiAlias(true);text_paint2.setStyle(Paint.Style.FILL);text_paint2.setTextAlign(Paint.Align.CENTER);text_paint3 = new Paint();text_paint3.setColor(Color.parseColor("#FFFF00"));text_paint3.setAntiAlias(true);text_paint3.setStyle(Paint.Style.FILL);text_paint3.setTextAlign(Paint.Align.CENTER);back_paint1 = new Paint();back_paint1.setAntiAlias(true);back_paint1.setStrokeWidth(4);back_paint1.setStyle(Paint.Style.STROKE);back_paint1.setColor(Color.parseColor("#FFFF00"));back_paint2 = new Paint();back_paint2.setAntiAlias(true);back_paint2.setStyle(Paint.Style.FILL);back_paint2.setColor(Color.parseColor("#000000"));button_paint1 = new Paint();button_paint1.setAntiAlias(true);button_paint1.setStyle(Paint.Style.FILL);button_paint1.setColor(Color.parseColor("#FFFF00"));button_paint2 = new Paint();button_paint2.setAntiAlias(true);button_paint2.setStyle(Paint.Style.FILL);button_paint2.setColor(Color.parseColor("#BBBB00"));bt_bitmap01=BitmapFactory.decodeResource(getResources(), R.drawable.button01);bt_bitmap02=BitmapFactory.decodeResource(getResources(), R.drawable.button02);bk_bitmap03=BitmapFactory.decodeResource(getResources(), R.drawable.bk_view);bt_rect01=new Rect(0, 0, bt_bitmap01.getWidth(), bt_bitmap01.getHeight());bt_rect02=new Rect(0, 0, bt_bitmap02.getWidth(), bt_bitmap02.getHeight());bk_rect03=new Rect(0, 0, bk_bitmap03.getWidth(), bk_bitmap03.getHeight());TC_StartGameThread = false;TC_CountTimeThread = false;TC_ResetGameThread = false;gamepause = false;setOnTouchListener(this);// 声音initSoundPool();sound_2 = playSound(2, 0);// 初始化最高分数SharedPreferences m_share = context.getSharedPreferences(ME_SHARE, Activity.MODE_PRIVATE);high_score = m_share.getInt(H_SCORE, 0);high_time = m_share.getString(H_TIME, "00:00:00");cret_score = 0;count_time = 0; }@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);// 绘制多余的边框
// canvas.drawRect(0, 0, offset_x, height, back_paint1);
// canvas.drawRect(width - offset_x, 0, width, height, back_paint1);
// canvas.drawRect(0, 0, width, offset_y, back_paint1);
// canvas.drawRect(0, offset_y + block_size * 20, width, height, back_paint1);//背景图片canvas.drawBitmap(bk_bitmap03, bk_rect03, view_rect, back_paint1);canvas.drawRect(view_rect,back_paint1);//游戏显示屏区背景canvas.drawRect(offset_x-5,offset_y-5,width - offset_x+5,offset_y+block_size * 20+5,back_paint1);canvas.drawRect(offset_x,offset_y,width - offset_x,offset_y+block_size * 20,back_paint2);// 绘制右边的显示组件int x = offset_x + block_size * 11;int y = offset_y; // 右边框int l_y = x+block_size*4;canvas.drawRect(x, y, l_y, y+block_size*4, block_paint1);
// canvas.drawRect(x, y+block_size*5, l_y, y+block_size*8f, block_paint1);
// canvas.drawRect(x, y+block_size*9, l_y, y+block_size*11f, block_paint1);
// canvas.drawRect(x, y+block_size*12, l_y, y+block_size*14f, block_paint1);
// canvas.drawRect(x, y+block_size*15, l_y, y+block_size*17f, block_paint1);
// canvas.drawRect(x, y+block_size*18, l_y, y+block_size*19.5f, block_paint1);if (next_tetrishape != null) {drawNextBlock(x,y,canvas); }x = x+block_size*2;// 最高得分canvas.drawText("最高记录", x, y + block_size * 6, text_paint1);canvas.drawText(high_score + "分", x, y + block_size * 7, text_paint2);canvas.drawText(high_time, x, y + block_size * 8, text_paint2);// 本局得分canvas.drawText("本局得分", x, y + block_size * 10, text_paint1);canvas.drawText(cret_score + "分", x, y + block_size * 11, text_paint2);// 本局耗时canvas.drawText("本局耗时", x, y + block_size * 13, text_paint1);String time = getStrCurrentTime();canvas.drawText(time, x, y + block_size * 14, text_paint2);// 当前下落速度canvas.drawText("速度等级", x, y + block_size * 16, text_paint1);canvas.drawText(speed + "级", x, y + block_size * 17, text_paint2);if(gamemusic){canvas.drawText("音乐开", x, y + block_size * 19, text_paint2);}else{canvas.drawText("音乐关", x, y + block_size * 19, text_paint2);}// 按钮界面// upif (isDownUp) {
// canvas.drawCircle(up_x, up_y, radius1, button_paint1); canvas.drawBitmap(bt_bitmap01, bt_rect01, up_rect, button_paint1);} else {
// canvas.drawCircle(up_x, up_y, radius1, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, up_rect, button_paint2);}// downif (isDownDown) {
// canvas.drawCircle(down_x, down_y, radius1, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, down_rect, button_paint1);} else {
// canvas.drawCircle(down_x, down_y, radius1, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, down_rect, button_paint2);}// leftif (isDownLeft) {
// canvas.drawCircle(left_x, left_y, radius1, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, left_rect, button_paint1);} else {
// canvas.drawCircle(left_x, left_y, radius1, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, left_rect, button_paint2);}// rightif (isDownRight) {
// canvas.drawCircle(right_x, right_y, radius1, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, right_rect, button_paint1);} else {
// canvas.drawCircle(right_x, right_y, radius1, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, right_rect, button_paint2);}// exitif (isDownExit) {
// canvas.drawCircle(exit_x, exit_y, radius2, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, exit_rect, button_paint1);} else {
// canvas.drawCircle(exit_x, exit_y, radius2, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, exit_rect, button_paint2);}canvas.drawText("退出", exit_x, exit_y + block_size, text_paint3);// startif (isDownStart) {
// canvas.drawCircle(start_x, start_y, radius2, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, start_rect, button_paint1);} else {
// canvas.drawCircle(start_x, start_y, radius2, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, start_rect, button_paint2);}canvas.drawText("开始", start_x, exit_y + block_size, text_paint3);// pauseif (isDownPasue) {
// canvas.drawCircle(pause_x, pause_y, radius2, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, pause_rect, button_paint1);} else {
// canvas.drawCircle(pause_x, pause_y, radius2, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, pause_rect, button_paint2);}canvas.drawText("暂停", pause_x, exit_y + block_size, text_paint3);// musicif (isDownMusic) {
// canvas.drawCircle(music_x, music_y, radius2, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, music_rect, button_paint1);} else {
// canvas.drawCircle(music_x, music_y, radius2, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, music_rect, button_paint2);}canvas.drawText("音乐", music_x, exit_y + block_size, text_paint3);// rotateif (isDownRotate) {
// canvas.drawCircle(rotate_x, rotate_y, radius3, button_paint1);canvas.drawBitmap(bt_bitmap01, bt_rect01, rotate_rect, button_paint1);} else {
// canvas.drawCircle(rotate_x, rotate_y, radius3, button_paint2);canvas.drawBitmap(bt_bitmap02, bt_rect02, rotate_rect, button_paint2);}// 当前方块for (int i = 0; i < 10; i++) {for (int j = 0; j < 20; j++) {if (block_array[j][i] == 1) {drawblock(i, j, canvas, block_paint2);} else {drawblock(i, j, canvas, block_paint1);}}}}private void drawblock(float w, float h, Canvas canvas, Paint paint) {float left = offset_x + w * block_size + 1;float top = offset_y + h * block_size + 1;float right = left + block_size - 2;float bottom = top + block_size - 2;canvas.drawRect(left, top, right, bottom, paint);}// 向左移动private void moveLeft() {move(cret_tetrishape.getLeft() - 1, cret_tetrishape.getTop(),cret_tetrishape.getRight() - 1, cret_tetrishape.getBottom());}// 向右移动private void moveRight() {move(cret_tetrishape.getLeft() + 1, cret_tetrishape.getTop(),cret_tetrishape.getRight() + 1, cret_tetrishape.getBottom());}// 向下移动private synchronized void moveDown() {if(cret_tetrishape==null||gamepause) return;boolean flag = move(cret_tetrishape.getLeft(), cret_tetrishape.getTop() + 1,cret_tetrishape.getRight(), cret_tetrishape.getBottom() + 1);if (!flag) {// 判断游戏是否结束for (int i = 0; i < 10; i++) {if (block_array[0][i] == 1) {// 游戏结束gamestop = true; break;}}if (!gamestop) {isDownDown = false;cret_tetrishape = next_tetrishape;next_tetrishape = new TetriShape();clearFullRows();} else {if(sound_2!=0){sp.stop(sound_2);}sound_2 = playSound(2,0);if(TC_ResetGameThread==false){TC_ResetGameThread=true;new ResetGameThread();}}}}private void clearFullRows() {new Thread(new Runnable() {@Overridepublic void run() {int num = 0;int new_block_array[][] = new int[20][10];int new_h = 19;for (int j = 19; j >= 0; j--) {boolean is_full = true;for (int i = 0; i < 10; i++) {if ((block_array[j][i]) == 0) {is_full = false;break;}}if (is_full) {num++;for (int i = 0; i < 10; i++) {block_array[j][i] = 0;}} else {for (int i = 0; i < 10; i++) {new_block_array[new_h][i] = block_array[j][i];}new_h--;}}if (num > 0) {if(sound_1!=0){sp.stop(sound_1); }sound_1 = playSound(1, 0);cret_score = cret_score + num * num * base_score;// 更新最高记录if (cret_score > high_score) {high_score=cret_score;high_time=getStrCurrentTime();SharedPreferences m_shares = context.getSharedPreferences(ME_SHARE,Activity.MODE_PRIVATE);SharedPreferences.Editor editor = m_shares.edit();editor.putInt(H_SCORE, high_score);editor.putString(H_TIME,high_time );editor.commit();}speed = cret_score / speed_score + 1;if (speed > 9) {speed = 9;}postInvalidate();try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}block_array = new_block_array.clone();postInvalidate();} else {if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);}} }).start();}private String getStrCurrentTime() {StringBuffer s_time = new StringBuffer();int hh = count_time/3600;int mm = (count_time/60)%60;int ss = count_time%60;if(hh<10){s_time.append("0");}s_time.append(hh+":");if(mm<10){s_time.append("0");}s_time.append(mm+":");if(ss<10){s_time.append("0");}s_time.append(ss);return s_time.toString();}// 判断能不能移动private synchronized boolean move(int left, int top, int right, int bottom) {// 擦除原来图像所在的数据eraseBlockArrayFormSharp(cret_tetrishape);boolean can_move = true;int shape[][] = cret_tetrishape.getShape();for (int i = left, w = 0; i <= right; i++, w++) {for (int j = top, h = 0; j <= bottom; j++, h++) {if (shape[h][w] == 1) {// 越界检测if (i < 0 || i >= 10 || j >= 20) {upBlockArrayFromSharp(cret_tetrishape);can_move = false;return can_move;}// 碰撞检测if (i >= 0 && j >= 0 && i < 10 && j < 20) {if (block_array[j][i] == 1) {upBlockArrayFromSharp(cret_tetrishape);can_move = false;return can_move;}}}}}cret_tetrishape.setPosition(left, top, right, bottom);upBlockArrayFromSharp(cret_tetrishape);postInvalidate();return can_move;}private void eraseBlockArrayFormSharp(TetriShape tetri) {int shape[][] = tetri.getShape();for (int i = tetri.getLeft(), w = 0; i <= tetri.getRight(); i++, w++) {for (int j = tetri.getTop(), h = 0; j <= tetri.getBottom(); j++, h++) {if (shape[h][w] == 1 && i >= 0 && j >= 0 && i < 10 && j < 20) {block_array[j][i] = 0;}}}}private void upBlockArrayFromSharp(TetriShape tetri) {int shape[][] = tetri.getShape();for (int i = tetri.getLeft(), w = 0; i <= tetri.getRight(); i++, w++) {for (int j = tetri.getTop(), h = 0; j <= tetri.getBottom(); j++, h++) {if (shape[h][w] == 1 && i >= 0 && j >= 0 && i < 10 && j < 20) {block_array[j][i] = 1;}}}}// 快速向下移动private void down() { new Thread(new Runnable() {@Overridepublic void run() {while (isDownDown) {moveDown();if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);try {Thread.sleep(20);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();}// 退出private void exit() { if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);TC_CountTimeThread = false;TC_StartGameThread = false;TC_ResetGameThread = false;gamepause = false;gamestop = true;cret_tetrishape = null;next_tetrishape = null;sp.stop(sound_1);sp.stop(sound_2);
// sp.stop(sound_3);Activity activity = (Activity) context;activity.finish();}// 从新开始private void start() {
// if(resetTask!=null){
// resetTask.cancel(true);
// }TC_ResetGameThread=false;if(sound_2!=0){sp.stop(sound_2);}if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);gamepause = false; cret_tetrishape=null;next_tetrishape=null;clearBlockArray(); postInvalidate();new Thread(new Runnable() {@Overridepublic void run() {if(TC_StartGameThread){gamestop = true;}while (TC_StartGameThread) {try {Thread.sleep(500 - 500 * speed / 10);} catch (InterruptedException e) {e.printStackTrace();}}TC_StartGameThread = true; new StartGameThread();}}).start();}// 暂停private void pause() {if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);if(cret_tetrishape!=null){gamepause = !gamepause;}}// 音乐private void music() {if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);gamemusic=!gamemusic;}// 旋转private boolean rotate() { if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);eraseBlockArrayFormSharp(cret_tetrishape);boolean can_rotate = true;int rot_shape[][] = new int[4][4];int left = cret_tetrishape.getLeft();int top = cret_tetrishape.getTop();int right = cret_tetrishape.getRight();int bottom = cret_tetrishape.getBottom();rot_shape = cret_tetrishape.getRotShape();for (int i = left, w = 0; i <= right; i++, w++) {for (int j = top, h = 0; j <= bottom; j++, h++) {if (rot_shape[h][w] == 1) {// 越界检测if (i < 0 || i >= 10 || j >= 20) {upBlockArrayFromSharp(cret_tetrishape);can_rotate = false;return can_rotate;}// 碰撞检测if (i >= 0 && j >= 0 && i < 10 && j < 20) {if (block_array[j][i] == 1) {upBlockArrayFromSharp(cret_tetrishape);can_rotate = false;return can_rotate;}}}}}cret_tetrishape.setShape(rot_shape);upBlockArrayFromSharp(cret_tetrishape);postInvalidate();return can_rotate;}@Overrideprotected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {super.onMeasure(widthMeasureSpec, heightMeasureSpec);int width = MeasureSpec.getSize(widthMeasureSpec);int height = MeasureSpec.getSize(heightMeasureSpec);if (width > 0 && height > 0) {this.width = width;
// this.height = height;if (width / 17 < height / 27) {block_size = width / 17;offset_x = block_size / 2;offset_y = (height - block_size * 26) / 2;} else {block_size = height / 27;offset_x = (width - block_size * 16) / 2;offset_y = block_size / 2;}view_rect.left = 0;view_rect.top = 0;view_rect.right = width;view_rect.bottom = height;// 设置字体大小float textSize = block_size * 0.7f;text_paint1.setTextSize(textSize); text_paint2.setTextSize(textSize);text_paint3.setTextSize(block_size * 0.5f);// 初始化按钮位置radius1 = block_size * 1.2f;up_x = offset_x + block_size * 4f;up_y = offset_y + block_size * 22;down_x = up_x;down_y = offset_y + block_size * 25;left_x = offset_x + block_size * 1.5f;left_y = offset_y + block_size * 23.5f;right_x = offset_x + block_size * 6.5f;right_y = left_y;radius2 = block_size * 0.5f;exit_x = offset_x + block_size * 9; start_x = offset_x + block_size * 11;pause_x = offset_x + block_size * 13;music_x = offset_x + block_size * 15;exit_y = start_y = pause_y = music_y = offset_y + block_size * 21f;rotate_x = offset_x + block_size * 13.5f;radius3 = block_size * 1.5f;rotate_y = offset_y + block_size * 24f;up_rect = new Rect((int) (up_x - radius1), (int) (up_y - radius1),(int) (up_x + radius1), (int) (up_y + radius1));down_rect = new Rect((int) (down_x - radius1), (int) (down_y - radius1),(int) (down_x + radius1), (int) (down_y + radius1));left_rect = new Rect((int) (left_x - radius1), (int) (left_y - radius1),(int) (left_x + radius1), (int) (left_y + radius1));right_rect = new Rect((int) (right_x - radius1), (int) (right_y - radius1),(int) (right_x + radius1), (int) (right_y + radius1));exit_rect = new Rect((int) (exit_x - radius2), (int) (exit_y - radius2),(int) (exit_x + radius2), (int) (exit_y + radius2));start_rect = new Rect((int) (start_x - radius2), (int) (start_y - radius2),(int) (start_x + radius2), (int) (start_y + radius2));pause_rect = new Rect((int) (pause_x - radius2), (int) (pause_y - radius2),(int) (pause_x + radius2), (int) (pause_y + radius2));music_rect = new Rect((int) (music_x - radius2), (int) (music_y - radius2),(int) (music_x + radius2), (int) (music_y + radius2));rotate_rect = new Rect((int) (rotate_x - radius3), (int) (rotate_y - radius3),(int) (rotate_x + radius3), (int) (rotate_y + radius3));setMeasuredDimension(width, height);}}class ResetGameThread extends Thread implements Runnable {public ResetGameThread() {gamepause = false;gamestop = true;cret_tetrishape=null;next_tetrishape=null;TC_CountTimeThread = false;TC_StartGameThread = false; this.start();}@Overridepublic void run() { for (int j = 19; j >= 0; j--) {for (int i = 9; i >= 0; i--) {if(!TC_ResetGameThread) return;block_array[j][i] = 1;postInvalidate();try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}}}for (int j = 0; j <20; j++) {if(!TC_ResetGameThread) return;for (int i = 0; i < 10; i++) {block_array[j][i] = 0;postInvalidate();try {Thread.sleep(30);} catch (InterruptedException e) {e.printStackTrace();}}}clearBlockArray();postInvalidate();TC_ResetGameThread = false;}}class StartGameThread extends Thread implements Runnable {public StartGameThread() { cret_tetrishape = new TetriShape();next_tetrishape = new TetriShape();// 读取最高分数SharedPreferences m_share = context.getSharedPreferences(ME_SHARE,Activity.MODE_PRIVATE);high_score = m_share.getInt(H_SCORE, 0);high_time = m_share.getString(H_TIME, "00:00:00");cret_score = 0; speed=1;this.start(); }@Overridepublic void run() { while(TC_CountTimeThread){try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}} count_time = 0;TC_CountTimeThread = true;gamestop = false;new CountTimeThread();postInvalidate();while (TC_StartGameThread&&!gamestop) {if (!gamepause) {moveDown();}try {Thread.sleep(500 - 500 * speed / 10);} catch (InterruptedException e) {e.printStackTrace();}}TC_StartGameThread = false;}}class CountTimeThread extends Thread implements Runnable {public CountTimeThread() {this.start();}@Overridepublic void run() {while (TC_CountTimeThread&&!gamestop) {long maxMemory = Runtime.getRuntime().maxMemory()/1024; long totalMemory = Runtime.getRuntime().totalMemory()/1024; long freeMemory = Runtime.getRuntime().freeMemory()/1024; Log.v(TAG, "MemoryInfo->" +"maxMemory:"+maxMemory+"totalMemory:" + totalMemory+"freeMemory:"+freeMemory); try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}if(!gamepause){count_time++;}postInvalidate();} TC_CountTimeThread = false;}}@SuppressLint("ClickableViewAccessibility")@Overridepublic boolean onTouch(View v, MotionEvent event) {switch (event.getAction() & MotionEvent.ACTION_MASK) {case MotionEvent.ACTION_DOWN:checkDownButton(event.getX(0), event.getY(0));break;case MotionEvent.ACTION_UP:if(isDownExit){isDownExit=false;exit();}else if(isDownStart){isDownStart=false;start();}else if(isDownPasue){isDownPasue = false;pause();}else if(isDownMusic){isDownMusic= false;music();}isDownLeft = isDownRight = isDownUp = isDownDown = isDownRotate = false;postInvalidate();break;case MotionEvent.ACTION_POINTER_DOWN:checkDownButton(event.getX(1), event.getY(1));break;case MotionEvent.ACTION_POINTER_UP:float x = event.getX(1);float y = event.getY(1);if (x > (left_x - radius1 * 1.5) && x < (left_x + radius1 * 1.5)&& y > (left_y - radius1 * 1.5)&& y < (left_y + radius1 * 1.5)) {isDownLeft = false;} else if (x > (right_x - radius1 * 1.5)&& x < (right_x + radius1 * 1.5)&& y > (right_y - radius1 * 1.5)&& y < (right_y + radius1) * 1.5) {isDownRight = false;}if(isDownExit){isDownExit=false;exit();}else if(isDownStart){isDownStart=false;start();}else if(isDownPasue){isDownPasue = false;pause();}else if(isDownMusic){isDownMusic= false;music();}isDownUp = isDownDown = isDownRotate = false;postInvalidate();break;}return true;}private void checkDownButton(float x, float y) {// exitif (x > (exit_x - block_size) && x < (exit_x + block_size)&& y > (exit_y - block_size) && y < (exit_y + block_size)) {isDownExit = true; }// startif (x > (start_x - block_size) && x < (start_x + block_size)&& y > (start_y - block_size) && y < (start_y + block_size)) {isDownStart = true; }// pauseif (x > (pause_x - block_size) && x < (pause_x + block_size)&& y > (pause_y - block_size) && y < (pause_y + block_size)) {isDownPasue = true; }// musicif (x > (music_x - block_size) && x < (music_x + block_size)&& y > (music_y - block_size) && y < (music_y + block_size)) {isDownMusic = true;}if(cret_tetrishape==null) {postInvalidate(); return;}// leftif (x > (left_x - radius1) && x < (left_x + radius1)&& y > (left_y - radius1) && y < (left_y + radius1)) {isDownLeft = true;postInvalidate();left();}// rightif (x > (right_x - radius1) && x < (right_x + radius1)&& y > (right_y - radius1) && y < (right_y + radius1)) {isDownRight = true;postInvalidate();right();}// upif (x > (up_x - radius1) && x < (up_x + radius1)&& y > (up_y - radius1) && y < (up_y + radius1)) {isDownUp = true;postInvalidate();}// downif (x > (down_x - radius1) && x < (down_x + radius1)&& y > (down_y - radius1) && y < (down_y + radius1)) {isDownDown = true;postInvalidate();down();} // rotateif (x > (rotate_x - radius3) && x < (rotate_x + radius3)&& y > (rotate_y - radius3) && y < (rotate_y + radius3)) {isDownRotate = true;postInvalidate(); rotate();}}private void right() { new Thread(new Runnable() {@Overridepublic void run() {while (isDownRight) {moveRight();if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();}private void left() { new Thread(new Runnable() {@Overridepublic void run() {while (isDownLeft) {moveLeft();if(sound_3!=0){sp.stop(sound_3); }sound_3 = playSound(3, 0);try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}}}}).start();}private void clearBlockArray() {for (int j = 0; j < 20; j++) {for (int i = 0; i < 10; i++) {block_array[j][i] = 0;}}}public void initSoundPool() {sp = new SoundPool(4, AudioManager.STREAM_MUSIC, 0);hm = new HashMap<Integer, Integer>(); hm.put(1, sp.load(context, R.raw.once_01, 1));hm.put(2, sp.load(context, R.raw.loop_02, 1));hm.put(3, sp.load(context, R.raw.once_03, 1));}public int playSound(int sound, int loop) { if(!gamemusic) return 0;AudioManager am = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);float streamVolumeCurrent = am.getStreamVolume(AudioManager.STREAM_MUSIC);float streamVolumeMax = am.getStreamMaxVolume(AudioManager.STREAM_MUSIC);float volume = streamVolumeCurrent / streamVolumeMax;return sp.play(hm.get(sound), volume, volume, 1, loop, 1.0f);}private void drawNextBlock(int x, int y, Canvas canvas) {int shape[][] = next_tetrishape.getShape();switch (next_tetrishape.getShape_cret()) {//正方形case 0: case 7:case 21:case 14:for (int i = 1; i < 3; i++) {for (int j = 1; j < 3; j++) {float left = x + i * block_size + 1;float top = y + j * block_size + 1;float right = left + block_size - 2;float bottom = top + block_size - 2; if (shape[j][i] == 1) { canvas.drawRect(left, top, right, bottom, block_paint2);}}}break; //(第一列空)case 1:case 4:case 5:case 6:case 9:case 10:case 15:case 18:case 19:case 23:case 24: for (int i = 1; i < 4; i++) {for (int j = 0; j < 4; j++) {float left = x + i * block_size-0.5f*block_size + 1;float top = y + j * block_size + 1;float right = left + block_size - 2;float bottom = top + block_size - 2; if (shape[j][i] == 1) { canvas.drawRect(left, top, right, bottom, block_paint2);}}}break;//(第一行空)case 2:case 3:case 8:case 11:case 12:case 16:case 17:case 22:case 25:case 26:case 27:for (int i = 0; i < 4; i++) {for (int j = 1; j < 4; j++) {float left = x + i * block_size + 1;float top = y + j * block_size-0.5f*block_size + 1;float right = left + block_size - 2;float bottom = top + block_size - 2; if (shape[j][i] == 1) { canvas.drawRect(left, top, right, bottom, block_paint2);}}} break;// (前两列空,第一行空)case 13:for (int i = 2; i < 4; i++) {for (int j = 1; j < 4; j++) {float left = x + (i-1) * block_size + 1;float top = y + j * block_size-0.5f*block_size + 1;float right = left + block_size - 2;float bottom = top + block_size - 2; if (shape[j][i] == 1) { canvas.drawRect(left, top, right, bottom, block_paint2);}}}break; //(前两行空,第一列空)case 20:for (int i = 1; i < 4; i++) {for (int j = 2; j < 4; j++) {float left = x + i * block_size-0.5f*block_size + 1;float top = y + (j-1) * block_size + 1;float right = left + block_size - 2;float bottom = top + block_size - 2; if (shape[j][i] == 1) { canvas.drawRect(left, top, right, bottom, block_paint2);}}}break;} }}
3、MainActivity.java
package com.flyzebra.tetris;import android.app.Activity;
import android.os.Bundle;
public class MainActivity extends Activity {private TetrisView myview;@Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);myview = new TetrisView(this);setContentView(myview);}
}
GitHub:https://github.com/TTFlyzebra/Tetris