python 之路,200行Python代碼寫了個打飛機遊戲!

早就知道pygame模塊,就是沒怎麼深刻研究過,恰逢這周未沒約到妹子,只能本身在家玩本身啦,一時興起,花了幾個小時寫了個打飛機程序。python

頗有意思,跟你們分享下。git

 

先看一下項目結構github

"""
PlayPlane/
|-- bin/
|   |-- main.py         程序運行主體程序
|-- config/
|   |-- settings.py     程序配置(例如: 遊戲背景音樂的加載等)
|-- material            程序素材放置(打飛機遊戲素材放置)
    |-- ...
|-- src/                程序主體模塊存放
|   |-- __init__.py 
|   |-- bullet.py       我方飛機發射子彈實現代碼存放
|   |-- enemy.py        敵方飛機實現代碼存放
|   |-- plane.py        我方飛機實現代碼存放
|-- manage.py           程序啓動文件
|-- README.md           
"""

 

再曬下項目成果圖微信

實現步驟app

1、首先在 config/settings.py 中進行如下功能的實現

  • 遊戲初始化
  • 遊戲混音器初始化
  • 背景音樂初始化
  • 我方飛機掛了音樂
  • 敵方飛機掛了音樂
  • 子彈發射音樂
#! /usr/bin/env python
# -*- coding: utf-8 -*-

import pygame

pygame.init()  # 遊戲初始化
pygame.mixer.init()  # 混音器初始化

# 遊戲背景音樂
pygame.mixer.music.load("material/sound/game_music.wav")
pygame.mixer.music.set_volume(0.2)

# 子彈發射音樂
bullet_sound = pygame.mixer.Sound("material/sound/bullet.wav")
bullet_sound.set_volume(0.2)

# 我方飛機掛了的音樂
me_down_sound = pygame.mixer.Sound("material/sound/game_over.wav")
me_down_sound.set_volume(0.2)

# 敵方飛機掛了的音樂
enemy1_down_sound = pygame.mixer.Sound("material/sound/enemy1_down.wav")
enemy1_down_sound.set_volume(0.2)

config/settings.py

 

注:遊戲素材滑動到文章底部點擊連接便可下載  dom

 

2、小試牛刀

飛機和子彈都是可移動的,那麼怎麼實現讓它們動起來呢(我方飛機能夠玩家進行操控,敵機就是隨機性的出現,子彈暫由我方飛機發射)。ide

在Pygame中,全部移動對象均可看作是一個精靈(sprite),精靈之間可以進行相互的交互通訊,例如如何讓碰撞檢測更加精準等等。函數

那麼先讓咱們先在屏幕上製做一個遊戲板,根據 settings.py 配置,並讓它有聲音播放,首先咱們在 bin/main.py 中這麼寫:oop

  咱們能夠直接運行它,那麼咱們會看到如下畫面,而且還會有激情的聲音吆!!!可是咱們要將文件配置爲絕對路徑才能夠運行,由於剛剛在settings中的加載的音樂文件爲相對路徑。ui

#! /usr/bin/env python
# -*- coding: utf-8 -*-

import sys

from config.settings import *


bg_size = 480, 852  # 初始化遊戲背景大小(寬, 高)
screen = pygame.display.set_mode(bg_size)  # 設置背景對話框
pygame.display.set_caption("飛機大戰")  # 設置標題

background = pygame.image.load(os.path.join(BASE_DIR, "material/image/background.png"))  # 加載背景圖片,並設置爲不透明


def main():
    pygame.mixer.music.play(loops=-1)  # loops 對應的值爲 -1 則音樂會無限循環播放

    while True:
        # 繪製背景圖
        screen.blit(background, (0, 0))

        # 響應用戶的操做(必定要有響應的用戶操做)
        for event in pygame.event.get():
            if event.type == 12:  # 若是用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出
                pygame.quit()
                sys.exit()

        # 再而咱們將背景圖像並輸出到屏幕上面
        pygame.display.flip()

if __name__ == '__main__':
    main()

  

 

接下來呢,咱們將要製做我方飛機,敵方飛機和子彈如何讓它們展現在遊戲畫板上,繼而讓它們變得可移動起來,請看代碼實現方案...

從遊戲畫板上添加飛機,首先咱們應怎樣在屏幕上輸出飛機???

