天天看點

pygame飛機大戰 小遊戲

運作效果

pygame飛機大戰 小遊戲

代碼

# 先導入系統子產品
import sys
# 随機子產品
import random

# 再導入第三方子產品
import pygame
import pygame.locals


# 背景圖檔路徑
IMG_BACKGROUND = "res/img_bg_level_1.jpg"
# 敵機圖檔路徑 元組
IMG_ENEMYPLANE = ("res/img-plane_1.png", "res/img-plane_2.png", "res/img-plane_3.png", "res/img-plane_4.png",
                  "res/img-plane_5.png", "res/img-plane_6.png", "res/img-plane_7.png")
# 玩家飛機圖檔路徑
IMG_PLAYER_PLANE = "res/hero2.png"
# 子彈圖檔
IMG_BULLET = "res/bullet_13.png"


class Model(object):
    """提供基礎模型"""
    # 視窗對象
    window = None

    def __init__(self, img_path, x, y):
        # 圖檔對象
        self.img = pygame.image.load(img_path)
        # x坐标
        self.x = x
        # y坐标
        self.y = y

    def display(self):
        # 将要顯示的對象添加到窗體中, 并指定其坐标
        Model.window.blit(self.img, (self.x, self.y))


class Game(object):
    """遊戲整體控制"""
    # 視窗寬度
    WINDOW_WIDTH = 512
    # 視窗高度
    WINDOW_HEIGHT = 768
    # 窗體标題
    WINDOW_TITLE = "Plane Battle v1.0"
    # 小圖示路徑
    APP_ICON = "res/app.ico"

    def __init__(self):
        # 窗體對象
        self.window = None
        # 背景對象
        self.background = None
        # 敵機對象
        self.enemy_planes = list()
        # 玩家對象
        self.player_plane = None

    def run(self):
        """運作入口, 整體遊戲控制"""
        # 架構初始化
        self.frame_init()
        # 模型初始化
        self.model_init()
        # 構造反複執行的機制, 重新整理窗體、使窗體保持在螢幕上
        while True:
            # 背景移動
            self.background.move()
            # 顯示背景
            self.background.display()

            for enemy_plane in self.enemy_planes:
                # 敵機下降
                enemy_plane.move()
                # 顯示敵機(加載貼圖)
                enemy_plane.display()

            # 顯示玩家
            self.player_plane.display()
            # 把敵機清單傳給玩家飛機, 好進行子彈與敵機的碰撞檢測
            self.player_plane.collision_checking(self.enemy_planes)
            # 重新整理窗體
            pygame.display.update()
            # 事件監聽
            self.event_init()

    def frame_init(self):
        """窗體初始化"""
        # 設定窗體對象
        self.window = pygame.display.set_mode((Game.WINDOW_WIDTH, Game.WINDOW_HEIGHT))
        # 将視窗對象傳給Model類屬性
        Model.window = self.window
        # 左上小圖示對象
        app_img = pygame.image.load(Game.APP_ICON)
        # 設定窗體圖示
        pygame.display.set_icon(app_img)
        # 設定窗體标題文本
        pygame.display.set_caption(Game.WINDOW_TITLE)

    def model_init(self):
        """初始化窗體中的對象"""
        # 背景對象
        self.background = Background(IMG_BACKGROUND, 0, 0)
        for _ in IMG_ENEMYPLANE:
            # 加入多加敵機到 敵機清單中
            self.enemy_planes.append(EnemyPlane())
        # 玩家對象
        self.player_plane = PlayerPlane(IMG_PLAYER_PLANE, PlayerPlane.PLAYERPLANE_X, PlayerPlane.PLAYERPLANE_Y)

    def event_init(self):
        """事件監聽"""
        # 擷取事件清單中的每一個事件
        for event in pygame.event.get():
            # 判斷事件類别是否為退出事件
            if event.type == pygame.locals.QUIT:
                # 退出程式
                sys.exit()
            # 當事件類别是滑鼠移動動作時
            if event.type == pygame.locals.MOUSEMOTION:
                # 擷取滑鼠坐标位置
                position = pygame.mouse.get_pos()
                # 根據滑鼠的位置設定玩家飛機的位置
                self.player_plane.x = position[0] - PlayerPlane.PLAYERPLANE_WIDTH / 2
                self.player_plane.y = position[1] - PlayerPlane.PLAYERPLANE_HEIGHT / 2 + 5
        # 擷取滑鼠是否按下的狀态
        mouse_state = pygame.mouse.get_pressed()
        # 判斷是否按下滑鼠左鍵
        if mouse_state[0] == 1:
            # 擷取滑鼠坐标位置
            position = pygame.mouse.get_pos()
            # 初始化子彈位置
            self.player_plane.bullets.append(
                Bullet(IMG_BULLET, position[0] - Bullet.BULLET_WIDTH / 2,
                       position[1] - Bullet.BULLET_HEIGHT - 30))
            # 當玩家按下滑鼠左鍵時, 才開始遊戲
            self.player_plane.start_game = True


