⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mysurfaceview.java

📁 Android开发精典案例60个
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
package com.bg;

import org.jbox2d.collision.AABB;
import org.jbox2d.collision.CircleDef;
import org.jbox2d.collision.PolygonDef;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.ContactListener;
import org.jbox2d.dynamics.World;
import org.jbox2d.dynamics.contacts.ContactPoint;
import org.jbox2d.dynamics.contacts.ContactResult;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.util.Log;
import android.view.KeyEvent;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;

public class MySurfaceView extends SurfaceView implements Callback, Runnable, ContactListener {
	private Thread th;
	private SurfaceHolder sfh;
	private Canvas canvas;
	private Paint paint;
	private boolean flag;
	// ----添加一个物理世界---->>
	private final float RATE = 30;// 屏幕到现实世界的比例 30px:1m;
	private World world;// 声明一个物理世界对象
	private AABB aabb;// 声明一个物理世界的范围对象
	private Vec2 gravity;// 声明一个重力向量对象
	private float timeStep = 1f / 60f;// 物理世界模拟的的频率
	private int iterations = 10;// 迭代值,迭代越大模拟越精确,但性能越低
	// 声明小球的Body,便于后续对小球进行操作
	private Body bodyBall;
	//声明胜利与失败的body,用于判定游戏的胜负
	private Body lostBody1, lostBody2, winBody;
	// 声明屏幕宽高
	private int screenW, screenH;
	// 声明游戏状态
	private final int GAMESTATE_MENU = 0;
	private final int GAMESTATE_HELP = 1;
	private final int GAMESTATE_GAMEING = 2;
	private int gameState = GAMESTATE_MENU;
	// 为了游戏暂停时,失败,胜利能继续可能到游戏中的状态,所以并没有将其写成一个状态
	private boolean gameIsPause, gameIsLost, gameIsWin;
	// Body图片资源
	private Bitmap bmpH, bmpS, bmpSh, bmpSs, bmpBall;
	// 菜单、按钮、游戏背景图片资源
	private Bitmap bmpMenu_help, bmpMenu_play, bmpMenu_exit, bmpMenu_resume, bmpMenu_replay, bmp_menubg, bmp_gamebg, bmpMenuBack, bmp_smallbg, bmpMenu_menu,
			bmp_helpbg, bmpBody_lost, bmpBody_win, bmpWinbg, bmpLostbg;
	// 创建按钮
	private HButton hbHelp, hbPlay, hbExit, hbResume, hbReplay, hbBack, hbMenu;