上述講過,pygame中的 sprite(精靈)可以使一張圖片或者一個靜態物體動起來,那麼製做飛機須要考慮並作些什麼呢?

  1. 飛機的初始位置
  2. 經過按鍵 上下左右 來調控飛機的位置移動
  3. 飛機只能呆在製做的遊戲畫板中
  4. 飛機的速度
  5. 飛機死亡的加載
  6. 設定一個狀態標識飛機的存活
  7. 讓飛機具備動態的噴氣式效果

那麼如何實現以上的功能呢?接下來結合上述的示例代碼咱們先將我方飛機繪製到畫板上方,而且咱們經過按鍵 J 斷定我方飛機的存活狀態爲死亡,繪製飛機的死亡畫面並重置飛機

"""
    建立飛機
    在pygame中, 全部可移動的對象均叫可看做一個精靈(sprite)
    該類並實現了碰撞方法 spritecollide

    我方飛機和敵方飛機指定掩膜屬性以及生存狀態標誌位 添加 self.mask 屬性(能夠實現更精準的碰撞效果)
"""

# 倒入精靈模塊, 使飛機能夠動起來
import pygame


class OurPlane(pygame.sprite.Sprite):

    def __init__(self, bg_size):
        super(OurPlane, self).__init__()
        # 肯定我方飛機背景圖(有倆張,可讓它們不停的切換,造成動態效果)
        self.image_one = pygame.image.load("material/image/hero1.png")
        self.image_two = pygame.image.load("material/image/hero2.png")
        # 獲取我方飛機的位置
        self.rect = self.image_one.get_rect()
        # 本地化背景圖片的尺寸
        self.width, self.height = bg_size[0], bg_size[1]
        # 獲取飛機圖像的掩膜用以更加精確的碰撞檢測
        self.mask = pygame.mask.from_surface(self.image_one)
        # 定義飛機初始化位置,底部預留60像素
        self.rect.left, self.rect.top = (self.width - self.rect.width) // 2, (self.height - self.rect.height - 60)
        # 設置飛機移動速度
        self.speed = 10
        # 設置飛機存活狀態(True爲存活, False爲死亡)
        self.active = True
        # 加載飛機損毀圖片
        self.destroy_images = []
        self.destroy_images.extend(
            [
                pygame.image.load("material/image/hero_blowup_n1.png"),
                pygame.image.load("material/image/hero_blowup_n2.png"),
                pygame.image.load("material/image/hero_blowup_n3.png"),
                pygame.image.load("material/image/hero_blowup_n4.png")
            ]
        )

    def move_up(self):
        """
        飛機向上移動的操做函數,其他移動函數方法相似
        """
        if self.rect.top > 0:  # 若是飛機還沒有移動出背景區域
            self.rect.top -= self.speed
        else:  # 若即將移動出背景區域,則及時糾正爲背景邊緣位置
            self.rect.top = 0

    def move_down(self):
        """
        飛機向下移動
        """
        if self.rect.bottom < self.height - 60:
            self.rect.top += self.speed
        else:
            self.rect.bottom = self.height - 60

    def move_left(self):
        """
        飛機向左移動
        """
        if self.rect.left > 0:
            self.rect.left -= self.speed
        else:
            self.rect.left = 0

    def move_right(self):
        """
        飛機向右移動
        """
        if self.rect.right < self.width:
            self.rect.right += self.speed
        else:
            self.rect.right = self.width

    def reset(self):
        # 初始化飛機(飛機掛了, 初始化到初始位置)
        self.rect.left, self.rect.top = (self.width - self.rect.width) // 2, (self.height - self.rect.height - 60)
        # 重置飛機的存活狀態
        self.active = True

  

上面的代碼寫了一個 咱們的飛機 (OurPlane) 類,它初始化了一些屬性以及 上下左右 移動的方法和重置方法,接下來將要運用它展現到遊戲畫板上面

因爲飛機是一直存在的,接下咱們主程序 main 下面的死循環中這樣寫

 

