android 2D 游戏的开发的方法

                                 最近学习了android 2D 应用的开发,拿来和大家分享一下,学习2D 开发前我们先了解一下SurfaceView的使用以及贴图技术的使用,最后呢,是一个简单的2的游戏的实现。


 1.SurfaceView的一些用法


                     提供了一个专门的绘图渲染的图形嵌入在一个视图层次;SurfaceView负责将图形正确的显示在屏幕上,访问底层图形是通过SurfaceHolder提供接口,可通过调用getHolder(),图形创建SurfaceView的窗口是可见的;实现方法是surfaceCreated(SurfaceHolder)和surfaceDestroyed(SurfaceHolder)销毁图形

 


                    简单的例子如下

package com.nyist.wj;

import android.app.Activity;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.graphics.Paint.Style;
import android.os.Bundle;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class SurfaceViewActivity extends Activity {
	MySurfaceView mySurfaceView;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		mySurfaceView = new MySurfaceView(this);
		setContentView(mySurfaceView);

	}
	public class MySurfaceView extends SurfaceView implements
	SurfaceHolder.Callback {
SurfaceViewActivity surfaceViewActivity; // Activity的引用
Paint paint; // 画笔的引用

public MySurfaceView(Context context) // 构造器
{
	super(context);
	this.surfaceViewActivity = (SurfaceViewActivity) context; // 拿到Activity引用
	this.getHolder().addCallback(this); // 设置生命周期回调接口的实现者
	paint = new Paint(); // 创建画笔
	paint.setAntiAlias(true); // 打开抗锯齿
}

@Override
protected void onDraw(Canvas canvas) // onDraw方法
{
	paint.setColor(Color.WHITE); // 设置画笔颜色为白色
	canvas.drawRect(0, 0, getWidth(), getHeight(), paint); // 绘制白色矩形背景
	paint.reset(); // 清除画笔设置
	paint.setARGB(50, 0, 255, 0); // 设置画笔颜色和透明度
	paint.setStrokeWidth(5); // 设置画笔宽度
	RectF rf = new RectF(50, 100, 160, 180); // 创建一个矩形
	canvas.drawRect(rf, paint); // 绘制矩形
	paint.setARGB(50, 0, 0, 255); // 设置画笔颜色和透明度
	paint.setStyle(Style.STROKE); // 设置风格为边框
	paint.setStrokeWidth(5); // 设置画笔宽度
	Rect r = new Rect(200, 100, 300, 180); // 创建一个矩形
	canvas.drawRect(r, paint); // 画一个矩形边框
	paint.setColor(Color.RED); // 设置画笔颜色
	paint.setAntiAlias(true); // 打开抗锯齿
	canvas.drawCircle(100, 250, 30, paint);// 画一个圆
	paint.setColor(Color.YELLOW); // 设置画笔颜色
	rf = new RectF(200, 250, 300, 300); // 创建一个矩形
	canvas.drawOval(rf, paint); // 画一个椭圆,充满矩形
	paint.reset(); // 清除画笔设置
	paint.setColor(Color.RED); // 设置画笔颜色

	paint.setTextSize(40); // 设置文字大小
	paint.setStyle(Style.FILL_AND_STROKE);
	canvas.drawText("loading...", 50, 350, paint); // 画一个字符串
}

@Override
public void surfaceCreated(SurfaceHolder holder) // 创建时被调用
{
	Canvas canvas = holder.lockCanvas(); // 获取画布
	try {
		synchronized (holder) {
			onDraw(canvas);
		} // 绘制
	} catch (Exception e) {
		e.printStackTrace();
	} finally {
		if (canvas != null) {
			holder.unlockCanvasAndPost(canvas);
		}
	}
}

@Override
public void surfaceDestroyed(SurfaceHolder holder) {
} // 继承方法,空实现

@Override
// 继承方法,空实现
public void surfaceChanged(SurfaceHolder holder, int format, int width,
		int height) {
}
}

}

实现的效果是:

2.贴图技术的使用

    贴图技术主要包括图片的移动、旋转、透明度、等变化

