这段时间一直没有更新自己的博客,很多东西不经常看看会生疏了许多。在这里我就把自己前段时间编写的android俄罗斯方块代码贴出来。

转载请注明出处~~~~~~~~~~~~~~~~谢谢!

http://blog.csdn.net/wu10045125/article/details/8248356

再贴出几张图片:

[置顶] android俄罗斯方块完整代码_第1张图片[置顶] android俄罗斯方块完整代码_第2张图片[置顶] android俄罗斯方块完整代码_第3张图片[置顶] android俄罗斯方块完整代码_第4张图片[置顶] android俄罗斯方块完整代码_第5张图片[置顶] android俄罗斯方块完整代码_第6张图片[置顶] android俄罗斯方块完整代码_第7张图片[置顶] android俄罗斯方块完整代码_第8张图片

整个游戏我分为10个java文件:

先是俄罗斯方块的形状存储statefang.java,代码如下:

package com.example.eluosifangkuai;

public class statefang { //方块的逻辑类

public static int [][][] state = new int[][][] {
{// I
{ 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } }, {// I1
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 } }, {// I2
{ 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } }, {// I3
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 1 } }, {// I4
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 } }, {// O5
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 } }, {// O6
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 } }, {// O7
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 1, 0 } }, {// O8
{ 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 } }, {// L9
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 1, 0, 0, 0 } }, {// L10
{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 } }, {// L11
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 1, 1, 1, 0 } }, {// L12
{ 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 } }, {// J13
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 1, 1, 0 } }, {// J14
{ 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 }, { 0, 1, 0, 0 } }, {// J15
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 0, 1, 0 } }, {// J16
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 1, 1, 1, 0 } }, {// T17
{ 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 } }, {// T18
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 1, 0 }, { 0, 1, 0, 0 } }, {// T19
{ 0, 0, 0, 0 }, { 1, 0, 0, 0 }, { 1, 1, 0, 0 }, { 1, 0, 0, 0 } }, {// T20
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 } }, {// S21
{ 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 } }, {// S22
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 0, 1, 1, 0 }, { 1, 1, 0, 0 } }, {// S23
{ 0, 0, 0, 0 }, { 0, 1, 0, 0 }, { 0, 1, 1, 0 }, { 0, 0, 1, 0 } }, {// Z24
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 } }, {// Z25
{ 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 } }, {// Z26
{ 0, 0, 0, 0 }, { 0, 0, 0, 0 }, { 1, 1, 0, 0 }, { 0, 1, 1, 0 } }, {// Z27
{ 0, 0, 0, 0 }, { 0, 0, 1, 0 }, { 0, 1, 1, 0 }, { 0, 1, 0, 0 } } // 28

};

}

我们当然还要编写音乐播放类,资源播放类了等等。。。。。。

我把所有的图片资源编写在一个类里面,叫做GameResources.java,具体代码如下:

package com.example.eluosifangkuai;

import android.content.Context;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Bitmap.Config;
import android.graphics.Paint;
import android.graphics.drawable.Drawable;

public class GameResources {

Resources m_Resources; // 资源类
Canvas m_Canvas; // 画布
Bitmap m_Bitmaphc = null; // 缓冲位图
Bitmap m_Bitmap01 = null; // 图像位图
Bitmap [] m_Bitmaps = new Bitmap[8]; //精灵位图
Bitmap score; // 分数位图
Bitmap Play; // 开始位图
Bitmap Level;
public GameResources(Context context) // 初始化 装载位图
{
m_Resources = context.getResources();
for(int i=0;i<7;i++)
{
m_Bitmaps[i] = createImage(m_Resources.getDrawable(R.drawable.cube_960_011+i),18,18);
}
m_Bitmap01 = createImage(m_Resources.getDrawable(R.drawable.bgcatcher),320,480);
m_Bitmaps[7] = createImage(m_Resources.getDrawable(R.drawable.main11),320,402);

score = createImage(m_Resources.getDrawable(R.drawable.score),87,150);
Play = createImage(m_Resources.getDrawable(R.drawable.b7),320,480);
Level = createImage(m_Resources.getDrawable(R.drawable.levelup),139,88);
m_Bitmaphc = Bitmap.createBitmap(320,480, Config.ARGB_8888);
m_Canvas = new Canvas(m_Bitmaphc);
bitmapB();
}

public void bitmapB()
{
Paint m_Paint = new Paint();
m_Paint.setAntiAlias(true);
m_Paint.setAlpha(220);
m_Canvas.drawBitmap(m_Bitmap01, 0,0,null);
}
public static Bitmap createImage(Drawable tile, int w, int h) { // 双缓冲 加载位图资源
Bitmap bitmap = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
tile.setBounds(0, 0, w, h);
tile.draw(canvas);
return bitmap;
}

}

音乐播放类,MusicPlay.java 具体代码如下:

package com.example.eluosifangkuai;


import java.util.HashMap;
import java.util.Map;
import android.content.Context;
import android.media.AudioManager;
import android.media.MediaPlayer;
import android.media.SoundPool;