class Background(Model):
    """背景"""
    def display(self):
        """裝載上下兩張圖檔到窗體中"""
        # 将要顯示的對象添加到窗體中, 并指定其坐标
        Model.window.blit(self.img, (self.x, self.y))
        Model.window.blit(self.img, (self.x, self.y - Game.WINDOW_HEIGHT))

    def move(self):
        """背景移動"""
        # 當縱軸的值小于等于螢幕高度時:
        if self.y <= Game.WINDOW_HEIGHT:
            # 移動圖檔
            self.y += 1
        else:
            # 圖檔歸位
            self.y = 0


class PlayerPlane(Model):
    """玩家飛機"""
    # 玩家飛機的寬度
    PLAYERPLANE_WIDTH = 120
    # 玩家飛機的高度
    PLAYERPLANE_HEIGHT = 78
    # 玩家飛機的初始位置
    PLAYERPLANE_X = 200
    PLAYERPLANE_Y = 500

    def __init__(self, img, x, y):
        super().__init__(img, x, y)
        # 子彈清單對象
        self.bullets = list()
        # 需要删除的子彈清單
        self.remove_bullets = list()
        # 玩家是否開始遊戲标志
        self.start_game = False

    def collision_checking(self, enemy_list):
        """子彈的顯示, 還有子彈與敵機的碰撞檢測"""
        for bullet in self.bullets:
            # 子彈移動
            bullet.move()
            # 子彈顯示
            bullet.display()
            # 當子彈飛出螢幕時:
            if bullet.y < -Bullet.BULLET_HEIGHT:
                # 将這個子彈添加到待删除子彈的清單
                self.remove_bullets.append(bullet)
            # 子彈沒有飛出螢幕
            else:
                # 子彈矩形
                bullet_rect = pygame.locals.Rect(bullet.x, bullet.y, Bullet.BULLET_WIDTH, Bullet.BULLET_HEIGHT)

                for enemy in enemy_list:
                    # 敵機矩形
                    enemy_rect = pygame.locals.Rect(enemy.x, enemy.y, EnemyPlane.ENEMYPLANE_WIDTH, EnemyPlane.ENEMYPLANE_HEIGHT)

                    # 兩個矩形碰撞檢測
                    if pygame.Rect.colliderect(bullet_rect, enemy_rect):
                        # 子彈碰撞敵機後, 敵機歸位到螢幕上方
                        enemy.enemy_plane_init()
                        # 子彈加入删除清單
                        self.remove_bullets.append(bullet)
                        # 一顆子彈隻能撞擊 一架敵機, 退出for循環
                        break
        # 玩家飛機矩形
        player_rect = pygame.locals.Rect(self.x, self.y, PlayerPlane.PLAYERPLANE_WIDTH,
                                         PlayerPlane.PLAYERPLANE_HEIGHT)

        for enemy in enemy_list:
            # 敵機矩形
            enemy_rect = pygame.locals.Rect(enemy.x, enemy.y, EnemyPlane.ENEMYPLANE_WIDTH,
                                            EnemyPlane.ENEMYPLANE_HEIGHT)
            # 玩家飛機與敵機碰撞檢測
            if pygame.Rect.colliderect(player_rect, enemy_rect):
                # 一開始遊戲時, 玩家按下滑鼠左鍵, 才能判斷玩家飛機與敵機碰撞檢測, 再退出遊戲
                if self.start_game:
                    # 退出程式
                    sys.exit()

        # 根據 待删除子彈的清單 删除子彈清單中的對象
        for bullet in self.remove_bullets:
            self.bullets.remove(bullet)
        else:
            # 删除完後, 需要将 待删除清單清空
            self.remove_bullets.clear()


class Bullet(Model):
    """子彈"""
    # 子彈的寬度
    BULLET_WIDTH = 20
    # 子彈的高度
    BULLET_HEIGHT = 29
    # 子彈間的移動速度
    BULLET_SPEED = 8

    def move(self):
        """子彈移動"""
        self.y -= Bullet.BULLET_SPEED


class EnemyPlane(Model):
    """敵機"""
    # 敵機的寬度
    ENEMYPLANE_WIDTH = 100
    # 敵機的高度
    ENEMYPLANE_HEIGHT = 68
    # 敵機移動速度
    ENEMYPLANE_SPEED = 4

    def __init__(self):
        self.enemy_plane_init()

    def enemy_plane_init(self):
        """初始化敵機"""
        # 敵機歸到視窗上方
        self.y = 0 - EnemyPlane.ENEMYPLANE_HEIGHT
        # 敵機橫坐标随機出現
        self.x = random.randint(0, Game.WINDOW_WIDTH - EnemyPlane.ENEMYPLANE_WIDTH)
        # 貼圖随機
        self.img = pygame.image.load(IMG_ENEMYPLANE[random.randint(0, 6)])

    def move(self):
        # 當敵機沒有下降出螢幕高度時
        if self.y <= Game.WINDOW_HEIGHT:
            # 移動敵機
            self.y += EnemyPlane.ENEMYPLANE_SPEED
        else:
            self.enemy_plane_init()


if __name__ == '__main__':
    Game().run()

           

打包成exe文章連結

記一次pygame小程式打包成exe

圖檔素材位址

連結: https://pan.baidu.com/s/1mMeJfSqEjSgMATxU6SXfZg

提取碼: 9cge

繼續閱讀