下面是关于贴图技术的使用方法  首先是自定义的一个布局

 <com.nyist.wj.MysurfaceView
        android:id="@+id/mysurfaceview"
        android:layout_width="fill_parent"
        android:layout_height="fill_parent" />

然后就是实现自定义布局引用的类

package com.nyist.wj;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.View;

public class MysurfaceView extends View {

 Bitmap bitmap;
 Paint paint;
 public MysurfaceView(Context context,AttributeSet attributeSet) {
  super(context,attributeSet);
  // TODO Auto-generated constructor stub
  this.initBitmap();
  
 }
 public  void initBitmap() {
  // TODO Auto-generated method stub
  paint=new Paint();
  bitmap=BitmapFactory.decodeResource(getResources(), R.drawable.ball);
  
 }
 @Override
 protected void onDraw(Canvas canvas) {
  // TODO Auto-generated method stub
  super.onDraw(canvas);
  //打开抗锯齿
  paint.setAntiAlias(true);
  canvas.drawBitmap(bitmap, 50,50,paint);
  canvas.save();
  
  Matrix matrix=new Matrix();
  //移动
  matrix.setTranslate(100, 100);
  Matrix matrix2=new Matrix();
//  旋转
  matrix2.setRotate(50);
  Matrix matrix3=new Matrix();
  matrix3.setConcat(matrix, matrix2);
  //缩放
  matrix.setScale(0.5f, 0.5f);
  matrix2.setConcat(matrix3, matrix);
  canvas.drawBitmap(bitmap, matrix2, paint);
  canvas.restore();
  canvas.save();
  paint.setAlpha(200);
  matrix.setTranslate(150, 150);
  //放大
  matrix2.setScale(1.3f, 1.3f);
  //设置总矩阵
  matrix3.setConcat(matrix, matrix2);
  canvas.drawBitmap(bitmap, matrix3, paint);
  paint.reset();
  
 }

 

}



实现的效果如下   解释一下:这是横屏显示的结果,左上方是原图片大小  接着是缩放的和放大的图片

3.广告条的实现方法

广告虽不好,但是这确实为android开发者提供了一点微薄的力量,下面就看看广告条的开发

效果图:

实现的过程有自定义的View

<com.nyist.wj.myView
        android:layout_width="fill_parent"
        android:layout_height="50dip"
        />

实现view的方法

package com.nyist.wj;

import android.content.Context;
import android.content.Intent;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

public class myView extends View {
	Bitmap[] bitmap;
	int currentindex = 1;
	int time = 3000;
	boolean isAnima = false;
	Paint paint;
	int[] imageID;
	// 初始化图片数阻
	boolean initFlag = false;
	float prex, prey;
	int xoffset;

	public myView(Context context, AttributeSet attributeSet) {
		super(context, attributeSet);
		// TODO Auto-generated constructor stub
		this.imageID = new int[] { R.drawable.test1, R.drawable.test2,
				R.drawable.test3, R.drawable.test4 };
		// 生成图片数组
		bitmap = new Bitmap[imageID.length];
		paint = new Paint();
		// 抗锯齿
		paint.setFlags(Paint.ANTI_ALIAS_FLAG);
		this.setOnTouchListener(null);
		new Thread() {
			public void run() {

				while (true) {
					if (!isAnima) {
						currentindex = (currentindex + 1) % imageID.length;

					}
					// 刷帧重绘
					myView.this.postInvalidate();
					try {
						Thread.sleep(time);
					} catch (Exception e) {
						// TODO: handthele exception
					}

				}

			};
		}.start();

	}

	public void initBitmap() {
		Resources resources = this.getResources();
		for (int i = 0; i < imageID.length; i++) {
			// ------------------------------
			// 实现图片 的缩放
			bitmap[i] = scaleChange(BitmapFactory.decodeResource(resources,
					imageID[i]

			));
		}

	}

	public static Bitmap scaleChange(Bitmap bitmap) {
		int w = bitmap.getWidth();
		int h = bitmap.getHeight();
		double xratio = (double) Constant.SCREEN_WIDTH / w;
		double yratio = 50.0 / h;
		// 生成矩阵
		Matrix matrix = new Matrix();
		matrix.postScale((float) xratio, (float) yratio);
		Bitmap result = Bitmap.createBitmap(bitmap, 0, 0, w, h, matrix, true);

		return result;

	}

	@Override
	public void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub
		// 第一次运行onDraw方法的时候,调用初始化图片数组的方法
		if (!initFlag) {
			initBitmap();
			initFlag = true;
		}
		if (canvas == null) {
			return;
		}
		if (!isAnima) {
			// -------------------------------------
			// 当没有播放动画时候绘制当前图片
			drawAD(canvas, xoffset, currentindex);
		}
		if (isAnima) {
			// 当向右滑动时候
			if (xoffset > 0) {
				int size = imageID.length;
				// 得到上一张图片的索引
				int preIndex = (currentindex - 1 + size) % size;
				// 根据x轴偏移量,算出上一张图片绘制时的x坐标
				int nextIndex = xoffset - Constant.SCREEN_WIDTH;
				// 绘制当前索引图片
				drawAD(canvas, xoffset, (preIndex + 1) % size);
				drawAD(canvas, nextIndex, preIndex);

			} // 当往左抹时
			else if (xoffset < 0) {
				int size = imageID.length;
				// 得到下一张图片的索引
				int preIndex = (currentindex + 1 + size) % size;
				int nextIndex = xoffset + Constant.SCREEN_WIDTH;
				// 绘制当前图片的索引
				drawAD(canvas, xoffset, (preIndex - 1 + size) % size);
				drawAD(canvas, nextIndex, preIndex);

			}
		}

	}

	public void drawAD(Canvas canvas, int offset, int Index) {
		canvas.drawBitmap(bitmap[Index], offset, 0, paint);

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {
		// TODO Auto-generated method stub

		float x = event.getX();
		float y = event.getY();
		switch (event.getAction()) {
		case MotionEvent.ACTION_DOWN:
			prex = x;
			prey = y;
			System.out.println("------------------------------------");
			System.out.println("+++++++++++++++++++++++++++++++++++"
					+ currentindex);

			return true;
		case MotionEvent.ACTION_MOVE:
			if (!isAnima && Math.abs(x - prex) > 10) {
				isAnima = true;
			}
			if (isAnima) {
				xoffset = (int) (xoffset + x - prex);
				prex = x;
				prey = y;

			}
			this.postInvalidate();
			return true;
		case MotionEvent.ACTION_UP:

			if (isAnima) {
				if (x < Constant.SCREEN_WIDTH / 4 && xoffset < 0) {
					int size = imageID.length;
					currentindex = (currentindex + 1) % size;

				} else if (x > Constant.SCREEN_WIDTH * 3 / 4 && xoffset > 0) {
					int size = imageID.length;
					currentindex = (currentindex - 1 + size) % size;

				}

			}
			isAnima = false;
			xoffset = 0;
			this.postInvalidate();
			return true;

		}

		return false;
	}

}


接着是在activity中的插入

package com.nyist.wj;


import android.app.Activity;
import android.content.pm.ActivityInfo;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.view.Window;
import android.view.WindowManager;

public class GuangGaoActivity extends Activity {
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
//        setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE);
        
        
        setContentView(R.layout.main);
        DisplayMetrics displayMetrics=new DisplayMetrics();
        getWindowManager().getDefaultDisplay().getMetrics(displayMetrics);
        Constant.SCREEN_HEIGHT=displayMetrics.heightPixels;	//获取具体的屏幕分辨率数值
        Constant.SCREEN_WIDTH=displayMetrics.widthPixels;
    }
}

 

4.下面是介绍2D下简单的游戏开发

效果图如下

主要用到的SurfaceView 和贴图技术以及声音的处理

用到的处理方法共有5个类

1.BallGameActivity                        设置屏幕的相关属性

2.GameSurfaceView                    实现显示界面的设置

3.ThreadForDraw                       刷帧线程重新绘制游戏界面

4.ThreadForGo                            控制小球移动

5.ThreadForTimecControl         计算小球运行的时间

