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")# 英雄機的子彈

飛行物類

import abc


class FlyingObject(object):
    """飛行物類,基類"""

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

    @abc.abstractmethod
    def outOfBounds(self):
        """檢查是否越界"""
        pass

    @abc.abstractmethod
    def step(self):
        """飛行物移動一步"""
        pass

    def shootBy(self, bullet):
        """檢查當前飛行物是否被子彈bullet(x,y)擊中"""
        x1 = self.x
        x2 = self.x + self.width
        y1 = self.y
        y2 = self.y + self.height
        x = bullet.x
        y = bullet.y
        return x > x1 and x < x2 and y > y1 and y < y2

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

英雄機

from flyingObject import FlyingObject
from bullet import Bullet
import pygame


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

        # self.screen = screen
        
        self.images = images  # 英雄級圖片數組,為Surface實例
        image = pygame.image.load(images[0])
        x = screen.get_rect().centerx
        y = screen.get_rect().bottom
        super(Hero,self).__init__(screen,x,y,image)
        self.life = 3  # 生命值為3
        self.doubleFire = 0  # 初始火力值為0

    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 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, image):

        x = random.randint(0, screen.get_rect()[2] - 50)
        y = -40
        super(Airplane, self).__init__(screen, x, y, image)

    def getScore(self):
        """獲得的分數"""
        return 5

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

        return self.y < 715

    def step(self):
        """移動"""
        self.y += 3  # 移動步數

Bee

import random
from flyingObject import FlyingObject
from award import Award


class Bee(FlyingObject, Award):

    def __init__(self, screen, image):
        x = random.randint(0, screen.get_rect()[2] - 60)
        y = -50
        super(Bee, self).__init__(screen, x, y, image)
        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


主類

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**
  
![這里寫圖片描述](http://img.blog.csdn.net/20171204191610703?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

**hero.gif**

![這里寫圖片描述](http://img.blog.csdn.net/20171204191721134?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
  
![這里寫圖片描述](http://img.blog.csdn.net/20171204191750956?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

![這里寫圖片描述](http://img.blog.csdn.net/20171204191820039?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

**bee.png**

![這里寫圖片描述](http://img.blog.csdn.net/20171204191837407?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

**enemy.png**

![這里寫圖片描述](http://img.blog.csdn.net/20171204191948067?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

**gameover.png**

![這里寫圖片描述](http://img.blog.csdn.net/20171204192039476?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

**start.png**

![這里寫圖片描述](http://img.blog.csdn.net/20171204192112850?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvTGl2ZW9yX0RpZQ==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM