1. 程式人生 > 其它 >20212108《Python程式設計》實驗四 Python綜合實踐實驗報告

20212108《Python程式設計》實驗四 Python綜合實踐實驗報告

20212108《Python程式設計》實驗四 Python綜合實踐實驗報告 

課程:        《Python程式設計》
班級:        2121
姓名:        王季延
學號:        20212108
實驗教師:  王志強
實驗日期:  2022年5月21日
必修/選修: 公選課

一、實驗內容

用Python做一個小遊戲i wanna flippy bird

1.想法介紹:

       大一上學期從課代表那裡瞭解到可以使用pygame模組製作遊戲,本學期在舍友那裡接觸到了i wanna類的遊戲(被坑哭了),最後是在雲班課中老師發的資料裡找到了用pygame製作經典flippy bird遊戲的視訊,所以就有了用python做一個簡單的兩者結合的小遊戲。

2.主要內容:

      玩家控制小鳥(畫成了一個腦袋)前進和跳躍(標準的flippy bird遊戲中小鳥是自動前進,玩家只需要操控小鳥的跳躍即可,但是由於此遊戲含有坑,前進需要玩家手動操控),通過管道獲得儘可能多的分數,但是在這個經典玩法中摻雜了擋路的怪物和坑的元素。(遊戲剛開始時玩家就是處於下墜狀態,只是單純為了讓玩家觀看死亡介面的遊戲規則,接下來每次重新開始遊戲後不會自動下墜,只有按下跳躍鍵後才會正常下落)

           

 二、實驗過程及結果

1.圖片素材準備

      在電腦附件“畫圖”中直接編輯,背景使用截圖

 2.pygame包下載和安裝

 pip install pygame -i https://pypi.mirrors.ustc.edu.cn/simple安裝pygame

pip show pygame檢視pygame是否安裝完成

重啟後電腦成功檢測到pygame

3.遊戲架構分析

 遊戲即讓圖片在一個視窗內運動,在執行對應操作時做出對應的動作。

關於類的建立,使用class函式實現,參考資料

①https://blog.csdn.net/weixin_34177886/article/details/111963062

②本學期python課堂對class知識的講授

關於視窗和檢測按鍵的使用,使用pygame相關程式碼和自定義變數實現,參考資料

(3)實驗過程

a.程式碼

import sys
import pygame
import random
import math