下面分别介绍每个类是如何实现的

1.BallGameActivity

package com.nyist.wj;

import java.util.HashMap;

import org.apache.http.auth.AUTH;

import android.app.Activity;
import android.content.Context;
import android.media.AudioManager;
import android.media.SoundPool;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class BallGameActivity extends Activity {
	GameSurfaceView gameSurfaceView;
	// 声音缓冲池
	SoundPool soundPool;
	// 存放声音ID的 map
	HashMap<Integer, Integer> soundpoolMap;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		// 初始化声音
		initSounds();
		// 设置全屏
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		gameSurfaceView = new GameSurfaceView(this);
		setContentView(gameSurfaceView);
		// 循环播放音乐
		playSound(1, -1);

	}

	public void playSound(int sound, int loop) {
		// TODO Auto-generated method stub
		// 播放声音的方法
		AudioManager audioManager = (AudioManager) this
				.getSystemService(Context.AUDIO_SERVICE);
		float streamVolumeMax = audioManager
				.getStreamMaxVolume(audioManager.STREAM_MUSIC);
		float streamVolumeCurrent = audioManager
				.getStreamVolume(AudioManager.STREAM_MUSIC);
		float volume = streamVolumeCurrent / streamVolumeMax;
		// 参数 声音资源的ID 左声道 右声道 优先级 循环次数 回访速度
		soundPool.play(soundpoolMap.get(sound), volume, volume, 1, loop, 0.5f);
	}

	public void initSounds() {
		// TODO Auto-generated method stub
		// 参数 播放的个数 音频类型 播放的质量
		soundPool = new SoundPool(4, AudioManager.STREAM_MUSIC, 100);
		// 创建声音资源的MAP
		soundpoolMap = new HashMap<Integer, Integer>();
		// 将加载声音的资源 放在map中
		soundpoolMap.put(1, soundPool.load(this, R.raw.bg, 1));

	}
}


 

2.GameSurfaceView

package com.nyist.wj;