public class MusicPlay {

public static MediaPlayer m_MediaPlay ; // 背景播放器
public static MediaPlayer m_MenuPlay ;
public static SoundPool soundPool;//声明 音效播放器
public MediaPlayer m_FastDown ;

private static boolean musicSwitch = true;//音乐开关
private static boolean soundSwitch = true;//音效开关
private static Map<Integer,Integer> soundMap; //音效资源id与加载过后的音源id的映射关系表
private static Context context;

public static void inItMusicPlay(Context c){
context = c;
}
public static void inItMenuMusicPlay(Context c){
context = c;
}
//初始化背景播放器
public static void BgMediaplayer()
{
m_MediaPlay = MediaPlayer.create(context, R.raw.gamebg);
m_MediaPlay.setLooping(true);
}
public static void menuMusic()
{
m_MenuPlay = MediaPlayer.create(context, R.raw.menubg);
m_MenuPlay.setLooping(true);
}
public static void pauseMusic()
{
if(m_MediaPlay.isPlaying())
{
m_MediaPlay.pause();
}
}
public static void pauseMenuMusic()
{
if(m_MenuPlay.isPlaying())
{
m_MenuPlay.pause();
}
}
public static void startMusic(){
if(musicSwitch){
m_MediaPlay.start();
}
}
public static void startMenuMusic(){
if(musicSwitch){
m_MenuPlay.start();
}
}
public static void releaseMusic(){
if(m_MediaPlay != null){
m_MediaPlay.release();
}
}
public static void releaseMenuMusic(){
if(m_MenuPlay != null)
{
m_MenuPlay.release();
}
}

//设置音乐开关
public static void setMusicSwitch(boolean musicSwitch){
MusicPlay.musicSwitch = musicSwitch;
if(MusicPlay.musicSwitch){
m_MediaPlay.start();
}
else{
m_MediaPlay.stop();
}
}
public static void inItSound()
{
soundPool = new SoundPool(8,AudioManager.STREAM_MUSIC,0);
soundMap = new HashMap<Integer, Integer>();
//将音效资源加入 soundPool,并做成soundMap 映射
soundMap.put(R.raw.action,soundPool.load(context, R.raw.action, 1));
soundMap.put(R.raw.fastdown,soundPool.load(context, R.raw.fastdown, 1));
soundMap.put(R.raw.rotation,soundPool.load(context, R.raw.rotation, 1));
soundMap.put(R.raw.down,soundPool.load(context, R.raw.down, 1));
soundMap.put(R.raw.delete1,soundPool.load(context, R.raw.delete1, 1));
soundMap.put(R.raw.delete2,soundPool.load(context, R.raw.delete2, 1));
soundMap.put(R.raw.delete3,soundPool.load(context, R.raw.delete3, 1));
soundMap.put(R.raw.delete4,soundPool.load(context, R.raw.delete4, 1));
}
public static int playSound(int resId,int loop)
{

if(!soundSwitch){
return 0;
}

Integer soundId = soundMap.get(resId);
if(soundId != null)
{
return soundPool.play(soundId, 1, 1, 1, loop, 1);
}
else
{
return 0;
}
}
public static void releaseSound(){
if(soundPool != null){
soundPool.release();
}
}
}

另外我还编写了一个图片按钮类,名为ImageButton.java 具体代码如下:

package com.example.eluosifangkuai;

import java.io.InputStream;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;

public class ImageButton {

// 按钮图片
private Bitmap mBitButton = null;

//图片绘制的XY坐标
private int mPosX =0;
private int mPosY =0;
//图片绘制的宽高
private int mWidth =0;
private int mHeight =0;

public ImageButton(Context context, int frameBitmapID, int x, int y) {
mBitButton = ReadBitMap(context,frameBitmapID);
mPosX = x;
mPosY = y;
mWidth = mBitButton.getWidth();
mHeight = mBitButton.getHeight();
}

//绘制图片按钮
public void DrawImageButton(Canvas canvas, Paint paint) {
canvas.drawBitmap(mBitButton, mPosX, mPosY, paint);
}


// 判断是否点中图片按钮
public boolean IsClick(int x, int y) {
boolean isClick = false;
if (x >= mPosX && x <= mPosX + mWidth && y >= mPosY
&& y <= mPosY + mHeight) {
isClick = true;
}
return isClick;
}


// 读取图片资源

public Bitmap ReadBitMap(Context context, int resId) {
BitmapFactory.Options opt = new BitmapFactory.Options();
opt.inPreferredConfig = Bitmap.Config.RGB_565;
opt.inPurgeable = true;
opt.inInputShareable = true;

// 获取资源图片

InputStream is = context.getResources().openRawResource(resId);
return BitmapFactory.decodeStream(is, null, opt);

}

}

下面是显示开始图片按钮MenuView.java,代码如下:

package com.example.eluosifangkuai;

import android.content.Context;
import android.graphics.Canvas;
import android.view.View;

public class MenuView extends View{

ImageButton m_ImageButton_Play; // 开始播放按钮
ImageButton m_ImageButton_Play_a;
ImageButton m_bg; // 背景图片
public MenuView(Context context) { // 初始化工作
super(context);
m_bg = new ImageButton(context,R.drawable.b7,0,0);
m_ImageButton_Play = new ImageButton(context,R.drawable.play,62,136);
m_ImageButton_Play_a = new ImageButton(context,R.drawable.play1,62,136);
}

public void onDraw(Canvas canvas) // 画布中显示位图
{
m_bg.DrawImageButton(canvas, null);
m_ImageButton_Play.DrawImageButton(canvas, null);

}
}

还有一个启动活动类,MainActivity.java 代码为:

package com.example.eluosifangkuai;

