500行代碼,教你用python寫個微信飛機大戰

来源:https://www.cnblogs.com/moonhmily/archive/2019/10/16/11682195.html
-Advertisement-
Play Games

這幾天在重溫微信小游戲的飛機大戰,玩著玩著就在思考人生了,這飛機大戰怎麼就可以做的那麼好,操作簡單,簡單上手。 幫助蹲廁族、YP族、飯圈女孩在無聊之餘可以有一樣東西讓他們振作起來!讓他們的左手 / 右手有節奏有韻律的朝著同一個方向來回移動起來! 這是史詩級的發明,是濃墨重彩的一筆,是……... ...


在這裡插入圖片描述

這幾天在重溫微信小游戲的飛機大戰,玩著玩著就在思考人生了,這飛機大戰怎麼就可以做的那麼好,操作簡單,簡單上手。

幫助蹲廁族、YP族、飯圈女孩在無聊之餘可以有一樣東西讓他們振作起來!讓他們的左手 / 右手有節奏有韻律的朝著同一個方向來回移動起來!

這是史詩級的發明,是濃墨重彩的一筆,是……
在一陣抽搐後,我結束了游戲,瞬時覺得一切都索然無味,正在我進入賢者模式時,突然想到,如果我可以讓更多人已不同的方式體會到這種美輪美奐的感覺豈不美哉?

所以我打開電腦,創建了一個 plan_game.py……

先看效果圖

在這裡插入圖片描述

操作環境

  • 操作系統:windows10
  • python版本:python 3.7
  • 代碼編輯器:pycharm 2018.2
  • 使用模塊:os,sys,random,pygame

因為實現代碼使用到了一個pygame的第三方模塊,沒有的先 pip install 一下,這裡順便提供一個比較好的pygame的教程.

https://eyehere.net/2011/python-pygame-novice-professional-index/

具體實現

  1. 首先我們先指定素材文件的文件目錄.方便我們後面的使用。這些素材已經全部上傳至公眾號Python專欄,後臺回覆:飛機大戰,即可獲得。
import os

# 得到當前文件夾下麵的material_images目錄的路徑
source_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'material_images')
  1. 實現一個Game類,用來完成這個游戲的主要邏輯。
import pygame


class Game():
    def __init__(self, background_image_path, size=(480, 700), title='飛機大戰', font_name='方正舒體', font_size=30, speed=2000):
        '''
        :param background_image_path: 背景圖片的路徑地址
        :param size: 游戲視窗的大小
        :param title: 游戲視窗的標題
        :param font_name: 指定字體
        :param font_size: 指定字體大小
        :param speed: 背景圖滾動整個視窗一次所用時間,單位為ms
        '''
        self.size = size
        self.screen = pygame.display.set_mode(size)
        self.title = title
        self.background_image_path = background_image_path
        self.background = pygame.image.load(self.background_image_path).convert()
        # 設置字體對象,得到系統中自帶的字體
        self.font = pygame.font.SysFont(font_name, font_size)
        # 得到Clock對象,我們可以使用它來獲取距離上次繪製圖像的時間
        self.clock = pygame.time.Clock()
        # 背景圖初始位置
        self.height = 0
        # 使用視窗的高度處於滾動的時間,就能得到每ms滾動的距離
        self.every_ms_move_distance = self.size[1] / speed   # 2秒
        # 分數
        self.score = 0
        # 存放所有的敵機
        self.enemies = []


    def show_score(self):
        '''
        顯示分數, 在視窗的的最上方距離上邊距10px, 左右居中
        '''
        pass


    def set_time_passed(self):
        # 控制畫 的幀, 越大越快
        # 得到上一次繪製圖像到到現在的時間, ms
        self.time_passed = self.clock.tick()


    def draw_background(self):
        '''
        繪製背景圖片,一直向下滾動,營造飛機一直往上面飛的感覺
        '''
        # 每次移動的距離 = 每ms移動的距離 * 上次到現在的時間(ms)
        pass


    def create_enemy(self, image_path=os.path.join(source_dir,'enemy1.png'), enemy_number=5):
        '''
        創建敵機
        :param image_path: 敵機的圖片地址
        :param enemy_number: 最多有幾個敵機在屏幕上
        '''
        pass


    def draw_enemies(self, time_passed, screen):
        '''
        繪製敵機到屏幕上,清理跑出視窗的敵機,
        :param time_passed: 上次繪製導向現在經過的時間
        :param screen: 繪製的視窗對象
        '''
        pass


    def bullet_and_enemy_crash_detection(self, bullets):
        '''
        檢測子彈是否擊中敵機
        :param bullets: 飛機的所有子彈
        '''
        pass


    def plan_and_enemy_crash_detection(self, plan, allow_crash_size=None):
        '''
        檢測敵機與飛機是否相撞
        :param plan: 飛機對象
        :param allow_crash_size: 允許飛機碰撞的大小,只有左右有效
        '''
        pass


    def draw_plan(self, plan, time_passed):
        '''
        繪製飛機
        :param plan: 飛機對象
        :param time_passed: 距離上次繪製的時間
        :return:
        '''
        pass


    def game_over(self):
        '''
        游戲結束
        '''
        while True:
            # 繪製背景圖
            pass


    def run(self):
        '''
        游戲入口函數,開始函數,主體函數
        :return:
        '''

        # 設置游戲視窗的大小
        pygame.display.set_caption(self.title)
        # 初始化一個飛機對象
        plan = Plan()

        while True:
            # 如果飛機自毀完成, 游戲結束, 調用game_over函數
            pass

            # 檢測監聽事件
            pass

            # 檢測上下左右的移動案件.
            # w,a,s,d 和 上,下,左,右鍵都可以
            # 然後執行plan.update函數,改變飛機的位置
            pass

            # 子彈和敵機的碰撞檢測
            self.bullet_and_enemy_crash_detection(plan.bullets)
            # 飛機與敵機的碰撞檢測
            self.plan_and_enemy_crash_detection(plan)
            # 設置屬性time_passed的值, 距離上次的時間,方便後面使用
            self.set_time_passed()
            # 繪製背景圖片
            self.draw_background()
            # 顯示分數
            self.show_score()
            # 生成敵機
            self.create_enemy()
            # 繪製敵機
            self.draw_enemies(time_passed=self.time_passed, screen=self.screen)
            # 繪製飛機
            self.draw_plan(plan=plan, time_passed=self.time_passed)
            # 繪製子彈
            plan.draw_bullets(time_passed=self.time_passed, screen=self.screen)
            # 顯示我們的圖像
            pygame.display.update()

這裡說以下怎樣查看自己的系統中有哪些自帶的字體.
pygame.font.get_fonts(),這個函數就能夠得到系統中所有的自帶字體文件。不過,當我們游戲中有中文的時候,我們也得選擇支持中文的字體,否則的話是顯示不出中文的。

在這裡插入圖片描述

  1. 實現DestroyAnimationMixin類,這個類主要是用來顯示飛機或敵機的自毀動畫
# 顯示飛機自毀動畫的Mixin類, 可用於飛機和敵機的自毀動畫顯示
class DestroyAnimationMixin():

    def show_destroy_animation(self, time_passed, destroy_time=200):
        '''
        顯示自毀動畫
        動畫其實就是幾張圖片切換的比較快,我們的眼睛識別不出來,所以認為他是動態的,也就是動畫
        :param time_passed: 距離上次繪製圖像到現在的時間,單位ms
        :param destroy_time: 自毀動畫總共顯示時間,單位ms
        '''

        # 因為我們的自毀圖片有四張,需要依次顯示,首先動畫的效果
        # self.destroy_image_position 表示第幾章自毀圖片,從零開始
        # 如果大於等於4了,說明自毀動畫顯示完成,設置self.destroyed變數為True, 方便別處調用
        if self.destroy_image_position >= 4:
            self.destroyed = True
            return

        # 依次載入自毀圖片
        if self.time_passed >= destroy_time / 4:
            self.image = pygame.image.load(os.path.join(source_dir, self.destroy_images[self.destroy_image_position])).convert_alpha()
            self.destroy_image_position += 1
            self.time_passed = 0
        else:
            self.time_passed += time_passed