import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class GameSurfaceView extends SurfaceView implements
		SurfaceHolder.Callback {

	BallGameActivity ballGameActivity;
	ThreadForTimecControl threadForTimecControl;
	ThreadForGo threadForGo;
	ThreadForDraw threadForDraw;

	int backSize = 16; // 背景块大小
	int screenWidth = 320; // 屏幕宽度
	int screenHeight = 480; // 屏幕高度
	int bannerWidth = 40; // 挡板宽度
	int bannerHeight = 6; // 挡板高度
	int bottomSpance = 16; // 下端留白
	int bannerSpan = 5; // 板每次移动的距离
	int ballSpan = 8; // 球每次移动的距离
	int ballSize = 16; // 小球大小
	int hintWidth = 100; // 游戏说明宽度
	int hintHeight = 20; // 游戏说明高度
	int status = 0; // 游戏状态控制 0-等待开始 1-进行中 2-游戏结束 3-游戏胜利
	int score = 0; // 得分
	int ballx; // 小球x坐标
	int bally; // 小球y坐标
	int direction = 0; // 小球方向
	int bannerX; // 挡板X坐标
	int bannerY; // 挡板Y坐标
	int scoreWidth = 32;
	Bitmap iback; // 背景图
	Bitmap[] iscore = new Bitmap[10];// 得分图
	Bitmap iball; // 小球用图
	Bitmap ibanner; // 挡板用图
	Bitmap ibegin; // 开始用图
	Bitmap igameover; // 游戏结束用图
	Bitmap iwin; // 游戏结束用图
	Bitmap iexit; // 退出用图
	Bitmap ireplay; // 重玩用图

	public GameSurfaceView(BallGameActivity ballGameActivity) {
		super(ballGameActivity);
		// 注册回调接口
		getHolder().addCallback(this);
		this.ballGameActivity = ballGameActivity;

		initBitmap();
		// /----------------------------------------------
		threadForDraw = new ThreadForDraw(this);
		// TODO Auto-generated constructor stub
	}

	public void initBitmap() {
		iback = BitmapFactory.decodeResource(getResources(), R.drawable.back);
		iscore[0] = BitmapFactory.decodeResource(getResources(), R.drawable.d0);
		iscore[1] = BitmapFactory.decodeResource(getResources(), R.drawable.d1);
		iscore[2] = BitmapFactory.decodeResource(getResources(), R.drawable.d2);
		iscore[3] = BitmapFactory.decodeResource(getResources(), R.drawable.d3);
		iscore[4] = BitmapFactory.decodeResource(getResources(), R.drawable.d4);
		iscore[5] = BitmapFactory.decodeResource(getResources(), R.drawable.d5);
		iscore[6] = BitmapFactory.decodeResource(getResources(), R.drawable.d6);
		iscore[7] = BitmapFactory.decodeResource(getResources(), R.drawable.d7);
		iscore[8] = BitmapFactory.decodeResource(getResources(), R.drawable.d8);
		iscore[9] = BitmapFactory.decodeResource(getResources(), R.drawable.d9);
		iball = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
		ibanner = BitmapFactory.decodeResource(getResources(),
				R.drawable.banner);
		ibegin = BitmapFactory.decodeResource(getResources(), R.drawable.begin);
		igameover = BitmapFactory.decodeResource(getResources(),
				R.drawable.gameover);
		iwin = BitmapFactory.decodeResource(getResources(), R.drawable.win);
		iexit = BitmapFactory.decodeResource(getResources(), R.drawable.exit);
		ireplay = BitmapFactory.decodeResource(getResources(),
				R.drawable.replay);
		// 初始化小球位置及板X坐标
		initBallAndBanner();
	}

	public void initBallAndBanner() {
		// 初始化小球位置
		bally = screenHeight - bottomSpance - bannerHeight - ballSize;
		ballx = screenWidth / 2 - ballSize / 2;
		// 初始化板X坐标
		bannerX = screenWidth / 2 - bannerWidth / 2;
		bannerY = screenHeight - bottomSpance - bannerHeight;
	}

	public void replay() {

		if (status == 2 || status == 3) {
			// 初始化小球的位置
			initBallAndBanner();
			score = 0;
			status = 0;
			direction = 3;

		}
	}

	@Override
	protected void onDraw(Canvas canvas) {
		// TODO Auto-generated method stub

		super.onDraw(canvas);
		// 清除背景
		int colum = screenWidth / backSize
				+ ((scoreWidth % backSize == 0) ?0:1);
		int rows = screenHeight / backSize
				+ ((screenHeight % backSize == 0) ? 0 : 1);
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < colum; j++) {

				canvas.drawBitmap(iback, 16*j, 16*i, null);

			}
		}
		// 绘制得分
		String scorestr = score + "";
		int loop = 3 - scorestr.length();
		for (int i = 0; i < loop; i++) {

			scorestr = "0" + scorestr;
		}
		int startX = screenWidth - scoreWidth * 3 - 10;
		for (int i = 0; i < 3; i++) {
			int tempScore = scorestr.charAt(i) - '0';
			canvas.drawBitmap(iscore[tempScore], startX + i * scoreWidth, 5,
					null);

		}
		// 绘制小球
		canvas.drawBitmap(iball, ballx, bally, null);
		// 绘制板
		canvas.drawBitmap(ibanner, bannerX, bannerY, null);
		// 绘制开始提示
		if (status == 0) {
			canvas.drawBitmap(ibegin, screenWidth / 2 - hintWidth / 2,
					screenHeight / 2 - hintHeight / 2, null);

		}
		// 绘制失败提示
		if (status == 2) {
			canvas.drawBitmap(igameover, screenWidth / 2 - hintWidth / 2,
					screenHeight / 2 - hintHeight / 2, null);

		}
		// 绘制胜利提示
		if (status == 3) {
			canvas.drawBitmap(iwin, screenWidth / 2 - hintWidth / 2,
					screenHeight / 2 - hintHeight / 2, null);

		}
		// 绘制退出提示
		canvas.drawBitmap(iexit, screenWidth - 32, screenHeight - 16, null);
		// /绘制重玩提示
		if (status == 2 || status == 3) {
			canvas.drawBitmap(ireplay, 0, screenHeight - 16, null);

		}

	}

	@Override
	public boolean onTouchEvent(MotionEvent event) {

		int x = (int) event.getX();
		int y = (int) event.getY();
		if (x < screenWidth && x > screenWidth - 32 && y < screenHeight
				&& y > screenHeight - 16) {
			// ----------------------------------------------------------
			// 按下退出选项退出系统
			ballGameActivity.soundPool.stop(1);
			System.exit(0);
		}
		// 等待状态
		if (status == 0) {
			status = 1;
			// ----------------------------------------------
			threadForTimecControl = new ThreadForTimecControl(this);
			threadForGo = new ThreadForGo(this);
			threadForTimecControl.start();
			threadForGo.start();
		} else if (status == 1) {
			bannerX = x;
		} else if (status == 2 || status == 3) {
			if (x < 32 && x > 0 && y < screenHeight && y > screenHeight - 16) {
				//按下重玩
				replay();

			}

		}

		// TODO Auto-generated method stub
		return super.onTouchEvent(event);

	}

	@Override
	public void surfaceChanged(SurfaceHolder holder, int format, int width,
			int height) {

		// TODO Auto-generated method stub

	}

	@Override
	public void surfaceCreated(SurfaceHolder holder) {
		// TODO Auto-generated method stub
		// ----------------------------------
		// 创建时候启动相关进程
		this.threadForDraw.flag = true;
		threadForDraw.start();

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder holder) {

		// 释放相应的进程
		boolean retry = true;
		this.threadForDraw.flag = false;
		// 不断的循环知道刷帧结束
		while (retry) {
			try {
				threadForDraw.join();
				retry = false;

			} catch (InterruptedException e) {
				// TODO: handle exception
			}

		}

	}

}


 

