# 2022 資訊之芽 Python 語法班一階段大作業 - Space Invaders ###### tags: `資芽` ## Deadline: 5/1 (日) ## Announcement :::info 日期: 2022/4/17 Controller.py 的 `enemy_shoot()` 的 TODO 註解中,「可以呼叫 `enemy.shoot(bullet)`」應改為 「可以呼叫 `enemy.shoot(bullets)`」 已經更新新的作業程式,造成不便敬請見諒 ::: ## Links [作業程式連結](https://drive.google.com/file/d/1yNFVaFxbQ97UpjR9oTiUteBHgnnySqBB/view?usp=sharing) [作業提交表單](https://docs.google.com/forms/d/e/1FAIpQLSd35a-920GLDiUGDlOFVrXbTIrfqgdxOxuCkhqIkpOYgB2wYw/viewform) [投影片連結](https://drive.google.com/file/d/1J8KI4fmsCU9eFoo2D46BWxF3Bqfi-jV3/view?usp=sharing) ## 事前準備 ### 安裝 python3 相信大家都安裝好了 如果有必要,可以再到[課程網站](https://tw-csie-sprout.github.io/py2022/#!slides.md)去看教學 ### 安裝 [pygame](https://www.pygame.org/) #### Windows 按下 Win+R,輸入 `cmd` 開啟命令提示字元 ![](https://i.imgur.com/A5AnXSB.png =300x150) 輸入以下指令安裝 pygame 的遊戲套件 ```bash python -m pip install pygame --user ``` #### MacOS/Linux 打開 terminal,輸入以下指令 ```bash python3 -m pip install pygame --user ``` ### 下載作業 ! 到 [#Links](#Links) 找到 「作業程式連結」並下載 然後解壓縮,裡面應該會有這些檔案: ![](https://i.imgur.com/FCMj1j2.png) ### 執行他 打開 `cmd` 或 terminal,使用以下指令 ```bash cd <程式所在資料夾> python game.py ``` 這時候你會看到以下畫面 ![](https://i.imgur.com/RvQA7Ag.png =450x485) 而且應該會發現沒辦法玩 QQ ~~因為寫遊戲的工程師寫到一半就跑路了 所以現在需要你來完成這個遊戲~~ ## 作業說明 透過左右方向鍵控制玩家船艦,可以透過空白鍵發射,遊戲開始後發射的第 n 發子彈需要按 n 下才會發射 每少一隻敵人,他們移動的時間間隔就會縮短 每次打完一波,敵人會全部重生,但每次移動的時間間隔會回到原本的長度 如果玩家沒命了,或是敵人碰到最底,遊戲就結束了 --- 一共有四個 .py 檔案 主要 game loop 在 `game.py` 中、`Config.py` 中定義了許多常數,另外 `GameObject.py` 放的是遊戲物件、`Controller.py` 處理了許多遊戲功能 你們主要得完成的部分都在 `Controller.py` 標示 `HOMEWORK` 的那段,其他的部分不太需要去動,但建議有空可以看一看了解整個架構 pygame 的詳細使用方式會在第二階段的時候教 `Config.py` 定義了許多常數,請多多使用他們 提交作業的時候請**只把 `Controller.py` 上傳**上來 ## Tasks 底下依照類別或功能做了分類,沒有說一定要按照這個順序 括號中的是跟該功能相關的 function 名稱 另外,每個你要完成的 function 中都有註解告訴你細節 ### 移動 - [ ] (10 pts) 玩家移動 (`player_move`) (class practice) - [ ] (10 pts) 敵人移動 (`get_enemy_movement`) - [ ] (5 pts) 移動不能超出邊界 (`in_border_check`) (class practice) ### 子彈 - [ ] (10 pts) 玩家發射 (`handle_player_shoot`) - 第 n 次發射,需要按 n 下空白鍵 - [ ] (10 pts) 敵人發射 (`enemy_shoot`) - 隨機挑一個敵人進行發射 ### 碰撞 - [ ] (5 pts) 偵測兩物件碰撞 (`check_collision`) #### 玩家子彈 - [ ] (5 pts) 射中敵人後加分 (`detect_bullet_collision`) - [ ] (5 pts) 射中敵人後敵人會消失 (`detect_bullet_collision`) - [ ] (5 pts) 只能射中一個敵人 (`detect_bullet_collision`) #### 敵人子彈 - [ ] (10 pts) 射中玩家後將子彈刪除,減少玩家一條命 (玩家不會消失)(`detect_bullet_collision`) - [ ] (10 pts) 不會導致敵人消失 (不會內戰) (`detect_bullet_collision`) ### 遊戲機制 - [ ] (5 pts) 敵人剩餘數量越少,動作間隔時間越短 (死光後重設) (`set_enemy_movement_timer`) - 依據剩餘敵人數量,計算敵人移動時間間隔 - 以線性的方式調整,最大為 `ENEMY_MOVE_TIME_MAX`;最小為 `ENEMY_MOVE_TIME_MIN`,取整數 - [ ] (10 pts) 若生命歸零或敵人觸底,遊戲結束 (`game_over`) ### 挑戰 (加分) - [ ] (10 pts) 子彈不是由從敵人中隨機挑一個發射,而是從每一直行離使用者最近的敵人中隨機挑一個發射 ## 可能用得到的小撇步 1. 題目中要實作的東西有用 `TODO` 來標示,雖然原本就有上色,但是安裝 [Todo Tree](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree) 之類的 extension 可以讓你更方便找 - 使用前 ![](https://i.imgur.com/70CKuNq.png) - 使用後 ![](https://i.imgur.com/9U5pCAh.png) 另外他還會整理所有的 `TODO` 出來,就像這樣: ![](https://i.imgur.com/VQtsgWD.png) 你可以做完一個就把註解刪掉,方便你追蹤進度 ## 參考資料 - https://www.spaceinvadersflash.com/ - https://www.youtube.com/watch?v=MU4psw3ccUI ## FAQ 1. `w_space_count` 跟 `shoot_thres` 是什麼? `w_space_count` 紀錄了此發子彈已經按了幾下空白鍵 `shoot_thres` 則代表此發子彈需按多少下空白鍵後才能發射 2. `set_enemy_movement_timer` 中的「線性調整」是甚麼意思? ![](https://i.imgur.com/8lApCYQ.png) 可參考此圖,橫軸是敵人數目,縱軸是應該設定的敵人移動時間間隔