【android游戏】海底世界

2023-10-16 03:10
文章标签 android 世界 游戏 海底

本文主要是介绍【android游戏】海底世界,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

目录

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.游戏运行截图

  

源码下载

这篇关于【android游戏】海底世界的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/218603

相关文章

揭秘世界上那些同时横跨两大洲的国家

我们在《世界人口过亿的一级行政区分布》盘点全球是那些人口过亿的一级行政区。 现在我们介绍五个横跨两州的国家,并整理七大洲和这些国家的KML矢量数据分析分享给大家,如果你需要这些数据,请在文末查看领取方式。 世界上横跨两大洲的国家 地球被分为七个大洲分别是亚洲、欧洲、北美洲、南美洲、非洲、大洋洲和南极洲。 七大洲示意图 其中,南极洲是无人居住的大陆,而其他六个大洲则孕育了众多国家和

Android实现任意版本设置默认的锁屏壁纸和桌面壁纸(两张壁纸可不一致)

客户有些需求需要设置默认壁纸和锁屏壁纸  在默认情况下 这两个壁纸是相同的  如果需要默认的锁屏壁纸和桌面壁纸不一样 需要额外修改 Android13实现 替换默认桌面壁纸: 将图片文件替换frameworks/base/core/res/res/drawable-nodpi/default_wallpaper.*  (注意不能是bmp格式) 替换默认锁屏壁纸: 将图片资源放入vendo

Android平台播放RTSP流的几种方案探究(VLC VS ExoPlayer VS SmartPlayer)

技术背景 好多开发者需要遴选Android平台RTSP直播播放器的时候,不知道如何选的好,本文针对常用的方案,做个大概的说明: 1. 使用VLC for Android VLC Media Player(VLC多媒体播放器),最初命名为VideoLAN客户端,是VideoLAN品牌产品,是VideoLAN计划的多媒体播放器。它支持众多音频与视频解码器及文件格式,并支持DVD影音光盘,VCD影

国产游戏崛起:技术革新与文化自信的双重推动

近年来,国产游戏行业发展迅猛,技术水平和作品质量均得到了显著提升。特别是以《黑神话:悟空》为代表的一系列优秀作品,成功打破了过去中国游戏市场以手游和网游为主的局限,向全球玩家展示了中国在单机游戏领域的实力与潜力。随着中国开发者在画面渲染、物理引擎、AI 技术和服务器架构等方面取得了显著进展,国产游戏正逐步赢得国际市场的认可。然而,面对全球游戏行业的激烈竞争,国产游戏技术依然面临诸多挑战,未来的

android-opencv-jni

//------------------start opencv--------------------@Override public void onResume(){ super.onResume(); //通过OpenCV引擎服务加载并初始化OpenCV类库,所谓OpenCV引擎服务即是 //OpenCV_2.4.3.2_Manager_2.4_*.apk程序包,存

从状态管理到性能优化:全面解析 Android Compose

文章目录 引言一、Android Compose基本概念1.1 什么是Android Compose?1.2 Compose的优势1.3 如何在项目中使用Compose 二、Compose中的状态管理2.1 状态管理的重要性2.2 Compose中的状态和数据流2.3 使用State和MutableState处理状态2.4 通过ViewModel进行状态管理 三、Compose中的列表和滚动

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标了,所以就需要看下mtk的camera2的相关横屏保存图片功能, 如何实现实现横屏保存图片功能 如图所示: 2.mtk

android应用中res目录说明

Android应用的res目录是一个特殊的项目,该项目里存放了Android应用所用的全部资源,包括图片、字符串、颜色、尺寸、样式等,类似于web开发中的public目录,js、css、image、style。。。。 Android按照约定,将不同的资源放在不同的文件夹中,这样可以方便的让AAPT(即Android Asset Packaging Tool , 在SDK的build-tools目

Android fill_parent、match_parent、wrap_content三者的作用及区别

这三个属性都是用来适应视图的水平或者垂直大小,以视图的内容或尺寸为基础的布局,比精确的指定视图的范围更加方便。 1、fill_parent 设置一个视图的布局为fill_parent将强制性的使视图扩展至它父元素的大小 2、match_parent 和fill_parent一样,从字面上的意思match_parent更贴切一些,于是从2.2开始,两个属性都可以使用,但2.3版本以后的建议使

Android Environment 获取的路径问题

1. 以获取 /System 路径为例 /*** Return root of the "system" partition holding the core Android OS.* Always present and mounted read-only.*/public static @NonNull File getRootDirectory() {return DIR_ANDR