500行代碼使用python寫個(gè)微信小游戲飛機(jī)大戰(zhàn)游戲
這幾天在重溫微信小游戲的飛機(jī)大戰(zhàn),玩著玩著就在思考人生了,這飛機(jī)大戰(zhàn)怎么就可以做的那么好,操作簡單,簡單上手。
幫助蹲廁族、YP族、飯圈女孩在無聊之余可以有一樣?xùn)|西讓他們振作起來!讓他們的左手 / 右手有節(jié)奏有韻律的朝著同一個(gè)方向來回移動(dòng)起來!
這是史詩級(jí)的發(fā)明,是濃墨重彩的一筆,是……
在一陣抽搐后,我結(jié)束了游戲,瞬時(shí)覺得一切都索然無味,正在我進(jìn)入賢者模式時(shí),突然想到,如果我可以讓更多人已不同的方式體會(huì)到這種美輪美奐的感覺豈不美哉?
所以我打開電腦,創(chuàng)建了一個(gè) plan_game.py……
先看效果圖

- 操作環(huán)境
- 操作系統(tǒng):windows10
- python版本:python 3.7
- 代碼編輯器:pycharm 2018.2
- 使用模塊:os,sys,random,pygame
因?yàn)閷?shí)現(xiàn)代碼使用到了一個(gè)pygame的第三方模塊,沒有的先 pip install 一下,這里順便提供一個(gè)比較好的pygame的教程.
https://eyehere.net/2011/python-pygame-novice-professional-index/
具體實(shí)現(xiàn)
首先我們先指定素材文件的文件目錄.方便我們后面的使用。
import os # 得到當(dāng)前文件夾下面的material_images目錄的路徑 source_dir = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'material_images')
實(shí)現(xiàn)一個(gè)Game類,用來完成這個(gè)游戲的主要邏輯。
import pygame
class Game():
def __init__(self, background_image_path, size=(480, 700), title='飛機(jī)大戰(zhàn)', font_name='方正舒體', font_size=30, speed=2000):
'''
:param background_image_path: 背景圖片的路徑地址
:param size: 游戲窗口的大小
:param title: 游戲窗口的標(biāo)題
:param font_name: 指定字體
:param font_size: 指定字體大小
:param speed: 背景圖滾動(dòng)整個(gè)窗口一次所用時(shí)間,單位為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()
# 設(shè)置字體對(duì)象,得到系統(tǒng)中自帶的字體
self.font = pygame.font.SysFont(font_name, font_size)
# 得到Clock對(duì)象,我們可以使用它來獲取距離上次繪制圖像的時(shí)間
self.clock = pygame.time.Clock()
# 背景圖初始位置
self.height = 0
# 使用窗口的高度處于滾動(dòng)的時(shí)間,就能得到每ms滾動(dòng)的距離
self.every_ms_move_distance = self.size[1] / speed # 2秒
# 分?jǐn)?shù)
self.score = 0
# 存放所有的敵機(jī)
self.enemies = []
def show_score(self):
'''
顯示分?jǐn)?shù), 在窗口的的最上方距離上邊距10px, 左右居中
'''
pass
def set_time_passed(self):
# 控制畫 的幀, 越大越快
# 得到上一次繪制圖像到到現(xiàn)在的時(shí)間, ms
self.time_passed = self.clock.tick()
def draw_background(self):
'''
繪制背景圖片,一直向下滾動(dòng),營造飛機(jī)一直往上面飛的感覺
'''
# 每次移動(dòng)的距離 = 每ms移動(dòng)的距離 * 上次到現(xiàn)在的時(shí)間(ms)
pass
def create_enemy(self, image_path=os.path.join(source_dir,'enemy1.png'), enemy_number=5):
'''
創(chuàng)建敵機(jī)
:param image_path: 敵機(jī)的圖片地址
:param enemy_number: 最多有幾個(gè)敵機(jī)在屏幕上
'''
pass
def draw_enemies(self, time_passed, screen):
'''
繪制敵機(jī)到屏幕上,清理跑出窗口的敵機(jī),
:param time_passed: 上次繪制導(dǎo)向現(xiàn)在經(jīng)過的時(shí)間
:param screen: 繪制的窗口對(duì)象
'''
pass
def bullet_and_enemy_crash_detection(self, bullets):
'''
檢測子彈是否擊中敵機(jī)
:param bullets: 飛機(jī)的所有子彈
'''
pass
def plan_and_enemy_crash_detection(self, plan, allow_crash_size=None):
'''
檢測敵機(jī)與飛機(jī)是否相撞
:param plan: 飛機(jī)對(duì)象
:param allow_crash_size: 允許飛機(jī)碰撞的大小,只有左右有效
'''
pass
def draw_plan(self, plan, time_passed):
'''
繪制飛機(jī)
:param plan: 飛機(jī)對(duì)象
:param time_passed: 距離上次繪制的時(shí)間
:return:
'''
pass
def game_over(self):
'''
游戲結(jié)束
'''
while True:
# 繪制背景圖
pass
def run(self):
'''
游戲入口函數(shù),開始函數(shù),主體函數(shù)
:return:
'''
# 設(shè)置游戲窗口的大小
pygame.display.set_caption(self.title)
# 初始化一個(gè)飛機(jī)對(duì)象
plan = Plan()
while True:
# 如果飛機(jī)自毀完成, 游戲結(jié)束, 調(diào)用game_over函數(shù)
pass
# 檢測監(jiān)聽事件
pass
# 檢測上下左右的移動(dòng)案件.
# w,a,s,d 和 上,下,左,右鍵都可以
# 然后執(zhí)行plan.update函數(shù),改變飛機(jī)的位置
pass
# 子彈和敵機(jī)的碰撞檢測
self.bullet_and_enemy_crash_detection(plan.bullets)
# 飛機(jī)與敵機(jī)的碰撞檢測
self.plan_and_enemy_crash_detection(plan)
# 設(shè)置屬性time_passed的值, 距離上次的時(shí)間,方便后面使用
self.set_time_passed()
# 繪制背景圖片
self.draw_background()
# 顯示分?jǐn)?shù)
self.show_score()
# 生成敵機(jī)
self.create_enemy()
# 繪制敵機(jī)
self.draw_enemies(time_passed=self.time_passed, screen=self.screen)
# 繪制飛機(jī)
self.draw_plan(plan=plan, time_passed=self.time_passed)
# 繪制子彈
plan.draw_bullets(time_passed=self.time_passed, screen=self.screen)
# 顯示我們的圖像
pygame.display.update()
這里說以下怎樣查看自己的系統(tǒng)中有哪些自帶的字體.
pygame.font.get_fonts(),這個(gè)函數(shù)就能夠得到系統(tǒng)中所有的自帶字體文件。不過,當(dāng)我們游戲中有中文的時(shí)候,我們也得選擇支持中文的字體,否則的話是顯示不出中文的。

實(shí)現(xiàn)DestroyAnimationMixin類,這個(gè)類主要是用來顯示飛機(jī)或敵機(jī)的自毀動(dòng)畫
# 顯示飛機(jī)自毀動(dòng)畫的Mixin類, 可用于飛機(jī)和敵機(jī)的自毀動(dòng)畫顯示
class DestroyAnimationMixin():
def show_destroy_animation(self, time_passed, destroy_time=200):
'''
顯示自毀動(dòng)畫
動(dòng)畫其實(shí)就是幾張圖片切換的比較快,我們的眼睛識(shí)別不出來,所以認(rèn)為他是動(dòng)態(tài)的,也就是動(dòng)畫
:param time_passed: 距離上次繪制圖像到現(xiàn)在的時(shí)間,單位ms
:param destroy_time: 自毀動(dòng)畫總共顯示時(shí)間,單位ms
'''
# 因?yàn)槲覀兊淖詺D片有四張,需要依次顯示,首先動(dòng)畫的效果
# self.destroy_image_position 表示第幾章自毀圖片,從零開始
# 如果大于等于4了,說明自毀動(dòng)畫顯示完成,設(shè)置self.destroyed變量為True, 方便別處調(diào)用
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

實(shí)現(xiàn)飛機(jī)類,完成飛機(jī)的主要操作。飛機(jī)的操作包括:飛機(jī)位置、飛機(jī)子彈、發(fā)射子彈等。
# 飛機(jī)類,繼承DestroyAnimationMixin, 方便使用顯示自毀動(dòng)畫的函數(shù)
class Plan(DestroyAnimationMixin):
def __init__(self, image_path=os.path.join(source_dir,'plan.png'), background_size=(480, 700)):
'''
:param image_path: 飛機(jī)圖片地址
: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]
# 飛機(jī)每次移動(dòng)的距離
self.every_time_move_distance = 0.5
# 飛機(jī)的子彈
self.bullets = []
# destroy association attributes, 自毀相關(guān)屬性
# 開始自毀
self.start_destroy = False
# 自毀結(jié)束
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
# 距離上次繪制圖像到現(xiàn)在的時(shí)間
self.time_passed = 0
def update(self, direction):
'''
更新飛機(jī)位置
:param direction: 飛機(jī)移動(dòng)方向
'''
pass
def shut(self, image_path=os.path.join(source_dir,'bullet.png')):
'''
飛機(jī)發(fā)射子彈
:param image_path: 子彈圖片
'''
pass
def draw_bullets(self, time_passed, screen):
'''
繪制飛機(jī)的所有子彈
:param time_passed: 距離上次繪制圖像到現(xiàn)在的時(shí)間
:param screen: 繪制到哪一個(gè)窗口中
'''
pass