if __name__ == '__main__':
    pygame.init()
    
    #
    def text_amazing(screen):
        text5 = "注意!按鍵反轉"
        font5 = pygame.font.SysFont("simsun",32)
        font_surface5 = font5.render(text5,True,(0,0,0))
        font_rect5 = font_surface5.get_rect()
        font_rect5.center = (200,100)
        screen.blit(font_surface5,font_rect5)
    def die(screen,score):
        text = "你無了!"
        font = pygame.font.SysFont("simsun",32)
        font_surface = font.render(text,True,(255,0,0))
        font_rect = font_surface.get_rect()
        font_rect.center = (200,100)
        screen.blit(font_surface,font_rect)


        text1 = "你的得分是" + str(score)
        font1 = pygame.font.SysFont("simsun",16)
        font_surface1 = font1.render(text1,True,(0,0,0))
        font_rect1 = font_surface1.get_rect()
        font_rect1.center = (180,150)
        screen.blit(font_surface1,font_rect1)

        text2 = "規則:右鍵前進,空格跳躍"
        font2 = pygame.font.SysFont("simsun",16)
        font_surface2 = font2.render(text2,True,(255,0,0))
        font_rect2 = font_surface2.get_rect()
        font_rect2.center = (180,250)
        screen.blit(font_surface2,font_rect2)

        text3 = "注意有坑,兩個按鍵可能交換"
        font3 = pygame.font.SysFont("simsun",16)
        font_surface3 = font3.render(text3,True,(0,0,0))
        font_rect3 = font_surface3.get_rect()
        font_rect3.center = (180,300)
        screen.blit(font_surface3,font_rect3)

    class bird(object):
        def __init__(self):
            self.sprite = [pygame.image.load("player0.png").convert_alpha(),#
                            pygame.image.load("player1.png").convert_alpha()]#死
            self.sprite_index = 0
            self.x = 120
            self.y = 350
            self.speed = 0
            self.jump = False
            self.gravity = 0.2
            self.gravity_distance = 0.1
            self.whether_dead = False

        def move(self):
            self.speed -= self.gravity
            self.y -= self.speed
            if not self.jump:
                self.gravity += self.gravity_distance
                self.gravity_distance = self.gravity_distance/2
    #######################
    class pipeline(object):
        def __init__(self):
            self.x = 400
            self.y_up = random.randint(-530,-100)
            self.y_distance = random.randint(140,300)
            self.sprite_up = pygame.image.load("up.png")
            self.sprite_down = pygame.image.load("down.png")
            self.move_state = 0
            #
            self.amazing = 0
            self.amazing3 = 4
            self.amazing1_state = 1
            self.score_state = 1
            self.x_scale = 94
            self.y_down = self.y_up + self.y_distance
            self.move_total = 0

        def pipeline_update(self):
            if self.move_state == 1 and self.move_total == 1:
                self.x -= 2
            if self.x <= -100:
                self.x = 400
                self.y_up = random.randint(-530,-100)
                self.y_distance = random.randint(140,300)
                self.y_down = self.y_up + self.y_distance
                self.yscale = random.randint(60,100)
                self.sprite_up = pygame.transform.scale(self.sprite_up,(self.x_scale,499))
                self.sprite_down = pygame.transform.scale(self.sprite_down,(self.x_scale,499))
                self.amazing = random.randint(0,3)
                self.score_state = 1
                self.amazing1_state = 1
                self.amazing3 = random.randint(0,3)
    ###################
    class demon(object):
        def __init__(self):
            self.sprite = [pygame.image.load("demon1.png"),
                            pygame.image.load("demon2.png")]
            self.sprite_index = 0
            self.sprite_state = 1
            self.x = 200
            self.y = random.randint(100,470)
            self.move_state = 0
            self.move_time = 100
            self.move_time2 = 100
            self.move_time_state = 0
            #
            self.amazing = 0
            self.attack = 0
            self.speed = 2
            self.time = self.move_time
            self.speed2 = 2
            self.time2 = self.move_time2
            self.move_time_state2 = 0
            self.amazing2_y = self.y + random.randint(-200,200)
            self.amazing2_y_state = 0
            self.step = 0

        def move(self):
            self.sprite_state -= 1
            if self.amazing >= 1:
                if self.time > 0 and self.amazing2_y_state == 0:
                    if self.move_time_state == 0:
                        self.y += self.speed
                    else:
                        self.y -= self.speed
                    self.time -= 1
                if self.time <= 0 and self.amazing2_y_state == 0:
                    self.time = self.move_time
                    if self.move_time_state == 0:
                        self.move_time_state = 1
                    elif self.move_time_state == 1:
                        self.move_time_state = 0
                if self.amazing == 2:
                    if self.amazing2_y_state == 0 and abs(self.y - self.amazing2_y) <= random.randint(10,15):
                        self.amazing2_y_state = 1
                    if self.amazing2_y_state == 1:
                        if self.time2 > 0 and self.amazing2_y_state == 1:
                            if self.move_time_state2 == 1:
                                self.x += self.speed2
                            else:
                                self.x -= self.speed2
                            self.time2 -= 1
                        if self.time2 <= 0 and self.amazing2_y_state == 1:
                            self.time2 = self.move_time2
                            if self.move_time_state2 == 0:
                                self.move_time_state2 = 1
                            elif self.move_time_state2 == 1:
                                self.move_time_state2 = 0
                            self.step += 1
                    if self.step == 2:
                        self.amazing2_y_state = 0
                        self.amazing2_y = self.y + random.randint(-120,200)
                        self.step = 0

            if self.sprite_index == 0 and self.sprite_state == 0:
                self.sprite_index = 1
                self.sprite_state = 30
            if self.sprite_index == 1 and self.sprite_state == 0:
                self.sprite_index = 0
                self.sprite_state = 30
            if self.move_state == 1:
                self.x -= 2
            if self.x <= -100:
                self.x = 400
                self.y = random.randint(200,450)
                self.attack = random.randint(0,3)
                self.move_time = random.randint(40,60)
                self.time = self.move_time
                self.amazing = random.randint(0,2)
                self.move_time_state = random.randint(0,1)
                self.speed = random.randint(2,5)
                self.amazing2_y = self.y + random.randint(-120,200)
                self.amazing2_y_state = 0
                #
                self.move_time2 = random.randint(20,30)
                self.move_time_state2 = random.randint(0,1)
                self.speed = random.randint(2,5)
                self.time2 = self.move_time2
                self.step = 0
    #

    size = width,height = 400,650
    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()
    score = 0
    cooldown = 0

    player = bird()
    pipe = pipeline()
    demon = demon()
    while True:
        clock.tick(100)

        pygame.display.set_caption("你的得分:"+str(score))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            if not player.whether_dead:
                if (pipe.amazing == pipe.amazing3 or pipe.amazing == 3) and player.x >= 20:
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_RIGHT:
                            player.jump = True
                            player.gravity = 0.2
                            player.speed = 5
                            player.gravity_distance = 0.02
                        if event.key == pygame.K_SPACE:
                            pipe.move_state = 1
                            demon.move_state = 1
                    elif event.type == pygame.KEYUP:
                        if event.key == pygame.K_RIGHT:
                            player.jump = False
                        if event.key == pygame.K_SPACE:
                            pipe.move_state = 0
                            demon.move_state = 0
                
                else:
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_SPACE:
                            pipe.move_total = 1
                            player.jump = True
                            player.gravity = 0.2
                            player.speed = 5
                            player.gravity_distance = 0.02
                        if event.key == pygame.K_RIGHT:
                            pipe.move_state = 1
                            demon.move_state = 1
                    elif event.type == pygame.KEYUP:
                        if event.key == pygame.K_SPACE:
                            player.jump = False
                        if event.key == pygame.K_RIGHT:
                            pipe.move_state = 0
                            demon.move_state = 0
            else:
                player.sprite_index = 1
        
        if player.x > pipe.x + pipe.x_scale and pipe.score_state == 1:
            score += 1
            pipe.score_state = 0
        background = pygame.image.load("background.png")
        screen.blit(background,(0,0))

        if not player.whether_dead:
            pipe.pipeline_update()
            #第一個坑
            if pipe.amazing == 1 and player.x >= pipe.x - random.randint(58,62):
                if pipe.y_up < pipe.y_down and pipe.amazing1_state == 1:
                    pipe.y_up += pipe.y_distance/10
                if pipe.y_up >= pipe.y_down:
                    pipe.amazing1_state = 0
                if pipe.amazing1_state == 0 and pipe.y_up > pipe.y_down - pipe.y_distance:
                    pipe.y_up -=  pipe.y_distance/10
            #第二個坑
            if pipe.amazing == 2 and pipe.amazing1_state == 1 and player.x >= pipe.x - random.randint(58,62):
                pipe.y_up = random.randint(-530,-100)
                pipe.y_distance = random.randint(140,300)
                pipe.y_down = pipe.y_up + pipe.y_distance
                pipe.amazing1_state = 0
        
        screen.blit(pipe.sprite_up,(pipe.x,pipe.y_up))
        if demon.attack != 0:
            screen.blit(demon.sprite[demon.sprite_index],(demon.x,demon.y))
        screen.blit(pipe.sprite_down,(pipe.x,pipe.y_down + 499))
        #反轉提示
        if (pipe.amazing == pipe.amazing3 or pipe.amazing == 3) and player.x >= 20 and score >= 1:
            text_amazing(screen)
        
        if player.whether_dead:
            player.sprite_index = 1
        else:
            player.sprite_index = 0
        screen.blit(player.sprite[player.sprite_index],(player.x,player.y))
        if cooldown != 1:
            player.move()
        if not player.whether_dead:
            demon.move()
        #死亡
        if player.y <= 0 or player.y >= 614:
            player.whether_dead = True
        if player.x > pipe.x - 48 and player.x < pipe.x + pipe.x_scale:
            if player.y < pipe.y_up + 499 or player.y > pipe.y_up + pipe.y_distance + 463:
                player.whether_dead = True
        if player.x >= demon.x - 48 and player.x <demon.x + 64 and demon.attack != 0:
            if player.y >= demon.y - 36 and player.y <= demon.y + 64:
                player.whether_dead = True
        if cooldown == 0 and player.y >= 614:
            cooldown = 1  
        if player.whether_dead:
            die(screen,score)
            pipe.amazing = 4 
            mouse_x,mouse_y = pygame.mouse.get_pos()
            #重生
            if mouse_x <= 296 and mouse_x >= 104 and mouse_y >= 184 and mouse_y <= 216:
                color = (255,255,255)
                for event in pygame.event.get():
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        score = 0
                        cooldown = 0
                        #
                        player.sprite_index = 0
                        player.x = 120
                        player.y = 350
                        player.speed = 0
                        player.jump = False
                        player.gravity = 0
                        player.gravity_distance = 0
                        player.whether_dead = False
                        #
                        pipe.x = 400
                        pipe.y_up = random.randint(-530,-100)
                        pipe.y_distance = random.randint(140,300)
                        pipe.move_state = 0
                        pipe.move_total = 0
                        #
                        pipe.amazing = 0
                        pipe.amazing3 = 4
                        pipe.amazing1_state = 1
                        pipe.score_state = 1
                        pipe.x_scale = 94
                        pipe.y_down = pipe.y_up + pipe.y_distance
                        #
                        demon.sprite_index = 0
                        demon.sprite_state = 1
                        demon.x = 200
                        demon.y = random.randint(100,470)
                        demon.move_state = 0
                        demon.move_time = 100
                        demon.move_time2 = 100
                        demon.move_time_state = 0
                        #
                        demon.amazing = 0
                        demon.attack = 0
                        demon.speed = 2
                        demon.time = demon.move_time
                        demon.speed2 = 2
                        demon.time2 = demon.move_time2
                        demon.move_time_state2 = 0
                        demon.amazing2_y = demon.y + random.randint(-200,200)
                        demon.amazing2_y_state = 0
                        demon.step = 0
            else:
                color = None
            text4 = "點我重新開始"
            font4 = pygame.font.SysFont("simsun",32)
            font_surface4 = font4.render(text4,True,(255,0,0),color)
            font_rect4 = font_surface4.get_rect()
            font_rect4.center = (200,200)
            screen.blit(font_surface4,font_rect4)
