Try   HackMD
Image Not Showing Possible Reasons
  • The image was uploaded to a note which you don't have access to
  • The note which the image was originally uploaded to has been deleted
Learn More →

2024 資訊之芽 Python 語法班第一階段大作業 - Flappy Bird

tags: 資訊之芽 大作業

DEADLINE: 4/21



事前準備

安裝 python3

相信大家都安裝好了。
如果有需要,可以再到 課程網站Week1簡報 去看教學~

安裝 pygame

依據自己電腦使用的作業系統進行安裝。
遇到任何問題請洽講師們,我們會盡快提供協助。

Windows

在鍵盤上按下 Win+R 快捷鍵開啟執行的視窗,
輸入 cmd 後按 確定 打開 命令提示字元

範例畫面

螢幕擷取畫面 2024-03-01 231317


在命令提示字元中輸入以下指令:

python -m pip install -U pygame==2.5.2 --user
範例畫面

(介面可能會根據版本/設定不同有所變化,大致是如下圖的文字介面)

螢幕擷取畫面 2024-03-01 231657


輸入後按 ENTER 就會開始安裝。

MacOS/Linux

打開 terminal 輸入以下指令:

python3 -m pip install -U pygame==2.5.2 --user

輸入後按 ENTER 就會開始安裝。

TODO Tree VSCode Extension(非必要)

為了方便定位大作業中,每一項任務分別要修改程式碼中的哪一部分,你可以下載和 TODO關鍵字 相關的插件在自己的編輯器中。大作業的任務們都有用 # TODO 做上標記及編號,透過插件你可以很快速的定位該任務你所需要修改的地方。

對於使用VSCode的同學,這裡推薦一個第一週就有講師推薦過的插件 TODO Tree ,使用它讓你的大作業更順利。

獲取作業

下載作業

Links 作業程式連結裡下載作業,檔案為壓縮檔,解壓縮後可在資料夾裡看到以下檔案:

資料夾檔案圖片

螢幕擷取畫面 2024-03-17 202702

執行方式

打開 命令提示字元 或者是 terminal,輸入以下指令:

cd <上面檔案存放的母資料夾路徑>

接下來輸入:

python main.py

或者是:

python3 main.py

來執行作業程式。

執行範例

這些檔案被存放在 C:\Users\anonymous\Desktop\Flappy_Bird 中,則輸入以下指令後ENTER

cd C:\Users\anonymous\Desktop\Flappy_Bird

再輸入以下指令後ENTER

python main.py

執行成功後,會看到的遊戲視窗如下:

遊戲視窗畫面

螢幕擷取畫面 2024-03-17 204547


到這裡就成功下載好作業了,用你喜歡的編輯器開始寫作業吧!

防雷區

以下列舉一些過程中你可能會遇到的問題,在遇到困難時不妨來這裡看看,你的問題有沒有在其中。

環境變數問題

如果你在下載 pygame 套件步驟時,發現視窗中顯示以下文字:

不是內部或外部命令、可執行的程式或批次檔

或者是跳出其他視窗,而沒有在原本的視窗中出現文字的下載進度條。
在確定你的電腦中安裝有 python 的情況下,
那麼問題有可能是來自,沒有設定好 python 的系統環境變數。
你可以用 [你的作業系統]+python環境變數 當關鍵字在網路上搜尋相關的處理方式。

使用 Mac/Linux 的同學可以到網路上查詢指令解決。

使用 Windows 的同學可以參考以下簡單的處理方式:

Windows 解法參考
確認你常用的python裝在哪個資料夾

為避免"孿生python悖論"(並沒有)導致你接下來設定的,和你實際上常用的不一致。請先確定你常用的 python 執行檔被存在哪個資料夾。

以上課用的VSCode做教學,
隨意點開一個 python 程式後按執行。

這是筆者的執行畫面,只是示意,你的路徑不是這個QQ

螢幕擷取畫面 2024-03-17 212547

黃色的字樣就是你常用的 python 執行檔路徑,
其所在資料夾是 python.exe 前面的那串路徑,
將其複製好後進行下一步。

設定環境變數
  • 命令提示字元中輸入:
rundll32 sysdm.cpl,EditEnvironmentVariables

