Python版飞机大战

Posted 杨立果

tags:

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

前面学了java用java写了飞机大战这次学完python基础后写了个python版的飞机大战,有兴趣的可以看下。

  父类是飞行物类是所有对象的父类,setting里面是需要加载的图片,你可以换称自己的喜欢的图片,敌机可以分为敌机和奖励,enemy为普通敌人的父类,award为奖励敌机的父类。

技术分享图片

各个类的基本属性

技术分享图片

主类的大概逻辑

技术分享图片

具体的代码:

settings配置

import pygame

class Settings(object):
    """设置常用的属性"""

    def __init__(self):
        self.bgImage = pygame.image.load('img/background.png')  # 背景图

        self.bgImageWidth = self.bgImage.get_rect()[2]  # 背景图宽
        self.bgImageHeight = self.bgImage.get_rect()[3]  # 背景图高
        self.start=pygame.image.load("img/start.png")
        self.pause=pygame.image.load("img/pause.png")
        self.gameover=pygame.image.load("img/gameover.png")
        self.heroImages = ["img/hero.gif",
                           "img/hero1.png", "img/hero2.png"]  # 英雄机图片
        self.airImage = pygame.image.load("img/enemy0.png") # airplane的图片
        self.beeImage = pygame.image.load("img/bee.png") # bee的图片
        self.heroBullet=pygame.image.load("img/bullet.png")# 英雄机的子弹

英雄机

from flyingObject import FlyingObject
from bullet import Bullet
import pygame


class Hero(FlyingObject):
    """英雄机"""
    index = 2  # 标志位
    def __init__(self, screen, images):

        self.screen = screen
        self.life = 3  # 生命值为3
        self.doubleFire = 0  # 初始火力值为0
        self.images = images  # 英雄级图片数组,为Surface实例
        self.image = pygame.image.load(images[0])
        self.width = self.image.get_rect()[2]
        self.height = self.image.get_rect()[3]
        self.x = screen.get_rect().centerx - self.width / 2
        self.y = screen.get_rect().bottom + self.height

    def isDoubleFire(self):
        """获取双倍火力"""
        return self.doubleFire

    def setDoubleFire(self):
        """设置双倍火力"""
        self.doubleFire = 40

    def addDoubleFire(self):
        """增加火力值"""
        self.doubleFire += 100
    def clearDoubleFire(self):
        """清空火力值"""
        self.doubleFire=0

    def addLife(self):
        """增命"""
        self.life += 1
    
    def sublife(self):
        """减命"""
        self.life-=1
   
    def getLife(self):
        """获取生命值"""
        return self.life
    def reLife(self):
        self.life=3
        self.clearDoubleFire()

    def blitme(self):
        """绘制英雄机"""
        self.screen.blit(self.image, (self.x, self.y))


    def outOfBounds(self):
        return False

    def step(self):
        """动态显示飞机"""
        if(len(self.images) > 0):
            Hero.index += 1
            Hero.index %= len(self.images)
            self.image = pygame.image.load(self.images[int(Hero.index)])  # 切换图片

    def move(self, x, y):
        self.x = x - self.width / 2
        self.y = y - self.height / 2

    def shoot(self,image):
        """英雄机射击"""
        xStep=int(self.width/4-5)
        yStep=20
        if self.doubleFire>=100:
            heroBullet=[Bullet(self.screen,image,self.x+1*xStep,self.y-yStep),Bullet(self.screen,image,self.x+2*xStep,self.y-yStep),Bullet(self.screen,image,self.x+3*xStep,self.y-yStep)]
            self.doubleFire-=3
            return heroBullet
        elif self.doubleFire<100 and self.doubleFire > 0:
            heroBullet=[Bullet(self.screen,image,self.x+1*xStep,self.y-yStep),Bullet(self.screen,image,self.x+3*xStep,self.y-yStep)]
            self.doubleFire-=2
            return heroBullet
        else:
            heroBullet=[Bullet(self.screen,image,self.x+2*xStep,self.y-yStep)]
            return heroBullet

    def hit(self,other):
        """英雄机和其他飞机"""
        x1=other.x-self.width/2
        x2=other.x+self.width/2+other.width
        y1=other.y-self.height/2
        y2=other.y+self.height/2+other.height
        x=self.x+self.width/2
        y=self.y+self.height
        return x>x1 and x<x2 and y>y1 and y<y2