pygame.display.update()#
pygame.display.flip()效果一樣

b.解釋

     sys用於對系統進行操作,在遊戲製作中主要用於結束遊戲;math庫提供許多數學函式,在遊戲中主要用於變數運算和判斷;random庫用於隨機數的使用,在用python做遊戲時可以避免變數的;pygame是用python做遊戲的主要庫,提供繪製視窗、顯示圖片、檢測按鍵等功能的函式。

     pygame.init()

     功能:用於對pygame庫進行初始化。

     pygame.display.set_mode(size)

     功能:用於建立遊戲的主螢幕,尺寸為size引數,為一個二元組(width,height),分別為房間的寬度和高度。

     class bird(object)(對其他類的定義同理):

     功能:定義鳥類(玩家類),__init__(self)函式用於定義該類的create變數(初始建立例項時獲得的變數),__move__(self)函式用於操控例項的運動。

     其中許多不常見的變數(比如self.amazing)用於製作遊戲坑的元素,比如self.amazing在每次管道從左側消失後會重新整理一次,用於決定在跳下一個管道時是

     否會有坑以及坑的型別,self.move_time和self.move_state等等在class demon()中的變數用於定義怪物的運動狀態。

     pygame.

     def die(screen,score):

     功能:此函式用於當玩家失敗後在螢幕screen上顯示的螢幕字樣,同時顯示玩家的得分score。

     for event in pygame.event.get():

     功能:用於歷遍pygame中的所有事件

     在此迴圈下用if pygame.type == ***來判斷事件的型別

     用if pygame.key == pygame.K_*來判斷具體按鍵

     以此在if語句下執行對應的效果,從而實現遊戲的效果。

     pygame.image.load(image)

     功能:用於匯入圖片

     image為圖片所在位置的地址(這裡的地址是相對主檔案所在的位置,如果和主檔案在同一資料夾下,則可以直接寫成圖片的名字,支援png和jpg)。

     注:image也可以是一個列表,裡面列舉多個圖片的路徑,在需要取用相應的圖片的時候用列表的標號取用即可,從而實現簡單的圖片變換過程。

     screen.blit(image,location)

     功能:用於在screen上將image在螢幕的location位置繪製出來

     其中location是一個二元組(x,y),引數分別為x和y座標。

    

     pygame.display.update()

     功能:用於更新螢幕畫面,沒有此條語句的話螢幕會保留上一次繪製的圖片的殘留象,讓整個螢幕一片混亂。

     clock = pygame.time.Clock():

     功能:用於定義一個時鐘,結合clock.tick(time)可以控制遊戲螢幕更新的速度,time引數是指每秒螢幕更新的次數

     該引數越大,遊戲執行的流暢度越高,同時,對電腦配置的要求也越高。(正常引數設定為60就差不多了)

     if __name__ == '__main__':

     功能:主函式:程式入口

     如果主檔案被當成模組匯入時,以下的程式碼將不會被執行