import android.os.Bundle;
import android.os.Handler;
import android.app.Activity;
import android.content.Intent;
import android.util.Log;
import android.view.Window;
import android.view.WindowManager;
public class MainActivity extends Activity {

private static final int GOTO_MAIN_ACTIVITY = 0; // 发送消息参数
private Handler mHandler = new Handler(){ // 消息推送类
public void handleMessage(android.os.Message msg) {

switch (msg.what) {
case GOTO_MAIN_ACTIVITY:
Log.i("yunxing","OK2222");
Intent intent = new Intent();
intent.setClass(MainActivity.this, WelcomeActivity.class); // 活动跳转
startActivity(intent);
Log.i("yunxing","ERROR");
finish();
break;

default:
break;
}
};
};
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); //设置窗口无标题和全屏
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
Log.i("yunxing","OK");
setContentView(R.layout.activity_main);
mHandler.sendEmptyMessageDelayed(GOTO_MAIN_ACTIVITY, 5000);//5秒跳转
Log.i("yunxing","OK111");
}

}

转向活动类,WelcomeActivity.java 代码为:

package com.example.eluosifangkuai;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;

import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.view.GestureDetector;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.view.GestureDetector.OnGestureListener;
import android.view.View.OnTouchListener;
import android.widget.TextView;

public class WelcomeActivity extends Activity implements OnTouchListener,OnGestureListener{

GestureDetector m_GestureDetector ; // 手势

public WelcomeActivity()
{
m_GestureDetector = new GestureDetector((OnGestureListener) this);
}
TextView mTextView = null;
MenuView m_MenuView = null;

public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置无标题,全面模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
m_MenuView = new MenuView(this);
setContentView(m_MenuView);
MusicPlay.inItMenuMusicPlay(this);
MusicPlay.menuMusic();
MusicPlay.startMenuMusic();
m_MenuView.setOnTouchListener((OnTouchListener) this);
m_MenuView.setClickable(true);
m_GestureDetector.setIsLongpressEnabled(true);
}


public boolean onKeyDown(int key,KeyEvent keyevent) //对按键的响应
{
if(key == KeyEvent.KEYCODE_BACK && keyevent.getRepeatCount() == 0) //返回键 提示对话框
{
dialog();
return true;
}
return true;//super.onKeyDown(key, keyevent);
}

protected void dialog() // 对话框函数
{
AlertDialog.Builder builder = new Builder(WelcomeActivity.this);
builder.setMessage("是否需要帮助!!!");
builder.setTitle("提示");
builder.setPositiveButton("取消",
new android.content.DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MusicPlay.releaseMenuMusic();
dialog.dismiss();
android.os.Process.killProcess(android.os.Process.myPid());
}
});
builder.setNegativeButton("确定",
new android.content.DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
Intent intent = new Intent(WelcomeActivity.this,helpActivity.class);
startActivity(intent);
}
});
builder.create().show();
}

public boolean onTouch(View v, MotionEvent event)
{
return m_GestureDetector.onTouchEvent(event);
}

public void onResume()
{
super.onResume();
MusicPlay.startMenuMusic();
}

public void onDestroy()
{
super.onDestroy();
MusicPlay.releaseMenuMusic();
WelcomeActivity.this.finish();
}

public boolean onDown(MotionEvent event) {
// TODO Auto-generated method stub
int x = (int)event.getX();
int y = (int)event.getY();
if(m_MenuView.m_ImageButton_Play.IsClick(x, y))
{
Intent intent = new Intent(WelcomeActivity.this,GameActivity.class);
startActivity(intent);
MusicPlay.pauseMenuMusic();
}

return true;
}
public boolean onFling(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
public void onLongPress(MotionEvent arg0) {
// TODO Auto-generated method stub

}
public boolean onScroll(MotionEvent arg0, MotionEvent arg1, float arg2,
float arg3) {
// TODO Auto-generated method stub
return false;
}
public void onShowPress(MotionEvent arg0) {
// TODO Auto-generated method stub

}
public boolean onSingleTapUp(MotionEvent arg0) {
// TODO Auto-generated method stub
return false;
}


}

帮助类,helpActivity.java 代码为:

package com.example.eluosifangkuai;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class helpActivity extends Activity{

public void onCreate(Bundle help)
{
super.onCreate(help);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置无标题,全面模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
setContentView(R.layout.help);
}
}

接下来就游戏的核心类了,所有游戏运行都在这两个类中,首先是一个游戏视图类,包括了游戏运行的核心代码。在以后我会慢慢解释这些代码的含义,希望大家支持。

GameView.java 具体代码为:

package com.example.eluosifangkuai;

import java.util.Random;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;