	public MySurfaceView(Context context) {
		super(context);
		this.setKeepScreenOn(true);
		sfh = this.getHolder();
		sfh.addCallback(this);
		paint = new Paint();
		paint.setAntiAlias(true);
		paint.setStyle(Style.STROKE);
		this.setFocusable(true);
		this.setFocusableInTouchMode(true);
		// --添加一个物理世界--->>
		aabb = new AABB();
		gravity = new Vec2(0, 10);
		aabb.lowerBound.set(-100, -100);
		aabb.upperBound.set(100, 100);
		world = new World(aabb, gravity, true);
		// ---实例化Body图片资源
		bmpH = BitmapFactory.decodeResource(getResources(), R.drawable.h);
		bmpS = BitmapFactory.decodeResource(getResources(), R.drawable.s);
		bmpSh = BitmapFactory.decodeResource(getResources(), R.drawable.sh);
		bmpSs = BitmapFactory.decodeResource(getResources(), R.drawable.ss);
		bmpBall = BitmapFactory.decodeResource(getResources(), R.drawable.ball);
		// 实例菜单、按钮、游戏背景图片资源
		bmpMenu_help = BitmapFactory.decodeResource(getResources(), R.drawable.menu_help);
		bmpMenu_play = BitmapFactory.decodeResource(getResources(), R.drawable.menu_play);
		bmpMenu_exit = BitmapFactory.decodeResource(getResources(), R.drawable.menu_exit);
		bmpMenu_resume = BitmapFactory.decodeResource(getResources(), R.drawable.menu_resume);
		bmpMenu_replay = BitmapFactory.decodeResource(getResources(), R.drawable.menu_replay);
		bmp_menubg = BitmapFactory.decodeResource(getResources(), R.drawable.menu_bg);
		bmp_gamebg = BitmapFactory.decodeResource(getResources(), R.drawable.game_bg);
		bmpMenuBack = BitmapFactory.decodeResource(getResources(), R.drawable.menu_back);
		bmp_smallbg = BitmapFactory.decodeResource(getResources(), R.drawable.smallbg);
		bmpMenu_menu = BitmapFactory.decodeResource(getResources(), R.drawable.menu_menu);
		bmp_helpbg = BitmapFactory.decodeResource(getResources(), R.drawable.helpbg);
		bmpBody_lost = BitmapFactory.decodeResource(getResources(), R.drawable.lostbody);
		bmpBody_win = BitmapFactory.decodeResource(getResources(), R.drawable.winbody);
		bmpWinbg = BitmapFactory.decodeResource(getResources(), R.drawable.gamewin);
		bmpLostbg = BitmapFactory.decodeResource(getResources(), R.drawable.gamelost);
	}
	//SurfaceView创建
	public void surfaceCreated(SurfaceHolder holder) {
		//防止Home按键导致游戏重置
		if (gameState == GAMESTATE_MENU) {
			screenW = this.getWidth();
			screenH = this.getHeight();
			// 实例化按钮
			hbPlay = new HButton(bmpMenu_play, screenW / 2 - bmpMenu_help.getWidth() / 2, 150);
			hbHelp = new HButton(bmpMenu_help, hbPlay.getX(), hbPlay.getY() + 50);
			hbExit = new HButton(bmpMenu_exit, hbPlay.getX(), hbHelp.getY() + 50);
			hbBack = new HButton(bmpMenuBack, 0, screenH - bmpMenu_help.getHeight());
			hbResume = new HButton(bmpMenu_resume, screenW / 2 - bmpMenu_help.getWidth() / 2, 200);
			hbReplay = new HButton(bmpMenu_replay, hbResume.getX(), hbResume.getY() + 50);
			hbMenu = new HButton(bmpMenu_menu, hbResume.getX(), hbReplay.getY() + 50);
			// 创建主角小球
			bodyBall = createCircle(bmpBall, bmpH.getHeight(), bmpH.getHeight(), bmpBall.getWidth() / 2, 5);
			//创建胜负Body
			lostBody1 = createCircle(bmpBody_lost, screenW - bmpH.getHeight() - bmpBody_lost.getWidth(), bmpH.getHeight(), bmpBody_lost.getWidth() / 2, 0);
			lostBody2 = createCircle(bmpBody_lost, bmpH.getHeight(), screenH - bmpH.getHeight() - bmpBody_lost.getHeight(), bmpBody_lost.getWidth() / 2, 0);
			winBody = createCircle(bmpBody_win, screenW - bmpH.getHeight() - bmpBody_win.getWidth(), screenH - bmpH.getHeight() - bmpBody_win.getHeight(),
					bmpBody_win.getWidth() / 2, 0);
			//设置传感器,发生碰撞,但无碰撞效果
			lostBody1.getShapeList().m_isSensor = true;
			lostBody2.getShapeList().m_isSensor = true;
			winBody.getShapeList().m_isSensor = true;
			// 创建边界
			createRect(bmpH, 0, 0, bmpH.getWidth(), bmpH.getHeight(), 0);// 上
			createRect(bmpH, 0, getHeight() - bmpH.getHeight(), bmpH.getWidth(), bmpH.getHeight(), 0);// 下
			createRect(bmpS, 0, 0, bmpS.getWidth(), bmpS.getHeight(), 0);// 左
			createRect(bmpS, getWidth() - bmpS.getWidth(), 0, bmpS.getWidth(), bmpS.getHeight(), 0);// 右
			// -----创建障碍物
			createRect(bmpSh, 0, 90, bmpSh.getWidth(), bmpSh.getHeight(), 0);
			createRect(bmpSh, 110, 170, bmpSh.getWidth(), bmpSh.getHeight(), 0);
			createRect(bmpSs, 110, 170, bmpSs.getWidth(), bmpSs.getHeight(), 0);
			createRect(bmpSs, getWidth() - 102, screenH - bmpSs.getHeight(), bmpSs.getWidth(), bmpSs.getHeight(), 0);
			//绑定监听器
			world.setContactListener(this);
		}
		flag = true;
		th = new Thread(this);
		th.start();
	}