c.本地執行

死亡介面及重新開始遊戲正常

跳躍、怪物、坑和計算得分正常

d.在ECS伺服器執行

       登陸PUTTY

       上傳檔案

       在伺服器上下載所需要的包

 執行成功

四、遇到的問題和解決辦法

1.下載安裝pygame後無法使用

       詢問課代表之後得知需要重啟才可以使用

2.執行時報錯找不到圖片

       沒把圖片和主檔案放在同一個資料夾下,引數也沒有寫成地址形式

3.無法在ESC雲伺服器上用python3來執行程式,且無法找到pygame包(最大的問題)

      版本不匹配,pygame是用python3.9編寫,而伺服器上的python版本是3.7

      試過pip3 install pygame但是出現報錯,試過把電腦上的pygame檔案直接拖進伺服器檔案中,仍然顯示報錯

五、實驗感悟

       首先,我想在此表達對王老師和幾位課代表的由衷感謝。本學期的python課堂幽默有趣,教的知識細緻全面,尤其是每節課老師都會親自為我們做實踐的演示,我也從這一學期學到了很多東西。

  我接觸程式設計是從初中教的Visual Basic開始的,但是當時老師只是讓我們對著書抄程式碼,只是單純覺得執行出來的跳青蛙遊戲很好玩,但是並沒有理解程式碼。在高中三年期間,同學給我推薦了一款名叫MinecraftVSZombies2的遊戲,製作新穎,遊戲體驗感強,最吸引我的是作者——是一個和我同一級的高中生,從那會兒我開始接觸程式設計領域(學校裡的Python課只教了一節就被其他課佔光了)。我瞭解到他使用的遊戲製作的平臺是GamemakerStudio2(現在正在使用Unity平臺製作重製版),於是我學著用GamemakerStudio8.1平臺也做了一個彈幕射擊遊戲(做的比較low),然後對python和C++等程式語言開始有更多的學習(但是由於高考和疫情等原因,總的學習時間還是不長)。進入大學之後,大一上學期也在自學python,學藝不精,但是在這學期的python公選課之後,感覺此方面有了新的提升(老師的實驗作業和各種python實踐讓我從理論階段開始跨入實踐階段)。

  以上就是我和程式語言相遇、相識、相知的過程。這學期的python學習除了鞏固Python中基本函式、模組、列表元組等知識之外,還讓我瞭解了一直覺得很遙遠的socket和遊戲領域,雖然沒能把老師教的全部知識都掌握,但是徹底打開了我的視野。雖然python公選課已經圓滿結課了,但是我對python的熱情不會消失,最後就以一句我第一次接觸的python程式碼結束吧!

  print("Hello Python!Thank you,Mr Wang!")

六、小建議

     如果下學期還開設這門課的話,希望能詳細地講一講socket和華為雲伺服器上的知識,然後也可以多爭取一些和這學期寫CSDN部落格然後評小獎勵的活動。老師上課的幽默感也希望能繼續保持下去

參考資料:

[1]: https://www.cnblogs.com/yuhaowang/p/10485185.html

[2]:https://www.pygame.org/download.shtml

[3]:https://pan.baidu.com/s/1wMDA-8zqd8eiu6iGWGPqFQ?_at_=1653577595955

[4]:https://www.linuxidc.com/Linux/2017-01/139241.htm

[5]:https://www.freesion.com/article/73691086600/

[6]:https://www.daehub.com/archives/9949.html#:~:text=%E5%85%B6%E4%B8%AD%20PuTTY%20%E6%98%AF%20SSH%20%E5%AE%A2%E6%88%B7%E7%AB%AF%EF%BC%8C%E8%80%8C,Xming%20%E5%88%99%E6%98%AF%20Windows%20%E5%B9%B3%E5%8F%B0%E7%9A%84%20X%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E3%80%82

[7]:https://www.jianshu.com/p/23ba123ee874