enemys

import abc

class Enemy(object):
    """敌人,敌人有分数"""
    @abc.abstractmethod
    def getScore(self):
        """获得分数"""
        pass

award

import abc


class Award(object):
    """奖励"""
    DOUBLE_FIRE = 0
    LIFE = 1

    @abc.abstractmethod
    def getType(self):
        """获得奖励类型"""
        pass


if __name__ == '__main__':

    print(Award.DOUBLE_FIRE)

airplane

import random
from flyingObject import FlyingObject
from enemy import Enemy


class Airplane(FlyingObject, Enemy):
    """普通敌机"""

    def __init__(self, screen, airImage):
        self.screen = screen
        self.image = airImage
        self.width = self.image.get_rect()[2]
        self.height = self.image.get_rect()[3]
        self.x = random.randint(0, screen.get_rect()[2] - self.width)
        self.y = -self.height

    def getScore(self):
        """获得的分数"""
        return 5

    def outOfBounds(self):
        """是否越界"""

        return self.y < 715

    def step(self):
        """移动"""
        self.y += 3  # 移动步数

    def blitme(self):
        """打印飞行物"""
        self.screen.blit(self.image, (self.x, self.y))

Bee

import random
from flyingObject import FlyingObject
from award import Award


class Bee(FlyingObject, Award):

    def __init__(self, screen, beeImage):
        self.screen = screen
        self.image = beeImage
        self.width = self.image.get_rect()[2]
        self.height = self.image.get_rect()[3]
        self.x = random.randint(0, screen.get_rect()[2] - self.width)
        self.y = -self.height
        self.awardType = random.randint(0, 1)
        self.index = True

    def outOfBounds(self):
        """是否越界"""
        return self.y < 715

    def step(self):
        """移动"""
        if self.x + self.width > 480:
            self.index = False
        if self.index == True:
            self.x += 3
        else:
            self.x -= 3
        self.y += 3  # 移动步数

    def getType(self):
        return self.awardType

    def blitme(self):
        """打印飞行物"""
        self.screen.blit(self.image, (self.x, self.y))

主类

import pygame
import sys
import random
from setting import Settings
from hero import Hero
from airplane import Airplane
from bee import Bee
from enemy import Enemy
from award import Award

START=0
RUNNING=1
PAUSE=2
GAMEOVER=3
state=START
sets = Settings()
screen = pygame.display.set_mode(
        (sets.bgImageWidth, sets.bgImageHeight), 0, 32) #创建窗口
hero=Hero(screen,sets.heroImages)
flyings=[]
bullets=[]
score=0
def hero_blitme():
    """画英雄机"""
    global hero
    hero.blitme()
   
def bullets_blitme():
    """画子弹"""
    for b in bullets:
        b.blitme()

def flyings_blitme():
    """画飞行物"""
    global sets
    for fly in flyings:
        fly.blitme()

def score_blitme():
    """画分数和生命值"""
    pygame.font.init()
    fontObj=pygame.font.Font("SIMYOU.TTF", 20) #创建font对象
    textSurfaceObj=fontObj.render(u'生命值:%d\n分数:%d\n火力值:%d'%(hero.getLife(),score,hero.isDoubleFire()),False,(135,100,184))
    textRectObj=textSurfaceObj.get_rect()
    textRectObj.center=(300,40)
    screen.blit(textSurfaceObj,textRectObj)



def state_blitme():
    """画状态"""
    global sets
    global state
    if state==START:
        screen.blit(sets.start, (0,0))
    elif state==PAUSE:
        screen.blit(sets.pause,(0,0))
    elif state== GAMEOVER:
        screen.blit(sets.gameover,(0,0))


def blitmes():
    """画图"""
    hero_blitme()
    flyings_blitme()
    bullets_blitme()
    score_blitme()
    state_blitme()

