Python——飞机大战(day10)

Posted 清园暖歌

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python——飞机大战(day10)相关的知识,希望对你有一定的参考价值。

目录

一、面向过程实现

二、面向对象


plane pro需求的描述:

存在四个对象:
我方飞机、敌方飞机、我方子弹、敌方子弹
功能:

背景音乐的添加

我方飞机可以移动【根据按键来控制的】
敌方飞机也可以移动【随机的自动移动】

双方飞机都可以发送子弹

步骤:
1.创建一个窗口
2.创建一个我方飞机 根据方向键左右的移动
3.给我方飞机添加发射子弹的功能【按下空格键去发送】
4.创建一个敌人飞机
5.敌人飞机可以自由的移动
6.敌人飞机可以自动的发射子弹

在安装pygame模块的时候尤其要注意一下:

如果在pychram中安装不成功  如下错误:
   EOFError: EOF when reading a line

    ----------------------------------------
Command "python setup.py egg_info" failed with error code 1 in C:\\Users\\Administrator\\AppData\\Local\\Temp\\pip-install-392v1at0\\pygame\\

此时我们就可以换种思路:

1:确保在系统层面的python环境里面 已经安装了pygame[pip install pygame] 一般都可以安装成功
2: 我们就可以把 已经安装好的 pygame 模块的 文件夹拷贝到 pycharm 所创建项目中的venv虚拟环境里面【E:\\PythonPro\\PlaneDemo\\venv\\Lib\\site-packages】

soure path:C:\\Users\\Administrator\\AppData\\Local\\Programs\\Python\\Python38-32\\Lib\\site-packages
dst path: 你的项目路径/venv\\Lib\\site-packages
 

一、面向过程实现

1、首先设置进行窗口、背景设置

import pygame # 引用pygame模块
from pygame.locals import  *
import time

def main():

#----------------------------- 窗口、背景的基本设置 -------------------------

    # 首先创建一个窗口,用来显示内容
    screen = pygame.display.set_mode((350,500)) # 设置宽、高:350,500
    # 创建一个背景图片对象
    background = pygame.image.load('./feiji/background.png') # 当前路径下的
    # 设置一个标题
    pygame.display.set_caption('阶段总结-飞机大战')
    # 添加背景音乐
    pygame.mixer.init() # 初始化这个函数
    pygame.mixer.music.load('./feiji/background.mp3')
    pygame.mixer.music.set_volume((0.2)) # 0-1之间设置音量
    pygame.mixer.music.play(-1) # 设置循环次数,-1表示无限循环
    #函数原型:pygame.key.set_repeat(delay, interval)

2、载入己方和地方飞机

# 载入玩家的飞机图片
    hero = pygame.image.load('./feiji/hero.png')
    # 初始化玩家的位置:
    x, y = 155, 450 # 玩家飞机hero大小:40×50;(155, 450)表示在窗口最下方居中显示的位置

3、循环更新显示界面

    # 设定要显示的内容
    while True:
        screen.blit(background, (0, 0)) # 显示背景图片,(对象,居中显示),(0,0)表示从窗口的(0,0)坐标开始显示
        screen.blit(hero, (x, y)) # 显示玩家飞机
        # 获取键盘事件
        eventlist = pygame.event.get()
        for event in eventlist:
            if event.type == QUIT:
                print('退出')
                exit()
                pass
            elif event.type == KEYDOWN: # 是否按下了键盘
                if event.key == K_a or event.key == K_LEFT: # 按下了左键
                    print('left')
                    if x > 0:
                        x -= 5
                    elif x < 0:
                        x = 0
                        pass

                elif event.key == K_d or event.key == K_RIGHT: # 按下了右键
                    print('right')
                    if x < 310:
                        x += 5
                    elif x > 310:
                        x = 310
                        pass

                elif event.key == K_SPACE:
                    print('K_SPACE')
        # 更新显示内容
        pygame.display.update()
    pass

if __name__ == '__main__':
    main()

到这里发现,可以控制飞机移动,但是每按下一次键盘只能移动一次,好像不符合正常游戏要求

所以添加