後按 ENTER 即可開啟編輯系統環境變數

螢幕擷取畫面 2024-03-17 214538

點選Path使其反白後按編輯

新增並貼上你從VSCode中複製過來的路徑:

C:\Users\anonymous\...\

新增一個:

C:\Users\anonymous\...\Scripts\

設定完成後按確認,重開命令提示字元後即可排除問題。

視窗大小問題

如果你成功打開了上方的遊戲視窗,卻發現視窗過大/過小,那麼意味著你可以直接開始著手作業程式的部分進行修改了!
打開作業程式中的 config.py ,此檔案中定義了許多你可能會用到的常數。
找到 BACKGROUND_SCALE 變數,此變數用來表示背景的縮放值常數,調整它讓視窗呈現令你舒適的大小。


作業說明

小芽是一位富有創造力的軟體工程師,他對於技術的探索和創新充滿了無限的熱情。儘管工作繁忙,但在閒暇時間,他喜歡探索各種新奇的事物,其中包括刷 YouTube Shorts 來放鬆心情。

一天,小芽無意間刷到一個引人入勝的影片,這是一款名為 Flappy Bird 的遊戲,他被畫面中那簡單無腦卻極具挑戰性的遊戲內容所吸引。盡管營銷號笨如菜雞的操作讓他差點昏厥,卻並不減少他對這款遊戲的興趣。

小芽迫不及待地上網搜索了Flappy Bird 網頁版,迅速投入到了遊戲的世界中。儘管是第一次嘗試,他單身50年的手速也讓他輕鬆破台了這款遊戲,這讓他感到悵然若失。

然而,小芽並不是個輕言放棄的人。他想,為何不自己動手製作一個屬於自己的 Flappy Bird 呢?這個想法在他心中生根,像是一顆資訊之芽迅速成長,充滿了他整個思緒。

於是,小芽展開了他的創作之旅。但故事迎來了轉折,因為長時間使用電腦,小芽得到了腕隧道症候群,在醫生的建議下他中止了遊戲的開發,甚是遺憾。

熱心的你決定冒著得到腕隧道症候群的風險,幫助可憐的小芽完成他夢想中的Flappy Bird。

遊戲內容

  • 透過點擊滑鼠左鍵讓Flappy Bird獲得向上的動力,往上飛。
  • 在未點擊時,Flappy Bird會因重力而自由下墜。
  • 場上會出現兩兩成對的水管對,當Flappy Bird撞到水管則遊戲結束。
  • 這些水管很皮(?),它們會移動。
  • 玩家控制Flappy Bird避開盡可能多的水管以賺取分數。

檔案內容

  • config.py 中定義了許多你可能會用到的常數,在開始上手程式前,不妨先翻翻看,了解有哪些常數你可以不用自己找。
  • main.py 是程式的進入點,執行這支程式可以開啟你的遊戲。
  • helper.py 是放置一些幫手的地方,你可以把關係上較為獨立,或者是多處可用的一些函式、物件放置在這裡。
  • game.py 放置遊戲物件,控制遊戲流程、遊戲中的物件、及管理遊戲物件間彼此互動的物件。
  • base.py 放置地基物件,定義遊戲中最下方的地基的物件。
  • bird.py 放置鳥(玩家)物件,定義遊戲中鳥(玩家)的物件。
  • pipe.py 放置水管物件,定義了遊戲中和水管相關的物件。
  • number.py 放置記分板中,單一位數數字的數字物件。
  • scoreboard.py 放置記分板物件,定義遊戲中最上方所顯示的記分板。

小內容提醒

Pygame中的座標位置和我們在數學中用的不太一樣,
數學上 x 軸向右為正 y 軸向上為正, (0,0)在左下角
Pygame中 x 軸向右為正 y 軸向下為正, (0,0)在左上角

遊戲中各物件的座標定位略有不同,詳細都說明在檔案中

Tasks

以下列舉了你需要完成的任務,任務編排為推薦完成的順序,當然也可以依據個人偏好順序完成。
你從小芽完成一半的程式接續製作,但小芽的程式內容僅為 支援某些已完成的內容,及提供未來“可能“的實作便利性 而存在。你可以依照小芽留下的線索完成任務。但某些時候,你也可以任意對小芽的程式進行想要的調整。