def main():
    pygame.mixer.music.play(loops=-1)  # loops 對應的值爲 -1 則音樂會無限循環播放

    our_plane = OurPlane(bg_size)  # 初始化
    switch_image = False  # 定義飛機的切圖效果標識

    while True:
        # 繪製背景圖
        screen.blit(background, (0, 0))

        # 飛機狀態是存活
        if our_plane.active:

            if switch_image:
                screen.blit(our_plane.image_one, our_plane.rect)
            else:
                screen.blit(our_plane.image_two, our_plane.rect)

            switch_image = not switch_image  # 讓切圖狀態不停的變換
        else:
            pass

        # 響應用戶的操做(必定要有響應的用戶操做)
        for event in pygame.event.get():
            if event.type == 12:  # 若是用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出
                pygame.quit()
                sys.exit()

        # 再而咱們將背景圖像並輸出到屏幕上面
        pygame.display.flip()

if __name__ == '__main__':
    main()
1.在屏幕上繪製飛機
def main():
    pygame.mixer.music.play(loops=-1)  # loops 對應的值爲 -1 則音樂會無限循環播放

    our_plane = OurPlane(bg_size)  # 初始化
    switch_image = False  # 定義飛機的切圖效果標識

    while True:
        # 繪製背景圖
        screen.blit(background, (0, 0))

        # 飛機狀態是存活
        if our_plane.active:

            if switch_image:
                screen.blit(our_plane.image_one, our_plane.rect)
            else:
                screen.blit(our_plane.image_two, our_plane.rect)

            switch_image = not switch_image  # 讓切圖狀態不停的變換
        else:
            pass

        # 得到用戶全部的鍵盤輸入序列(若是用戶經過鍵盤發出「向上」的指令,其餘相似)
        key_pressed = pygame.key.get_pressed()
        if key_pressed[K_w] or key_pressed[K_UP]:
            our_plane.move_up()
        if key_pressed[K_s] or key_pressed[K_DOWN]:
            our_plane.move_down()
        if key_pressed[K_a] or key_pressed[K_LEFT]:
            our_plane.move_left()
        if key_pressed[K_d] or key_pressed[K_RIGHT]:
            our_plane.move_right()

        # 響應用戶的操做(必定要有響應的用戶操做)
        for event in pygame.event.get():
            if event.type == 12:  # 若是用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出
                pygame.quit()
                sys.exit()

        # 再而咱們將背景圖像並輸出到屏幕上面
        pygame.display.flip()

if __name__ == '__main__':
    main()
2.讓飛機上下左右動起來
def main():
    pygame.mixer.music.play(loops=-1)  # loops 對應的值爲 -1 則音樂會無限循環播放

    our_plane = OurPlane(bg_size)  # 初始化
    switch_image = False  # 定義飛機的切圖效果標識

    our_plane_destroy_index = 0

    while True:
        # 繪製背景圖
        screen.blit(background, (0, 0))

        # 飛機狀態是存活(若是按鍵 爲 J, 讓飛機死亡並繪製爆炸效果)
        if our_plane.active:

            if switch_image:
                screen.blit(our_plane.image_one, our_plane.rect)
            else:
                screen.blit(our_plane.image_two, our_plane.rect)

            switch_image = not switch_image  # 讓切圖狀態不停的變換
        else:
            """
            飛機死亡也是進行按順序的圖片切換, 那麼在死循環以外定義索引
            """
            me_destroy_index = (our_plane_destroy_index + 1) % 4
            if me_destroy_index == 1:
                me_down_sound.play()  # 爆炸聲音效果
                our_plane.reset()  # 初始化飛機
            if our_plane_destroy_index >= len(our_plane.destroy_images):
                our_plane_destroy_index = 0
            else:
                screen.blit(our_plane.destroy_images[our_plane_destroy_index], our_plane.rect)

            our_plane_destroy_index += 1

        # 得到用戶全部的鍵盤輸入序列(若是用戶經過鍵盤發出「向上」的指令,其餘相似)
        key_pressed = pygame.key.get_pressed()
        if key_pressed[K_w] or key_pressed[K_UP]:
            our_plane.move_up()
        if key_pressed[K_s] or key_pressed[K_DOWN]:
            our_plane.move_down()
        if key_pressed[K_a] or key_pressed[K_LEFT]:
            our_plane.move_left()
        if key_pressed[K_d] or key_pressed[K_RIGHT]:
            our_plane.move_right()

        # 按鍵爲 j 飛機更改存活標識
        if key_pressed[K_j]:
            our_plane.active = False

        # 響應用戶的操做(必定要有響應的用戶操做)
        for event in pygame.event.get():
            if event.type == 12:  # 若是用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出
                pygame.quit()
                sys.exit()

        # 再而咱們將背景圖像並輸出到屏幕上面
        pygame.display.flip()