課程:        《Python程式設計》
班級:        2121
姓名:        王季延
學號:        20212108
實驗教師:  王志強
實驗日期:  2022年5月21日
必修/選修: 公選課

一、實驗內容

用Python做一個小遊戲i wanna flippy bird

1.想法介紹:

       大一上學期從課代表那裡瞭解到可以使用pygame模組製作遊戲,本學期在舍友那裡接觸到了i wanna類的遊戲(被坑哭了),最後是在雲班課中老師發的資料裡找到了用pygame製作經典flippy bird遊戲的視訊,所以就有了用python做一個簡單的兩者結合的小遊戲。

2.主要內容:

      玩家控制小鳥(畫成了一個腦袋)前進和跳躍(標準的flippy bird遊戲中小鳥是自動前進,玩家只需要操控小鳥的跳躍即可,但是由於此遊戲含有坑,前進需要玩家手動操控),通過管道獲得儘可能多的分數,但是在這個經典玩法中摻雜了擋路的怪物和坑的元素。(遊戲剛開始時玩家就是處於下墜狀態,只是單純為了讓玩家觀看死亡介面的遊戲規則,接下來每次重新開始遊戲後不會自動下墜,只有按下跳躍鍵後才會正常下落)

           

 二、實驗過程及結果

1.圖片素材準備

      在電腦附件“畫圖”中直接編輯,背景使用截圖

 2.pygame包下載和安裝

 pip install pygame -i https://pypi.mirrors.ustc.edu.cn/simple安裝pygame

pip show pygame檢視pygame是否安裝完成

重啟後電腦成功檢測到pygame

3.遊戲架構分析

 遊戲即讓圖片在一個視窗內運動,在執行對應操作時做出對應的動作。

關於類的建立,使用class函式實現,參考資料

①https://blog.csdn.net/weixin_34177886/article/details/111963062

②本學期python課堂對class知識的講授

關於視窗和檢測按鍵的使用,使用pygame相關程式碼和自定義變數實現,參考資料

(3)實驗過程

a.程式碼

import sys
import pygame
import random
import math