Optional系列最高只會得到15pts (也就是可以四選二或三),Extra系列最高只會得到10pts。

一般得分(包括Optional)每一筆的得分都會有:

  • 45% 功能完成
  • 50% 功能穩定(能重複不斷成功發生)
  • 5% code乾淨程度(不要太髒即可)

Extra 得分則是有完成功能即可拿滿。

01. 讓世界動起來

(10pts) 完成 base.py 中的 TODO 0

  • (10pts) 讓下方的地基動起來

02. 讓鳥鳥飛起來

(20pts) 完成 bird.py 中的 TODO 1, 2

  • (5pts) 讓鳥(玩家)能夠垂直移動
  • (5pts) 讓鳥(玩家)在接收到滑鼠點擊的訊號時,能向上移動
    並讓鳥(玩家)在未接受到滑鼠點擊的訊號時,能向下移動
  • (10pts) 讓鳥(玩家)在接收到單一次滑鼠點擊的訊號後,能"自然"移動
    (note: 看起來像受到重力影響,像是有向上初速垂直拋起的拋體)

03. 把水管加進來

(15pts) 完成 pipe.py 中的 TODO 3

  • (15pts) 讓水管能以合理的速率加到遊戲中

休息一下

恭喜你,到這裡你應該完成了基本能夠運行的遊戲
後面任務出現的順序比較沒有先後關係,可以依照自己喜歡的順序完成

_

1280

04. 讓鳥鳥更生動

(10pts) 完成 bird.py 中的 TODO 4

  • (5pts) 讓鳥(玩家)以合理的速率持續拍動翅膀
  • (5pts) 讓鳥(玩家)向上飛時略往上仰,向下墜時略往下看

05. 有個性的水管

(10pts) 完成 pipe.py 中的 TODO 5

  • (5pts) 讓每次新出現的上下水管間隙及開口位置略有不同
  • (5pts) 讓遊戲的"難度"能隨著時間推進漸漸增加

06. 記分板

(10pts) 完成 scoreboard.py 中的 TODO 6

  • (5pts) 在視窗中間偏上的位置顯示出數字表示得分
  • (5pts) 在玩家(鳥)每經過一對水管時,往上加一分

07. 更多遊戲流程

(5pts+10pts) 完成 game.py 中的 TODO 7

  • (5pts) 等待玩家第一次點擊才開始遊戲
  • (Option 1 5pts) 結束時顯示 Game Over 提示語並顯示得分
    (參考pygame docs與圖片、文字在視窗中顯示相關的功能)
  • (Option 2 5pts) 遊戲結束後,讓玩家能按任意鍵重新開始遊戲
  • (Extra 5pts) 其他豐富遊戲的功能(暫停功能、歷史分數紀錄 etc)

08. 過動的水管

(+10pts) 完成 pipe.py 中的 TODO 8

  • (Option 3 5pts) 讓每一對水管對能朝固定目標移動,不同對間彼此需朝自己(不同)的目標移動
    (note: 為維持遊戲的可玩性,水管的移動僅為擾亂玩家視線,而非限制玩家移動,
    需在合理的時間內變回固定位置)
  • (Option 4 5pts) 讓每一對水管對能朝>1種移動方向移動
  • (Extra 5pts) 以"繼承"的方式實作帶有移動模式的水管、水管對
  • (Extra 5pts) 做出其他種移動模式的水管、水管對

其他

(Extra 0~5pts)
任何自己做出來的新功能,或是在此作業中用到額外學習的內容,都可能可以爭取到額外的分數。
請在這些內容的前方加上 #TODO 的註解,並簡單描述你實做的東西,以方便批改。


繳交作業

Links 作業繳交表單連結中繳交作業
繳交檔案需為壓縮檔,將你整個專案資料夾底下的所有檔案放在同一個名為 [姓名]_資芽py班大作業 的資料夾底下,壓縮此資料夾成.zip檔後繳交

e.g. 王小明應該會繳交 王小明_資芽py班大作業.zip

表單會設為可修改,期間內不滿意/發現有bug都可以修改回覆的內容


問答&後續公告

Announcement

3/24 更 1: 程式連結進去的程式是好的,請安心服用。
3/24 更 2: 有一些上課來不及說,但有點重要的放在FAQ 02. 大家記得看。
3/24 更 3: 這次作業會隨著大家的提問,解鎖更多的hint,希望大家踴躍提問。

3/29 更 1: 更新config.py裡的圖片路徑設定,可以到 Links 去下載新的config.py下來更換。
3/29 更 2: 作業程式連結裡的config.py也更新成新版了,3/29後下載的不需要另外再更新。

4/14 更 1: 更新number.py裡的draw方法不存在的問題,可以到 Links 去下載新的number.py下來更換。

4/17 更 1: pipe.py中,class Pipe的建構子__init__參數註解誤植,direction為水管開口的方向,應為"UP""DOWN",表示此水管開口朝上(下面那根)或者朝下(上面那根)。

FAQ

00. 如何提問

Ans: 你可以透過 Discord群組 或者使用 HackMD 的留言功能 進行反饋/問問題/投訴(?),被解決過的問題就會像這裡的形式,精選後留下,供大家查詢、參考。


01. 不會寫怎麼辦

Ans: 你可以利用 Discord群組 和學員們、講師們進行交流、討論,也可以在 課堂下課時 向左右鄰居、後面的講師們面對面聊聊,相信大家都非常樂意幫助你解決問題、提供想法給你。


02. 我不知道到底要寫什麼

Ans:
你可以把這次作業看成 I/O 形式和平常不同的作業。
Input來自每一個class裡存著的屬性及可用的方法,或者說是,上一個時刻的遊戲狀態。
Output就是要更改這些遊戲狀態成下一個時刻該有的狀態。
由於我們會在每一新時刻開始前呼叫每個物件的 .update(),因此 .update() (你要寫的內容)需要維護好這個class裡,會因為時間或其他因素產生改變的屬性,讓他們變成新的狀態。
也就是,在.update()中完成 Output 的要求。
(你會發現有的任務請你修改的不在.update()中,但它們都會在.update()中被呼叫)
至於詳細要完成些什麼,就是每個不同的任務了。
e.g. TODO 0
base.py中的Base物件紀錄有.scroll的屬性代表地板圖片的滑動(平移),我們希望這個地板圖片有不斷捲動的效果。
你可以先解讀這段話成平常寫judge時會有的樣子:
Input: 給定.scroll屬性代表上一刻地板圖片與其原本位置的平移量。
Output: 請將.scroll屬性更新成下一刻地板圖片與其原本位置的平移量。讓下一刻與這一刻的地板圖片,看起來有捲動的效果。
我們要做的會是 將 Output: 下一刻的.scroll 設定成 Input: 上一刻的.scroll 加一點點變動量,看起來就會有不斷平移的效果(你可以用物理課學到過的

x=x0+vt 來理解,其中
v(/)1()
就會是變動量
v()
)。
但單純只有位移的邏輯是不夠的。因為圖片是有限長度,當你將圖片不斷往左移,最終會露出破綻(圖片起始位置+圖片長度 落在視窗中,破綻是在視窗中看到圖片結束的斷點)。
因此我們加上當更新完會露出破綻時,讓平移量歸0的邏輯,來達成會不斷不斷重複平移的效果(可以將它想像成,當他抵達終點時,再把他拉回起點開始跑),透過這樣的邏輯去取得我們的 Output ,便可達成任務。


03. 運行程式沒有跳出視窗怎麼辦

Ans: 首先先檢查你是否是運行 main.py 以開啟你的程式。若你遇到的是No file found in working directory的情況,記得下載新版本的config.py取代原本的config.py來快速解決此問題。
若還是無法開啟,可以在 Discord 中詢問,我們會盡快提供協助。


04. 如何在計分板的更新函式中獲得水管數量相關的資訊

Ans: 要如何在函式中獲得外面的資訊,你可以透過參數傳遞的方式來達成。
所以要達成這個目的,你需要改

  1. scoreboard的update方法,讓他可以接受一個水管數量的參數
  2. 找到同時控制pipe和scoreboard的地方,就是game這個管理所有實體的物件啦。找到呼叫pipe.update()的地方,把你需要的水管數量參數傳遞進去。
  3. 至於水管數量在哪裡,你就需要看pipe中有沒有相關的屬性供你使用。