3.按鍵爲 j 繪製飛機的死亡狀態

那麼上述的功能都已經實現了,接下來就開始真正的"打飛機"

3、接下來能夠製做我方飛機,敵方戰機,子彈等,這些功能均在 src/ 目錄下實現

  • 我方飛機根據按鍵上下左右進行移動,初始化位置,噴氣式圖片加載切換及重置效果等
#! /usr/bin/env python
# -*- coding: utf-8 -*-

"""
    建立飛機
    在pygame中, 全部可移動的對象均叫可看做一個精靈(sprite)
    該類並實現了碰撞方法 spritecollide

    我方飛機和敵方飛機指定掩膜屬性以及生存狀態標誌位 添加 self.mask 屬性(能夠實現更精準的碰撞效果)
"""

# 倒入精靈模塊, 使飛機能夠動起來
import pygame


class OurPlane(pygame.sprite.Sprite):

    def __init__(self, bg_size):
        super(OurPlane, self).__init__()
        # 肯定我方飛機背景圖
        self.image_one = pygame.image.load("material/image/hero1.png")
        self.image_two = pygame.image.load("material/image/hero2.png")
        # 獲取我方飛機的位置
        self.rect = self.image_one.get_rect()
        # 本地化背景圖片的尺寸
        self.width, self.height = bg_size[0], bg_size[1]
        # 獲取飛機圖像的掩膜用以更加精確的碰撞檢測
        self.mask = pygame.mask.from_surface(self.image_one)
        # 定義飛機初始化位置,底部預留60像素
        self.rect.left, self.rect.top = (self.width - self.rect.width) // 2, (self.height - self.rect.height - 60)
        # 設置飛機移動速度
        self.speed = 10
        # 設置飛機存活狀態(True爲存活, False爲死亡)
        self.active = True
        # 加載飛機損毀圖片
        self.destroy_images = []
        self.destroy_images.extend(
            [
                pygame.image.load("material/image/hero_blowup_n1.png"),
                pygame.image.load("material/image/hero_blowup_n2.png"),
                pygame.image.load("material/image/hero_blowup_n3.png"),
                pygame.image.load("material/image/hero_blowup_n4.png")
            ]
        )

    def move_up(self):
        """
        飛機向上移動的操做函數,其他移動函數方法相似
        """
        if self.rect.top > 0:  # 若是飛機還沒有移動出背景區域
            self.rect.top -= self.speed
        else:  # 若即將移動出背景區域,則及時糾正爲背景邊緣位置
            self.rect.top = 0

    def move_down(self):
        if self.rect.bottom < self.height - 60:
            self.rect.top += self.speed
        else:
            self.rect.bottom = self.height - 60

    def move_left(self):
        if self.rect.left > 0:
            self.rect.left -= self.speed
        else:
            self.rect.left = 0

    def move_right(self):
        if self.rect.right < self.width:
            self.rect.right += self.speed
        else:
            self.rect.right = self.width

    def reset(self):
        # 初始化飛機(飛機掛了, 初始化到初始位置)
        self.rect.left, self.rect.top = (self.width - self.rect.width) // 2, (self.height - self.rect.height - 60)
        self.active = True