if __name__ == '__main__':
    pygame.init()
    
    #
    def text_amazing(screen):
        text5 = "注意!按鍵反轉"
        font5 = pygame.font.SysFont("simsun",32)
        font_surface5 = font5.render(text5,True,(0,0,0))
        font_rect5 = font_surface5.get_rect()
        font_rect5.center = (200,100)
        screen.blit(font_surface5,font_rect5)
    def die(screen,score):
        text = "你無了!"
        font = pygame.font.SysFont("simsun",32)
        font_surface = font.render(text,True,(255,0,0))
        font_rect = font_surface.get_rect()
        font_rect.center = (200,100)
        screen.blit(font_surface,font_rect)


        text1 = "你的得分是" + str(score)
        font1 = pygame.font.SysFont("simsun",16)
        font_surface1 = font1.render(text1,True,(0,0,0))
        font_rect1 = font_surface1.get_rect()
        font_rect1.center = (180,150)
        screen.blit(font_surface1,font_rect1)

        text2 = "規則:右鍵前進,空格跳躍"
        font2 = pygame.font.SysFont("simsun",16)
        font_surface2 = font2.render(text2,True,(255,0,0))
        font_rect2 = font_surface2.get_rect()
        font_rect2.center = (180,250)
        screen.blit(font_surface2,font_rect2)

        text3 = "注意有坑,兩個按鍵可能交換"
        font3 = pygame.font.SysFont("simsun",16)
        font_surface3 = font3.render(text3,True,(0,0,0))
        font_rect3 = font_surface3.get_rect()
        font_rect3.center = (180,300)
        screen.blit(font_surface3,font_rect3)

    class bird(object):
        def __init__(self):
            self.sprite = [pygame.image.load("player0.png").convert_alpha(),#
                            pygame.image.load("player1.png").convert_alpha()]#死
            self.sprite_index = 0
            self.x = 120
            self.y = 350
            self.speed = 0
            self.jump = False
            self.gravity = 0.2
            self.gravity_distance = 0.1
            self.whether_dead = False

        def move(self):
            self.speed -= self.gravity
            self.y -= self.speed
            if not self.jump:
                self.gravity += self.gravity_distance
                self.gravity_distance = self.gravity_distance/2
    #######################
    class pipeline(object):
        def __init__(self):
            self.x = 400
            self.y_up = random.randint(-530,-100)
            self.y_distance = random.randint(140,300)
            self.sprite_up = pygame.image.load("up.png")
            self.sprite_down = pygame.image.load("down.png")
            self.move_state = 0
            #
            self.amazing = 0
            self.amazing3 = 4
            self.amazing1_state = 1
            self.score_state = 1
            self.x_scale = 94
            self.y_down = self.y_up + self.y_distance
            self.move_total = 0

        def pipeline_update(self):
            if self.move_state == 1 and self.move_total == 1:
                self.x -= 2
            if self.x <= -100:
                self.x = 400
                self.y_up = random.randint(-530,-100)
                self.y_distance = random.randint(140,300)
                self.y_down = self.y_up + self.y_distance
                self.yscale = random.randint(60,100)
                self.sprite_up = pygame.transform.scale(self.sprite_up,(self.x_scale,499))
                self.sprite_down = pygame.transform.scale(self.sprite_down,(self.x_scale,499))
                self.amazing = random.randint(0,3)
                self.score_state = 1
                self.amazing1_state = 1
                self.amazing3 = random.randint(0,3)
    ###################
    class demon(object):
        def __init__(self):
            self.sprite = [pygame.image.load("demon1.png"),
                            pygame.image.load("demon2.png")]
            self.sprite_index = 0
            self.sprite_state = 1
            self.x = 200
            self.y = random.randint(100,470)
            self.move_state = 0
            self.move_time = 100
            self.move_time2 = 100
            self.move_time_state = 0
            #
            self.amazing = 0
            self.attack = 0
            self.speed = 2
            self.time = self.move_time
            self.speed2 = 2
            self.time2 = self.move_time2
            self.move_time_state2 = 0
            self.amazing2_y = self.y + random.randint(-200,200)
            self.amazing2_y_state = 0
            self.step = 0

        def move(self):
            self.sprite_state -= 1
            if self.amazing >= 1:
                if self.time > 0 and self.amazing2_y_state == 0:
                    if self.move_time_state == 0:
                        self.y += self.speed
                    else:
                        self.y -= self.speed
                    self.time -= 1
                if self.time <= 0 and self.amazing2_y_state == 0:
                    self.time = self.move_time
                    if self.move_time_state == 0:
                        self.move_time_state = 1
                    elif self.move_time_state == 1:
                        self.move_time_state = 0
                if self.amazing == 2:
                    if self.amazing2_y_state == 0 and abs(self.y - self.amazing2_y) <= random.randint(10,15):
                        self.amazing2_y_state = 1
                    if self.amazing2_y_state == 1:
                        if self.time2 > 0 and self.amazing2_y_state == 1:
                            if self.move_time_state2 == 1:
                                self.x += self.speed2
                            else:
                                self.x -= self.speed2
                            self.time2 -= 1
                        if self.time2 <= 0 and self.amazing2_y_state == 1:
                            self.time2 = self.move_time2
                            if self.move_time_state2 == 0:
                                self.move_time_state2 = 1
                            elif self.move_time_state2 == 1:
                                self.move_time_state2 = 0
                            self.step += 1
                    if self.step == 2:
                        self.amazing2_y_state = 0
                        self.amazing2_y = self.y + random.randint(-120,200)
                        self.step = 0

            if self.sprite_index == 0 and self.sprite_state == 0:
                self.sprite_index = 1
                self.sprite_state = 30
            if self.sprite_index == 1 and self.sprite_state == 0:
                self.sprite_index = 0
                self.sprite_state = 30
            if self.move_state == 1:
                self.x -= 2
            if self.x <= -100:
                self.x = 400
                self.y = random.randint(200,450)
                self.attack = random.randint(0,3)
                self.move_time = random.randint(40,60)
                self.time = self.move_time
                self.amazing = random.randint(0,2)
                self.move_time_state = random.randint(0,1)
                self.speed = random.randint(2,5)
                self.amazing2_y = self.y + random.randint(-120,200)
                self.amazing2_y_state = 0
                #
                self.move_time2 = random.randint(20,30)
                self.move_time_state2 = random.randint(0,1)
                self.speed = random.randint(2,5)
                self.time2 = self.move_time2
                self.step = 0
    #

    size = width,height = 400,650
    screen = pygame.display.set_mode(size)
    clock = pygame.time.Clock()
    score = 0
    cooldown = 0

    player = bird()
    pipe = pipeline()
    demon = demon()
    while True:
        clock.tick(100)

        pygame.display.set_caption("你的得分:"+str(score))

        for event in pygame.event.get():
            if event.type == pygame.QUIT:
                sys.exit()
            if not player.whether_dead:
                if (pipe.amazing == pipe.amazing3 or pipe.amazing == 3) and player.x >= 20:
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_RIGHT:
                            player.jump = True
                            player.gravity = 0.2
                            player.speed = 5
                            player.gravity_distance = 0.02
                        if event.key == pygame.K_SPACE:
                            pipe.move_state = 1
                            demon.move_state = 1
                    elif event.type == pygame.KEYUP:
                        if event.key == pygame.K_RIGHT:
                            player.jump = False
                        if event.key == pygame.K_SPACE:
                            pipe.move_state = 0
                            demon.move_state = 0
                
                else:
                    if event.type == pygame.KEYDOWN:
                        if event.key == pygame.K_SPACE:
                            pipe.move_total = 1
                            player.jump = True
                            player.gravity = 0.2
                            player.speed = 5
                            player.gravity_distance = 0.02
                        if event.key == pygame.K_RIGHT:
                            pipe.move_state = 1
                            demon.move_state = 1
                    elif event.type == pygame.KEYUP:
                        if event.key == pygame.K_SPACE:
                            player.jump = False
                        if event.key == pygame.K_RIGHT:
                            pipe.move_state = 0
                            demon.move_state = 0
            else:
                player.sprite_index = 1
        
        if player.x > pipe.x + pipe.x_scale and pipe.score_state == 1:
            score += 1
            pipe.score_state = 0
        background = pygame.image.load("background.png")
        screen.blit(background,(0,0))

        if not player.whether_dead:
            pipe.pipeline_update()
            #第一個坑
            if pipe.amazing == 1 and player.x >= pipe.x - random.randint(58,62):
                if pipe.y_up < pipe.y_down and pipe.amazing1_state == 1:
                    pipe.y_up += pipe.y_distance/10
                if pipe.y_up >= pipe.y_down:
                    pipe.amazing1_state = 0
                if pipe.amazing1_state == 0 and pipe.y_up > pipe.y_down - pipe.y_distance:
                    pipe.y_up -=  pipe.y_distance/10
            #第二個坑
            if pipe.amazing == 2 and pipe.amazing1_state == 1 and player.x >= pipe.x - random.randint(58,62):
                pipe.y_up = random.randint(-530,-100)
                pipe.y_distance = random.randint(140,300)
                pipe.y_down = pipe.y_up + pipe.y_distance
                pipe.amazing1_state = 0
        
        screen.blit(pipe.sprite_up,(pipe.x,pipe.y_up))
        if demon.attack != 0:
            screen.blit(demon.sprite[demon.sprite_index],(demon.x,demon.y))
        screen.blit(pipe.sprite_down,(pipe.x,pipe.y_down + 499))
        #反轉提示
        if (pipe.amazing == pipe.amazing3 or pipe.amazing == 3) and player.x >= 20 and score >= 1:
            text_amazing(screen)
        
        if player.whether_dead:
            player.sprite_index = 1
        else:
            player.sprite_index = 0
        screen.blit(player.sprite[player.sprite_index],(player.x,player.y))
        if cooldown != 1:
            player.move()
        if not player.whether_dead:
            demon.move()
        #死亡
        if player.y <= 0 or player.y >= 614:
            player.whether_dead = True
        if player.x > pipe.x - 48 and player.x < pipe.x + pipe.x_scale:
            if player.y < pipe.y_up + 499 or player.y > pipe.y_up + pipe.y_distance + 463:
                player.whether_dead = True
        if player.x >= demon.x - 48 and player.x <demon.x + 64 and demon.attack != 0:
            if player.y >= demon.y - 36 and player.y <= demon.y + 64:
                player.whether_dead = True
        if cooldown == 0 and player.y >= 614:
            cooldown = 1  
        if player.whether_dead:
            die(screen,score)
            pipe.amazing = 4 
            mouse_x,mouse_y = pygame.mouse.get_pos()
            #重生
            if mouse_x <= 296 and mouse_x >= 104 and mouse_y >= 184 and mouse_y <= 216:
                color = (255,255,255)
                for event in pygame.event.get():
                    if event.type == pygame.MOUSEBUTTONDOWN:
                        score = 0
                        cooldown = 0
                        #
                        player.sprite_index = 0
                        player.x = 120
                        player.y = 350
                        player.speed = 0
                        player.jump = False
                        player.gravity = 0
                        player.gravity_distance = 0
                        player.whether_dead = False
                        #
                        pipe.x = 400
                        pipe.y_up = random.randint(-530,-100)
                        pipe.y_distance = random.randint(140,300)
                        pipe.move_state = 0
                        pipe.move_total = 0
                        #
                        pipe.amazing = 0
                        pipe.amazing3 = 4
                        pipe.amazing1_state = 1
                        pipe.score_state = 1
                        pipe.x_scale = 94
                        pipe.y_down = pipe.y_up + pipe.y_distance
                        #
                        demon.sprite_index = 0
                        demon.sprite_state = 1
                        demon.x = 200
                        demon.y = random.randint(100,470)
                        demon.move_state = 0
                        demon.move_time = 100
                        demon.move_time2 = 100
                        demon.move_time_state = 0
                        #
                        demon.amazing = 0
                        demon.attack = 0
                        demon.speed = 2
                        demon.time = demon.move_time
                        demon.speed2 = 2
                        demon.time2 = demon.move_time2
                        demon.move_time_state2 = 0
                        demon.amazing2_y = demon.y + random.randint(-200,200)
                        demon.amazing2_y_state = 0
                        demon.step = 0
            else:
                color = None
            text4 = "點我重新開始"
            font4 = pygame.font.SysFont("simsun",32)
            font_surface4 = font4.render(text4,True,(255,0,0),color)
            font_rect4 = font_surface4.get_rect()
            font_rect4.center = (200,200)
            screen.blit(font_surface4,font_rect4)
