android 之 SurfaceView使用(桌面弹球)

整个项目一共3个类:MyConstant,MainActivity,MySurfaceView

效果截图:

 

注意; 由于手机屏幕分辨的差异,在运行程序时应把AndroidManifest.xml中的

<uses-sdk
        android:minSdkVersion="8"
        android:targetSdkVersion="18" />


删掉

1,MyConstant 用于存放动画中所用的常量

package com.example.sl.desktoppinball;
/**
 * 动画中用到的常量
 * @author songliang
 *
 */
public class MyConstant {
	public static int SCREENWIDTH=320;	//屏幕宽//580*320
	public static int SCREENHEIGHT=490;	//屏幕高
	public static int PICWIDTH=64;		//图片宽
	public static int PICHEIGHT=64;		//图片高
	public static float PICXSPEED=4.5f;	//图片水平移动速度
	public static float PICYSPEED=2;	//图片垂直移动速度
}


2,MainActivity 显示SurfaceView


package com.example.sl.desktoppinball;

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

public class MainActivity extends Activity {

	private MySurfaceView sfv = null;

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		sfv = new MySurfaceView(MainActivity.this);
		requestWindowFeature(Window.FEATURE_NO_TITLE); // 设置屏幕显示没有title栏
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN); // 设置全屏
		setContentView(sfv);
	}

}


3, MySurfaceView                                                      


package com.example.sl.desktoppinball;

import com.example.sl.deskball.R;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.view.SurfaceHolder;
import android.view.SurfaceView;

public class MySurfaceView extends SurfaceView implements
		SurfaceHolder.Callback, Runnable {
	private SurfaceHolder sh;
	private MainActivity ma;
	private float[][] d = new float[2][2];// 用于记录小球一次位移的起始坐标
	private Canvas cv;
	private Paint paint;// 画笔
	private float picX = 0; // 图片x坐标
	private float picY = 0; // 图片y坐标
	private Boolean compX = null;// 判断起始坐标x的大小
	private Boolean compY = null;// 判断起始坐标y的大小
	private int flag = 0;// 标记,用于控制显示不同的小球
	int flag2 = 0;// 标记,用于控制小球的运动方向
	private Boolean isRunning = true;// 判断线程是否正在运行

	public MySurfaceView(Context context) {
		super(context);
		ma = (MainActivity) context;
		sh = this.getHolder();
		sh.addCallback(this);
		paint = new Paint();
	}

	public float getPicX() {
		return picX;
	}

	public void setPicX(float picX) {
		this.picX = picX;
	}

	public float getPicY() {
		return picY;
	}

	public void setPicY(float picY) {
		this.picY = picY;
	}

	public void setFlag(int flag) {
		this.flag = flag;
	}

	// 用于绘制图像,图形等
	public void doDrawView() {
		if (sh != null) {
			cv = sh.lockCanvas();// 锁定画布
			if (cv != null) {
				Bitmap bitmapBackGround = null;
				Bitmap bitmapDuke = null;
				switch (flag) {// 根据flag的值绘制不同的图片(此处为不同颜色的小球)
				case 1:
					bitmapBackGround = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.fp_1);
					cv.drawBitmap(bitmapBackGround, 0, 0, paint);

					bitmapDuke = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.w1);
					cv.drawBitmap(bitmapDuke, picX, picY, paint);
					break;
				case 2:
					bitmapBackGround = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.fp_2);
					cv.drawBitmap(bitmapBackGround, 0, 0, paint);

					bitmapDuke = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.w2);
					cv.drawBitmap(bitmapDuke, picX, picY, paint);
					break;
				case 3:
					bitmapBackGround = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.fp_3);
					cv.drawBitmap(bitmapBackGround, 0, 0, paint);

					bitmapDuke = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.w3);
					cv.drawBitmap(bitmapDuke, picX, picY, paint);
					break;
				default:
					bitmapBackGround = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.fp_2);
					cv.drawBitmap(bitmapBackGround, 0, 0, paint);

					bitmapDuke = BitmapFactory.decodeResource(
							ma.getResources(), R.drawable.w4);
					cv.drawBitmap(bitmapDuke, picX, picY, paint);
					break;
				}
				sh.unlockCanvasAndPost(cv);
			}
		}

	}

	@Override
	public void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {

	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		// 当surfaceView创建完成后启动画图线程
		new Thread(this).start();

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		isRunning = false;
		try {
			Thread.sleep(300);
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	// 记录前后两次位移的坐标
	private void storageXY(float x, float y) {
		d[0][0] = d[1][0];
		d[0][1] = d[1][1];
		d[1][0] = x;
		d[1][1] = y;
	}

	// 比较前后坐标x,y的大小,用以确定小球当前运动的方向
	private void compXY() {

		if ((d[1][0] - d[0][0]) > 0) {
			compX = true;
		} else if ((d[1][0] - d[0][0]) < 0)
			compX = false;
		if ((d[1][1] - d[0][1]) > 0) {
			compY = true;
		} else if ((d[1][1] - d[0][1]) < 0)
			compY = false;

	}

	// 画图线程
	@Override
	public void run() {
		while (isRunning) {
			while (true) {
				flag2 = 1; // 小球移动方向:1-->右上,2-->右下,3-->左上,4-->左下
				int flag1 = 0;// 控制不同小球的切换
				picX = 0;
				picY = MyConstant.SCREENHEIGHT - MyConstant.PICHEIGHT;
				while (flag2 < 5) {
					this.setPicX(picX);// 设置x坐标
					this.setPicY(picY);// 设置y坐标
					this.setFlag(flag1);// 设置flag1的值
					storageXY(picX, picY);// 记录前后两次位移的坐标
					doDrawView();// 通过坐标绘制图像
					switch (flag2) {
					case 1:// 右上
						picY = picY - MyConstant.PICYSPEED;
						picX = picX + MyConstant.PICXSPEED;
						flag1 = 1;
						break;
					case 2:// 右下
						picY = picY + MyConstant.PICYSPEED;
						picX = picX + MyConstant.PICXSPEED;
						flag1 = 2;
						break;
					case 3:// 左上
						picY = picY - MyConstant.PICYSPEED;
						picX = picX - MyConstant.PICXSPEED;
						flag1 = 3;
						break;
					case 4:// 左下
						picY = picY + MyConstant.PICYSPEED;
						picX = picX - MyConstant.PICXSPEED;
						flag1 = 4;
						break;
					}
					compXY();// 比较小球运动过程中其实位置的x,y
					if (picY <= 0) { // 到达屏幕上沿
						if (compX == true && compY == false) {
							flag2 = 2;
						}
						if (compX == false && compY == false) {
							flag2 = 4;
						}
					}
					if (picY >= MyConstant.SCREENHEIGHT - MyConstant.PICHEIGHT) {// 到达屏幕下沿
						if (compX == true && compY == true) {
							flag2 = 1;
						}
						if (compX == false && compY == true) {
							flag2 = 3;
						}
					}
					if (picX >= MyConstant.SCREENWIDTH - MyConstant.PICWIDTH) {// 到达屏幕右沿
						if (compX == true && compY == false) {
							flag2 = 3;
						}
						if (compX == true && compY == true) {
							flag2 = 4;
						}
					}
					if (picX <= 0) {// 到达屏幕左沿
						if (compX == false && compY == false) {
							flag2 = 1;
						}
						if (compX == false && compY == true) {
							flag2 = 2;
						}
					}

				}
			}
		}
	}

}


SurfaceHolder.Callback, Runnable


转载于:https://my.oschina.net/u/2393951/blog/488305

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值