src/plane.py
src/plane.py
  • 敵方飛機隨機移動出現及重置(製做出我方飛機以後,敵機和子彈其實都是大同小異的)
  • #! /usr/bin/env python
    # -*- coding: utf-8 -*-
    
    """
        定義敵機
    """
    
    from random import randint
    
    import pygame
    
    
    class SmallEnemy(pygame.sprite.Sprite):
        """
        定義小飛機敵人
        """
        def __init__(self, bg_size):
            super(SmallEnemy, self).__init__()
            self.image = pygame.image.load("material/image/enemy1.png")
            self.rect = self.image.get_rect()
            self.width, self.height = bg_size[0], bg_size[1]
            self.mask = pygame.mask.from_surface(self.image)  # 獲取飛機圖像的掩膜用以更加精確的碰撞檢測
            self.speed = 2
            # 定義敵機出現的位置, 保證敵機不會在程序已開始就當即出現
            self.rect.left, self.rect.top = (
                randint(0, self.width - self.rect.width),  randint(-5 * self.rect.height, -5),
            )
            self.active = True
            # 加載飛機損毀圖片
            self.destroy_images = []
            self.destroy_images.extend(
                [
                    pygame.image.load("material/image/enemy1_down1.png"),
                    pygame.image.load("material/image/enemy1_down2.png"),
                    pygame.image.load("material/image/enemy1_down3.png"),
                    pygame.image.load("material/image/enemy1_down4.png")
                ]
            )
    
        def move(self):
            """
            定義敵機的移動函數
            :return:
            """
            if self.rect.top < self.height:
                self.rect.top += self.speed
            else:
                self.reset()
    
        def reset(self):
            """
            當敵機向下移動出屏幕時, 以及敵機死亡
            :return:
            """
            self.rect.left, self.rect.top = (randint(0, self.width - self.rect.width), randint(-5 * self.rect.height, 0))
            self.active = True
    src/enemy.py
  • 子彈按照我方飛機正中上方發射及頻率調控,重置
#! /usr/bin/env python
# -*- coding: utf-8 -*-

"""
    子彈的實現
"""

import pygame


class Bullet(pygame.sprite.Sprite):

    def __init__(self, position):
        super(Bullet, self).__init__()
        self.image = pygame.image.load("material/image/bullet1.png")
        self.rect = self.image.get_rect()
        self.rect.left, self.rect.top = position
        self.speed = 30
        self.active = True
        self.mask = pygame.mask.from_surface(self.image)

    def move(self):
        """
        子彈移動, 超出屏幕範圍, 則設置死亡
        :return:
        """
        if self.rect.top < 0:
            self.active = False
        else:
            self.rect.top -= self.speed

    def reset(self, position):
        """
        復位函數
        :param position:
        :return:
        """
        self.rect.left, self.rect.top = position
        self.active = True

src/bullet.py
src/bullet.py

 

在上面的內容中,使用面向對象的形式製做了遊戲中可移動的對象並繼承 pygame.sprite.Sprite 

4、而後在 bin/main.py 中進行主體功能的實現

  • 初始化背景圖及大小
  • 我方飛機移動及發射子彈
  • 敵方飛機移動
  • 我方飛機和敵方飛機碰撞檢測
  • 鍵盤按鍵監測效果
  • 我方飛機和敵方飛機掛了效果繪製
import sys

from pygame.locals import *

from config.settings import *
from src.plane import OurPlane
from src.enemy import SmallEnemy
from src.bullet import Bullet


bg_size = 480, 852  # 初始化遊戲背景大小(寬, 高)
screen = pygame.display.set_mode(bg_size)  # 設置背景對話框
pygame.display.set_caption("飛機大戰")  # 設置標題

background = pygame.image.load("material/image/background.png")  # 加載背景圖片,並設置爲不透明

# 獲取我方飛機
our_plane = OurPlane(bg_size)


def add_small_enemies(group1, group2, num):
    """
    添加小型敵機
    指定個敵機對象添加到精靈組(sprite.group)
    參數group一、group2是兩個精靈組類型的形參,用以存儲多個精靈對象(敵機)。
    須要注意的一點是group既然是特定的精靈組結構體,在向其內部添加精靈對象時須要調用其對應的成員函數add()
    :return:
    """
    for i in range(num):
        small_enemy = SmallEnemy(bg_size)
        group1.add(small_enemy)
        group2.add(small_enemy)