pygame.display.update()#
pygame.display.flip()效果一樣

b.解釋

     sys用於對系統進行操作,在遊戲製作中主要用於結束遊戲;math庫提供許多數學函式,在遊戲中主要用於變數運算和判斷;random庫用於隨機數的使用,在用python做遊戲時可以避免變數的;pygame是用python做遊戲的主要庫,提供繪製視窗、顯示圖片、檢測按鍵等功能的函式。

     pygame.init()

     功能:用於對pygame庫進行初始化。

     pygame.display.set_mode(size)

     功能:用於建立遊戲的主螢幕,尺寸為size引數,為一個二元組(width,height),分別為房間的寬度和高度。

     class bird(object)(對其他類的定義同理):

     功能:定義鳥類(玩家類),__init__(self)函式用於定義該類的create變數(初始建立例項時獲得的變數),__move__(self)函式用於操控例項的運動。

     其中許多不常見的變數(比如self.amazing)用於製作遊戲坑的元素,比如self.amazing在每次管道從左側消失後會重新整理一次,用於決定在跳下一個管道時是

     否會有坑以及坑的型別,self.move_time和self.move_state等等在class demon()中的變數用於定義怪物的運動狀態。

     pygame.

     def die(screen,score):

     功能:此函式用於當玩家失敗後在螢幕screen上顯示的螢幕字樣,同時顯示玩家的得分score。

     for event in pygame.event.get():

     功能:用於歷遍pygame中的所有事件

     在此迴圈下用if pygame.type == ***來判斷事件的型別

     用if pygame.key == pygame.K_*來判斷具體按鍵

     以此在if語句下執行對應的效果,從而實現遊戲的效果。

     pygame.image.load(image)

     功能:用於匯入圖片

     image為圖片所在位置的地址(這裡的地址是相對主檔案所在的位置,如果和主檔案在同一資料夾下,則可以直接寫成圖片的名字,支援png和jpg)。

     注:image也可以是一個列表,裡面列舉多個圖片的路徑,在需要取用相應的圖片的時候用列表的標號取用即可,從而實現簡單的圖片變換過程。

     screen.blit(image,location)

     功能:用於在screen上將image在螢幕的location位置繪製出來

     其中location是一個二元組(x,y),引數分別為x和y座標。

    

     pygame.display.update()

     功能:用於更新螢幕畫面,沒有此條語句的話螢幕會保留上一次繪製的圖片的殘留象,讓整個螢幕一片混亂。

     clock = pygame.time.Clock():

     功能:用於定義一個時鐘,結合clock.tick(time)可以控制遊戲螢幕更新的速度,time引數是指每秒螢幕更新的次數

     該引數越大,遊戲執行的流暢度越高,同時,對電腦配置的要求也越高。(正常引數設定為60就差不多了)

     if __name__ == '__main__':

     功能:主函式:程式入口

     如果主檔案被當成模組匯入時,以下的程式碼將不會被執行