public class GameView extends View{

public final static int of_Width = 24; // 游戏运行的长度
public final static int of_Height = 10; // 游戏运行的宽度
int gradeCourt = 0; // 分数、等级、 消行数
int levl = 1;
int line = 0;
private int[][] m_screen = new int[of_Width][of_Height]; //屏幕数组
private int[][] m_color = new int[of_Width][of_Height]; // 颜色方块数组
private int[] log_color = new int[of_Height]; // 消行数时记录颜色值
private int k = 0,a = 0,state = 0,statenext = 0; // 随即数和随即方块
private int of_x = 0,of_y = 0; // 下落位置
private int of_x_x = 0; // 阴影离下方物的距离
private int add_dis_y = 0; // 震动距离
public int log_X = 0; // 升级位图绘制标志
public int timeTask = 1000; // 等级级数相关参数
private boolean buttonLeft = false; //按键变换颜色值
private boolean buttonRight = false;
public boolean buttonRotate = false;
public boolean buttonDown = false;
public boolean buttonFastDown = false;
public boolean buttonPause = false;
ImageButton m_ButtonLeft = null; //图像按钮
ImageButton m_ButtonLeft_a = null;
ImageButton m_ButtonRight = null;
ImageButton m_ButtonRight_a = null;
ImageButton m_ButtonDown = null;
ImageButton m_ButtonDown_a = null;
ImageButton m_ButtonFastDown = null;
ImageButton m_ButtonFastDown_a = null;
ImageButton m_ButtonRotate = null;
ImageButton m_ButtonRotate_a = null;
ImageButton m_ButtonPause = null;
ImageButton m_ButtonPause_a = null;
Canvas m_Canvas = null;
GameResources m_GameResources;
Random m_Random = null;

public GameView(Context context) // 视图类构造函数 负责一些变量的初始化
{
super(context);
m_GameResources = new GameResources(context); // 初始化位图资源变量
inItButton(context); // 初始化图像按钮
clean(); // 清除游戏开始方块数组值
m_Random = new Random(); // 产生随即值函数
state = Math.abs(m_Random.nextInt()%7); //当前方块颜色值
statenext = Math.abs(m_Random.nextInt()%7); //下一个方块颜色值
k = Math.abs(m_Random.nextInt()%28); // 当前方块
a = Math.abs(m_Random.nextInt()%28); // 下一个方块
for(int i=0;i<4;i++) // 初始化方块
{
for(int j=0;j<4;j++)
{
if(0 != statefang.state[k][i][j])
{
m_screen[i][j+3] = statefang.state[k][i][j];
m_color[i][j+3] = state;
}
}
}
of_y = 3; // 出现方块的位置值
fastDown(1); // 获取下方透明方块的距离
setFocusable(true); // 获取按键焦点,可以响应触摸事件
setFocusableInTouchMode(true);
}

public void inItButton(Context context) // 初始化图像按钮
{
m_ButtonLeft = new ImageButton(context,R.drawable.control_left1,0,354);
m_ButtonLeft_a = new ImageButton(context,R.drawable.control_left2,0,354);
m_ButtonRight = new ImageButton(context,R.drawable.control_right1,80,354);
m_ButtonRight_a = new ImageButton(context,R.drawable.control_right2,80,354);
m_ButtonRotate = new ImageButton(context,R.drawable.control_rotate1,160,354);
m_ButtonRotate_a = new ImageButton(context,R.drawable.control_rotate2,160,354);
m_ButtonDown = new ImageButton(context,R.drawable.control_down1,240,354);
m_ButtonDown_a = new ImageButton(context,R.drawable.control_down2,240,354);
m_ButtonFastDown = new ImageButton(context,R.drawable.control_drop1,230,300);
m_ButtonFastDown_a = new ImageButton(context,R.drawable.control_drop2,230,300);
}
public void clean()
{
for(int i = 0;i<of_Width;i++)
{
for(int j=0;j<of_Height;j++)
{
m_screen[i][j] = 0;
m_color[i][j] = -1;
}
}
}
public void onDraw(Canvas canvas) // 画图函数 ,主线程中实现不停刷新 此函数响应刷新
{
super.onDraw(canvas);
Paint m_Paint = new Paint(); // 新建画笔
m_Paint.setAntiAlias(true); // 设置抗锯齿
m_Paint.setFakeBoldText(true); //true为粗体,false为非粗体
m_Paint.setColor(Color.RED);
m_Paint.setAlpha(100); // 设置透明度
this.setKeepScreenOn(true); // 保存屏幕常亮
Log.i("onDraw","执行了");
canvas.drawBitmap(m_GameResources.m_Bitmaphc,0,0,null); // 画出双缓冲中的图片
canvas.drawBitmap(m_GameResources.m_Bitmaps[7],0,add_dis_y,null);
canvas.drawBitmap(m_GameResources.score,230,150+add_dis_y,null);


PaintTm(canvas,m_Paint); // 绘制下方透明方块
Paintnext(canvas); // 绘制下一个产生方块
paintCourt(canvas); // 绘制方块本身,在屏幕数组的位置
PaintButton(canvas,m_Paint); // 绘制下方方向导航按键
canvas.drawText(" "+levl,256,185+add_dis_y,m_Paint); // 绘制等级、分数、消行数
canvas.drawText(" "+gradeCourt,255,185+add_dis_y+50,m_Paint);
canvas.drawText(" "+line,255,185+add_dis_y+100,m_Paint);
add_dis_y = 0; // 调整震动原始值
m_Canvas = canvas;
}
public void PaintButton(Canvas canvas,Paint m_Paint)// 绘制下方方向导航按键和升级位图
{
if(timeTask == 800 || timeTask == 500 || timeTask == 200)
{
if(log_X == 0)
{
canvas.drawBitmap(m_GameResources.Level,35,200, m_Paint);
log_X = 1;
}
}
if(buttonLeft)
{
m_ButtonLeft_a.DrawImageButton(m_Canvas, m_Paint);
}
else
{
m_ButtonLeft.DrawImageButton(canvas, m_Paint);
}

buttonLeft = false;

if(buttonRight)
{
m_ButtonRight_a.DrawImageButton(canvas, m_Paint);
}
else
{
m_ButtonRight.DrawImageButton(canvas, m_Paint);
}

buttonRight = false;

if(buttonRotate)
{
m_ButtonRotate_a.DrawImageButton(canvas, m_Paint);
}
else
{
m_ButtonRotate.DrawImageButton(canvas, m_Paint);
}

buttonRotate = false;

if(buttonDown)
{
m_ButtonDown_a.DrawImageButton(canvas, m_Paint);
}
else
{
m_ButtonDown.DrawImageButton(canvas, m_Paint);
}

buttonDown = false;

if(buttonFastDown)
{
m_ButtonFastDown_a.DrawImageButton(canvas, m_Paint);
}
else
{
m_ButtonFastDown.DrawImageButton(canvas, m_Paint);
}

buttonFastDown = false;

}
public void paintCourt(Canvas canvas)
{
for(int i=0;i<of_Width;i++)
{
for(int j=0;j<of_Height;j++)
{
if(0 != m_screen[i][j] && i > 3)
{
canvas.drawBitmap(m_GameResources.m_Bitmaps[m_color[i][j]],j*18+17,(i-4)*18+11+add_dis_y,null);
}
}
}
}


public void colorstate(int x,int y,int stateColor) // 颜色的状态值
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
m_color[x+i][y+j] = stateColor;
}
}
}
public void PaintTm(Canvas canvas,Paint paint) // 绘制下方半透明方块
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
int num = ((of_x_x-4+i)*18+11+add_dis_y);