3.ThreadForDraw

package com.nyist.wj;

import android.graphics.Canvas;
import android.view.SurfaceHolder;

public class ThreadForDraw extends Thread {
boolean flag=true;
int sleep=100;
GameSurfaceView gameSurfaceView;
SurfaceHolder surfaceHolder;

public ThreadForDraw (GameSurfaceView gameSurfaceView){
	
	
	this.gameSurfaceView=gameSurfaceView;
	this.surfaceHolder=gameSurfaceView.getHolder();
	
}

@Override
public void run() {
	// TODO Auto-generated method stub
	
	Canvas canvas;
	while (this.flag) {
		
		canvas=null;
		try {
			canvas=this.surfaceHolder.lockCanvas(null);
			synchronized (this.surfaceHolder) {
				gameSurfaceView.onDraw(canvas);
			}
		} catch (Exception e) {
		
		}finally{
			if (canvas!=null) {
				this.surfaceHolder.unlockCanvasAndPost(canvas);
				
			}
		}
		try {
			Thread.sleep(sleep);
		} catch (Exception e) {
			// TODO: handle exception
		}
	}
	super.run();
}




}


 

4.ThreadForGo

package com.nyist.wj;

//游戏过程中移动小球的线程
public class ThreadForGo extends Thread {
	// 设置线程执行的标志
	boolean flag = true;
	// 游戏界面的引用
	GameSurfaceView gameSurfaceView;