實(shí)現(xiàn)敵機(jī)類,完成敵機(jī)的主要操作。主要是用來更新位置。
# 敵機(jī)類,繼承DestroyAnimationMixin, 方便使用顯示自毀動(dòng)畫的函數(shù)
class Enemy(DestroyAnimationMixin):
def __init__(self, image_path=os.path.join(source_dir, 'enemy1.png'), speed=2000, background_size=(480, 700)):
'''
:param image_path: 敵機(jī)圖片地址
:param speed: 敵機(jī)移動(dòng)整個(gè)窗口需要的時(shí)間,單位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']
# 距離上次繪制圖像到現(xiàn)在的時(shí)間
self.time_passed = 0
# 自毀圖片在self.destroy_images的位置
self.destroy_image_position = 0
def update(self, time_passed):
'''
更新敵機(jī)的位置
:param time_passed: 距離上次繪制圖像到現(xiàn)在的時(shí)間
:return:
'''
pass
實(shí)現(xiàn)子彈類,完成子彈的主要操作
# 飛機(jī)子彈類
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: 飛機(jī)對(duì)象
:param speed: 子彈飛行速度
'''
self.image = pygame.image.load(image_path).convert_alpha()
self.background_size = background_size
self.speed = background_size[1] / speed
# 子彈是否擊中敵機(jī)
self.destroyed = False
self.position = self._get_position(plan)
def _get_position(self, plan):
'''
根據(jù)plan得到子彈發(fā)出位置
:param plan: 飛機(jī)對(duì)象
'''
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: 距離上次繪制圖像到現(xiàn)在的時(shí)間
'''
# 如果子彈超出屏幕或者擊中敵機(jī),就設(shè)置self.position[1]為-100,在plan.draw的時(shí)候就移除它
if self.position[1] + self.image.get_size()[1] <= 0 or self.destroyed:
self.position[1] = -100
return
# 改變的距離 = 時(shí)間 * 速率
self.position[1] -= time_passed * self.speed

這樣,我們就把所有的操作都實(shí)現(xiàn)完了,接下來只需要使用 Game().run(),就可以運(yùn)行我們的游戲了。
總結(jié)
以上所述是小編給大家介紹的500行代碼使用python寫個(gè)微信飛機(jī)大戰(zhàn)游戲,希望對(duì)大家有所幫助,如果大家有任何疑問請(qǐng)給我留言,小編會(huì)及時(shí)回復(fù)大家的。在此也非常感謝大家對(duì)腳本之家網(wǎng)站的支持!
如果你覺得本文對(duì)你有幫助,歡迎轉(zhuǎn)載,煩請(qǐng)注明出處,謝謝!
相關(guān)文章
在交互式環(huán)境中執(zhí)行Python程序過程詳解
這篇文章主要介紹了在交互式環(huán)境中執(zhí)行Python程序過程詳解,運(yùn)行Python腳本程序的方式有多種,目前主要的方式有:交互式環(huán)境運(yùn)行、命令行窗口運(yùn)行、開發(fā)工具上運(yùn)行等,其中在不同的操作平臺(tái)上還互不相同,需要的朋友可以參考下2019-07-07
python實(shí)現(xiàn)將列表中各個(gè)值快速賦值給多個(gè)變量
這篇文章主要介紹了python實(shí)現(xiàn)將列表中各個(gè)值快速賦值給多個(gè)變量,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-04-04
基于Python實(shí)現(xiàn)將列表數(shù)據(jù)生成折線圖
這篇文章主要介紹了如何利用Python中的pandas庫和matplotlib庫,實(shí)現(xiàn)將列表數(shù)據(jù)生成折線圖,文中的示例代碼簡潔易懂,需要的可以參考一下2022-03-03
Python+OpenCV進(jìn)行人臉面部表情識(shí)別
這篇文章主要介紹了通過Python OpenCV實(shí)現(xiàn)對(duì)人臉面部表情識(shí)別,判斷人是否為笑臉,文中的示例代碼非常詳細(xì),需要的朋友可以參考一下2021-12-12