if(0 != statefang.state[k][i][j] && num >= 11)
{
canvas.drawBitmap(m_GameResources.m_Bitmaps[state],(of_y+1+j)*18,(of_x_x-4+i)*18+11+add_dis_y,paint);

}
}
}
}
public voidPaintnext(Canvas canvas)
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(0 != statefang.state[a][i][j])
{
canvas.drawBitmap(m_GameResources.m_Bitmaps[statenext],j*15+225,60+i*15+add_dis_y,null);
}
}
}
}

public void idKeyDown(int key,KeyEvent keyevent) //对按键的响应
{
if(key == KeyEvent.KEYCODE_DPAD_DOWN && moveDownOn())//&& of_x < of_Width-4){
{
Down();
fastDown(1);
buttonDown = false;
}
if(key == KeyEvent.KEYCODE_DPAD_RIGHT && moveRightOn())
{
Right();
fastDown(1);
buttonRight = false;
}
if(key == KeyEvent.KEYCODE_DPAD_LEFT && moveLeftOn() )//&& of_y > 0)
{
Left();
fastDown(1);
buttonLeft = false;
}
if(key == KeyEvent.KEYCODE_DPAD_UP&&rotateOnCourt())
{
rate();
fastDown(1);
buttonRotate = false;
}
if(key == KeyEvent.KEYCODE_DPAD_CENTER && moveDownOn())
{
FastDown();
fastDown(1);
buttonFastDown = false;
}

}


public boolean availableForTile(int[][] tile,int x,int y) //方块旋转判断
{
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
if (tile[i][j] != 0) {
if (!isSpace(x + i, y + j)) {
return false;
}
}
}
}
return true;
}
public boolean rotateOnCourt() { // 是否能够旋转,能返回true,方块按向右旋转
int tempX = 0, tempY = 0;
int tempShape;
int[][] tempTile = new int[4][4];

tempShape = k;
if (tempShape % 4 > 0) {
tempShape--;
} else {
tempShape += 3;
}
for (int i = 0; i < 4; i++) {
for (int j = 0; j < 4; j++) {
tempTile[i][j] = statefang.state[tempShape][i][j];
}
}

tempX = of_x;
tempY = of_y;
boolean canTurn = false;
cleanstate(of_x,of_y);
if( availableForTile(tempTile,tempX,tempY) )
{
canTurn = true;
}
else if(availableForTile(tempTile,tempX-1,tempY) )
{
canTurn = true;
tempX--;
}
else if(availableForTile(tempTile,tempX-2,tempY) )
{
canTurn =true;
tempX -=2;
}
else if(availableForTile(tempTile,tempX+1,tempY) )
{
canTurn = true;
tempX++;
}
else if(availableForTile(tempTile,tempX+2,tempY) )
{
canTurn = true;
tempX += 2;
}

if (canTurn) {
k = tempShape;
of_x = tempX;
of_y = tempY;
return true;
}
for(int i=0;i<4;i++) // 执行旋转之前屏幕数组和颜色数组回到当前值
{
for(int j=0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
{
m_screen[of_x+i][of_y+j] = 1;
m_color[of_x+i][of_y+j] = state;
}
}
}
return false;
}

public boolean isSpace(int x,int y) // 判断x、y 这个方块是否在超越边界 以及是否为原始值0
{
if(x< 0 || x>=of_Width)
return false;
if(y<0 || y>=of_Height)
return false;
if(m_screen[x][y] == 0)
return true;
return false;
}
public boolean moveDownOn() // 判断能否继续下落
{
int n = 0;
for(int i=0;i<4;i++)
{
for(int j =0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
{
n = i;
while(n<3 && statefang.state[k][n+1][j] != 0)
n++;
if(!isSpace(of_x+n+1,of_y+j))
return false;
}
}
}

return true;
}

public int cleanFullLine() // 清楚满行的行
{
int num = 0,n=0,linenum = 0;
num = brigeLine();
for(int i = of_x+3;i>=of_x-1;i--)
{
if(fullLine(i))
{
n = i;
for(int r=0;r<of_Height;r++)
{
log_color[r] = m_color[n][r];
}

linenum++;
for(int j = n;j>=num;j--)
{
for(int k=0;k<of_Height;k++)
{
if(j == num)
{
m_screen[j][k] = 0;
m_color[j][k] = -1;
}
else
{
m_screen[j][k] = m_screen[j-1][k];
m_color[j][k] = m_color[j-1][k];
}

}
}
for(int t=0;t<of_Height;t++) // 画出满行去掉的剪切态
{
m_Canvas.drawBitmap(m_GameResources.m_Bitmaps[log_color[t]],24+t*18,(n-4)*18+25,null);
}
MusicPlay.playSound(R.raw.delete1+linenum,0);

i = n+1;
}
}

return linenum;
}