	//在物理世界中添加矩形Body
	public Body createRect(Bitmap bmp, float x, float y, float w, float h, float density) {
		PolygonDef pd = new PolygonDef();
		pd.density = density;
		pd.friction = 0.8f;
		pd.restitution = 0.3f;
		pd.setAsBox(w / 2 / RATE, h / 2 / RATE);
		BodyDef bd = new BodyDef();
		bd.position.set((x + w / 2) / RATE, (y + h / 2) / RATE);
		Body body = world.createBody(bd);
		body.m_userData = new MyRect(bmp, x, y);
		body.createShape(pd);
		body.setMassFromShapes();
		return body;
	}

	//在物理世界中添加圆形Body
	public Body createCircle(Bitmap bmp, float x, float y, float r, float density) {
		CircleDef cd = new CircleDef();
		cd.density = density;
		cd.friction = 0.8f;
		cd.restitution = 0.3f;
		cd.radius = r / RATE;
		BodyDef bd = new BodyDef();
		bd.position.set((x + r) / RATE, (y + r) / RATE);
		Body body = world.createBody(bd);
		body.m_userData = new MyCircle(bmp, x, y, r);
		body.createShape(cd);
		body.setMassFromShapes();
		//放置小球进入休眠,导致改变重力方向,小球无法移动
		body.allowSleeping(false);
		return body;
	}

	public void myDraw() {
		try {
			canvas = sfh.lockCanvas();
			canvas.drawColor(Color.BLACK);
			switch (gameState) {
			case GAMESTATE_MENU:
				//绘制主菜单背景
				canvas.drawBitmap(bmp_menubg, 0, 0, paint);
				//绘制Play按钮
				hbPlay.draw(canvas, paint);
				//绘制Help按钮
				hbHelp.draw(canvas, paint);
				//绘制Exit按钮
				hbExit.draw(canvas, paint);
				break;
			case GAMESTATE_HELP:
				//绘制帮助界面背景
				canvas.drawBitmap(bmp_helpbg, 0, 0, paint);
				//绘制Back按钮
				hbBack.draw(canvas, paint);
				break;
			case GAMESTATE_GAMEING:
				//绘制游戏背景
				canvas.drawBitmap(bmp_gamebg, 0, 0, paint);
				//遍历物理世界中所有存在的Body;
				Body body = world.getBodyList();
				for (int i = 1; i < world.getBodyCount(); i++) {
					if ((body.m_userData) instanceof MyRect) {
						MyRect rect = (MyRect) (body.m_userData);
						rect.drawMyRect(canvas, paint);
					} else if ((body.m_userData) instanceof MyCircle) {
						MyCircle mcc = (MyCircle) (body.m_userData);
						mcc.drawArc(canvas, paint);
					}
					body = body.m_next;
				}
				//当游戏暂停或失败或成功时
				if (gameIsPause || gameIsLost || gameIsWin) {
					// 当游戏暂停或失败或成功时画一个半透明黑色矩形,突出界面
					Paint paintB = new Paint();
					paintB.setAlpha(0x77);
					canvas.drawRect(0, 0, screenW, screenH, paintB);
				}
				// 游戏暂停
				if (gameIsPause) {
					//绘制暂停背景
					canvas.drawBitmap(bmp_smallbg, screenW / 2 - bmp_smallbg.getWidth() / 2, screenH / 2 - bmp_smallbg.getHeight() / 2, paint);
					//绘制Resume按钮
					hbResume.draw(canvas, paint);
					//绘制Replay按钮
					hbReplay.draw(canvas, paint);
					//绘制Menu按钮
					hbMenu.draw(canvas, paint);
				} else
				//游戏失败
				if (gameIsLost) {
					//绘制游戏背景
					canvas.drawBitmap(bmpLostbg, screenW / 2 - bmpLostbg.getWidth() / 2, screenH / 2 - bmpLostbg.getHeight() / 2, paint);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -