1. 程式人生 > 其它 >python飛機大戰

python飛機大戰

技術標籤:pythonpygame遊戲遊戲開發2d遊戲

飛機大戰

前言

開始

獻上程式碼

from tkinter.messagebox import showinfo
from pygame.locals import *
import tkinter as tk
from random import *
import pygame
base = tk.Tk()
base.geometry('0x0')
base.resizable(False,False)
def intersect_p2f(p,f):
    return
pygame.Rect(f).collidepoint(*p) def intersect_f2f(f1,f2): return pygame.Rect(f1).colliderect(pygame.Rect(f2)) def main(): WIDTH,HEIGHT = 480,640 scr = pygame.display.set_mode((WIDTH,HEIGHT)) bg = pygame.image.load('background.jpg') fighter = pygame.image.load('fighter.jpg') plane_enemy =
pygame.image.load('plane_enemy.jpg') enemy_bullet = pygame.image.load('enemy_bullet.jpg') fighter_bullet = pygame.image.load('fighter_bullet.jpg') planes = [] enemy_bullets = [] fighter_x = 0 fighter_bullets = [] score = 0 n = 1 R_P = L_P = False while(1): for
i in enemy_bullets: if(intersect_p2f(i,((fighter_x, HEIGHT - 64),(fighter_x, HEIGHT - 64)))): return score for i in range(len(planes)): if(i >= len(planes)): break for j in fighter_bullets: if(intersect_p2f(j,(planes[i],(planes[i][0] + 64,planes[i][1] + 64)))): planes.pop(i) score += 10 pygame.display.update() scr.blit(bg,(0,0)) n = (n + 1) % 600 if(not n): x = randint(0,WIDTH - 64) y = randint(0,HEIGHT / 2) planes.append((x,y)) elif(not n % 90): for i in range(len(planes)): enemy_bullets.append((planes[i][0] + 32, planes[i][1] + 64)) fighter_bullets.append((fighter_x + 32, HEIGHT - 64)) elif(not n % 8): if(L_P and (not R_P)): fighter_x = max(fighter_x - 5, 0) if(R_P and (not L_P)): fighter_x = min(fighter_x + 5, WIDTH - 64) for i in range(len(planes)): planes[i] = (planes[i][0],planes[i][1] + 0.5) scr.blit(plane_enemy,planes[i]) scr.blit(fighter, (fighter_x, HEIGHT - 64)) for i in range(len(enemy_bullets)): if (i >= len(enemy_bullets)): break enemy_bullets[i] = (enemy_bullets[i][0],enemy_bullets[i][1] + 5) if(enemy_bullets[i][1] >= WIDTH): enemy_bullets.pop(i) if (i >= len(enemy_bullets)): break scr.blit(enemy_bullet,enemy_bullets[i]) for i in range(len(fighter_bullets)): if (i >= len(fighter_bullets)): break fighter_bullets[i] = (fighter_bullets[i][0],fighter_bullets[i][1] - 5) if(fighter_bullets[i][1] <= 0): fighter_bullets.pop(i) if (i >= len(fighter_bullets)): break scr.blit(fighter_bullet,fighter_bullets[i]) for ev in pygame.event.get(): if(ev.type == QUIT): exit() elif(ev.type == KEYDOWN): if(ev.key == K_LEFT): L_P = True elif(ev.key == K_RIGHT): R_P = True elif(ev.type == KEYUP): if (ev.key == K_LEFT): L_P = False elif (ev.key == K_RIGHT): R_P = False if(__name__ == '__main__'): while(1): score = main() showinfo('GAMEOVER!','GAMEOVER!score:%s'%score)

程式碼剖析

from tkinter.messagebox import showinfo
from pygame.locals import *
import tkinter as tk
from random import *
import pygame
base = tk.Tk()
base.geometry('0x0')
base.resizable(False,False)

匯入庫及初始化

def intersect_p2f(p,f):
    return pygame.Rect(f).collidepoint(*p)
def intersect_f2f(f1,f2):
    return pygame.Rect(f1).colliderect(pygame.Rect(f2))

