android平台俄罗斯方块游戏完整代码_俄罗斯方块安卓
android平台俄罗斯方块游戏完整代码_俄罗斯方块安卓
整个游戏我分为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;
}
}