在這裡插入圖片描述

  1. 實現飛機類,完成飛機的主要操作。飛機的操作包括:飛機位置、飛機子彈、發射子彈等。
# 飛機類,繼承DestroyAnimationMixin, 方便使用顯示自毀動畫的函數
class Plan(DestroyAnimationMixin):
    def __init__(self, image_path=os.path.join(source_dir,'plan.png'), background_size=(480, 700)):
        '''
        :param image_path: 飛機圖片地址
        :param background_size: 游戲視窗大小
        '''
        self.background_size = background_size
        self.image = pygame.image.load(image_path).convert_alpha()
        self.image_size = self.image.get_size()
        self.position = [(background_size[0]-self.image_size[0]) / 2, 500]
        # 飛機每次移動的距離
        self.every_time_move_distance = 0.5
        # 飛機的子彈
        self.bullets = []
        # destroy association attributes, 自毀相關屬性
        # 開始自毀
        self.start_destroy = False
        # 自毀結束
        self.destroyed = False
        # 自毀圖片
        self.destroy_images = ['me_destroy_1.png', 'me_destroy_2.png', 'me_destroy_3.png', 'me_destroy_4.png']
        # 自毀圖片位置
        self.destroy_image_position = 0
        # 距離上次繪製圖像到現在的時間
        self.time_passed = 0

    def update(self, direction):
        '''
        更新飛機位置
        :param direction: 飛機移動方向
        '''
        pass

    def shut(self, image_path=os.path.join(source_dir,'bullet.png')):
        '''
        飛機發射子彈
        :param image_path: 子彈圖片
        '''
        pass

    def draw_bullets(self, time_passed, screen):
        '''
        繪製飛機的所有子彈
        :param time_passed: 距離上次繪製圖像到現在的時間
        :param screen: 繪製到哪一個視窗中
        '''
        pass

在這裡插入圖片描述

  1. 實現敵機類,完成敵機的主要操作。主要是用來更新位置。
# 敵機類,繼承DestroyAnimationMixin, 方便使用顯示自毀動畫的函數
class Enemy(DestroyAnimationMixin):
    def __init__(self, image_path=os.path.join(source_dir, 'enemy1.png'), speed=2000, background_size=(480, 700)):
        '''
        :param image_path: 敵機圖片地址
        :param speed: 敵機移動整個視窗需要的時間,單位ms,也就是速度
        :param background_size: 游戲視窗的尺寸
        '''
        self.image = pygame.image.load(image_path).convert_alpha()
        self.speed = background_size[1] / speed
        self.background_size = background_size
        self.position = [random.randint(0, background_size[0]-self.image.get_size()[0]), -self.image.get_size()[1]]
        # 開始自毀
        self.start_destroy = False
        # 自毀完成
        self.destroyed = False
        # 自毀圖片路徑
        self.destroy_images = ['enemy1_down1.png', 'enemy1_down2.png', 'enemy1_down3.png', 'enemy1_down3.png']
        # 距離上次繪製圖像到現在的時間
        self.time_passed = 0
        # 自毀圖片在self.destroy_images的位置
        self.destroy_image_position = 0

    def update(self, time_passed):
        '''
        更新敵機的位置
        :param time_passed: 距離上次繪製圖像到現在的時間
        :return:
        '''
        pass
  1. 實現子彈類,完成子彈的主要操作