使用pygame.Rect物件提供的collide*方法檢查是否重疊。

def main():
    WIDTH,HEIGHT = 480,640
    scr = pygame.display.set_mode((WIDTH,HEIGHT))
    bg = pygame.image.load('background.jpg')
    fighter = pygame.image.load('fighter.jpg')
    plane_enemy = pygame.image.load('plane_enemy.jpg')
    enemy_bullet = pygame.image.load('enemy_bullet.jpg')
    fighter_bullet = pygame.image.load('fighter_bullet.jpg')
    planes = []
    enemy_bullets = []
    fighter_x = 0
    fighter_bullets = []
    score = 0
    n = 1
    R_P = L_P = False
    while(1):
        for i in enemy_bullets:
            if(intersect_p2f(i,((fighter_x, HEIGHT - 64),(fighter_x, HEIGHT - 64)))):
                return score
        for i in range(len(planes)):
            if(i >= len(planes)):
                break
            for j in fighter_bullets:
                if(intersect_p2f(j,(planes[i],(planes[i][0] + 64,planes[i][1] + 64)))):
                    planes.pop(i)
                    score += 10
        pygame.display.update()
        scr.blit(bg,(0,0))
        n = (n + 1) % 600
        if(not n):
            x = randint(0,WIDTH - 64)
            y = randint(0,HEIGHT / 2)
            planes.append((x,y))
        elif(not n % 90):
            for i in range(len(planes)):
                enemy_bullets.append((planes[i][0] + 32, planes[i][1] + 64))
            fighter_bullets.append((fighter_x + 32, HEIGHT - 64))
        elif(not n % 8):
            if(L_P and (not R_P)):
                fighter_x = max(fighter_x - 5, 0)
            if(R_P and (not L_P)):
                fighter_x = min(fighter_x + 5, WIDTH - 64)
        for i in range(len(planes)):
            planes[i] = (planes[i][0],planes[i][1] + 0.5)
            scr.blit(plane_enemy,planes[i])
        scr.blit(fighter, (fighter_x, HEIGHT - 64))
        for i in range(len(enemy_bullets)):
            if (i >= len(enemy_bullets)):
                break
            enemy_bullets[i] = (enemy_bullets[i][0],enemy_bullets[i][1] + 5)
            if(enemy_bullets[i][1] >= WIDTH):
                enemy_bullets.pop(i)
            if (i >= len(enemy_bullets)):
                break
            scr.blit(enemy_bullet,enemy_bullets[i])
        for i in range(len(fighter_bullets)):
            if (i >= len(fighter_bullets)):
                break
            fighter_bullets[i] = (fighter_bullets[i][0],fighter_bullets[i][1] - 5)
            if(fighter_bullets[i][1] <= 0):
                fighter_bullets.pop(i)
            if (i >= len(fighter_bullets)):
                break
            scr.blit(fighter_bullet,fighter_bullets[i])
        for ev in pygame.event.get():
            if(ev.type == QUIT):
                exit()
            elif(ev.type == KEYDOWN):
                if(ev.key == K_LEFT):
                    L_P = True
                elif(ev.key == K_RIGHT):
                    R_P = True
            elif(ev.type == KEYUP):
                if (ev.key == K_LEFT):
                    L_P = False
                elif (ev.key == K_RIGHT):
                    R_P = False

這裡分開剖析

    WIDTH,HEIGHT = 480,640
    scr = pygame.display.set_mode((WIDTH,HEIGHT))
    bg = pygame.image.load('background.jpg')
    fighter = pygame.image.load('fighter.jpg')
    plane_enemy = pygame.image.load('plane_enemy.jpg')
    enemy_bullet = pygame.image.load('enemy_bullet.jpg')
    fighter_bullet = pygame.image.load('fighter_bullet.jpg')
    planes = []
    enemy_bullets = []
    fighter_x = 0
    fighter_bullets = []
    score = 0
    n = 1
    R_P = L_P = False

