欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Java開發(fā)實(shí)現(xiàn)飛機(jī)大戰(zhàn)

 更新時(shí)間:2022年05月07日 15:22:49   作者:小孫仗劍走天涯  
這篇文章主要為大家詳細(xì)介紹了Java開發(fā)實(shí)現(xiàn)飛機(jī)大戰(zhàn),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了Java實(shí)現(xiàn)飛機(jī)大戰(zhàn)的具體代碼,供大家參考,具體內(nèi)容如下

一、飛機(jī)大戰(zhàn)

1 封裝所有飛行物公共屬性和功能的父類

import java.awt.image.BufferedImag

/**
?* 封裝所有飛行物的公共屬性和功能的父類
?*/
public abstract class Flyer {
? ? protected int x; //飛行物左上角x坐標(biāo)
? ? protected int y; //飛行物左上角y坐標(biāo)
? ? protected int height; //飛行物的高度
? ? protected int width; //飛行物的寬度
? ? protected BufferedImage image; //飛行物的圖片

? ? /**
? ? ?* 要求所有飛行物必須都能移動(dòng)
? ? ?* 但移動(dòng)的方式由子類自己實(shí)現(xiàn)
? ? ?*/
? ? public abstract void step();

? ? /**
? ? ?* 檢查越界的方法
? ? ?* @return 是否越界
? ? ?*/
? ? public abstract boolean outOfBounds();

? ? /**
? ? ?* 專門檢測(cè)兩個(gè)矩形飛行物是否碰撞的工具方法
? ? ?* 和具體對(duì)象無關(guān),所以定義為靜態(tài)方法
? ? ?* @param f1 飛行對(duì)象1
? ? ?* @param f2 飛行對(duì)象2
? ? ?* @return 是否碰撞
? ? ?*/
? ? public static boolean boom(Flyer f1,Flyer f2){
? ? ? ? //step1: 求出兩個(gè)矩形的中心點(diǎn)
? ? ? ? int f1x = f1.x + f1.width/2;
? ? ? ? int f1y = f1.y + f1.height/2;
? ? ? ? int f2x = f2.x + f2.width/2;
? ? ? ? int f2y = f2.y + f2.height/2;
? ? ? ? //step2: 橫向和縱向碰撞檢測(cè)
? ? ? ? boolean H = Math.abs(f1x - f2x) < (f1.width + f2.width)/2;
? ? ? ? boolean V = Math.abs(f1y -f2y) < (f1.height + f2.height)/2;
? ? ? ? //step3: 必須兩個(gè)方向同時(shí)碰撞
? ? ? ? return H&V;
? ? }

}

2 封裝英雄機(jī)屬性和功能類

import java.util.Random;

/**
?* 封裝英雄機(jī)的屬性和功能類
?*/
public class Hero extends Flyer {

? ? private int doubleFire; //雙倍火力子彈數(shù)
? ? private int life; //生命值
? ? private int score; //得分

? ? //對(duì)外提供讀取生命值的方法
? ? public int getLife(){
? ? ? ? return life;
? ? }

? ? //對(duì)外提供的獲取得分的方法
? ? public int getScore(){
? ? ? ? return score;
? ? }

? ? /**
? ? ?* 英雄機(jī)對(duì)象的無參構(gòu)造方法
? ? ?*/
? ? public Hero(){
? ? ? ? image = ShootGame.hero0;
? ? ? ? height = image.getHeight();
? ? ? ? width = image.getWidth();
? ? ? ? x = 127;
? ? ? ? y = 388;
? ? ? ? doubleFire = 0;
? ? ? ? life = 3;
? ? ? ? score = 0;
? ? }

? ? /**
? ? ?* 實(shí)現(xiàn)英雄機(jī)的動(dòng)畫效果的方法
? ? ?* 讓英雄機(jī)的圖片在hero0和hero1之斗切換
? ? ?*/
? ? @Override
? ? public void step() {
? ? ? ? Random r = new Random();
? ? ? ? if(r.nextInt(2) == 0){
? ? ? ? ? ? image = ShootGame.hero0;
? ? ? ? }else{
? ? ? ? ? ? image = ShootGame.hero1;
? ? ? ? }
? ? }

? ? @Override
? ? public boolean outOfBounds() {
? ? ? ? // TODO Auto-generated method stub
? ? ? ? return false;
? ? }

? ? /**
? ? ?* 英雄機(jī)隨鼠標(biāo)移動(dòng)的方法
? ? ?* 要求傳入鼠標(biāo)當(dāng)前的位置
? ? ?* @param x 鼠標(biāo)位置的x坐標(biāo)
? ? ?* @param y 鼠標(biāo)位置的y坐標(biāo)
? ? ?*/
? ? public void move(int x,int y){
? ? ? ? //傳入的x,y是鼠標(biāo)的坐標(biāo)
? ? ? ? //move的作用是讓英雄機(jī)的中心位置和鼠標(biāo)位置一致
? ? ? ? this.x = x - width / 2;
? ? ? ? this.y = y - height / 2;
? ? }

? ? /**
? ? ?* 英雄機(jī)獲得分?jǐn)?shù)或獎(jiǎng)勵(lì)的方法
? ? ?* @param f 是一個(gè)飛行物父類方法,可以指向敵機(jī)或者大飛機(jī)
? ? ?*/
? ? public void getScore_Award(Flyer f){
? ? ? ? //先判斷敵人對(duì)象的類型
? ? ? ? if(f instanceof Airplane){ //如果敵人是敵機(jī)
? ? ? ? ? ? //獲得敵機(jī)對(duì)象中的分?jǐn)?shù),加到當(dāng)現(xiàn)分?jǐn)?shù)上
? ? ? ? ? ? score += ((Airplane)f).getScore();
? ? ? ? }else{ //如果對(duì)象是大飛機(jī)
? ? ? ? ? ? //繼續(xù)判斷大飛機(jī)對(duì)象中保存的獎(jiǎng)勵(lì)類型
? ? ? ? ? ? if(((BigPlane)f).getAwardType() == BigPlane.DOUBLE_FIRE){
? ? ? ? ? ? ? ? //如果保存的是雙倍火力
? ? ? ? ? ? ? ? doubleFire += 20;
? ? ? ? ? ? }else{
? ? ? ? ? ? ? ? //如果保存的是生命值獎(jiǎng)勵(lì)
? ? ? ? ? ? ? ? life += 1;
? ? ? ? ? ? }
? ? ? ? }

? ? }

? ? /**
? ? ?* 英雄機(jī)發(fā)射子彈的方法
? ? ?* @return 新創(chuàng)建出來的子彈對(duì)名
? ? ?* ? ? ? ? ?可能是一發(fā),也可能 是兩發(fā),用數(shù)組保存
? ? ?*/
? ? public Bullet[] shoot(){
? ? ? ? Bullet[] bullets = null;
? ? ? ? //何時(shí)開啟雙倍火力:
? ? ? ? if(doubleFire != 0){ //創(chuàng)建雙倍火力
? ? ? ? ? ? bullets = new Bullet[2];
? ? ? ? ? ? Bullet b1 = new Bullet(x + width/4 - ShootGame.bullet.getWidth()/2,y + ShootGame.bullet.getWidth());
? ? ? ? ? ? Bullet b2 = new Bullet(x + width*3/4 - ShootGame.bullet.getWidth()/2,y + ShootGame.bullet.getWidth());
? ? ? ? ? ? bullets[0] = b1;
? ? ? ? ? ? bullets[1] = b2;
? ? ? ? ? ? //每創(chuàng)建一個(gè)雙倍火力,doubleFire-1
? ? ? ? ? ? doubleFire -= 1;
? ? ? ? }else{
? ? ? ? ? ? //單倍火力:
? ? ? ? ? ? //子彈x坐標(biāo):x+英雄機(jī)寬度/2-子彈寬度/2
? ? ? ? ? ? //子彈y坐標(biāo):y-子彈高度
? ? ? ? ? ? bullets = new Bullet[1];
? ? ? ? ? ? bullets[0] = new Bullet(x + width/2 - ShootGame.bullet.getWidth()/2,y - ShootGame.bullet.getHeight());
? ? ? ? }
? ? ? ? return bullets;
? ? }

? ? /**
? ? ?* 英雄機(jī)自帶和敵人碰撞檢測(cè)方法
? ? ?* @param f 可能發(fā)生碰撞的敵人
? ? ?* ? ? ? ? ?可能是敵機(jī)也可能是大飛機(jī)
? ? ?* @return 是否碰撞
? ? ?*/
? ? public boolean hit(Flyer f){
? ? ? ? //調(diào)用碰撞檢測(cè)方法,檢測(cè)是否碰撞
? ? ? ? boolean r = Flyer.boom(this, f);
? ? ? ? if(r){ //如果碰撞
? ? ? ? ? ? life--;
? ? ? ? ? ? doubleFire = 0;
? ? ? ? }
? ? ? ? return r;
? ? }

}

3 封裝敵機(jī)屬性和功能的類

import java.util.Random;

/**
?* 封裝敵機(jī)屬性和功能的類
?*/
public class Airplane extends Flyer {

? ? private int speed = 2; //敵機(jī)每次下落2個(gè)單位長(zhǎng)度
? ? private int score = 5; //敵機(jī)包含的獎(jiǎng)勵(lì)分?jǐn)?shù)

? ? //對(duì)外提供的讀取敵機(jī)獎(jiǎng)勵(lì)分?jǐn)?shù)的方法
? ? public int getScore(){
? ? ? ? return score;
? ? }

? ? /**
? ? ?* 敵機(jī)類的無參構(gòu)造方法
? ? ?*/
? ? public Airplane(){
? ? ? ? image = ShootGame.airplane;
? ? ? ? width = image.getWidth();
? ? ? ? height = image.getHeight();
? ? ? ? y = -height;
? ? ? ? Random r = new Random();
? ? ? ? x = r.nextInt(ShootGame.WIDTH - width);
? ? }

? ? @Override
? ? public void step() {
? ? ? ? //敵機(jī)每次向下移動(dòng)一個(gè)speed長(zhǎng)度
? ? ? ? y += speed;
? ? }

? ? @Override
? ? public boolean outOfBounds() {
? ? ? ? //敵機(jī)y坐標(biāo)>游戲界面,越界
? ? ? ? return y > ShootGame.HEIGHT;
? ? }

}

4 封裝大飛機(jī)屬性和功能的類

import java.util.Random;

/**
?* 封裝大飛機(jī)屬性和功能的類
?*/
public class BigPlane extends Flyer {

? ? /*定義獎(jiǎng)勵(lì)類型的備選項(xiàng)常量*/
? ? public static final int DOUBLE_FIRE = 0; //獎(jiǎng)勵(lì)類型是0,說明獎(jiǎng)勵(lì)雙倍火力
? ? public static final int FILE = 1; //獎(jiǎng)勵(lì)類型是1,說明獎(jiǎng)勵(lì)一次生命

? ? /*大飛機(jī)類私有成員*/
? ? private int xspeed = 1; //水平移動(dòng)的速度為1
? ? private int yspeed = 2; //垂直移動(dòng)的速度為2
? ? private int awardType; //當(dāng)前大飛機(jī)保存的獎(jiǎng)勵(lì)類型

? ? //對(duì)外提供的讀取大飛機(jī)獎(jiǎng)勵(lì)類型的方法
? ? public int getAwardType(){
? ? ? ? return awardType;
? ? }

? ? /**
? ? ?* 大飛機(jī)的無參構(gòu)造方法
? ? ?*/
? ? public BigPlane(){
? ? ? ? //step1: 從主程序中獲取大飛機(jī)圖片的靜態(tài)變量——bigplane
? ? ? ? image = ShootGame.bigplane;
? ? ? ? //step2: 使用圖片寬高設(shè)置對(duì)象寬高
? ? ? ? width = image.getWidth();
? ? ? ? height= image.getHeight();
? ? ? ? //step3: 設(shè)置大飛機(jī)開始下落的高度
? ? ? ? y = -height;
? ? ? ? //step4: ?大飛機(jī)對(duì)象開始下落的x坐標(biāo)在0~(界面寬度 - 大飛機(jī)圖片寬度)之前隨機(jī)
? ? ? ? Random r = new Random();
? ? ? ? x = r.nextInt(ShootGame.WIDTH - width);
? ? ? ? //在0和1之間隨機(jī)先擇一種獎(jiǎng)勵(lì)類型
? ? ? ? awardType = r.nextInt(2);
? ? }

? ? @Override
? ? public void step() {
? ? ? ? //每次x移動(dòng)一個(gè)xspeed,y移動(dòng)一個(gè)yspeed
? ? ? ? x += xspeed;
? ? ? ? y += yspeed;
? ? ? ? //大飛機(jī)不能起出邊界,一旦超出那么xspeed*(-1),相當(dāng)于反向移動(dòng)
? ? ? ? if(x < 0 || x > ShootGame.WIDTH - width){
? ? ? ? ? ? xspeed *= -1;
? ? ? ? }
? ? }

? ? @Override
? ? public boolean outOfBounds() {
? ? ? ? //大飛機(jī)的y坐標(biāo)>游戲界面,越界
? ? ? ? return y > ShootGame.HEIGHT;
? ? }
}

5 子彈類

public class Bullet extends Flyer{

? ? private int speed = 5; //子彈上升的速度為3

? ? /**
? ? ?* 子彈類的帶參構(gòu)造方法
? ? ?* 因?yàn)樽訌棇?duì)象創(chuàng)造的位置要根據(jù)英雄機(jī)的位置決定
? ? ?* 所以子彈對(duì)名的x和y要從外界傳入
? ? ?* @param x 英雄機(jī)指定子彈創(chuàng)造位置的x坐標(biāo)
? ? ?* @param y 英雄機(jī)指定子彈創(chuàng)造位置的y坐標(biāo)
? ? ?*/
? ? public Bullet(int x,int y){
? ? ? ? image = ShootGame.bullet;
? ? ? ? width = image.getWidth();
? ? ? ? height = image.getHeight();
? ? ? ? this.x = x;
? ? ? ? this.y = y;
? ? }

? ? @Override
? ? public void step() {
? ? ? ? //子彈每次向上移動(dòng)一個(gè)speed長(zhǎng)度
? ? ? ? y -= speed;
? ? }

? ? @Override
? ? public boolean outOfBounds() {
? ? ? ? //子彈的y坐標(biāo)+子彈的高度<0,越界
? ? ? ? return (y + height) < 0;
? ? }
}

6 飛機(jī)大戰(zhàn)射擊的主方法

import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class ShootGame extends JPanel {

? ? private static final long serialVersionUID = 1L;

? ? //背景圖片的大小320*568
? ? public static final int WIDTH = 320;
? ? public static final int HEIGHT = 568;
? ? //游戲界面固定大小336*607
? ? public static final int FRAME_WIDTH = 336;
? ? public static final int FRAME_HEIGHT = 607;

? ? /*
? ? ?* 游戲啟動(dòng)第一件事是從硬盤加載所有要用到的圖片到內(nèi)存當(dāng)中
? ? ?* 而且僅在啟動(dòng)時(shí)加載一次——靜態(tài)塊
? ? ?* 緩存在程序中的所有圖片,都會(huì)反復(fù)使用,僅保存一份——靜態(tài)變量
? ? ?* 下面,為每張圖片加載一個(gè)靜態(tài)變量,然后在靜態(tài)塊加加載每張圖片
? ? ?*/
? ? public static BufferedImage background; //背景圖片
? ? public static BufferedImage start; //開始圖片
? ? public static BufferedImage airplane; //敵機(jī)圖片
? ? public static BufferedImage bigplane; //大飛機(jī)
? ? public static BufferedImage hero0; //英雄機(jī)狀態(tài)0
? ? public static BufferedImage hero1; //英雄機(jī)狀態(tài)1
? ? public static BufferedImage bullet; //子彈
? ? public static BufferedImage pause; //暫停圖片
? ? public static BufferedImage gameover; //游戲結(jié)束

? ? //靜態(tài)塊,在類加載到方法區(qū)時(shí)執(zhí)行一次,專門加載靜態(tài)資源
? ? static{
? ? ? ? /*
? ? ? ? ?* java從硬盤中加載圖片到內(nèi)存中:
? ? ? ? ?* ImageIO.read方法:專門從硬盤中加載圖片的靜態(tài)方法
? ? ? ? ?* 不用實(shí)例化,直接調(diào)用
? ? ? ? ?* ShootGame.class:獲得當(dāng)前類的加載器所在路徑
? ? ? ? ?* ShootGame.class.getRerource("文件名"); 從當(dāng)前類所在路徑加載指定文件到程序中
? ? ? ? ?*/
? ? ? ? try {
? ? ? ? ? ? background = ImageIO.read(ShootGame.class.getResource("background.png"));
? ? ? ? ? ? airplane = ImageIO.read(ShootGame.class.getResource("airplane.png"));
? ? ? ? ? ? bigplane = ImageIO.read(ShootGame.class.getResource("bigplane.png"));
? ? ? ? ? ? bullet = ImageIO.read(ShootGame.class.getResource("bullet.png"));
? ? ? ? ? ? start = ImageIO.read(ShootGame.class.getResource("start.png"));
? ? ? ? ? ? pause = ImageIO.read(ShootGame.class.getResource("pause.png"));
? ? ? ? ? ? hero0 = ImageIO.read(ShootGame.class.getResource("hero0.png"));
? ? ? ? ? ? hero1 = ImageIO.read(ShootGame.class.getResource("hero1.png"));
? ? ? ? ? ? gameover = ImageIO.read(ShootGame.class.getResource("gameover.png"));
? ? ? ? } catch (IOException e) {
? ? ? ? ? ? // TODO Auto-generated catch block
? ? ? ? ? ? e.printStackTrace();
? ? ? ? }
? ? }

? ? /*
? ? ?* 為游戲中的角色定義數(shù)據(jù)結(jié)構(gòu),包括:
? ? ?* 1個(gè)英雄機(jī)對(duì)象
? ? ?* 1個(gè)存儲(chǔ)所有敵人(敵機(jī)和大飛機(jī))的對(duì)象數(shù)組
? ? ?* 1個(gè)存儲(chǔ)所有子彈的對(duì)象數(shù)組
? ? ?*/
? ? public Hero hero = new Hero();
? ? public Flyer[] flyers = {}; //存儲(chǔ)所有敵人對(duì)象的數(shù)組
? ? public Bullet[] bullets = {}; //存儲(chǔ)所有子彈對(duì)象的數(shù)組

? ? //定義游戲狀態(tài):當(dāng)前狀態(tài)變量:默認(rèn)為開始狀態(tài)
? ? private int state = START;
? ? //定義游戲狀態(tài)的備選項(xiàng)常量:
? ? public static final int START = 0;
? ? public static final int RUNNING = 1;
? ? public static final int PAUSE = 2;
? ? public static final int GAME_OVER = 3;


? ? public static void main(String[] args) {

? ? ? ? /*
? ? ? ? ?* java中繪制窗體:JFrame對(duì)象——窗框
? ? ? ? ?* 要想在窗體中繪制內(nèi)容,還需要嵌入背景面板——JPanel
? ? ? ? ?*/
? ? ? ? JFrame frame = new JFrame("ShootGame");
? ? ? ? frame.setSize(FRAME_WIDTH,FRAME_HEIGHT);//(336, 607);
? ? ? ? frame.setAlwaysOnTop(true); //設(shè)置窗體置頂
? ? ? ? //設(shè)置窗體關(guān)閉同時(shí),退出程序
? ? ? ? frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
? ? ? ? frame.setLocationRelativeTo(null); //設(shè)置窗體的位置,null表示居中

? ? ? ? /*在窗體中嵌入背景面板對(duì)象——JPanel*/
? ? ? ? ShootGame game = new ShootGame(); //創(chuàng)建背景面板對(duì)象
? ? ? ? frame.add(game); //將背景面板對(duì)象嵌入到窗體對(duì)象中
? ? ? ? /*窗體默認(rèn)不可見!必須調(diào)用setVisible方法才能顯示窗體*/
? ? ? ? frame.setVisible(true); //自動(dòng)調(diào)用窗體的paint方法
? ? ? ? game.action();
? ? }

? ? /**
? ? ?* 游戲啟動(dòng)時(shí)要做的事
? ? ?*/
? ? public void action(){

? ? ? ? /*游戲開始時(shí),要定義鼠標(biāo)事件的監(jiān)聽*/
? ? ? ? //step1: 創(chuàng)建MouseAdapter匿名內(nèi)部類——事件的響應(yīng)程序
? ? ? ? MouseAdapter l = new MouseAdapter(){
? ? ? ? ? ? //step2: 重寫希望的鼠標(biāo)事件——鼠標(biāo)移動(dòng)
? ? ? ? ? ? @Override
? ? ? ? ? ? public void mouseMoved(MouseEvent e) {
? ? ? ? ? ? ? ? //只有在RUNNING狀態(tài)下英雄機(jī)才跟隨鼠標(biāo)移動(dòng)
? ? ? ? ? ? ? ? if(state == RUNNING){
? ? ? ? ? ? ? ? ? ? //step3: 獲得鼠標(biāo)新位置
? ? ? ? ? ? ? ? ? ? int x = e.getX();
? ? ? ? ? ? ? ? ? ? int y = e.getY();
? ? ? ? ? ? ? ? ? ? //step4: 將鼠標(biāo)位置傳給英雄機(jī)的move方法
? ? ? ? ? ? ? ? ? ? hero.move(x, y);
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? ? ? @Override
? ? ? ? ? ? public void mouseClicked(MouseEvent e) {
? ? ? ? ? ? ? ? if(state == START || state == PAUSE){ //START或者PAUSE狀態(tài),單擊才會(huì)改改為RUNNING狀態(tài)
? ? ? ? ? ? ? ? ? ? state = RUNNING;
? ? ? ? ? ? ? ? }else if(state == RUNNING){ //游戲點(diǎn)擊暫停
? ? ? ? ? ? ? ? ? ? state = PAUSE;
? ? ? ? ? ? ? ? }else if(state == GAME_OVER){ //游戲結(jié)束后單擊,游戲初始化
? ? ? ? ? ? ? ? ? ? state = START;
? ? ? ? ? ? ? ? ? ? //從GAME_OVER到START,要重新初始化游戲數(shù)據(jù)
? ? ? ? ? ? ? ? ? ? flyers = new Flyer[0];
? ? ? ? ? ? ? ? ? ? bullets = new Bullet[0];
? ? ? ? ? ? ? ? ? ? hero = new Hero();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }


? ? ? ? ? ? @Override
? ? ? ? ? ? public void mouseExited(MouseEvent e) {
? ? ? ? ? ? ? ? if(state == RUNNING){
? ? ? ? ? ? ? ? ? ? //僅在處于RUNNING狀態(tài)下,鼠標(biāo)移出才暫停
? ? ? ? ? ? ? ? ? ? state = PAUSE;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? ? ? @Override
? ? ? ? ? ? public void mouseEntered(MouseEvent e) {
? ? ? ? ? ? ? ? if(state == PAUSE){
? ? ? ? ? ? ? ? ? ? state = RUNNING;
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }

? ? ? ? }; //匿名內(nèi)部類要以分號(hào)結(jié)尾
? ? ? ? /*step5: 要響應(yīng)鼠標(biāo)事件,必須將鼠標(biāo)事件添加到程序的監(jiān)聽器中*/
? ? ? ? this.addMouseMotionListener(l); //支持鼠標(biāo)的移動(dòng)事件,不支持鼠標(biāo)單擊事件
? ? ? ? this.addMouseListener(l);; //支持鼠標(biāo)單擊事件

? ? ? ? //step1: 創(chuàng)建定時(shí)器
? ? ? ? Timer timer = new Timer();
? ? ? ? //step2: 調(diào)用定時(shí)器對(duì)象的schedule方法,做計(jì)劃
? ? ? ? // ? ? ? 第一個(gè)參數(shù):TimerTask類型的匿名內(nèi)部類
? ? ? ? // ? ? ? ? ? ? ? 必須重寫run方法——核心——要做什么事
? ? ? ? timer.schedule(new TimerTask(){
? ? ? ? ? ? //首先定義一個(gè)計(jì)時(shí)器變量index,記錄run方法運(yùn)行的次數(shù)
? ? ? ? ? ? private int runTimes = 0;

? ? ? ? ? ? @Override
? ? ? ? ? ? public void run() {
? ? ? ? ? ? ? ? //除了repaint方法,其余功能只在RUNNING狀態(tài)下執(zhí)行
? ? ? ? ? ? ? ? if(state == RUNNING){
? ? ? ? ? ? ? ? ? ? //每執(zhí)行一次run方法,runTimes就+1
? ? ? ? ? ? ? ? ? ? runTimes++;

? ? ? ? ? ? ? ? ? ? //每500亳秒生成一次敵人
? ? ? ? ? ? ? ? ? ? if(runTimes % 50 == 0){
? ? ? ? ? ? ? ? ? ? ? ? nextOne(); //自動(dòng)隨機(jī)創(chuàng)建敵人對(duì)象
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? //遍歷每一個(gè)對(duì)象,調(diào)用對(duì)象的step方法,移動(dòng)一次對(duì)象的位置
? ? ? ? ? ? ? ? ? ? for(int i = 0;i < flyers.length;i++){
? ? ? ? ? ? ? ? ? ? ? ? flyers[i].step();
? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? //每300亳秒生成一次子彈
? ? ? ? ? ? ? ? ? ? if(runTimes % 30 == 0){
? ? ? ? ? ? ? ? ? ? ? ? shoot(); //創(chuàng)建一次子彈
? ? ? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? ? ? //遍歷子彈數(shù)組的每一個(gè)對(duì)象,移動(dòng)位置
? ? ? ? ? ? ? ? ? ? for(int i = 0;i < bullets.length;i++){
? ? ? ? ? ? ? ? ? ? ? ? bullets[i].step();
? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? //英雄機(jī)動(dòng)畫效果
? ? ? ? ? ? ? ? ? ? hero.step();

? ? ? ? ? ? ? ? ? ? //添加子彈和敵人的碰撞檢測(cè)
? ? ? ? ? ? ? ? ? ? boom();

? ? ? ? ? ? ? ? ? ? //英雄機(jī)碰撞檢測(cè)
? ? ? ? ? ? ? ? ? ? hit();

? ? ? ? ? ? ? ? ? ? //添加越界檢測(cè)
? ? ? ? ? ? ? ? ? ? outOfBounds();
? ? ? ? ? ? ? ? }
? ? ? ? ? ? ? ? /*強(qiáng)調(diào):只要界面發(fā)生變化,必須調(diào)用repaint方法重新繪制界面*/
? ? ? ? ? ? ? ? repaint();
? ? ? ? ? ? }

? ? ? ? }, 10,10); //界面每隔10亳秒變化一次

? ? }


? ? @Override
? ? public void paint(Graphics g) {
? ? ? ? //step1: 繪制背景圖片
? ? ? ? g.drawImage(background, 0, 0, null);
? ? ? ? //step2: 繪制英雄機(jī)
? ? ? ? paintHero(g);
? ? ? ? //step3: 批量繪制敵人數(shù)組
? ? ? ? paintFlyers(g);
? ? ? ? //step4: 批量繪制子彈數(shù)組
? ? ? ? paintBullets(g);
? ? ? ? //繪制分?jǐn)?shù)和生命值
? ? ? ? paintScore_Life(g);

? ? ? ? //根據(jù)游戲狀態(tài)繪制不同圖片
? ? ? ? if(state == START){
? ? ? ? ? ? g.drawImage(start, 0, 0, null);
? ? ? ? }else if(state == PAUSE){
? ? ? ? ? ? g.drawImage(pause, 0, 0, null);
? ? ? ? }else if(state == GAME_OVER){
? ? ? ? ? ? g.drawImage(gameover, 0, 0, null);
? ? ? ? }

? ? }

? ? /**
? ? ?* 繪制英雄機(jī)對(duì)象的方法
? ? ?* @param g 畫筆
? ? ?*/
? ? public void paintHero(Graphics g){
? ? ? ? g.drawImage(hero.image, hero.x, hero.y, null);
? ? }

? ? /**
? ? ?* 遍歷敵人數(shù)組,批量繪制所有敵人的方法
? ? ?* @param g
? ? ?*/
? ? public void paintFlyers(Graphics g){
? ? ? ? for(int i = 0;i < flyers.length;i++){
? ? ? ? ? ? g.drawImage(flyers[i].image, flyers[i].x, flyers[i].y, null);
? ? ? ? }
? ? }

? ? /**
? ? ?* 遍歷子彈數(shù)組,批量繪制所有子彈的方法
? ? ?* @param g
? ? ?*/
? ? public void paintBullets(Graphics g){
? ? ? ? for(int i = 0;i < bullets.length;i++){
? ? ? ? ? ? g.drawImage(bullets[i].image, bullets[i].x, bullets[i].y, null);
? ? ? ? }
? ? }

? ? /**
? ? ?* 隨機(jī)生成1個(gè)敵人對(duì)象
? ? ?* 每生成一個(gè)新敵人, flyers數(shù)組就要擴(kuò)容1
? ? ?* 然后將新敵人放入數(shù)組最后一個(gè)元素
? ? ?*/
? ? public void nextOne(){
? ? ? ? Random r = new Random();
? ? ? ? Flyer f = null;
? ? ? ? if(r.nextInt(20) == 0){ //只有隨機(jī)數(shù)取0時(shí)才創(chuàng)建大飛機(jī)
? ? ? ? ? ? f = new BigPlane();
? ? ? ? }else{ //其余全部生成敵機(jī)
? ? ? ? ? ? f = new Airplane();
? ? ? ? }
? ? ? ? //對(duì)flyers數(shù)組擴(kuò)容1
? ? ? ? flyers = Arrays.copyOf(flyers, flyers.length + 1);
? ? ? ? //將新敵人放入數(shù)組末尾
? ? ? ? flyers[flyers.length - 1] = f;
? ? }

? ? /**
? ? ?* 獲得英雄機(jī)對(duì)象發(fā)射的子彈對(duì)象
? ? ?* 將新的子彈對(duì)象保存到子彈數(shù)組中,統(tǒng)一管理
? ? ?*/
? ? public void shoot(){
? ? ? ? Bullet[] newBullets = hero.shoot(); //獲得英雄機(jī)返回的新子彈數(shù)組
? ? ? ? //根據(jù)返回新子彈的數(shù)量,擴(kuò)容子彈數(shù)組
? ? ? ? bullets = Arrays.copyOf(bullets, bullets.length + newBullets.length);
? ? ? ? //從newBullets數(shù)組中拷貝所有元素到bullets數(shù)組末尾
? ? ? ? System.arraycopy(newBullets, 0, bullets, bullets.length - newBullets.length, newBullets.length);

? ? }

? ? /**
? ? ?* 遍歷子彈數(shù)組和敵人數(shù)組,進(jìn)行碰撞檢測(cè)
? ? ?* 一旦發(fā)生碰撞,子彈和敵人都減少一個(gè)
? ? ?*/
? ? public void boom(){
? ? ? ? for(int i = 0;i < bullets.length;i++){
? ? ? ? ? ? for(int j = 0;j < flyers.length;j++){
? ? ? ? ? ? ? ? if(Flyer.boom(bullets[i], flyers[j])){
? ? ? ? ? ? ? ? ? ? //為英雄機(jī)獲得分?jǐn)?shù)和獎(jiǎng)勵(lì)
? ? ? ? ? ? ? ? ? ? hero.getScore_Award(flyers[j]);
? ? ? ? ? ? ? ? ? ? //從敵人數(shù)組中刪除被擊中的敵機(jī)
? ? ? ? ? ? ? ? ? ? //step1: 使用敵人數(shù)組最后一個(gè)元素替換被擊中的敵機(jī)
? ? ? ? ? ? ? ? ? ? flyers[j] = flyers[flyers.length - 1];
? ? ? ? ? ? ? ? ? ? //step2: 壓縮數(shù)組
? ? ? ? ? ? ? ? ? ? flyers = Arrays.copyOf(flyers, flyers.length - 1);
? ? ? ? ? ? ? ? ? ? //從子彈數(shù)組中刪除擊中敵機(jī)的子彈
? ? ? ? ? ? ? ? ? ? bullets[i] = bullets[bullets.length - 1];
? ? ? ? ? ? ? ? ? ? bullets = Arrays.copyOf(bullets, bullets.length -1);
? ? ? ? ? ? ? ? ? ? i--; //第發(fā)現(xiàn)一次碰撞,子彈就要退一個(gè)元素,重新檢測(cè)當(dāng)前位置
? ? ? ? ? ? ? ? ? ? break; //只要發(fā)現(xiàn)碰撞就退出當(dāng)前敵人數(shù)組的循環(huán)
? ? ? ? ? ? ? ? }
? ? ? ? ? ? }
? ? ? ? }
? ? }

? ? /**
? ? ?* 繪制分?jǐn)?shù)和生命值的方法
? ? ?* @param g
? ? ?*/
? ? public void paintScore_Life(Graphics g){
? ? ? ? int x = 10; //文字在左上角的x坐標(biāo)
? ? ? ? int y = 15; //文字在左上角的y坐標(biāo)
? ? ? ? Font font = new Font(Font.SANS_SERIF,Font.BOLD,14);
? ? ? ? g.setFont(font); //設(shè)置字體的畫筆對(duì)象
? ? ? ? //繪制第一行:分?jǐn)?shù)
? ? ? ? g.drawString("SCORE: " + hero.getScore(), x, y);
? ? ? ? //繪制第二行:生命值,y坐標(biāo)下移20個(gè)單位
? ? ? ? y += 20;
? ? ? ? g.drawString("LIFE: " + hero.getLife(), x, y);
? ? }

? ? /**
? ? ?* 檢查所有飛行物是否越界
? ? ?*/
? ? public void outOfBounds(){
? ? ? ? //檢查所有敵人是否越界
? ? ? ? Flyer[] Flives = new Flyer[flyers.length];
? ? ? ? //遍歷敵人數(shù)組,將存活的敵人對(duì)象存到新數(shù)組中
? ? ? ? //設(shè)置Flives數(shù)組的計(jì)數(shù)器index: 1.標(biāo)示下一個(gè)存活對(duì)象的位置
? ? ? ? // ? ? ? ? ? ? ? ? ? ? ? ?2.統(tǒng)計(jì)Flives中一共有多少元素
? ? ? ? int index = 0;
? ? ? ? for(int i = 0;i < flyers.length;i++){
? ? ? ? ? ? if(!flyers[i].outOfBounds()){ //沒有越界的對(duì)象
? ? ? ? ? ? ? ? Flives[index] = flyers[i];
? ? ? ? ? ? ? ? index++;
? ? ? ? ? ? } //遍歷結(jié)束后:
? ? ? ? ? ? //index是存活對(duì)象的個(gè)數(shù)
? ? ? ? ? ? //Flives數(shù)組里是存活的對(duì)象,個(gè)數(shù)為index
? ? ? ? ? ? //把Flives數(shù)組壓縮為index大小
? ? ? ? ? ? //壓縮后的新數(shù)組 應(yīng)替換回flyers數(shù)組
? ? ? ? }
? ? ? ? flyers = Arrays.copyOf(Flives, index);

? ? ? ? //檢測(cè)所有子彈是否越界
? ? ? ? Bullet[] Blives = new Bullet[bullets.length];
? ? ? ? index = 0;
? ? ? ? for(int i = 0;i < bullets.length;i++){
? ? ? ? ? ? if(!bullets[i].outOfBounds()){
? ? ? ? ? ? ? ? Blives[index] = bullets[i];
? ? ? ? ? ? ? ? index++;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? bullets = Arrays.copyOf(Blives, index);
? ? }

? ? /**
? ? ?* 遍歷敵人數(shù)組,判斷英雄機(jī)和每個(gè)敵人是否碰撞
? ? ?*/
? ? public void hit(){
? ? ? ? Flyer[] lives = new Flyer[flyers.length];
? ? ? ? //記錄存活的敵人
? ? ? ? int index = 0;
? ? ? ? for(int i = 0;i < flyers.length;i++){
? ? ? ? ? ? if(!hero.hit(flyers[i])){
? ? ? ? ? ? ? ? lives[index] = flyers[i];
? ? ? ? ? ? ? ? index++;
? ? ? ? ? ? }
? ? ? ? }
? ? ? ? if(hero.getLife() <= 0){ //如果英雄機(jī)生命值小于等于0,游戲結(jié)束
? ? ? ? ? ? state = GAME_OVER;
? ? ? ? }
? ? ? ? //壓縮敵人數(shù)組,并替換數(shù)組
? ? ? ? flyers = Arrays.copyOf(lives, index);

? ? }
}

二、測(cè)試結(jié)果

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論