def main():
    # 響應音樂
    pygame.mixer.music.play(-1)  # loops 接收該參數, -1 表示無限循環(默認循環播放一次)
    running = True
    switch_image = False  # 切換飛機的標識位(使飛機具備噴氣式效果)
    delay = 60  # 對一些效果進行延遲, 效果更好一些

    enemies = pygame.sprite.Group()  # 生成敵方飛機組(一種精靈組用以存儲全部敵機精靈)
    small_enemies = pygame.sprite.Group()  # 敵方小型飛機組(不一樣型號敵機建立不一樣的精靈組來存儲)

    add_small_enemies(small_enemies, enemies, 4)  # 生成若干敵方小型飛機

    # 定義子彈, 各類敵機和我方敵機的毀壞圖像索引
    bullet_index = 0
    e1_destroy_index = 0
    me_destroy_index = 0

    # 定義子彈實例化個數
    bullet1 = []
    bullet_num = 6
    for i in range(bullet_num):
        bullet1.append(Bullet(our_plane.rect.midtop))

    while running:

        # 繪製背景圖
        screen.blit(background, (0, 0))

        # 微信的飛機貌似是噴氣式的, 那麼這個就涉及到一個幀數的問題
        clock = pygame.time.Clock()
        clock.tick(60)

        # 繪製我方飛機的兩種不一樣的形式
        if not delay % 3:
            switch_image = not switch_image

        for each in small_enemies:
            if each.active:
                # 隨機循環輸出小飛機敵機
                for e in small_enemies:
                    e.move()
                    screen.blit(e.image, e.rect)
            else:
                if e1_destroy_index == 0:
                    enemy1_down_sound.play()
                screen.blit(each.destroy_images[e1_destroy_index], each.rect)
                e1_destroy_index = (e1_destroy_index + 1) % 4
                if e1_destroy_index == 0:
                    each.reset()

        # 當我方飛機存活狀態, 正常展現
        if our_plane.active:
            if switch_image:
                screen.blit(our_plane.image_one, our_plane.rect)
            else:
                screen.blit(our_plane.image_two, our_plane.rect)

            # 飛機存活的狀態下才能夠發射子彈
            if not (delay % 10):  # 每十幀發射一顆移動的子彈
                bullet_sound.play()
                bullets = bullet1
                bullets[bullet_index].reset(our_plane.rect.midtop)
                bullet_index = (bullet_index + 1) % bullet_num

            for b in bullets:
                if b.active:  # 只有激活的子彈纔可能擊中敵機
                    b.move()
                    screen.blit(b.image, b.rect)
                    enemies_hit = pygame.sprite.spritecollide(b, enemies, False, pygame.sprite.collide_mask)
                    if enemies_hit:  # 若是子彈擊中飛機
                        b.active = False  # 子彈損毀
                        for e in enemies_hit:
                            e.active = False  # 小型敵機損毀

        # 毀壞狀態繪製爆炸的場面
        else:
            if not (delay % 3):
                screen.blit(our_plane.destroy_images[me_destroy_index], our_plane.rect)
                me_destroy_index = (me_destroy_index + 1) % 4
                if me_destroy_index == 0:
                    me_down_sound.play()
                    our_plane.reset()

        # 調用 pygame 實現的碰撞方法 spritecollide (我方飛機若是和敵機碰撞, 更改飛機的存活屬性)
        enemies_down = pygame.sprite.spritecollide(our_plane, enemies, False, pygame.sprite.collide_mask)
        if enemies_down:
            our_plane.active = False
            for row in enemies:
                row.active = False

        # 響應用戶的操做
        for event in pygame.event.get():
            if event.type == 12:  # 若是用戶按下屏幕上的關閉按鈕,觸發QUIT事件,程序退出
                pygame.quit()
                sys.exit()

        if delay == 0:
            delay = 60
        delay -= 1

        # 得到用戶全部的鍵盤輸入序列(若是用戶經過鍵盤發出「向上」的指令,其餘相似)
        key_pressed = pygame.key.get_pressed()
        if key_pressed[K_w] or key_pressed[K_UP]:
            our_plane.move_up()
        if key_pressed[K_s] or key_pressed[K_DOWN]:
            our_plane.move_down()
        if key_pressed[K_a] or key_pressed[K_LEFT]:
            our_plane.move_left()
        if key_pressed[K_d] or key_pressed[K_RIGHT]:
            our_plane.move_right()

        # 繪製圖像並輸出到屏幕上面
        pygame.display.flip()
bin/main.py

 

5、暢汗淋漓,一鼓作氣打飛機

from bin.main import main


if __name__ == '__main__':
    """
    環境: python3 + pygame
    running 起來就能夠打飛機了O(∩_∩)O~.
    """
    main()

  

最終效果!

 

 

完整項目代碼 : https://github.com/triaquae/jerkoff 

另外,本項目所用到的基礎知識視頻 已上傳至 路飛學城 ,須要者自取! http://luffy.oldboyedu.com/course/detail/python/5 

相關文章
相關標籤/搜索