pygame.key.set_repeat(10, 15) # 放到初始化中,这两个参数都是以ms为单位的

 函数即可实现,按下连续移动

只需要将这段代码放到初始化中即可!(ps:)

代码的具体意义:
在pygame中对按键的连续检测是默认失能的,调用上述函数便可以使能按键的连续检测。按键的连续检测使能后,当按键按下时,将会以delay的延时去触发第一次的KEYDOWN事件,之后则会以interval的延时去触发接下来的KEYDOWN事件。通俗的讲,第一个参数影响着按键的灵敏度,第二个参数影响着按键的移动时间间隔。即:以上述(10,15)来说,每次按下键盘触发KEYDOWN事件后,延时10ms后再次检测是否有还在按下,若在10ms内有按下,则之后以15ms的延时连续触发接下来的KEYDOWN。

二、面向对象

import pygame # 引用pygame模块
from pygame.locals import  *
import time
import random
# ---------------------------------- 面对对象 -------------------------------------

'''
1:实现飞机的显示,并且可以控制飞机的移动【面向对象】
'''
# 抽象出来一个飞机的基类
class BasePlane(object):
    def __init__(self, screen, imagePath):
        '''
        初始化基类函数
        :param screen: 主窗体对象
        :param imageName: 加载的图片
        '''
        self.screen = screen
        self.image = pygame.image.load(imagePath)
        self.bulletlist = [] #存储所有的子弹
        pass
    def display(self):
        self.screen.blit(self.image, (self.x, self.y))
        # 完善子弹的展示逻辑,删除越界的子弹,释放内存
        needDelItemList = []
        for item in self.bulletlist:
            if item.judge():
                needDelItemList.append(item)
                pass
            pass
        # 重新遍历一遍
        for i in needDelItemList:
            self.bulletlist.remove(i)
            pass
        for bullet in self.bulletlist:
            bullet.display()  # 显示子弹的位置
            bullet.move()  # 让这个子弹移动,下次再显示的就会看到子弹在修改后的位置
        pass
    pass

class CommonBullet(object):
    '''
    公共的子弹类
    '''
    def __init__(self, x, y, screen, bullettype):
        self.type = bullettype
        self.screen = screen
        if self.type == "hero":
            self.x += 20
            self.y -= 20
            self.imagePath = './feiji/bullet.png'
        elif self.type == "enemy":
            self.x = x
            self.y += 10
            self.imagePath = './feiji/bullet1.png'
        self.image = pygame.image.load(self.imagePath)
    def move(self):
        '''
        子弹的移动
        :return:
        '''
        if self.type == 'hero':
            self.y -= 2
        elif self.type == 'enemy':
            self.y += 2
    def display(self):
        self.screen.blit(self.image,(self.x, self.y))
    pass

class HeroPlane(BasePlane):
    def __init__(self, screen):
        '''
        初始化函数
        :param screen: 主窗体对象
        '''

        super().__init__(screen, './feiji/hero.png') # 调用父类的构造方法
        # 飞机的默认位置
        self.x = 155
        self.y = 450
        pass
    def moveleft(self):
        '''
        左移动
        :return:
        '''
        if self.x > 0:
            self.x -= 5
        elif self.x <= 0:
            self.x = 0
        pass
    def moveright(self):
        '''
        右移动
        :return:
        '''
        if self.x < 310:
            self.x += 5
        elif self.x >= 310:
            self.x = 310
        pass
    def moveup(self):
        '''
        上移动
        :return:
        '''
        if self.y > 0:
            self.y -= 5
        elif self.y <= 0:
            self.y = 0
        pass
    def movedown(self):
        '''
        下移动
        :return:
        '''
        if self.y < 450:
            self.y += 5
        elif self.y >= 450:
            self.y = 450
        pass
    # 发射子弹
    def ShotBullet(self):
        # 创建一个新的子弹对象
        newbullet = CommonBullet(self.x, self.y, self.screen, 'hero')
        self.bulletlist.append(newbullet)
        pass

'''
创建敌机类
'''
class EnemyPlane(BasePlane):
    def __init__(self, screen):
        super().__init__(screen, './feiji/enemy0.png')
        # 默认设置一个方向
        self.direction = 'right'
        # 飞机的默认位置
        self.x = 0
        self.y = 0
        pass
    def shotenemybullet(self):
        '''
        敌机随机发射
        :return:
        '''
        num = random.randint(1,50)
        if num == 3:
            newbullet = CommonBullet(self.x, self.y, self.screen, 'enemy')
            self.bulletlist.append(newbullet)
        pass
    def move(self):
        '''
        敌机移动 随机进行
        :return:
        '''
        if self.direction == 'right':
            self.x += 2
        elif self.direction == 'left':
            self.x -= 2
        if self.x > 330:
            self.direction = 'left'
        elif self.x < 0:
            self.direction = 'right'
    pass

def key_control(HeroObj):
    '''
    定义普通的函数,用来实现键盘的检测
    :param HeroObj:可控制检测的对象
    :return:
    '''

    # 获取键盘事件
    eventlist = pygame.event.get()
    # pygame.key.set_repeat(10, 15)
    pygame.key.set_repeat(200, 15)
    # pygame.key.set_repeat(200, 200)
    for event in eventlist:
        if event.type == QUIT:
            print('退出')
            exit()
            pass
        elif event.type == KEYDOWN:  # 是否按下了键盘
            if event.key == K_a or event.key == K_LEFT:  # 按下了左键
                print('left')
                HeroObj.moveleft() # 调用函数实现左移动
                pass
            elif event.key == K_d or event.key == K_RIGHT:  # 按下了右键
                print('right')
                HeroObj.moveright()  # 调用函数实现右移动
                pass
            elif event.key == K_w or event.key == K_UP:  # 按下了右键
                print('up')
                HeroObj.moveup()  # 调用函数实现上移动
                pass
            elif event.key == K_s or event.key == K_DOWN:  # 按下了右键
                print('down')
                HeroObj.movedown()  # 调用函数实现下移动
                pass
            elif event.key == K_SPACE:
                print('K_SPACE')
                HeroObj.ShotBullet()


def main():
#----------------------------- 窗口、背景的基本设置 -------------------------
    # 首先创建一个窗口,用来显示内容
    screen = pygame.display.set_mode((350,500)) # 设置宽、高:350,500
    # 创建一个背景图片对象
    background = pygame.image.load('./feiji/background.png') # 当前路径下的
    # 设置一个标题
    pygame.display.set_caption('阶段总结-飞机大战')
    # 添加背景音乐
    pygame.mixer.init() # 初始化这个函数
    pygame.mixer.music.load('./feiji/background.mp3')
    pygame.mixer.music.set_volume((0.2)) # 0-1之间设置音量
    pygame.mixer.music.play(-1) # 设置循环次数,-1表示无限循环
    #函数原型:pygame.key.set_repeat(delay, interval)

    # 创建一个飞机对象
    hero = HeroPlane(screen)
    # 创建一个敌人
    enemyplane = EnemyPlane(screen)

    # 设定要显示的内容
    while True:
        screen.blit(background, (0, 0)) # 显示背景图片,(对象,居中显示),(0,0)表示从窗口的(0,0)坐标开始显示
        hero.display()
        enemyplane.display() # 显示敌机
        enemyplane.move()  # 敌机移动
        enemyplane.shotenemybullet() # 敌机随机发射子弹
        # 获取键盘事件
        key_control(hero)
        # 更新显示内容
        pygame.display.update()
        # time.sleep(1)
        pygame.time.Clock().tick(15) # 每秒发生15次
    pass

if __name__ == '__main__':
    main()


  

Java学习二(飞机大战项目)day09

day09

1.子弹与敌人的碰撞
    1)在超类中FlyingObject设计hit()实现敌人与子弹/英雄机得碰撞

    /** 成员方法:检测敌人与子弹/英雄机的碰撞
     *  this:敌人    other:子弹 */
    public boolean hit(FlyingObject other) {
        int x1 = this.x - other.width;
        int x2 = this.x + this.width;        
        int y1 = this.y - other.height;    
        int y2 = this.y + this.height;    
        int x = other.x;                                
        int y = other.y;                                
        return x>=x1 && x<=x2 && y>=y1 && y<=y2;    
    }

    在超类中FlyingObject设计goDead()实现飞行物去死的

    /** 成员方法:飞行物去死 */
    public void goDead() {
        state = DEAD;    //将当前状态修改为DEAD
    }
import java.util.Random;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.awt.Graphics;
/**
 * 飞行物--超类
 * @author soft01
 */
public abstract class FlyingObject {
    /** 常量: 三种状态(活着的、死了的、删除的)    */
    public static final int LIFE = 0;
    public static final int DEAD = 1;
    public static final int REMOVE = 2;
    
    /** 成员变量:当前状态(默认为活着的) */
    protected int state = LIFE;    
    
    /** 成员变量:宽、高、x轴、y轴 */
    protected int width;        
    protected int height;    
    protected int x;                
    protected int y;                
    
    /** 构造方法:专门给英雄机、天空、子弹用 */
    public FlyingObject(int width,int height,int x,int y) {
        this.width = width;
        this.height = height;
        this.x = x;
        this.y = y;
    }
    
    /** 构造方法:专门给小敌机、大敌机、小蜜蜂用 */
    public FlyingObject(int width,int height) {
        this.width = width;
        this.height = height;
        Random rand = new Random();
        x = rand.nextInt(World.WIDTH-width);
        y = -height;    
    }

    /**    抽象方法:飞行物移动        */
    public abstract void step();
    
    /**    抽象方法:获取图片        */
    public abstract BufferedImage getImage();
    
    /** 抽象方法:检查飞行物是否越界 */
    public abstract boolean outOfBounds();
    
    /** 静态方法:读取图片 */
    public static BufferedImage loadImage(String fileName) {
        try {
            BufferedImage img = ImageIO.read(FlyingObject.class.getResource(fileName));    //同包中读图片
            return img;
        } catch (Exception e) {
            e.printStackTrace();
            throw new RuntimeException();
        }
    }

    /** 成员方法:判断状态(活着的、死了的、删除的) */
    public boolean isLife() {
        return state == LIFE;
    }
    public boolean isDead() {
        return state == DEAD;
    }
    public boolean isRemove() {
        return state == REMOVE;
    }

    /** 成员方法:画对象的 g:画笔 */
    public void paintObject(Graphics g) {
        g.drawImage(getImage(),x,y,null);
    }
    
    /** 成员方法:检测敌人与子弹/英雄机的碰撞
     *  this:敌人    other:子弹 */
    public boolean hit(FlyingObject other) {
        int x1 = this.x - other.width;        //敌人的x - 子弹/英雄机的宽
        int x2 = this.x + this.width;        //敌人的x + 敌人的宽
        int y1 = this.y - other.height;    //敌人的y - 子弹/英雄机的高
        int y2 = this.y + this.height;        //敌人的y + 敌人的高
        int x = other.x;                                //子弹/英雄机的x
        int y = other.y;                                //子弹/英雄机的y    
        return x>=x1 && x<=x2 && y>=y1 && y<=y2;    //x在x1和x2之间,y在y1和y2之间
    }
    
    /** 成员方法:飞行物去死 */
    public void goDead() {
        state = DEAD;        //将当前状态修改为DEAD
    }
}

 


    在Hero类中设计addLife()增命、addDoubleFire()增火力

    /**    成员方法:命数增加    */
    public void addLife() {
        life++;    //命数增1
    }
    
    /**    成员方法:火力值增加        */
    public void addDoubleFire() {
        doubleFire += 40;        //火力值增40
    }
import java.awt.image.BufferedImage;

/**
 * 英雄机
 * @author soft01
 */
public class Hero extends FlyingObject{
    /** 静态变量:英雄机图片    */
    private static BufferedImage[] images;
    static {
        images = new BufferedImage[2];
        for (int i = 0; i < images.length; i++) {
            images[i] = loadImage("hero" + i + ".png");
        }
    }
    
    /**    成员变量:生命、火力值    */
    private int life;        //生命
    private int doubleFire;        //火力值
    
    /**    构造方法    */
    public Hero(){
        super(97,124,140,400);
        life = 3;
        doubleFire = 0;
    }
    
    /**    成员方法:命数增加    */
    public void addLife() {
        life++;    //命数增1
    }
    
    /**    成员方法:获取命数    */
    public int getLife() {
        return life;    //返回命
    }
    
    /**    成员方法:火力值增加        */
    public void addDoubleFire() {
        doubleFire += 40;        //火力值增40
    }
    
    /**    成员方法:英雄机移动        */
    public void step() {}
    
    /**    成员方法:英雄机随鼠标移动x,y    */
    public void moveTo(int x,int y) {    
        this.x = x - this.width/2;        //英雄机的x=鼠标的x-1/2英雄机的宽
        this.y = y - this.height/2;    //英雄机的y=鼠标的y-1/2英雄机的高
    }
    
    /**    成员方法:获取图片    */
    int index = 0;
    @Override
    public BufferedImage getImage() {
        if(isLife()) {
            return images[index++%2];        //(index++%2)余数为0或1
        }
        return null;
    }
    
    /**    成员方法:英雄机发射子弹(创建子弹对象)    */
    public Bullet[] shoot() {
        int xStep = this.width/4;    //xStep:1/4英雄机的宽
        int yStep = 20;            //yStep:固定的20
        if (doubleFire > 0) {        //
            Bullet[] bs = new Bullet[2];        //2发子弹
            //英雄机的x坐标加1/4英雄机的宽
        bs[0] = new Bullet(this.x + 1 * xStep,y-yStep);    
            //英雄机的x坐标加3/4英雄机的宽
        bs[1] = new Bullet(this.x + 3 * xStep, y-yStep);    
            doubleFire -= 2;    //发射一次双倍火力,火力值减2
            return bs;
        } else {                    //
            Bullet[] bs = new Bullet[1];        //1发子弹
        //英雄机的x坐标加2/4英雄机的宽
        bs[0] = new Bullet(this.x + 2 * xStep, y-yStep);    
            return bs;
        }
    }
    
    /**    成员方法:英雄机永不越界    */
    @Override
    public boolean outOfBounds() {
        return false;
    }
}

  2)子弹与敌人的碰撞为定时发生的,所以在run()中调用BulletBangAction()方法
在BulletBangAction()中:
遍历所有子弹,获取每一个子弹,遍历所有敌人,获取每个敌人
判断是否撞上了,若撞上了:
    1)子弹去死,敌人去死
    2)小敌机和大敌机 ----------得分
       小蜜蜂 ----------------英雄机得命或双倍火力

/** 成员方法:子弹与敌人的碰撞 */
int score = 0;
public void bulletBangAction() {    //每10个毫秒走一次
    //遍历子弹数组        
    for (int i = 0; i < bullets.length; i++) {    
        Bullet b = bullets[i];//得到每一个子弹
        //遍历敌人数组
        for (int j = 0; j < enemies.length; j++) {    
            FlyingObject f = enemies[j];    //得到每一个敌人
            //如果活着的子弹和活着的敌人撞上了
            if(b.isLife() && f.isLife() && f.hit(b)) {        
                b.goDead();            //子弹去死
                f.goDead();            //敌人去死            
                if (f instanceof Enemy) {//若被撞对象是敌人
                    Enemy e = (Enemy)f;//强转为得分接口        
                    score += e.getScore();//玩家得分
                }
                if (f instanceof Award) {//若被撞对象是奖励
                  Award a = (Award)f;//    强转为奖励接口
                  int type = a.getType();//获取奖励类型                      //基于不同的类型来得到不同的奖励
                  switch (type) {
                  //若奖励为火力值                
                  case Award.DOUBLE_FIRE:
                    hero.addDoubleFire();    //则增加火力值        
                    break;
                    case Award.LIFE:        //若奖励为命        
                    hero.addLife();        //则增加命        
                    break;                                              }
                }
            }
        }
    }
}


2.画分和画命
    1)在Hero类中设计getLife()获取命

    /**    成员方法:获取命数    */
    public int getLife() {
        return life;    //返回命
    }

    2)在paint()方法中,画分和画命

    g.drawString("SCORE:" + score,10,25);
    g.drawString("LIFE:" + hero.getLife(), 10, 45);

import java.awt.Graphics;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.util.Timer;
import java.util.TimerTask;
import java.util.Random;
import java.util.Arrays;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;;

/**
 * 整个世界
 * @author soft01
 */
public class World extends JPanel{
    /** 常量:窗口宽、窗口高 */
    public static final int WIDTH = 400;
    public static final int HEIGHT = 700;

    /**    成员变量:天空、英雄机、飞行物敌人数组、子弹数组    */
    private Sky sky = new Sky();                            
    private Hero hero = new Hero();                        
    private FlyingObject[] enemies = {};
    private Bullet[] bullets = {};        
    
    /**    启动程序的执行    */
    public void action() {
        Timer timer = new Timer();                                    //创建定时器对象
        int interval = 10;                                                //定时间隔(以毫秒为单位)
        timer.schedule(new TimerTask() {                        //匿名内部类
            @Override
            public void run() {                                            //定时干的事(每10个毫秒走一次)
                enterAction();                                                //敌人入场,子弹入场,飞行物移动
                shootAction();                                                //子弹入场,英雄机发射子弹
                stepAction();                                                    //飞行物入场
                outOfBoundsAction();                                    //删除越界
                bulletBangAction();                                        //子弹与敌人的碰撞
                repaint();                                                     //重画(重新调用paint()方法)
            }
        },interval,interval);                                            //定时计划
        
        /** 鼠标侦听器 */
        MouseAdapter l = new MouseAdapter() {
            /** 重写mouseMoved()鼠标移动 */
            public void mouseMoved(MouseEvent e) {
                int x = e.getX();        //获取鼠标的x坐标
                int y = e.getY();        //获取鼠标的y坐标
                hero.moveTo(x, y);    //英雄机随着鼠标移动
            }
        };
        this.addMouseListener(l);                //处理鼠标操作事件
        this.addMouseMotionListener(l);    //处理鼠标滑动事件
    }
    
    
    /** 成员方法:生成敌人(小敌机、大敌机、小蜜蜂)对象 */
    public FlyingObject nextOne() {
        Random rand = new Random();    //随机数对象
        int type = rand.nextInt(20);    //0~19之间的数
        if (type < 11) {                            //0~7返回小敌机
            return new Airplane();
        } else if(type < 17){                //8~15返回小敌机
            return new BigAirplane();
        } else {                                        //16~19返回小敌机
            return new Bee();
        }
    }
    
    /** 成员方法:敌人(小敌机、大敌机、小蜜蜂)入场 */
    int enterIndex = 0;                            //敌人入场计数
    public void enterAction() {            //每10个毫秒走一次
        enterIndex++;                                    //每10毫秒增1
        if(enterIndex%40 == 0) {            //每400(10*40)毫秒走一次
            FlyingObject obj = nextOne();
            enemies = Arrays.copyOf(enemies, enemies.length+1);    //数组扩容
            enemies[enemies.length-1] = obj;                //将敌人对象填充到enemies数组的最后一个元素上
        }
    }
    
    /** 成员方法:子弹入场,英雄机发射子弹 */
    int shootIndex = 0;                            //子弹入场计数
    public void shootAction() {            //每10个毫秒走一次
        shootIndex++;                                    //每10毫秒增1
        if(shootIndex%20 == 0) {            //每300(10*30)毫秒走一次
            Bullet[] bs = hero.shoot();    //获取英雄机发射出来的子弹对象
            bullets = Arrays.copyOf(bullets, bullets.length+bs.length);    //扩容(bs有几个元素就扩大几个)
            System.arraycopy(bs, 0, bullets, bullets.length - bs.length, bs.length);     //数组的追加
        }
    }
    
    /** 成员方法:飞行物入场 */
    public void stepAction() {
        sky.step();                    //天空移动
        for (int i = 0; i < enemies.length; i++) {
            enemies[i].step();    //飞行物移动
        }
        for (int i = 0; i < bullets.length; i++) {
            bullets[i].step();    //子弹移动
        }
    }
    
    /** 成员方法:删除越界 */
    public void outOfBoundsAction() {    //每10个毫秒走一次
        int index = 0;        //1)不越界敌人下标    2)不越界敌人个数
        FlyingObject[] enemyLives = new FlyingObject[enemies.length];     //不越界敌人数组
        for (int i = 0; i < enemies.length; i++) {    //获取敌人数组
            FlyingObject f = enemies[i];        //获取每一个敌人
            if(!f.outOfBounds()) {    //不越界
                enemyLives[index] = f;    //将不越界敌人放到不越界数组中
                index++;        //1)不越界敌人数组下标增一        2)不越界敌人个数增1
            }
        }
        enemies = Arrays.copyOf(enemyLives, index);    //将不越界数组中的元素复制到敌人数组之中,数组的长度为index
        
        index = 0;
        Bullet[] bulletLives = new Bullet[bullets.length];
        for (int i = 0; i < bullets.length; i++) {
            Bullet b = bullets[i];
            if(!b.outOfBounds()) {
                bulletLives[index] = b;
                index++;
            }
        }
        bullets = Arrays.copyOf(bulletLives, index);
    }
    
    /** 成员方法:子弹与敌人的碰撞 */
    int score = 0;
    public void bulletBangAction() {                                        //每10个毫秒走一次
        for (int i = 0; i < bullets.length; i++) {                //遍历子弹数组
            Bullet b = bullets[i];                                                //得到每一个子弹
            for (int j = 0; j < enemies.length; j++) {            //遍历敌人数组
                FlyingObject f = enemies[j];                                    //得到每一个敌人
                if(b.isLife() && f.isLife() && f.hit(b)) {        //如果活着的子弹和活着的敌人撞上了
                    b.goDead();                                                            //子弹去死
                    f.goDead();                                                            //敌人去死                
                    if (f instanceof Enemy) {                                    //若被撞对象是敌人
                        Enemy e = (Enemy)f;                                            //强转为得分接口
                        score += e.getScore();                                    //玩家得分
                    }
                    if (f instanceof Award) {                                    //    若被撞对象是奖励
                        Award a = (Award)f;                                            //    强转为奖励接口
                        int type = a.getType();                                    //获取奖励类型
                        switch (type) {                                                    //基于不同的类型来得到不同的奖励
                        case Award.DOUBLE_FIRE:                                    //若奖励为火力值
                            hero.addDoubleFire();                                    //则增加火力值
                            break;
                        case Award.LIFE:                                                //若奖励为命
                            hero.addLife();                                                //则增加命
                            break;                                                                
                        }
                    }
                }
            }
        }
    }
    
    
    /** 成员方法:paint()方法 */
    @Override
    public void paint(Graphics g) {
        sky.paintObject(g);                                                //画天空
        hero.paintObject(g);                                            //画英雄机
        for (int i = 0; i < enemies.length; i++) {    //遍历所有敌人
            enemies[i].paintObject(g);                                //画敌对飞行物
        }
        for (int i = 0; i < bullets.length; i++) {    //遍历子弹
            bullets[i].paintObject(g);                                //画子弹
        }
        g.drawString("SCORE:" + score,10,25);
        g.drawString("LIFE:" + hero.getLife(), 10, 45);
    }
    
    /** main主方法 */
    public static void main(String[] args) {
        JFrame frame = new JFrame();                                                    //创建窗口
        World world = new World();                                                        //创建面板
        frame.add(world);                                                                        //将面板添加到窗口
        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);    //设置关闭窗口即停止运行程序
        frame.setSize(WIDTH,HEIGHT);                                                    //设置窗口大小
        frame.setLocationRelativeTo(null);                                     //设置窗口居中显示
        frame.setVisible(true);                                                         //1)设置窗口可见        2)尽快调用paint()方法
        
        world.action();                                                                            //启动程序
    }

}

 

 


以上是关于Python——飞机大战(day10)的主要内容,如果未能解决你的问题,请参考以下文章

python(pygame)滑稽大战(类似飞机大战) 教程

怎么用python学飞机大战?

python学习——飞机大战之初期

Python——飞机大战(day10)

Python飞机大战,Pygame入门,源码

如何用用python写飞机大战?