目录
1.游戏的运行窗口主类
2.游戏的开机动画类
3.游戏的菜单类
4.游戏的关于界面
5.游戏的主界面
6.游戏的常量类
7.游戏的玩家类
8.游戏的玩家子弹类
9.游戏的怪兽类
10.游戏的BOSS子弹类
11.游戏运行截图
1.游戏的运行窗口主类
import android.app.Activity;
import android.app.ActivityManager;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Display;
import android.view.Window;
import android.view.WindowManager;
import android.content.pm.ActivityInfo;public class MainActivity extends Activity {public static int SCREEN_WIDTH; //屏幕的宽度public static int SCREEN_HEIGHT; //屏幕的高度private int message ; //定义一个整型变量,用于获取消息public Handler gameHandler = null; //定义Handler对象@Overridepublic void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE); //请求把屏幕设置成横屏requestWindowFeature(Window.FEATURE_NO_TITLE); //请求隐藏标题,设置全屏状态getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN); WindowManager wm = getWindowManager(); //获取WindowManager对象Display display = wm.getDefaultDisplay(); //实例化Display对象SCREEN_WIDTH = display.getWidth(); //获取屏幕的宽度SCREEN_HEIGHT = display.getHeight(); //获取屏幕的高度switchContentView(GameConstant.START_CARTOON); //每次当程序启动的时候,运行开机动画gameHandler = new Handler(){@Overridepublic void handleMessage(Message msg) {message = msg.what; //把消息赋值给messageswitchContentView(message); //根据message选择程序运行的视图}};}/*** 选择视图* @param gameState*/public void switchContentView(int gameState) {switch(gameState) {case GameConstant.START_CARTOON: //开机动画setContentView(new StartCartoonView(this));break;case GameConstant.GAME_MENU: //菜单界面setContentView(new MenuView(this));break;case GameConstant.START_GAME: //开始游戏setContentView(new GameView(this));break;case GameConstant.ABOUT_GAME: //关于游戏setContentView(new AboutView(this));break; case GameConstant.EXIT_GAME: //退出游戏finish();break;}}/*** 返回到菜单界面*/private void returnMenuView() {Message msg = new Message(); //实例化Message对象msg.what = GameConstant.GAME_MENU; //把菜单界面的常量赋值给msg.what gameHandler.sendMessage(msg); //给Handler发送消息}@Overridepublic void onBackPressed() {switch(message) { case GameConstant.GAME_MENU : //当界面显示的是MenuView的时候finish(); //结束程序break;case GameConstant.START_GAME: //当界面显示的是GameView的时候returnMenuView(); //返回菜单界面break;case GameConstant.ABOUT_GAME : //当界面显示的是AboutView的时候returnMenuView(); //返回菜单界面break;}}}
2.游戏的开机动画类
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Message;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;public class StartCartoonView extends SurfaceView implements Runnable, Callback {private Main main; //定义Main对象private int count=0; //开机动画的持续时间private Thread subThread = null; //定义一个线程private boolean subThreadFlag = true; //标志子线程循环运行private SurfaceHolder myHolder = null; //定义SurfaceHolder对象private Bitmap img_start_cartoon = null; //定义Bitmap对象public StartCartoonView(Context context) {super(context); //调用父类构造方法main = (Main)context; //实例化Main对象 subThread = new Thread(this); //实例化子线程myHolder = getHolder(); //获取SurfaceHolder对象实例myHolder.addCallback(this); //添加Callback接口}/*** 运行子线程*/public void run() {while(subThreadFlag) {count += 1; //开机动画的持续时间自增Canvas canvas = myHolder.lockCanvas(); //锁定画布if(canvas != null) { //判断画布不为空canvas.drawBitmap(img_start_cartoon, 0, 0, null); //绘制开机动画图myHolder.unlockCanvasAndPost(canvas); //解除画布锁定}if(count>3) { //判断开机动画的持续时间大于5Message msg = new Message(); //实例化Message对象msg.what = GameConstant.GAME_MENU; //把表示菜单界面的常量给msg.what赋值main.gameHandler.sendMessage(msg); //给Handler发送消息}try {Thread.sleep(1000); //线程每隔1秒运行一次} catch (InterruptedException e) {}}}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {//当SurfaceView实例尺寸改变时调用}public void surfaceCreated(SurfaceHolder holder) {//当SurfaceView实例创建时调用img_start_cartoon = BitmapFactory.decodeResource(getResources(),R.drawable.start_cartoon); //初始化背景图片subThread.start(); //启动子线程}public void surfaceDestroyed(SurfaceHolder holder) {//当SurfaceView实例销毁时调用subThreadFlag = false; //停止子线程循环count = 0; //开机动画时间清零}}
3.游戏的菜单类
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Message;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;public class MenuView extends SurfaceView implements Runnable, Callback {private Main main; //定义Main对象private Thread subThread = null; //定义一个线程private boolean subThreadFlag = true; //标志子线程循环运行private SurfaceHolder holder = null; //定义SurfaceHolder对象private Bitmap imgMenu = null; //定义Bitmap对象public MenuView(Context context) {super(context); //调用父类构造方法main = (Main)context; //实例化Main对象 subThread = new Thread(this); //实例化子线程holder = getHolder(); //获取SurfaceHolder对象实例holder.addCallback(this); //添加Callback接口}/*** 绘制菜单界面*/private void drawGameMenu() {Canvas canvas = holder.lockCanvas(); //锁定画布if(canvas != null) { //判断画布不为空canvas.drawBitmap(imgMenu, 0, 0, null); //绘制菜单背景图holder.unlockCanvasAndPost(canvas); //解除画布锁定}}/*** 运行子线程*/public void run() {while(subThreadFlag) {drawGameMenu(); //绘制菜单界面}}@Overridepublic boolean onTouchEvent(MotionEvent event) {float touchX = event.getX(); //获取用户点击屏幕的X坐标float touchY = event.getY(); //获取用户点击屏幕的Y坐标System.out.println("touchX:" +touchX + "touchY" +touchY);//先判断点击的事件是用户点击屏幕松口手的那一瞬间,再判断触摸的X坐标是否满足条件if(event.getAction() == MotionEvent.ACTION_DOWN && imgMenu.getWidth()*0.63 <= touchX && touchX <= imgMenu.getWidth()*0.9) {if(imgMenu.getHeight()*0.28 <= touchY && touchY <= imgMenu.getHeight()*0.42) {//开始游戏Message msg = new Message(); //实例化Message对象msg.what = GameConstant.START_GAME; //把开始游戏的常量给msg.what赋值main.gameHandler.sendMessage(msg); //给Handler发送消息} else if(imgMenu.getHeight()*0.48 <= touchY && touchY <= imgMenu.getHeight()*0.62) {//关于游戏Message msg = new Message(); //实例化Message对象msg.what = GameConstant.ABOUT_GAME; //把关于游戏的常量给msg.what赋值main.gameHandler.sendMessage(msg); //给Handler发送消息} else if(imgMenu.getHeight()*0.68 <= touchY && touchY <= imgMenu.getHeight()*0.82) {//退出游戏Message msg = new Message(); //实例化Message对象msg.what = GameConstant.EXIT_GAME; //把退出游戏的常量给msg.what赋值main.gameHandler.sendMessage(msg); //给Handler发送消息}}return super.onTouchEvent(event);}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {//当SurfaceView实例尺寸改变时调用}public void surfaceCreated(SurfaceHolder holder) {//当SurfaceView实例创建时调用imgMenu = BitmapFactory.decodeResource(getResources(), R.drawable.menu); //初始化背景图片subThread.start(); //启动子线程}public void surfaceDestroyed(SurfaceHolder holder) {//当SurfaceView实例销毁时调用subThreadFlag = false; //停止子线程循环}}
4.游戏的关于界面
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.view.SurfaceView;
import android.view.SurfaceHolder;
import android.graphics.BitmapFactory;
import android.view.SurfaceHolder.Callback;public class AboutView extends SurfaceView implements Runnable, Callback {private Thread subThread = null; //定义一个线程private boolean subThreadFlag = true; //标志子线程循环运行private SurfaceHolder myHolder = null; //定义SurfaceHolder对象private Bitmap img_about = null; //定义Bitmap对象public AboutView(Context context) {super(context); //调用父类构造方法subThread = new Thread(this); //实例化子线程myHolder = getHolder(); //获取SurfaceHolder对象实例myHolder.addCallback(this); //添加Callback接口}/*** 运行子线程*/public void run() {while(subThreadFlag) {Canvas canvas = myHolder.lockCanvas(); //锁定画布if(canvas != null) { //判断画布不为空canvas.drawBitmap(img_about, 0, 0, null); //绘制开机动画图myHolder.unlockCanvasAndPost(canvas); //解除画布锁定}}}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {//当SurfaceView实例尺寸改变时调用}public void surfaceCreated(SurfaceHolder holder) {//当SurfaceView实例创建时调用img_about = BitmapFactory.decodeResource(getResources(),R.drawable.about); //初始化背景图片subThread.start(); //启动子线程}public void surfaceDestroyed(SurfaceHolder holder) {//当SurfaceView实例销毁时调用subThreadFlag = false; //停止子线程循环}}
5.游戏的主界面
import java.util.ArrayList;
import java.util.Iterator;
import android.app.Service;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.SurfaceHolder.Callback;public class GameView extends SurfaceView implements Runnable, Callback {private Thread subThread = null; // 定义一个线程private boolean subThreadFlag = true; // 标志子线程循环运行private SurfaceHolder myHolder = null; // 定义SurfaceHolder对象private Bitmap imgBackground = null; // 背景图片private int backgroundX; // 背景图片的X坐标public int gameCustom = 1; // 游戏关卡,开始时默认第一关private int time = 0; // 定义一个时间来控制画怪兽鱼private int bossTime = 0; // 定义出现BOSS的时间private int customTime = 30; // 根据不同的关卡来控制出怪物的时间,开始的时候默认第一关private int customBossTime = 5000; // 出现BOSS的时间private int customBossTime2; // 出BOSS的时间private int coolingTime = 0; // 技能冷却时间private int bossBulletTime = 0; // 定义BOSS出子弹的时间private Player player; // 定义玩家对象private int orientation = 1; // BOSS的方向, 1往下走,2往上走private Bitmap imgPlayerBullet; // 玩家子弹图private Bitmap imgFish1; // 第一关的怪兽鱼private Bitmap imgFish2; // 第二关的怪兽鱼private Bitmap imgFish3; // 第三关的怪兽鱼private Bitmap imgBoss1; // 第一关的BOSSprivate Bitmap imgBoss2; // 第二关的BOSSprivate Bitmap imgBossBullet; // BOSS的子弹private Bitmap imgBossBullet2; // BOSS的子弹private Bitmap imgBossHP; // 血条private Bitmap imgBossHP1; // 空血条private Bitmap imgGameOver; // 游戏结束图private Bitmap imgGameWin; // 游戏胜利图private int boss1X; // BOSS的X坐标private int boss1Y; // BOSS的Y坐标private int boss1HP; // BOSS1血条private int boss2HP; // BOSS2血条private int boss2X; // BOSS2的X坐标private int boss2Y; // BOSS2的Y坐标private ArrayList<PlayerBullet> playerBulletList = new ArrayList<PlayerBullet>(); // 玩家子弹集合private ArrayList<Fish> fishList = new ArrayList<Fish>(); // 怪兽鱼的集合private ArrayList<BossBullet> bossBulletList = new ArrayList<BossBullet>(); // BOSS子弹集合private boolean bossFlag = false; // 标志出现BOSS的时候private boolean gameoverFlag = false; // 标志游戏结束private boolean gameCustom2Flag = false; // 进入下一关游戏private Sensor sensor; // 定义一个传感器private SensorManager sensorManager; // 定义传感器对象private SensorEventListener smListener; // 定义传感器监听对象public GameView(Context context) {super(context);initResourceImg(); // 初始化资源图片initData(); // 初始化数据sensorMethod(); // 传感器方法subThread = new Thread(this); // 实例化子线程myHolder = getHolder(); // 获取SurfaceHolder对象实例myHolder.addCallback(this); // 添加Callback接口}/*** 初始化图片资源*/private void initResourceImg() {imgBackground = BitmapFactory.decodeResource(getResources(),R.drawable.background); // 初始化背景图片imgPlayerBullet = BitmapFactory.decodeResource(getResources(),R.drawable.player_bullet); // 初始化玩家子弹imgFish1 = BitmapFactory.decodeResource(getResources(),R.drawable.fish1); // 初始化怪兽鱼1号imgFish2 = BitmapFactory.decodeResource(getResources(),R.drawable.fish2); // 初始化怪兽鱼2号imgFish3 = BitmapFactory.decodeResource(getResources(),R.drawable.fish3); // 初始化怪兽鱼3号imgBoss1 = BitmapFactory.decodeResource(getResources(),R.drawable.boss1); // 初始化Boss1imgBossBullet = BitmapFactory.decodeResource(getResources(),R.drawable.boss_bullet); // 初始化BOSS子弹imgBossBullet2 = BitmapFactory.decodeResource(getResources(),R.drawable.boss2_bullet); // 初始化BOSS子弹imgBossHP = BitmapFactory.decodeResource(getResources(),R.drawable.boss_hp); // 初始化BOSS血条imgBossHP1 = BitmapFactory.decodeResource(getResources(),R.drawable.boss_hp1); // 初始化BOSS空血条imgBoss2 = BitmapFactory.decodeResource(getResources(),R.drawable.longwang); // 初始化Boss2图imgGameOver = BitmapFactory.decodeResource(getResources(),R.drawable.gameover); // 初始化游戏结束图imgGameWin = BitmapFactory.decodeResource(getResources(),R.drawable.passgame);}/*** 初始化数据*/private void initData() {player = new Player(getContext()); // 实例化玩家对象boss1X = (int) (Main.SCREEN_WIDTH - imgBoss1.getWidth()); // 初始化BOSS的X坐标boss1Y = (int) Main.SCREEN_HEIGHT / 2; // 初始化BOSS的Y坐标boss1HP = 1000; // 初始化BOSS满血}/*** 传感器方法*/private void sensorMethod() {sensorManager = (SensorManager) getContext().getSystemService(Service.SENSOR_SERVICE); // 获取SensorManager对象sensor = sensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER); // 获取加速传感器smListener = new SensorEventListener() { // 监听传感器事件public void onAccuracyChanged(Sensor sensor, int accuracy) {// 传感器精度发生变化的时候调用}public void onSensorChanged(SensorEvent event) {// 传感器发生加速度分量值发生改变时调用float[] values = event.values;float sensorX = values[0];float sensorY = values[1];// 判断X轴方向的加速度是否大于Y轴方向的加速if (Math.abs(sensorX) > Math.abs(sensorY)) {if (sensorX > 0) { // 如果X轴传感加速度为正数player.playerY += 10;if (player.playerY + player.imgPlayerH >= Main.SCREEN_HEIGHT) {player.playerY -= 10;}} else if (sensorX < 0) { // 如果X轴传感加速度为负数player.playerY -= 10;if (player.playerY <= 0) {player.playerY += 10;}}} else {if (sensorY > 0) { // 如果Y轴传感加速度为正player.playerX += 10;if (player.playerX + player.imgPlayerW >= Main.SCREEN_WIDTH) {player.playerX -= 10;}} else if (sensorY < 0) { // 如果Y轴传感加速度为负player.playerX -= 10;if (player.playerX <= 0) {player.playerX += 10;}}}}};sensorManager.registerListener(smListener, sensor,SensorManager.SENSOR_DELAY_FASTEST); // 注册加速传感器的监听}/*** 玩家发子弹*/private void playerSendBullet() {synchronized (playerBulletList) { // 同步把玩家子弹放进集合中,保证线程的安全性if(player.fraction<10000) { //当玩家分数少于一万时PlayerBullet playerBullet = new PlayerBullet(imgPlayerBullet,(int) (player.playerX + player.imgPlayerW),player.playerY, 5, 0);// 子弹水平方向playerBulletList.add(playerBullet); // 把子弹添加到集合中去}else { PlayerBullet playerBullet1 = new PlayerBullet(imgPlayerBullet,(int) (player.playerX + player.imgPlayerW),player.playerY, 5, -4);// 子弹向上方向PlayerBullet playerBullet2 = new PlayerBullet(imgPlayerBullet,(int) (player.playerX + player.imgPlayerW),player.playerY, 5, 0);// 子弹水平方向PlayerBullet playerBullet3 = new PlayerBullet(imgPlayerBullet,(int) (player.playerX + player.imgPlayerW),player.playerY, 5, 4);// 子弹向下方向playerBulletList.add(playerBullet1); // 把第一颗子弹添加到集合中去playerBulletList.add(playerBullet2); // 把第二颗子弹添加到集合中去playerBulletList.add(playerBullet3); // 把第三颗子弹添加到集合中去}}}/*** 把集合中的子弹绘制在屏幕上*/private void drawPlayerBulletOnScreen(Canvas canvas) {synchronized (playerBulletList) { // 同步把玩家子弹放进集合中,保证线程的安全性for (Iterator<PlayerBullet> iterator = playerBulletList.iterator(); iterator.hasNext();) {PlayerBullet bullet = iterator.next(); // 用迭代的方法把子弹从集合中取出来bullet.drawPlayerBullet(canvas); // 绘制玩家子弹}}}/*** 往集合中不断的添加怪兽鱼*/private void addFishToList() {time++; // 让时间累加if (time > customTime) { // 判断时间是否大于关卡时间time = 0; // 重新计时synchronized (fishList) {switch (gameCustom) {case GameConstant.GAME_CUSTOM1: // 游戏的第一关Fish oneF1 = new Fish(imgFish1, getWidth(),(int) ((float) getHeight() / 4));Fish oneF2 = new Fish(imgFish1, getWidth(),(int) ((float) getHeight() / 2));Fish oneF3 = new Fish(imgFish1, getWidth(),(int) ((float) getHeight() / 1.2));fishList.add(oneF1); // 把第一条鱼添加到集合中去fishList.add(oneF2); // 把第二条鱼添加到集合中去fishList.add(oneF3); // 把第三条鱼添加到集合中去break;case GameConstant.GAME_CUSTOM2: // 游戏的第二关Fish twoF1 = new Fish(imgFish2, getWidth(),(int) ((float) getHeight() / 5));Fish twoF2 = new Fish(imgFish3, getWidth(),(int) ((float) getHeight() / 3.5));Fish threeF1 = new Fish(imgFish2, getWidth(),(int) ((float) getHeight() / 1.8));Fish threeF2 = new Fish(imgFish3, getWidth(),(int) ((float) getHeight() / 1.2));fishList.add(twoF1); // 把第一条鱼添加到集合中去fishList.add(threeF1); // 把第三条鱼添加到集合中去fishList.add(twoF2); // 把第二条鱼添加到集合中去fishList.add(threeF2); // 把第四条鱼添加到集合中去break;}}}}/*** 把集合中的鱼绘制在屏幕上*/private void drawFishOnScreen(Canvas canvas) {addFishToList(); // 先把怪兽鱼添加到集合中来synchronized (fishList) { // 同步怪兽鱼的线程for (Iterator<Fish> iterator = fishList.iterator(); iterator.hasNext();) {Fish fish = iterator.next(); // 用迭代的方法把怪兽鱼逐个的从集合中取出int random = (int) (Math.random() * 10); // 产生一个随机数fish.fishX -= random; // 随机移动怪兽鱼的X坐标if (random > 6) {fish.fishY += random; // 随机移动怪兽鱼的Y坐标if (fish.fishY + imgFish1.getHeight() >= getHeight()) {fish.fishY -= random;}} else {fish.fishY -= random; // 随机移动怪兽鱼的Y坐标if (fish.fishY <= 0) {fish.fishY += random;}}fish.drawFish(canvas); // 画怪兽鱼}}}/*** 把集合中的鱼绘制在屏幕上2*/private void drawFishOnScreen2(Canvas canvas) {addFishToList(); // 先把怪兽鱼添加到集合中来synchronized (fishList) {for (Iterator<Fish> iterator = fishList.iterator(); iterator.hasNext();) {Fish fish = iterator.next(); // 用迭代的方法把怪兽鱼逐个的从集合中取出int random = (int) (Math.random() * 10); // 产生一个随机数fish.fishX -= random; // 随机移动怪兽鱼的X坐标if (random > 6) {fish.fishY += random; // 随机移动怪兽鱼的Y坐标if (fish.fishY + imgFish1.getHeight() >= getHeight()) {fish.fishY -= random;}} else {fish.fishY -= random; // 随机移动怪兽鱼的Y坐标if (fish.fishY <= 0) {fish.fishY += random;}}fish.drawFish(canvas); // 画怪兽鱼}}}/*** 判断子弹是否打中怪兽鱼*/private void bulletHitFish() {synchronized (playerBulletList) { // 同步子弹线程synchronized (fishList) { // 同步怪兽鱼线程PlayerBullet playerBullet = null;Fish fish = null;for (PlayerBullet bullet : playerBulletList) {int bulletX = bullet.playerBulletX; // 获取该子弹对象的X坐标int bulletY = bullet.playerBulletY; // 获取该子弹对象的Y坐标for (Fish fishs : fishList) {int fishX = fishs.fishX; // 获取该怪兽鱼对象的X坐标int fishY = fishs.fishY; // 获取该怪兽鱼对象的Y坐标if (Math.abs(bulletX - fishX) <= 10&& Math.abs(bulletY - fishY) <= 10) { // 判断是否相撞playerBullet = bullet; // 把相撞的子弹对象赋值出去fish = fishs; // 把相撞的怪兽鱼对象赋值出去player.fraction += 100; // 将分数值自增100}}}playerBulletList.remove(playerBullet); // 把子弹从集合中移除fishList.remove(fish); // 把怪兽鱼从集合中移除}}}/*** 判断怪兽鱼是否碰撞到了玩家*/private void fishCollidePlayer() {synchronized (fishList) {Fish fish = null;for (Fish f : fishList) {int fishX = f.fishX;int fishY = f.fishY;if (Math.abs(fishX - player.playerX - player.imgPlayerW) <= 10&& Math.abs(fishY + (imgFish1.getHeight() / 2)- player.playerY - (player.imgPlayerH / 2)) <= 10) {fish = f;player.playerHP -= 30;}}fishList.remove(fish);}}/*** 判断BOSS1子弹是否打中玩家*/private void bossBulletHitPlayer() {synchronized (bossBulletList) {BossBullet bossBullet = null;for (BossBullet bb : bossBulletList) {int bossBulletX = bb.bossBulletX;int bossBulletY = bb.bossBulletY;if (Math.abs(bossBulletX - player.playerX - player.imgPlayerW) <= 10&& Math.abs(bossBulletY+ (bb.imgBullet.getHeight() / 2)- player.playerY - (player.imgPlayerH / 2)) <= 10) {bossBullet = bb;switch (gameCustom) {case GameConstant.GAME_CUSTOM1:player.playerHP -= 50; //玩家减血break;case GameConstant.GAME_CUSTOM2:player.playerHP -= 50; //玩家减血break;}}}bossBulletList.remove(bossBullet);}}/*** 判断玩家子弹是否打中BOSS*/private void playerBulletHitBoss() {synchronized (playerBulletList) {PlayerBullet playerBullet = null;for (PlayerBullet pb : playerBulletList) {int playerBulletX = pb.playerBulletX;int playerBulletY = pb.playerBulletY;switch (gameCustom) {case GameConstant.GAME_CUSTOM1:if (playerBulletX > boss1X && playerBulletX < getWidth()&& playerBulletY > boss1Y&& playerBulletY < boss1Y + imgBoss1.getHeight()) {playerBullet = pb; // 传递玩家子弹对象player.fraction += 200; // 玩家加分boss1HP -= 10; // BOSS减血}break;case GameConstant.GAME_CUSTOM2:if (playerBulletX > boss2X && playerBulletX < getWidth()&& playerBulletY > boss2Y&& playerBulletY < boss2Y + imgBoss2.getHeight()) {playerBullet = pb; // 传递玩家子弹对象player.fraction += 500; // 玩家加分boss2HP -= 20; // BOSS减血}break;}}playerBulletList.remove(playerBullet); // 移除玩家子弹}}/*** 往BOSS子弹集合中添加子弹*/private void addBossBulletToList() {switch (gameCustom) {case GameConstant.GAME_CUSTOM1:bossBulletTime++; // 发子弹的时间累加if (bossBulletTime > 30) { // 判断发子弹的时间是否大于10synchronized (bossBulletList) {BossBullet bossBullet1 = new BossBullet(imgBossBullet,boss1X,(int) (boss1Y + (imgBoss1.getHeight() / 2)), -5, -3);BossBullet bossBullet2 = new BossBullet(imgBossBullet,boss1X,(int) (boss1Y + (imgBoss1.getHeight() / 2)), -5, 0);BossBullet bossBullet3 = new BossBullet(imgBossBullet,boss1X,(int) (boss1Y + (imgBoss1.getHeight() / 2)), -5, 3);bossBulletList.add(bossBullet1);bossBulletList.add(bossBullet2);bossBulletList.add(bossBullet3);}bossBulletTime = 0; // 重新计时}break;case GameConstant.GAME_CUSTOM2:bossBulletTime++; // 发子弹的时间累加if (bossBulletTime > 10) {synchronized (bossBulletList) {BossBullet bossBullet2 = new BossBullet(imgBossBullet2,boss1X,(int) (boss2Y + (imgBoss2.getHeight() / 2)), -5, -4);BossBullet bossBullet1 = new BossBullet(imgBossBullet2,boss1X,(int) (boss2Y + (imgBoss2.getHeight() / 2)), -5, -2);BossBullet bossBullet3 = new BossBullet(imgBossBullet2,boss1X,(int) (boss2Y + (imgBoss2.getHeight() / 2)), -5, 0);BossBullet bossBullet4 = new BossBullet(imgBossBullet2,boss1X,(int) (boss2Y + (imgBoss2.getHeight() / 2)), -5, 2);BossBullet bossBullet5 = new BossBullet(imgBossBullet2,boss1X,(int) (boss2Y + (imgBoss2.getHeight() / 2)), -5, 4);bossBulletList.add(bossBullet1);bossBulletList.add(bossBullet2);bossBulletList.add(bossBullet3);bossBulletList.add(bossBullet4);bossBulletList.add(bossBullet5);}bossBulletTime = 0; // 重新计时}break;}}/*** BOSS1发子弹*/private void sendBossBullet(Canvas canvas) {addBossBulletToList(); // 先往集合中装子弹synchronized (bossBulletList) {for (Iterator<BossBullet> iterator = bossBulletList.iterator(); iterator.hasNext();) {BossBullet bossBullet = iterator.next();bossBullet.drawBossBullet(canvas);}}}/*** 绘制BOSS*/private void drawBoss(Canvas canvas) {switch (gameCustom) { // 判断关卡case GameConstant.GAME_CUSTOM1: // 游戏的第一关canvas.drawBitmap(imgBoss1, boss1X, boss1Y, null); // 绘制BOSSif (orientation == 1) { // 判断BOSS的方向boss1Y++; // 移动BOSS的Y坐标向下走} else if (orientation == 2) { // 判断BOSS的方向boss1Y--; // 移动BOSS的Y坐标向上走}if (boss1Y <= 0) { // 判断BOS的Y坐标是否小于等于0orientation = 1; // 改变BOSS的方向,往下走} else if (boss1Y + imgBoss1.getHeight() >= getHeight()) {orientation = 2; // 改变BOSS的方向,往上走}sendBossBullet(canvas); // BOSS发子弹int width = imgBossHP.getWidth() + 10;canvas.drawBitmap(imgBossHP1, getWidth() - width, 10, null); // 绘制空血条canvas.save(); // 先保存画布canvas.clipRect(getWidth() - width, 10,((getWidth() - width) + ((float) boss1HP / 1000)* imgBossHP.getWidth()), 10 + imgBossHP.getHeight()); // 剪切出一个矩形canvas.drawBitmap(imgBossHP, getWidth() - width, 10, null); // 画血条HPcanvas.restore(); // 恢复画布break;case GameConstant.GAME_CUSTOM2: // 游戏的第二关canvas.drawBitmap(imgBoss2, boss2X, boss2Y, null); // 绘制BOSSif (orientation == 1) { // 判断BOSS的方向boss2Y++; // 移动BOSS的Y坐标向下走} else if (orientation == 2) { // 判断BOSS的方向boss2Y--; // 移动BOSS的Y坐标向上走}if (boss2Y <= 0) { // 判断BOS的Y坐标是否小于等于0orientation = 1; // 改变BOSS的方向,往下走} else if (boss2Y + imgBoss2.getHeight() >= getHeight()) {orientation = 2; // 改变BOSS的方向,往上走}sendBossBullet(canvas); // BOSS发子弹int width2 = imgBossHP.getWidth() + 10;canvas.drawBitmap(imgBossHP1, getWidth() - width2, 10, null); // 绘制空血条canvas.save(); // 先保存画布canvas.clipRect(getWidth() - width2, 10,((getWidth() - width2) + ((float) boss2HP / 1000)* imgBossHP.getWidth()), 10 + imgBossHP.getHeight()); // 剪切出一个矩形canvas.drawBitmap(imgBossHP, getWidth() - width2, 10, null); // 画血条HPcanvas.restore(); // 恢复画布break;}}/*** 判断BOSS1是否出现了*/private void judgeBossAppear() {if (bossTime > customBossTime) { // 判断是否到了出BOSS时间bossFlag = true; // 标志着BOSS已经出现fishList.clear(); // 清空怪兽鱼集合}}/*** 判断BOSS2是否出现了*/private void judgeBoss2Appear() {if (bossTime > customBossTime2 || player.fraction>=100000) { // 判断是否到了出BOSS2的时间bossFlag = true; // 标志着BOSS已经出现fishList.clear(); // 清空怪兽鱼集合}}/*** 根据BOSS的血条判断通过游戏*/private void judgeGamePass(Canvas canvas) {if (boss1HP <= 0) { // 判断BOSS的血是否小于等于零,gameCustom = GameConstant.GAME_CUSTOM2; // 游戏进入第二关gameCustom2Flag = true; // 标志着进入下一关游戏bossFlag = false; // BOSS出现为假player.playerHP = 1000; // 让玩家满血player.fraction += 3000; //打死BOSS玩家加三千分time = 0; // 把控制出怪物的冷却时间清零customTime = 10; // 出怪物的时间间隔bossTime = 0; // 把计算出BOSS的时间清零customBossTime2 = 6000; // 出第二关BOSS的时间boss2HP = 1000; // 初始化第二关BOSS的血boss2X = (int) (Main.SCREEN_WIDTH - imgBoss2.getWidth()); // 初始化BOSS2的X坐标boss2Y = (int) (Main.SCREEN_HEIGHT / 2); // 初始化BOSS2的Y坐标bossBulletList.clear(); // BOSS子弹集合清零bossBulletTime = 0; // BOSS发子弹累加清零}}/*** 根据玩家血条判断游戏结束*/private void judgeGameOver(Canvas canvas) {if (player.playerHP <= 0) { // 判断玩家的血是否小于等于零canvas.drawBitmap(imgGameOver, 50, getHeight() / 3, null); // 画游戏结束图canvas.save(); // 保存画布gameoverFlag = true; // 标志游戏结束}}/*** 移动背景图片*/private void moveImgBackground() {// 判断背景图的X坐标是否小于背景图的宽度减去视图的宽度再减去5个像素if (backgroundX < imgBackground.getWidth() - getWidth() - 5) {backgroundX += 5; // 背景图的X自增5个像素if (backgroundX >= imgBackground.getWidth() - getWidth() - 5) {backgroundX = 0; // 重新定位背景图的X坐标}} else {backgroundX = 0; // 重新定位背景图的X坐标}}/*** 绘制游戏界面*/private void drawGameView() {if (!gameoverFlag) { // 如果游戏结束不为真Canvas canvas = myHolder.lockCanvas(); // 锁定画布if (canvas != null) { // 判断画布不为空Bitmap imgBackgrounds = Bitmap.createBitmap(imgBackground,backgroundX, 0, getWidth(), getHeight()); // 创建新的背景图片canvas.drawBitmap(imgBackgrounds, 0, 0, null); // 绘制游戏界面的背景图片moveImgBackground(); // 移动背景图片player.drawPlayer(canvas); // 画出玩家drawPlayerBulletOnScreen(canvas); // 画出子弹if (!gameCustom2Flag) { // 判断进入下一关是否为假judgeBossAppear(); // 判断BOSS是否出现if (!bossFlag) { // 判断如果BOSS没有出现drawFishOnScreen(canvas); // 画出怪兽鱼bulletHitFish(); // 判断子弹是否击中怪兽鱼fishCollidePlayer(); // 判断怪兽鱼是否碰撞到玩家} else if (bossFlag) {if (boss1HP > 0) {drawBoss(canvas); // 绘制BOSSbossBulletHitPlayer(); // 判断BOSS子弹是否打中玩家playerBulletHitBoss(); // 判断玩家子弹是否打中BOS}}judgeGamePass(canvas); // 判断游戏是否进入下一关} else { // 绘制第二关游戏界面judgeBoss2Appear();if (!bossFlag) {drawFishOnScreen2(canvas); // 绘制怪物鱼bulletHitFish(); // 判断子弹是否打中怪兽鱼fishCollidePlayer(); // 判断怪兽鱼是否碰撞到玩家} else if (bossFlag) {if (boss2HP > 0) {drawBoss(canvas); // 绘制BOSS2bossBulletHitPlayer(); // 判断BOSS子弹是否打中玩家playerBulletHitBoss(); // 判断玩家子弹是否打中BOS} else {canvas.drawBitmap(imgGameWin, 50, 100, null); // 画出游戏胜利canvas.save(); // 保存画布gameoverFlag = true; // 结束游戏}}}bossTime++; // 出现BOSS的时间自增coolingTime++; // 玩家技能冷却时间自增player.drawPlayerHP(canvas); // 画出玩家血条和分数值judgeGameOver(canvas); // 判断游戏是否结束myHolder.unlockCanvasAndPost(canvas); // 解除画布锁定}}}/*** 运行子线程*/public void run() {while (subThreadFlag) {drawGameView(); // 绘制游戏界面try {Thread.sleep(10);} catch (InterruptedException e) {}}}@Overridepublic boolean onTouchEvent(MotionEvent event) {// TODO Auto-generated method stubif (event.getAction() == MotionEvent.ACTION_DOWN) {switch (gameCustom) {case GameConstant.GAME_CUSTOM1: // 游戏第一关if (coolingTime > 12) { // 判断冷却时间是否大于12playerSendBullet(); // 玩家发子弹player.playerState = GameConstant.PLAYER_STATE1; // 把玩家发子弹时的状态赋值给玩家状态coolingTime = 0; // 重置技能冷却时间}break;case GameConstant.GAME_CUSTOM2: // 游戏第二关if (coolingTime > 8) { // 判断冷却时间是否大于8playerSendBullet(); // 玩家发子弹player.playerState = GameConstant.PLAYER_STATE1; // 把玩家发子弹时的状态赋值给玩家状态coolingTime = 0; // 重置技能冷却时间}break;}}return super.onTouchEvent(event);}public void surfaceChanged(SurfaceHolder holder, int format, int width,int height) {// 当SurfaceView实例尺寸改变时调用}public void surfaceCreated(SurfaceHolder holder) {// 当SurfaceView实例创建时调用backgroundX = 0; // 初始化背景图的X坐标subThread.start(); // 启动子线程}public void surfaceDestroyed(SurfaceHolder holder) {// 当SurfaceView实例销毁时调用subThreadFlag = false; // 停止子线程循环sensorManager.unregisterListener(smListener); // 取消传感器的注册监听}}
6.游戏的常量类
public class GameConstant {/** 开机动画、菜单的常量 */public final static int START_CARTOON = 110;public final static int GAME_MENU = 120;/** 开始游戏、关于游戏和退出游戏的常量 */public final static int START_GAME = 0;public final static int ABOUT_GAME = 1;public final static int EXIT_GAME = 2;/**玩家发子弹时候的状态*/public final static int PLAYER_STATE = 0;public final static int PLAYER_STATE1 = 1;/**游戏的关卡*/public final static int GAME_CUSTOM1 = 1;public final static int GAME_CUSTOM2 = 2;}
7.游戏的玩家类
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;public class Player {private Context context; //定义一个上下文public Bitmap imgPlayer; //玩家正常状态public Bitmap imgPlayer1; //玩家发子弹时的状态 public Bitmap imgPlayerHP; //玩家血条public Bitmap imgPlayerHP1; //玩家空血条public int imgPlayerW; //玩家图片的宽度public int imgPlayerH; //玩家图片的高度public int playerX; //玩家的X坐标public int playerY; //玩家的Y坐标public int playerState; //玩家的状态public int playerHP; //玩家的血条public int fraction = 0; //玩家的分数值public Paint paint; //定义画笔对象public Player(Context c) {context = c; //传递上下文给当前玩家类imgPlayer = BitmapFactory.decodeResource(context.getResources(), R.drawable.player); //初始化玩家图片imgPlayer1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.player1); //初始化玩家图片imgPlayerHP = BitmapFactory.decodeResource(context.getResources(), R.drawable.player_hp); //初始化玩家血条图片imgPlayerHP1 = BitmapFactory.decodeResource(context.getResources(), R.drawable.player_hp1); //初始化玩家空血条图片imgPlayerW = imgPlayer.getWidth(); //获取玩家图片宽度imgPlayerH = imgPlayer.getHeight(); //获取玩家图片的高度playerX = 100; //初始化玩家的X坐标playerY = 100; //初始化玩家的Y坐标playerState = 0; //初始化玩家状态playerHP = 1000; //初始化玩家的血条paint = new Paint(); //实例化画笔}/*** 绘制玩家* @param canvas*/public void drawPlayer(Canvas canvas) {switch(playerState) {case GameConstant.PLAYER_STATE: //玩家正常状态canvas.drawBitmap(imgPlayer, playerX, playerY, null); //根据X,Y坐标绘制玩家break; case GameConstant.PLAYER_STATE1: //玩家发子弹时的状态canvas.drawBitmap(imgPlayer1, playerX, playerY, null); //根据X,Y坐标绘制玩家playerState = GameConstant.PLAYER_STATE; //把玩家正常时的状态赋值给玩家状态break;}}/*** 绘制玩家血条和分数值* @param canvas*/public void drawPlayerHP(Canvas canvas) {paint.setColor(Color.YELLOW); //设置字体颜色paint.setTextSize(15); //设置字体大小paint.setAntiAlias(true); //消除锯齿canvas.drawText("HP ", 10 , 10 + imgPlayerHP.getHeight(), paint);canvas.drawBitmap(imgPlayerHP1, 35, 10, null); //绘制空血条canvas.save(); //先保存画布canvas.clipRect(35, 10, (35+((float)playerHP/1000)*imgPlayerHP.getWidth()),10 + imgPlayerHP.getHeight()); //剪切出一个矩形,大小为血条值的百分比乘以血条图的宽度canvas.drawBitmap(imgPlayerHP, 35, 10, null); //画血条HPcanvas.restore(); //恢复画布canvas.drawText("分数值:"+fraction, (40+imgPlayerHP.getWidth()),10 + imgPlayerHP.getHeight(), paint); //画出分数值}}
8.游戏的玩家子弹类
import android.graphics.Bitmap;
import android.graphics.Canvas;public class PlayerBullet {public Bitmap imgBullet; //玩家子弹public int playerBulletX; //玩家子弹的X坐标public int playerBulletY; //玩家子弹的Y坐标public int bulletSpeedX; //玩家子弹的X加速度public int bulletSpeedY; //玩家子弹的Y加速度public PlayerBullet(Bitmap bitmap, int x, int y, int speedX, int speedY) {imgBullet = bitmap; //把传递过来的图片赋值给子弹图片playerBulletX = x; //把传递过来的X坐标赋值给子弹X坐标playerBulletY = y; //把传递过来的Y坐标赋值给子弹Y坐标bulletSpeedX = speedX; //把传递过来的值赋值给子弹X加速度bulletSpeedY = speedY; //把传递过来的值赋值给子弹Y加速度}/*** 绘制玩家子弹* @param canvas*/public void drawPlayerBullet(Canvas canvas) {playerBulletX += bulletSpeedX; //把当前玩家子弹的X坐标加上传递过来的加速度再赋值给玩家的X坐标playerBulletY += bulletSpeedY; //把当前玩家子弹的Y坐标加上传递过来的加速度再赋值给玩家的Y坐标canvas.drawBitmap(imgBullet, playerBulletX, playerBulletY, null); //绘制玩家子弹}
}
9.游戏的怪兽类
import android.graphics.Bitmap;
import android.graphics.Canvas;public class Fish {private Bitmap imgFish; //怪兽鱼public int fishX; //怪兽鱼的X坐标public int fishY; //怪兽鱼的Y坐 标public Fish(Bitmap bitmap, int x, int y) {imgFish = bitmap; //把传递过来的图片赋值给怪兽鱼fishX = x; //把传递过来的X坐标赋值给怪兽鱼的X坐标fishY = y; //把传递过来的Y坐标赋值给怪兽鱼的Y坐标}/*** 绘制怪兽鱼* @param canvas*/public void drawFish(Canvas canvas) {canvas.drawBitmap(imgFish, fishX, fishY, null); //画怪兽鱼}
}
10.游戏的BOSS子弹类
import android.graphics.Bitmap;
import android.graphics.Canvas;public class BossBullet {public Bitmap imgBullet;public int bossBulletX;public int bossBulletY;public int bossBulletSpeedX;public int bossBulletSpeedY;public BossBullet (Bitmap bitmap, int x, int y, int speedX, int speedY) {imgBullet = bitmap;bossBulletX = x;bossBulletY = y;bossBulletSpeedX = speedX;bossBulletSpeedY = speedY;}/*** 绘制BOSS子弹* @param canvas*/public void drawBossBullet(Canvas canvas) {bossBulletX += bossBulletSpeedX;bossBulletY += bossBulletSpeedY;canvas.drawBitmap(imgBullet, bossBulletX, bossBulletY, null);}
}
11.游戏运行截图
源码下载