def nextOne():
    """生成敌人"""
    type=random.randint(0,20)
    if type<4:
        return Bee(screen,sets.beeImage)
    elif type==5:
        return Bee(screen,sets.beeImage) #本来准备在写几个敌机的,后面没找到好看的图片就删了
    else:
        return Airplane(screen,sets.airImage)

flyEnteredIndex=0
def enterAction():
    """生成敌人"""
    global flyEnteredIndex
    flyEnteredIndex+=1
    if flyEnteredIndex%40==0:
        flyingobj=nextOne()
        flyings.append(flyingobj)

shootIndex=0
def shootAction():
    """子弹入场,将子弹加到bullets"""
    global shootIndex
    shootIndex +=1
    if shootIndex % 10 ==0:
        heroBullet=hero.shoot(sets.heroBullet)
        for bb in heroBullet:
            bullets.append(bb)

def stepAction():
    """飞行物走一步"""
    
    hero.step()
    for flyobj in flyings:
        flyobj.step()
    global bullets
    for b in bullets:       
        b.step()

def outOfBoundAction():
    """删除越界的敌人和飞行物"""
    global flyings
    flyingLives=[]
    index=0
    for f in flyings:
        if f.outOfBounds()==True:
            flyingLives.insert(index,f)
            index+=1
    flyings=flyingLives
    index=0
    global bullets
    bulletsLive=[]
    for b in bullets:
        if b.outOfBounds()==True:
            bulletsLive.insert(index,b)
            index+=1
    bullets=bulletsLive


j=0
def bangAction():
    """子弹与敌人碰撞"""
    for b in bullets:
        bang(b)


def bang(b):
    """子弹与敌人碰撞检测"""
    index=-1
    for x in range(0,len(flyings)):
        f=flyings[x]
        if f.shootBy(b):
            index=x
            break
    if index!=-1:
        one=flyings[index]
        if isinstance(one,Enemy):
            global score
            score+=one.getScore() # 获得分数
            flyings.remove(one) # 删除

        if isinstance(one,Award):
            type=one.getType()
            if type==Award.DOUBLE_FIRE:
                hero.addDoubleFire()
            else:
                hero.addLife()
            flyings.remove(one)

        bullets.remove(b)

def checkGameOverAction():
    if isGameOver():
        global state
        state=GAMEOVER
        hero.reLife()

def isGameOver():
    for f in flyings:
        if hero.hit(f):
            hero.sublife()
            hero.clearDoubleFire()
            flyings.remove(f)

    return hero.getLife()<=0


def action():
    x, y = pygame.mouse.get_pos()
    
    blitmes()  #打印飞行物 
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            sys.exit()
        if event.type == pygame.MOUSEBUTTONDOWN:
            flag=pygame.mouse.get_pressed()[0] #左键单击事件
            rflag=pygame.mouse.get_pressed()[2] #右键单击事件
            global state
            if flag==True and (state==START or state==PAUSE):
                state=RUNNING
            if flag==True and state==GAMEOVER:
                state=START
            if rflag==True:
                state=PAUSE

    if state==RUNNING:
        hero.move(x,y)  
        enterAction()
        shootAction()
        stepAction()      
        outOfBoundAction()
        bangAction()
        checkGameOverAction()
    
         
def main():
   
    pygame.display.set_caption("飞机大战")
   
    while True:
        screen.blit(sets.bgImage, (0, 0))  # 加载屏幕

        action()
        pygame.display.update()  # 重新绘制屏幕
        # time.sleep(0.1)       # 过0.01秒执行,减轻对cpu的压力


if __name__ == '__main__':
    main()

 写这个主要是练习一下python,把基础打实些。pygame的文本书写是没有换行,得在新建一个对象去写,为了简单我把文本都书写在了一行。

background.png

技术分享图片

hero.gif

技术分享图片

技术分享图片

技术分享图片

bee.png

技术分享图片

enemy.png

技术分享图片

gameover.png

技术分享图片

start.png

技术分享图片

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

重温经典:Python版飞机大战源码 神器 玩游戏就玩自己开发的

重温经典:Python版飞机大战源码,装逼神器。玩游戏就玩自己开发的~

豪华版飞机大战系列

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

Html5版飞机大战游戏中(Boss战)制作

python3飞机大战