public int brigeLine() //找出哪行没有方块 并返回行值 否则返回0
{
for(int i = of_x+3;i>0;i--)
{
int j = 0;
while(j<of_Height && m_screen[i][j] == 0)
j++;
if(j == of_Height)
return i+1;

}
return 0;
}
public boolean fullLine(int hang) // 判断改行是否是满行
{
int j = 0;
while(j<of_Height && m_screen[hang][j] == 1)
j++;
if(j == of_Height)
return true;

return false;
}

public void move() // 移动时,必须对屏幕数组和颜色数组校正
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
{
m_screen[i+of_x][j+of_y] = 1;
m_color[i+of_x][j+of_y] = state;
}
}
}
}

public boolean moveRightOn() // 能否右移动
{
buttonRight = true;
for(int i=0;i<4;i++)
{
for(int j =0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
{
while(j<3 && statefang.state[k][i][j+1] != 0)
j++;
if(!isSpace(of_x+i,of_y+j+1))
return false;
}
}
}
return true;
}
public boolean moveLeftOn() // 能否左移动
{
buttonLeft = true;

for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
{
if(!isSpace(of_x+i,of_y+j-1))
return false;
else
break;
}
}
}
return true;
}
public int fastDown(int log) //能否快速下落,此函数有两种状态 一种是返回阴影的值 另一种是下落所学值
{
int a[] = {100,100,100,100};
int n=0,s = 0,m = 0;
for(int i=0;i<4;i++)
{
for(int j =0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
{
m = i;
while(m<3 && statefang.state[k][m+1][j] != 0)
m++;
if(isSpace(of_x+m+1,of_y+j))
{
n = 1;
while(isSpace(of_x+m+(++n),of_y+j));
a[s++] = n-1;
}
}
}
}
switch(log) // 一个是下方透明方块的距离值,一个是实际下落方块的距离
{
case 1:of_x_x = of_x+min(min(a[0],a[1]),min(a[2],a[3]));return of_x_x;
case 2:s = of_x;
of_x += min(min(a[0],a[1]),min(a[2],a[3]));break;
}

return s;
}
public int min(int a,int b)
{
if(a>=b)
return b;
else
return a;
}
public void cleanstate(int x,int y) // 清楚函数状态
{
for(int i=0;i<4;i++)
{
for(int j=0;j<4;j++)
{
if(statefang.state[k][i][j] != 0)
{
m_screen[x+i][y+j] = 0;
m_color[x+i][y+j] = -1;
}
}
}
}

public void Court(int grade) // 计分
{
line += grade;
switch(grade)
{
case 1:gradeCourt+=100;break;
case 2:gradeCourt+=300;break;
case 3:gradeCourt+=500;break;
case 4:gradeCourt+=800;break;
}
}
public boolean GameOver() // 游戏结束
{
for(int i=0;i<of_Height;i++)
{
if(m_screen[4][i] != 0)
return true;
}
return false;
}
public void Right() // 右移函数
{
cleanstate(of_x,of_y);
of_y++;
move();
}
public void Left() // 左移函数
{
cleanstate(of_x,of_y);
of_y--;
move();
}
public void Down() // 下落函数
{
cleanstate(of_x,of_y);
of_x++;
move();
}
public void FastDown() // 快速下落函数
{
add_dis_y = 5;
cleanstate(fastDown(2),of_y);
move();
}
public void rate() // 旋转函数
{
cleanstate(of_x,of_y);
move();
}
public void NotDown() // 方块下落到地步 对屏幕数组进行一系列的处理
{
of_x_x = 0;
colorstate(of_x, of_y,state); // 保存颜色值
Court(cleanFullLine()); // 消行计分
}
public void newState()
{
k = a; // 交换方块值
state = statenext; //交换颜色值
a = Math.abs(m_Random.nextInt()%28); // 产生方块值
statenext = Math.abs(m_Random.nextInt()%7); // 产生颜色值
of_y = 3; // 重置下落位置
of_x = 0;
}
}

游戏视图类有了,当然需要一个活动去执行它了,定义了一个GameActivity.java 具体代码为:

package com.example.eluosifangkuai;

import android.app.Activity;
import android.app.AlertDialog;
import android.app.AlertDialog.Builder;
import android.app.Service;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.os.Vibrator;
import android.util.Log;
import android.view.GestureDetector;
import android.view.GestureDetector.OnGestureListener;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.view.Window;
import android.view.WindowManager;