	public ThreadForGo(GameSurfaceView gameSurfaceView) {
		this.gameSurfaceView = gameSurfaceView;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while (flag) {
			switch (gameSurfaceView.direction) {

			case 0:
				// 右上控制当前方向移动球
				gameSurfaceView.ballx = gameSurfaceView.ballx
						+ gameSurfaceView.ballSpan;
				gameSurfaceView.bally = gameSurfaceView.bally
						- gameSurfaceView.ballSpan;
				// 判断是否碰壁
				if (gameSurfaceView.ballx >= gameSurfaceView.screenWidth
						- gameSurfaceView.ballSize) {
					// 碰到上壁
					gameSurfaceView.direction = 3;
				} else if (gameSurfaceView.bally <= 0) {
					gameSurfaceView.direction = 1;

				}

				break;

			case 1:
				// 右下
				gameSurfaceView.ballx = gameSurfaceView.ballx
						+ gameSurfaceView.ballSpan;
				gameSurfaceView.bally = gameSurfaceView.bally
						+ gameSurfaceView.ballSpan;
				// 碰到下壁
				if (gameSurfaceView.bally >= gameSurfaceView.screenHeight
						- gameSurfaceView.bannerHeight
						- gameSurfaceView.bottomSpance
						- gameSurfaceView.ballSize) {
					// /-----------------------------------------
					checkCollision(1);
					// 碰到右臂
				} else if (gameSurfaceView.ballx >= gameSurfaceView.screenWidth
						- gameSurfaceView.ballSize) {
					gameSurfaceView.direction = 2;
				}

				break;
			case 2:
				// 左下
				gameSurfaceView.ballx = gameSurfaceView.ballx
						- gameSurfaceView.ballSpan;
				gameSurfaceView.bally = gameSurfaceView.bally
						+ gameSurfaceView.ballSpan;
				// 碰到下壁
				if (gameSurfaceView.bally >= gameSurfaceView.screenHeight
						- gameSurfaceView.bannerHeight
						- gameSurfaceView.bottomSpance
						- gameSurfaceView.ballSize) {
					// -----------------------------------
					checkCollision(2);

				}
				// 碰到左壁
				else if (gameSurfaceView.ballx <= 0) {

					gameSurfaceView.direction = 1;

				}

				break;

			case 3:
				gameSurfaceView.ballx = gameSurfaceView.ballx
						- gameSurfaceView.ballSpan;
				gameSurfaceView.bally = gameSurfaceView.bally
						- gameSurfaceView.ballSpan;
				// /碰到左壁
				if (gameSurfaceView.ballx <= 0) {
					gameSurfaceView.direction = 0;
				}
				// 碰到上壁
				else if (gameSurfaceView.bally <= 0) {
					gameSurfaceView.direction = 2;
				}

				break;

			default:
				break;

			}
			try {
				Thread.sleep(100);
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	}

	public void checkCollision(int dirction) {
		if (gameSurfaceView.ballx >= gameSurfaceView.bannerX
				- gameSurfaceView.ballSize
				&& gameSurfaceView.ballx <= gameSurfaceView.bannerX
						+ gameSurfaceView.bannerWidth) {
			switch (dirction) {
			case 1:
				gameSurfaceView.direction = 0;
				break;
			case 2:
				gameSurfaceView.direction = 3;
				break;
			default:
				break;
			}
		} else {
			// 没有碰到板
			gameSurfaceView.threadForTimecControl.flag = false;
			gameSurfaceView.threadForGo.flag = false;
			gameSurfaceView.status = 2;
		}

	}
}


 

 

 5.ThreadForTimecControl

 

package com.nyist.wj;

public class ThreadForTimecControl extends Thread {
	//计算生存时间的线程
	//判断是否胜利的值
	int highest = 200;
//	游戏界面的引入
	GameSurfaceView gameSurfaceView;
	//线程标志位
	boolean flag = true;

	public ThreadForTimecControl(GameSurfaceView gameSurfaceView) {

		this.gameSurfaceView = gameSurfaceView;
	}

	@Override
	public void run() {
		// TODO Auto-generated method stub
		while(flag){
			
			gameSurfaceView.score++;
			if (gameSurfaceView.score==highest) {
				//游戏胜利
				gameSurfaceView.status=3;
				//----------------------------------------
				gameSurfaceView.threadForTimecControl.flag=false;
				gameSurfaceView.threadForGo.flag=false;
				
			}
			try {
				Thread.sleep(1000);
				
			} catch (Exception e) {
				// TODO: handle exception
			}
		}
	
	}

}



 

ps:个人总结

小球的初始位置确定

代码是

	// 初始化小球位置
		bally = screenHeight - bottomSpance - bannerHeight - ballSize;
		ballx = screenWidth / 2 - ballSize / 2;
		// 初始化板X坐标
		bannerX = screenWidth / 2 - bannerWidth / 2;
		bannerY = screenHeight - bottomSpance - bannerHeight;


 

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员Android

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值