c.本地執行

死亡介面及重新開始遊戲正常

跳躍、怪物、坑和計算得分正常

d.在ECS伺服器執行

       登陸PUTTY

       上傳檔案

       在伺服器上下載所需要的包

 執行成功

四、遇到的問題和解決辦法

1.下載安裝pygame後無法使用

       詢問課代表之後得知需要重啟才可以使用

2.執行時報錯找不到圖片

       沒把圖片和主檔案放在同一個資料夾下,引數也沒有寫成地址形式

3.無法在ESC雲伺服器上用python3來執行程式,且無法找到pygame包(最大的問題)

      版本不匹配,pygame是用python3.9編寫,而伺服器上的python版本是3.7

      試過pip3 install pygame但是出現報錯,試過把電腦上的pygame檔案直接拖進伺服器檔案中,仍然顯示報錯

五、實驗感悟

       首先,我想在此表達對王老師和幾位課代表的由衷感謝。本學期的python課堂幽默有趣,教的知識細緻全面,尤其是每節課老師都會親自為我們做實踐的演示,我也從這一學期學到了很多東西。

  我接觸程式設計是從初中教的Visual Basic開始的,但是當時老師只是讓我們對著書抄程式碼,只是單純覺得執行出來的跳青蛙遊戲很好玩,但是並沒有理解程式碼。在高中三年期間,同學給我推薦了一款名叫MinecraftVSZombies2的遊戲,製作新穎,遊戲體驗感強,最吸引我的是作者——是一個和我同一級的高中生,從那會兒我開始接觸程式設計領域(學校裡的Python課只教了一節就被其他課佔光了)。我瞭解到他使用的遊戲製作的平臺是GamemakerStudio2(現在正在使用Unity平臺製作重製版),於是我學著用GamemakerStudio8.1平臺也做了一個彈幕射擊遊戲(做的比較low),然後對python和C++等程式語言開始有更多的學習(但是由於高考和疫情等原因,總的學習時間還是不長)。進入大學之後,大一上學期也在自學python,學藝不精,但是在這學期的python公選課之後,感覺此方面有了新的提升(老師的實驗作業和各種python實踐讓我從理論階段開始跨入實踐階段)。

  以上就是我和程式語言相遇、相識、相知的過程。這學期的python學習除了鞏固Python中基本函式、模組、列表元組等知識之外,還讓我瞭解了一直覺得很遙遠的socket和遊戲領域,雖然沒能把老師教的全部知識都掌握,但是徹底打開了我的視野。雖然python公選課已經圓滿結課了,但是我對python的熱情不會消失,最後就以一句我第一次接觸的python程式碼結束吧!

  print("Hello Python!Thank you,Mr Wang!")

六、小建議

     如果下學期還開設這門課的話,希望能詳細地講一講socket和華為雲伺服器上的知識,然後也可以多爭取一些和這學期寫CSDN部落格然後評小獎勵的活動。老師上課的幽默感也希望能繼續保持下去

參考資料:

[1]: https://www.cnblogs.com/yuhaowang/p/10485185.html

[2]:https://www.pygame.org/download.shtml

[3]:https://pan.baidu.com/s/1wMDA-8zqd8eiu6iGWGPqFQ?_at_=1653577595955

[4]:https://www.linuxidc.com/Linux/2017-01/139241.htm

[5]:https://www.freesion.com/article/73691086600/

[6]:https://www.daehub.com/archives/9949.html#:~:text=%E5%85%B6%E4%B8%AD%20PuTTY%20%E6%98%AF%20SSH%20%E5%AE%A2%E6%88%B7%E7%AB%AF%EF%BC%8C%E8%80%8C,Xming%20%E5%88%99%E6%98%AF%20Windows%20%E5%B9%B3%E5%8F%B0%E7%9A%84%20X%20%E6%9C%8D%E5%8A%A1%E5%99%A8%E3%80%82

[7]:https://www.jianshu.com/p/23ba123ee874