# 飛機子彈類
class Bullet():
    def __init__(self, image_path=os.path.join(source_dir,'bullet.png'), background_size=(480, 700), plan=None, speed=1000):
        '''
        :param image_path: 子彈的圖片地址
        :param background_size: 游戲視窗大小
        :param plan: 飛機對象
        :param speed: 子彈飛行速度
        '''
        self.image = pygame.image.load(image_path).convert_alpha()
        self.background_size = background_size
        self.speed = background_size[1] / speed
        # 子彈是否擊中敵機
        self.destroyed = False
        self.position = self._get_position(plan)

    def _get_position(self, plan):
        '''
        根據plan得到子彈發出位置
        :param plan: 飛機對象
        '''
        bullet_size = self.image.get_size()
        plan_width = plan.image_size[0]
        x = (plan_width-bullet_size[0]) / 2
        return [plan.position[0] + x, plan.position[1]]

    def update(self, time_passed):
        '''
        改變子彈位置
        :param time_passed: 距離上次繪製圖像到現在的時間
        '''
        # 如果子彈超出屏幕或者擊中敵機,就設置self.position[1]為-100,在plan.draw的時候就移除它
        if self.position[1] + self.image.get_size()[1] <= 0 or self.destroyed:
            self.position[1] = -100
            return

        # 改變的距離 = 時間 * 速率
        self.position[1] -= time_passed * self.speed

在這裡插入圖片描述

這樣,我們就把所有的操作都實現完了,接下來只需要使用 Game().run(),就可以運行我們的游戲了。

關註公眾號:Python專欄,後臺回覆:飛機大戰,即可獲得完整代碼及素材包。


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 簡單的描述了淺拷貝和深拷貝的區別後,分別進行實現且所有方法都已進行試驗。 ...
  • CSS樣式 CSS概述 CSS Cascading Style Shees層疊樣式表 HTML定義網頁的內容,CSS定義內容的樣式。 內容和樣式相互分離,便於修改樣式。 CSS語法 註意:1.最後一條聲明可以沒有分號,但是為了以後修改方便,一般也加上分號。 2.為了使用樣式更加容易閱讀,可以將每條代 ...
  • 前言 設計前端組件是最能考驗開發者基本功的測試之一,因為調用Material design、Antd、iView 等現成組件庫的 API 每個人都可以做到,但是很多人並不知道很多常用組件的設計原理。 能否設計出通用前端組件也是區分前端工程師和前端api調用師的標準之一,那麼應該如何設計出一個通用組件 ...
  • 前言 雙向綁定 其實已經是一個老掉牙的問題了,只要涉及到MVVM框架就不得不談的知識點,但它畢竟是Vue的三要素之一. Vue三要素 響應式: 例如如何監聽數據變化,其中的實現方法就是我們提到的雙向綁定 模板引擎: 如何解析模板 渲染: Vue如何將監聽到的數據變化和解析後的HTML進行渲染 可以實 ...
  • HTTP有哪些方法? HTTP1.0定義了三種請求方法: GET, POST 和 HEAD方法 HTTP1.1新增了五種請求方法:OPTIONS, PUT, DELETE, TRACE 和 CONNECT 這些方法的具體作用是什麼? GET: 通常用於請求伺服器發送某些資源 HEAD: 請求資源的頭 ...
  • 前言 雖然前端開發作為 GUI 開發的一種,但是存在其特殊性,前端的特殊性就在於“動態”二字,傳統 GUI 開發,不管是桌面應用還是移動端應用都是需要預先下載的,只有先下載應用程式才會在本地操作系統運行,而前端不同,它是“動態增量”式的,我們的前端應用往往是實時載入執行的,並不需要預先下載,這就造成 ...
  • 降級 降級 對於一個高可用服務,很重要的一個設計就是降級開關。在設計降級開關時,主要有以下思路: 1.開關集中化管理:通過推送機制把開關推送到各個應用。 2.可降級的多級服務:比如服務調用降級為只讀本地緩存,只讀分散式緩存,只讀預設降級數據(如庫存狀態預設有貨) 3.開關前置化:如架構是nginx ...
  • 本篇文章代碼內容較多,講的可能會有些粗糙,大家可以選擇性閱讀。 本篇文章的目的是簡單的分析動態代理的原理及模仿 手寫一個動態代理以及對幾種代理做一個總結。 對於代理模式的介紹和講解,網上已經有很多優質的文章,我這裡就不會再過多的介紹了,這裡推薦幾篇優質的文章作為參考: 1. "給女朋友講解什麼是代理 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...