初始化變數:

  • 視窗長寬
  • 視窗物件
  • 5張圖片
  • 敵方飛機列表
  • 敵方子彈列表
  • 己方飛機x軸座標
  • 己方子彈列表
  • 迴圈圈數
  • 是否正在按左箭頭和右箭頭(pygame.K_LEFTpygame.K_RIGHT)
    while(1):
        for i in enemy_bullets:
            if(intersect_p2f(i,((fighter_x, HEIGHT - 64),(fighter_x, HEIGHT - 64)))):
                return score
        for i in range(len(planes)):
            if(i >= len(planes)):
                break
            for j in fighter_bullets:
                if(intersect_p2f(j,(planes[i],(planes[i][0] + 64,planes[i][1] + 64)))):
                    planes.pop(i)
                    score += 10

進入遊戲迴圈,檢查飛機是否被射下:

  • 己方飛機被敵方射下,遊戲結束(敵方子彈在我方飛機上)
  • 敵方飛機被己方射下,加10分(我放子彈在敵方飛機上)
        pygame.display.update()
        scr.blit(bg,(0,0))
        n = (n + 1) % 600
        if(not n):
            x = randint(0,WIDTH - 64)
            y = randint(0,HEIGHT / 2)
            planes.append((x,y))
        elif(not n % 90):
            for i in range(len(planes)):
                enemy_bullets.append((planes[i][0] + 32, planes[i][1] + 64))
            fighter_bullets.append((fighter_x + 32, HEIGHT - 64))
        elif(not n % 8):
            if(L_P and (not R_P)):
                fighter_x = max(fighter_x - 5, 0)
            if(R_P and (not L_P)):
                fighter_x = min(fighter_x + 5, WIDTH - 64)

重新整理頁面並按照迴圈圈數執行:

  • 每600次迴圈生成新的敵方飛機
  • 每90次迴圈生成發射新的子彈(敵、我方)
  • 每8次處理按下左箭頭和右箭頭一次。
        for i in range(len(planes)):
            planes[i] = (planes[i][0],planes[i][1] + 0.5)
            scr.blit(plane_enemy,planes[i])
        scr.blit(fighter, (fighter_x, HEIGHT - 64))
        for i in range(len(enemy_bullets)):
            if (i >= len(enemy_bullets)):
                break
            enemy_bullets[i] = (enemy_bullets[i][0],enemy_bullets[i][1] + 5)
            if(enemy_bullets[i][1] >= WIDTH):
                enemy_bullets.pop(i)
            if (i >= len(enemy_bullets)):
                break
            scr.blit(enemy_bullet,enemy_bullets[i])
        for i in range(len(fighter_bullets)):
            if (i >= len(fighter_bullets)):
                break
            fighter_bullets[i] = (fighter_bullets[i][0],fighter_bullets[i][1] - 5)
            if(fighter_bullets[i][1] <= 0):
                fighter_bullets.pop(i)
            if (i >= len(fighter_bullets)):
                break
            scr.blit(fighter_bullet,fighter_bullets[i])

敵方飛機自動移動0.5個畫素,子彈自動移動5個畫素,刪除出界的子彈。

        for ev in pygame.event.get():
            if(ev.type == QUIT):
                exit()
            elif(ev.type == KEYDOWN):
                if(ev.key == K_LEFT):
                    L_P = True
                elif(ev.key == K_RIGHT):
                    R_P = True
            elif(ev.type == KEYUP):
                if (ev.key == K_LEFT):
                    L_P = False
                elif (ev.key == K_RIGHT):
                    R_P = False

當左箭頭(K_LEFT)被按下時將L_P(Left Pressed)跟改為True
當左箭頭(K_LEFT)被放開時將L_P(Left Pressed)跟改為False
當左箭頭(K_RIGHT)被按下時將R_P(Right Pressed)跟改為True
當又箭頭(K_RIGHT)被放開時將R_P(Right Pressed)跟改為False

if(__name__ == '__main__'):
    while(1):
        score = main()
        showinfo('GAMEOVER!','GAMEOVER!score:%s'%score)

執行並提示gameover

專案github

github傳送門

其他

專案素材均來自這篇文章中提供的網盤。


作者

hit-road

拜拜,下課!
回到頂部