public class GameActivity extends Activity implements OnTouchListener,OnGestureListener { // 实现手势,触摸监听

GestureDetector m_GestureDetector ; // 定义手势

public GameActivity() //构造函数 完成手势的相关初始化
{
m_GestureDetector = new GestureDetector((OnGestureListener) this);
}

protected static final int ii = 0x101; // UI主线程发送消息匹配代码
protected static final int kk = 0x110;
private int dialog_xx = 0;
private boolean Thread_Log = true; // 线程运行标志,用来暂停游戏
private float log = 0; // 左滑时获取距离存放变量
private int log_num = 0; // 下落在自由下落 和快速下滑是声音选择变量
private int log_log = 0;
public int m_time_a,i=0; // 下落时间变量,和运行次数的相关参数

Vibrator vibrator; // 震动类声明
long[] pattern = {0,10,10,30}; //根据指定的模式进行震动 //第一个参数:该数组中第一个元素是等待多长的时间才启动震动, //之后将会是开启和关闭震动的持续时间,单位为毫秒 //第二个参数:重复震动时在pattern中的索引,如果设置为-1则表示不重复震动

GameView m_GameView = null; // 定义视图类变量

Handler m_Handler = new Handler() // 定义Handler变量 实现更新View视图
{
public void handleMessage(Message msg)
{
switch(msg.what)
{
case GameActivity.kk:
Thread_Log = false;
dialog_a();
break ;
case GameActivity.ii:
m_GameView.invalidate();
}
super.handleMessage(msg);
}
};

public void onCreate(Bundle saved)
{
super.onCreate(saved);
requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置无标题的全屏模式
getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
m_GameView = new GameView(this); // 实例化GameView对象
init(); // 初始化工作,包括声音
new Thread(new GameThread()).start(); // 新建游戏线程
}

private void init() // 初始化
{
setContentView(m_GameView); // 活动绘制GameView的内容
vibrator = (Vibrator) getSystemService(Service.VIBRATOR_SERVICE); // 获取系统服务震动
m_GameView.setOnTouchListener((OnTouchListener) this); // 设置可以响应触摸事件
m_GameView.setClickable(true);
m_GestureDetector.setIsLongpressEnabled(true); // 可以响应长按
MusicPlay.inItMusicPlay(this); // 初始化播放器及相关操作
MusicPlay.inItSound();
MusicPlay.BgMediaplayer();
MusicPlay.startMusic();
Log.i("aiai", "run begin 111");
}

class GameThread implements Runnable{

public void run()
{
while(!Thread.currentThread().isInterrupted())
{
while(Thread_Log) // 游戏是否暂停标志
{
Message message = new Message(); // 新建消息函数
if(dialog_xx == 0)
message.what = GameActivity.ii; // 赋值消息
else
message.what = GameActivity.kk; // 赋值消息
GameActivity.this.m_Handler.sendMessage(message); //发送消息
Log.i("Thread run","yunxing22222");
try
{
Thread.sleep(100); // 线程休眠时间
}
catch(InterruptedException e)
{
Thread.currentThread().interrupt();
}

m_time_a = ++i*100; //循环获取时间的叠加值,满足一定条件是执行下落函数块
if(m_time_a == (10-2*m_GameView.levl+1)*100) //时间满足执行
{
onNotDown(); // 执行下落处理函数
i = 0; // 重置变量i
}
}
}
}
}


public void onNotDown()
{
if(Thread_Log) //暂停标志
{
if(m_GameView.moveDownOn()) // 能够下落
{
m_GameView.Down();
log_num = 0;
}
else
{
if(log_num == 0)
MusicPlay.playSound(R.raw.down,0);
m_GameView.NotDown();
if(m_GameView.GameOver()) //游戏结束
{
dialog_xx = 1;
}
if(dialog_xx == 0)
m_GameView.newState();

if(m_GameView.gradeCourt >= 3000&&m_GameView.timeTask == 1000) //一定分数升级
{
m_GameView.timeTask = 800;
m_GameView.levl+=1;
}
if(m_GameView.gradeCourt >= 6000 && m_GameView.timeTask == 800)
{
m_GameView.timeTask = 500;
m_GameView.levl+=1;
m_GameView.log_X = 0;
}
if(m_GameView.gradeCourt >= 9000&&m_GameView.timeTask == 500)
{
m_GameView.timeTask = 200;
m_GameView.levl+=1;
m_GameView.log_X = 0;
}

m_GameView.fastDown(1);


}
}
}

public boolean onTouch(View v, MotionEvent event) // 重写onTouch函数
{
return m_GestureDetector.onTouchEvent(event); // 可以响应手势
}

public boolean onKeyDown(int key,KeyEvent keyevent) //对按键的响应
{
m_GameView.idKeyDown(key, keyevent);

if(key == KeyEvent.KEYCODE_BACK && keyevent.getRepeatCount() == 0) //返回键 提示对话框
{
Thread_Log = false;
dialog();
return true;
}
return true;//super.onKeyDown(key, keyevent);
}

protected void dialog() // 对话框函数
{
AlertDialog.Builder builder = new Builder(GameActivity.this);
builder.setMessage("确定要退出吗?");
builder.setTitle("提示");
builder.setPositiveButton("确认",
new android.content.DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
MusicPlay.releaseMusic();
dialog.dismiss();
android.os.Process.killProcess(android.os.Process.myPid());
}
});
builder.setNegativeButton("取消",
new android.content.DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
Thread_Log = true;
}
});
builder.create().show();
}

protected void dialog_a()
{
AlertDialog.Builder builder = new Builder(GameActivity.this);
builder.setMessage("游戏结束!!!");
builder.setTitle("提示");
builder.setPositiveButton("确认",
new android.content.DialogInterface.OnClickListener()
{
public void onClick(DialogInterface dialog, int which)
{
m_GameView = null;
Intent intent = new Intent(GameActivity.this,WelcomeActivity.class);
MusicPlay.releaseMusic();
startActivity(intent);
// GameActivity.this.finish();
}
});

builder.create().show();
}

public void onDestroy() // 销毁函数
{
super.onDestroy();
MusicPlay.releaseMusic();
}


public boolean onDown(MotionEvent event) //按下触摸事件
{
int x = (int)event.getX(); //获取按下的坐标位置
int y = (int)event.getY();

if(m_GameView.m_ButtonLeft.IsClick(x, y)) // 按下坐标是否在图标区域
{
vibrator.vibrate(pattern,-1); // 真机下按键震动响应

if(m_GameView.moveLeftOn()&& Thread_Log)
{
m_GameView.Left();
m_GameView.fastDown(1); // 计算此时与下方方块的最短距离,以便绘制透明方块
}

MusicPlay.playSound(R.raw.action,0);
}

if(m_GameView.m_ButtonRight.IsClick(x, y))
{
vibrator.vibrate(pattern,-1);

if(m_GameView.moveRightOn()&& Thread_Log)
{
m_GameView.Right();
m_GameView.fastDown(1);
}

MusicPlay.playSound(R.raw.action,0);
}

if(m_GameView.m_ButtonDown.IsClick(x, y))
{
m_GameView.buttonDown = true;
vibrator.vibrate(pattern,-1);

if(m_GameView.moveDownOn()&& Thread_Log)
{
m_GameView.Down();
m_GameView.fastDown(1);
}
}

if(m_GameView.m_ButtonRotate.IsClick(x, y))
{
m_GameView.buttonRotate = true;
vibrator.vibrate(pattern,-1);

if(m_GameView.rotateOnCourt()&& Thread_Log)
{
m_GameView.rate();
m_GameView.fastDown(1);
}

MusicPlay.playSound(R.raw.action,0);
}

if(m_GameView.m_ButtonFastDown.IsClick(x, y))
{
m_GameView.buttonFastDown = true;
vibrator.vibrate(pattern,-1);

if(m_GameView.moveDownOn()&& Thread_Log)
{
m_GameView.FastDown();
}

MusicPlay.playSound(R.raw.fastdown,0);
}

return true;
}

public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX,float velocityY)
{
final int FLING_MIN_DISTANCE = 100, FLING_MIN_VELOCITY = 200;

if(e2.getY()-e1.getY()>FLING_MIN_DISTANCE && Math.abs(velocityY)>FLING_MIN_VELOCITY && m_GameView.moveDownOn()&& Thread_Log)
{
log_num = 1;
m_GameView.FastDown();
MusicPlay.playSound(R.raw.fastdown,0);
}

if(e2.getY()-e1.getY()<0&&Math.abs(velocityY)>FLING_MIN_VELOCITY)
{
if(log_log == 0)
{
Thread_Log = false;
log_log = 1;
}
else
{
Thread_Log = true;
log_log = 0;
}

}
return false;
}

public void onLongPress(MotionEvent event)
{
}

public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX,float distanceY) {

Log.i("onScroll","Downstill");

if(e1.getAction() == MotionEvent.ACTION_DOWN)
log = e1.getX();
float e1x = e1.getX() ;
float e2x = e2.getX() ;
float x1 = e2x - e1x ;
float e1y = e1.getY() ;
float e2y = e2.getY() ;
float y1 = e2y - e1y ;
float absX = Math.abs(x1), absY = Math.abs(y1) ;
float ex2 = e2.getX();
float x = ex2-log;
if(absX > absY)
{
if(x>60f&&x<70f || x>-70f&&x<-60f)
{
log = ex2;

if( x>-70f&&x<-60f&& m_GameView.moveLeftOn())
{
m_GameView.Left();
m_GameView.fastDown(1);
MusicPlay.playSound(R.raw.action,0);
}
if(x>60f&&x<70f && m_GameView.moveRightOn())
{
m_GameView.Right();
m_GameView.fastDown(1);
MusicPlay.playSound(R.raw.action,0);
}
}
}

return true;
}

public void onShowPress(MotionEvent event) {

}

public boolean onSingleTapUp(MotionEvent e) // 点击屏幕
{
// TODO Auto-generated method stub
if(e.getY()<400)
{
if(e.getX()<240 || e.getY()<300)
{
if(m_GameView.rotateOnCourt())
{
m_GameView.rate();
m_GameView.fastDown(1);
MusicPlay.playSound(R.raw.rotation,0);
}

}
}
return false;
}



}

主要的都有了。虽然自己在还没有学C++,没有学java,没有学android,但我自己的自学程度,在短短的两个月内自学完。我只是想用自己的经历告诉大家,只要我们努力去做就会走向成功,就算不成功,这个历程也是值得我们回味的。。希望大家批评指正,如有更好的建议,希望大家多多交流。~~~~~~~~~~~·期待你们的意见。。

转载请注明出处~~~~~~~~~~~~~~~~~~~谢谢!!!!!!!!!!!!


下载地址我贴出来了,很早时候写的,大家勿喷啊。如果你能够修改我的代码欢迎交流了。

http://download.csdn.net/detail/wu10045125/8219063


另外小弟开源了一个项目也欢迎大家fork了,支持了。小弟github开源地址:

https://github.com/10045125/vanda


更多相关文章

  1. 某个蝰蛇音效的卡刷包代码分析
  2. Android自动生成代码工具整理
  3. Android不常用代码(1)
  4. Android获取网页源代码
  5. android - Jni 接口函数表
  6. java 打印函数名称
  7. android中执行线程的部分代码
  8. android 学习笔记有用代码片段(3)

随机推荐

  1. BlackBerry SIP VOIP softPhone, open so
  2. 分享Android入门学习资料
  3. 【转】Android Intent Action 大全
  4. android之延时操作
  5. 一步步探索学习Android(安卓)Touch事件分
  6. Android开发笔记(一百二十三)下拉刷新布局S
  7. Android定义的路径全局变量
  8. Android Adapter详解
  9. android样式学习(二) android给listview设
  10. Android:图文解析带你快速了解RxJava原理