德瑞克的筆記園區
  • NEW!
    NEW!  Connect Ideas Across Notes
    Save time and share insights. With Paragraph Citation, you can quote others’ work with source info built in. If someone cites your note, you’ll see a card showing where it’s used—bringing notes closer together.
    Got it
      • Create new note
      • Create a note from template
        • Sharing URL Link copied
        • /edit
        • View mode
          • Edit mode
          • View mode
          • Book mode
          • Slide mode
          Edit mode View mode Book mode Slide mode
        • Customize slides
        • Note Permission
        • Read
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Write
          • Only me
          • Signed-in users
          • Everyone
          Only me Signed-in users Everyone
        • Engagement control Commenting, Suggest edit, Emoji Reply
      • Invite by email
        Invitee

        This note has no invitees

      • Publish Note

        Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

        Your note will be visible on your profile and discoverable by anyone.
        Your note is now live.
        This note is visible on your profile and discoverable online.
        Everyone on the web can find and read all notes of this public team.

        Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

        Explore these features while you wait
        Complete general settings
        Bookmark and like published notes
        Write a few more notes
        Complete general settings
        Write a few more notes
        See published notes
        Unpublish note
        Please check the box to agree to the Community Guidelines.
        View profile
      • Commenting
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
        • Everyone
      • Suggest edit
        Permission
        Disabled Forbidden Owners Signed-in users Everyone
      • Enable
      • Permission
        • Forbidden
        • Owners
        • Signed-in users
      • Emoji Reply
      • Enable
      • Versions and GitHub Sync
      • Note settings
      • Note Insights New
      • Engagement control
      • Make a copy
      • Transfer ownership
      • Delete this note
      • Save as template
      • Insert from template
      • Import from
        • Dropbox
        • Google Drive
        • Gist
        • Clipboard
      • Export to
        • Dropbox
        • Google Drive
        • Gist
      • Download
        • Markdown
        • HTML
        • Raw HTML
    Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Create Help
    Create Create new note Create a note from template
    Menu
    Options
    Engagement control Make a copy Transfer ownership Delete this note
    Import from
    Dropbox Google Drive Gist Clipboard
    Export to
    Dropbox Google Drive Gist
    Download
    Markdown HTML Raw HTML
    Back
    Sharing URL Link copied
    /edit
    View mode
    • Edit mode
    • View mode
    • Book mode
    • Slide mode
    Edit mode View mode Book mode Slide mode
    Customize slides
    Note Permission
    Read
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Write
    Only me
    • Only me
    • Signed-in users
    • Everyone
    Only me Signed-in users Everyone
    Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note No publishing access yet

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.

    Your account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Your team account was recently created. Publishing will be available soon, allowing you to share notes on your public page and in search results.

    Explore these features while you wait
    Complete general settings
    Bookmark and like published notes
    Write a few more notes
    Complete general settings
    Write a few more notes
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    7
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    # Pygame 遊戲實作 ## Pygame 基礎 ### 淺談遊戲 根據維基百科 : 「遊戲既可以指人的一種娛樂活動,也可以指這種活動過程。」 因此要滿足「遊戲」的條件,勢必是「娛樂性佳」的,否則只是操作介面和動畫。 本次課程中,無法讓各位做出非常大型的遊戲 ( 譬如X紀帝國、X世神、Cyberxxxk等 ) 但是有了基本的概念,剩下的就僅是想法、美術、和利用各種工具滿足需求了。 ### 安裝Pygame 真的很簡單,只需要在終端機上面輸入 : pip install pygame ![](https://i.imgur.com/OR5xnK6.png) ### 第一支程式 ```python= import pygame, sys from pygame.locals import * # main pygame.init() # 設定視窗大小,可以改變參數設定成喜歡的大小。 DISPLAY = pygame.display.set_mode((800,600)) # 設定標題 pygame.display.set_caption("HELLO") # 這邊會顯示黑色,可以透過修改參數的方式改成自己喜歡的顏色。 DISPLAY.fill((0,0,0)) # 無窮迴圈 while True: # 取得所有的Event for event in pygame.event.get(): # 如果event是QUIT,也就是按右上角的x if event.type == pygame.QUIT: # 將pygame殺掉 pygame.quit() # 終止程式 sys.exit() # 一直更新pygame的畫面 pygame.display.update() ``` <br> ![](https://i.imgur.com/vPNquVt.png) 好的,恭喜你寫了第一個「遊戲」,~~是不是覺得很快樂呢?~~ 看到這邊的你們肯定想燒了這份講義,但是不要緊張,一定會教你們怎麼寫能玩的遊戲。 ### GUI vs CLI :::success 在上午的課中,我們介紹了print()函數並在終端機上面看結果,那就是CLI 而真正的遊戲因為有各種圖片及操作,因此可以算是一種GUI ::: | 比較 | GUI| CLI | | -------- | -------- | -------- | | 中文名稱 | 圖形化介面 | 命令列介面 | | 定義 | 使用各種圖形建立的介面 | 純文字介面 | | 操作方式 | 點擊、鍵盤 | 只能使用鍵盤 | | 視覺體驗 | 較豐富且生動 | 只有文字,偏無聊 | | 對使用者來說 | 較友善且容易操作 | 較不友善且不易操作 | | 開發難度 | __很難__ | __很難__ | | 開發時間 | __很長__ | __很長__ | ### Game Loop ![](https://i.imgur.com/YkBh9ZS.png) 大部分的遊戲都是照著上面的 Game Loop 運作。 ### 座標 :::success 數學的原點是在中心點。往右x增加,往上y增加。 但是在程式裡面 原點是在「左上角」,且往下y增加。 ::: ![](https://i.imgur.com/zR5taRf.gif =100%x) ### 顏色 :::success 遊戲怎麼可能少了顏色呢? 有了好的顏色,可以讓遊戲變得更好看、更熱賣。 ::: 在程式設計裡面,顏色是由三原色 ( RGB ) 組成。 常用的顏色 | 顏色 | RGB | -------- | -------- | 水藍色 | ( 0, 255, 255 ) | 黑色 | ( 0, 0, 0 ) | 藍色 | ( 0, 0, 255 ) | 紫紅色 | ( 255, 0, 255 ) | 灰色 | ( 128, 128, 128 ) | 紅色 | ( 128, 128, 128 ) | 綠色 | ( 0, 128, 0 ) | 黃色 | ( 255, 255, 0 ) | 白色 | ( 255, 255, 255 ) 當然還有更多顏色等著大家去探索。連結 : https://www.peko-step.com/zhtw/tool/tfcolor.html 。 ### 事件 (pygame.event) :::success 在 Pygame 中,每個事件都是存在 pygame.event 裡面。在前面的程式中,我們看到了 for event in pygame.event.get(),這是用來將Pygame裡的每個事件取出來。 ::: 以下是常用的 event 種類 #### 退出 pygame.QUIT : 若使用者按下了右上角的叉叉 #### 滑鼠 pygame.MOUSEBUTTONDOWN : 按下滑鼠按鍵 pygame.MOUSEMOTION : 移動滑鼠 pygame.mouse.get_pos() : 抓取滑鼠的位置 #### 鍵盤 pygame.KEYDOWN : 按下鍵盤按鍵 如果有偵測到 pygame.KEYDOWN 就可以進一步偵測是哪個按鍵 以下是 pygame 常用的按鍵 pygame.K_UP : 上 pygame.K_DOWN : 下 pygame.K_w : W 鍵 依此類推 ### 基本圖形 :::success 好的遊戲怎麼能缺少圖案呢? 有了圖案,可以增加視覺體驗。 ::: Pygame本身提供了很多圖形,像是多邊形、方型、線段、圓形、橢圓、曲線等 #### 線段 pygame.draw.line( surface, color, ( x1, y1 ), ( x2, y2 ), width = 0 ) surface : 想畫在哪個平面 color : 顏色 x1 跟 y1 : 起始位置的 x 和 y 座標 x2 跟 y2 : 終點位置的 x 和 y 座標 width : 粗度 :::info 補充 : 一次畫出多個連續線段。 pygame.draw.lines( surface, color, closed, points, width ) closed : 是否為封閉圖形 True的話,基本上就跟下面的polygon差不多,只是差在無法做出實心的多邊形。 False的話 就是一組線段,最後一個點並不會連到第一個點。 ::: #### 多邊形 pygame.draw.polygon( surface, color, points, width=0 ) points : 點座標集合,點越多就可以畫出越多邊 像是 [ ( 146, 0 ), ( 291, 106 ), ( 236, 277 ), ( 56, 277 ), ( 0, 106 ) ] 就可以畫出一個五邊形。 width : ( 可以不用加,預設是0 ) 增加多邊形的粗度。 width > 0 : 空心的多邊形,線段會因為 width 增加而加粗。 width = 0 : 填滿的多邊形。 width < 0 : 什麼都沒有,什麼都看不到。 #### 方形 pygame.draw.rect(surface, color, rect) rect : Rect物件,可以直接寫( x, y, width, height ) x : 方形左上角的x座標 y : 方形左上角的y座標 width : 方形的長 height : 方形的寬 #### 圓形 pygame.draw.circle( surface, color, center_point, radius, width ) center_point : 中心點 radius : 半徑 width : 請參考多邊形的width __以上只是舉例幾種,當然還有更多種好玩的圖形等著大家去發掘 ( Google )__ :::info 在實際撰寫遊戲時,當然不可能一個圖形接著一個這樣子慢慢畫,肯定是借助各種圖案以及模型做出複雜的圖形,接下來將會講到圖片。 ::: 開始練習畫圖吧! ```python= import pygame, sys from pygame.locals import * pygame.init() # 設定螢幕大小 DISPLAYSURF = pygame.display.set_mode((500, 400), 0, 32) pygame.display.set_caption('Drawing') # 設定顏色 BLACK = ( 0, 0, 0) WHITE = (255, 255, 255) RED = (255, 0, 0) GREEN = ( 0, 255, 0) BLUE = ( 0, 0, 255) ''' 判斷是否在多邊形內部 原理 : 利用射線法就可以判斷一個點是否在多邊形內部 如果焦點個數為奇數就是在多邊形內 反之則在外面 參考 : https://blog.csdn.net/leviopku/article/details/111224539 ''' def isInPolygon(p,poly): # 先取得輸入進來的點 放進去px, py裡面 px,py = p # 先假設 flag 為 False 也就代表在外面 flag = False # 用 i 來當作記錄在該陣列的第幾個位置 # corner來當作數值 for i, corner in enumerate(poly): j = i + 1 # 下一個點 if(j>=len(poly)) : j = 0 # 先取兩個相鄰的點 x1, y1 = corner x2, y2 = poly[j] #如果在點上 就直接寫True if(x1 == px and y1 == py) or (x2 == px and y2 == py): flag = True break # 如果該點在兩端點的y之間 if(min(y1,y2)<py<=max(y1,y2)): # 計算 X # X 為 x1去加上 (py - y1) 乘以斜率分之一 x = x1 + (py-y1) * (x2-x1)/(y2-y1) # 如果x在點上 就代表在內部 if(x==px): flag = True break # 有焦點 讓 flag 變成 flag的相反 elif x > px: flag = not flag return flag # 判斷是否在方形區塊內 def isInRect(p,rect): x1, y1 = p x2, y2, len, width = rect if(x1<x2 or x1 > x2+len) : return False elif (y1<y2 or y1>y2+width) : return False else: return True # 定義座標位置 POLYGON = ((146, 0), (291, 106), (236, 277), (56, 277), (0, 106)) RECT = (200, 150, 100, 50) # 一開始設定為 True 代表每個都會顯示 DISPLAY = [True,True,True,True,True,True,True] # 開始繪圖吧 def draw(): DISPLAYSURF.fill(WHITE) if (DISPLAY[0]) : pygame.draw.polygon(DISPLAYSURF, GREEN, POLYGON) if (DISPLAY[1]) : pygame.draw.line(DISPLAYSURF, BLUE, (60, 60), (120, 60), 4) if (DISPLAY[2]) : pygame.draw.line(DISPLAYSURF, BLUE, (120, 60), (60, 120)) if (DISPLAY[3]) : pygame.draw.line(DISPLAYSURF, BLUE, (60, 120), (120, 120), 4) if (DISPLAY[4]) : pygame.draw.circle(DISPLAYSURF, BLUE, (300, 50), 20, 0) if (DISPLAY[5]) : pygame.draw.ellipse(DISPLAYSURF, RED, (300, 250, 40, 80), 1) if (DISPLAY[6]) : pygame.draw.rect(DISPLAYSURF, RED, RECT) # 點擊 被點到就設定為False def click(): global DISPLAY x,y = pygame.mouse.get_pos() if isInPolygon((x,y),POLYGON) : DISPLAY[0] = False if isInRect((x,y),(300,50,20,20)): DISPLAY[4] = False if isInRect((x,y),(300, 250, 40, 80)) : DISPLAY[5] = False if isInRect((x,y),RECT): DISPLAY[6] = False def show(): global DISPLAY DISPLAY = [True,True,True,True,True,True,True] # 執行 Game loop while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() if event.type == MOUSEBUTTONDOWN: click() if event.type == pygame.KEYDOWN: show() # 每次進來都要再重畫一遍 才能看得出特色 draw() pygame.display.update() ``` ![](https://i.imgur.com/TZdkTHW.png) ### 匯入圖片&簡單的動畫 為何遊戲這麼吸引人,當然是因為可以隨著使用者的想法操作動畫,比起傳統的動畫有了更多互動性。 :::success 我們所看到的動畫,在電腦裡面其實只是一張一張圖片隨著時間慢慢地改變位置。 用專業術語講的話,就是禎數,禎數越多代表每秒顯示的圖片數越多。 ::: 若要執行以下程式,請先去 http://invpy.com/cat.png 下載貓的圖案,並且跟程式放在同一個資料夾。 ```python= import pygame, sys from pygame.locals import * # 初始化 pygame.init() FPS = 60 # 設定每秒幾禎 fpsClock = pygame.time.Clock() # Clock # 設定視窗 DISPLAYSURF = pygame.display.set_mode((400,300), 0, 32) pygame.display.set_caption('Cat Animation') # 設定一些基本的數值 WHITE = (255, 255, 255) catImg = pygame.image.load('cat.png') # 設定貓的x y 軸 catx = 10 caty = 10 direction = 'right' # 一開始的方向 while True: # the main game loop DISPLAYSURF.fill(WHITE) if direction == 'right': # 往右跑 catx = catx + 5 if catx > DISPLAYSURF.get_width()-catImg.get_width(): # 如果跑到邊界 就讓貓往下跑 direction = 'down' elif direction == 'down': # 往下跑 caty = caty + 5 if caty > DISPLAYSURF.get_height()-catImg.get_height(): # 如果讓貓跑到邊界 就讓貓往左跑 direction = 'left' elif direction == 'left': # 往左跑 catx = catx - 5 if catx < 10: direction = 'up' elif direction == 'up': # 往上跑 caty = caty - 5 if caty < 10: direction = 'right' DISPLAYSURF.blit(catImg, (catx, caty)) #繪製覆蓋整個視窗 # 偵測事件 for event in pygame.event.get(): # 按叉叉就退出 if event.type == QUIT: pygame.quit() sys.exit() #記得更新畫面 pygame.display.update() #並且讓clock tick 一下 fpsClock.tick(FPS) ``` ![](https://i.imgur.com/gyKHN4q.png) :::info 這個程式有個好玩的地方 : 當你把FPS調得越高,貓移動的速度越快。 ::: :::danger 若把fpsClock.tick(FPS)註解掉,程式就不會暫停,貓移動的速度會根據每台電腦的性能而增加 ( 像我的電腦配備R7+3080,跑特別快 ) ::: #### 匯入圖片: catImg = pygame.image.load('cat.png') 其中catImg是個surface,透過 load 讀 cat.png DISPLAYSURF.blit(catImg,(catx,caty)) catImg就是上面讀的那張圖片 catx跟caty就是圖片呈現的位置(左上角) :::success 若想要免費的素材庫 可以在 https://craftpix.net/ 中尋找,或者是在Google上搜尋 Game Sprite 即可。 ::: ### 文字 :::success 怎麼樣顯示出還有多少時間以及得了多少分? 最直覺的就是用文字表達了。 ::: 如果你們很認真看講義的話,搞不好你們會想做一件事 : 嘗試用draw.line()畫出文字,__但這麼做只會把你們逼瘋。__ 下面是一個能夠輸出Hello World的一個程式 ```python= import pygame, sys from pygame.locals import * pygame.init() DISPLAYSURF = pygame.display.set_mode((400, 300)) pygame.display.set_caption('Hello World!') WHITE = (255, 255, 255) GREEN = (0, 255, 0) BLACK = (0,0,0) fontObj = pygame.font.Font('freesansbold.ttf', 32) #創字體的物件 textSurfaceObj = fontObj.render('Hello world!', True, GREEN,BLACK) #創文字Surface textRectObj = textSurfaceObj.get_rect() #文字方塊 textRectObj.center = (200, 150) while True: # main game loop DISPLAYSURF.fill(WHITE) DISPLAYSURF.blit(textSurfaceObj, textRectObj) for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() pygame.display.update() ``` 要創文字,需要以下六步驟 1. 創 pygame.font.Font 物件 ( 13行 ) 2. 使用 fontObj.render() 創 Surface ( 14行 ) 3. 使用 get_rect() 方法 創 Rect物件 ( 15行 ) 4. 設定center的位置( 16行 ) 5. 使用blit畫出字體 6. 使用 pygame.display.update() 顯示在螢幕上 這樣完美的字體就能呈現了 :::info 很多人會感到疑惑,為何第14行的第二個參數要設成True? 因為當設成True時,pygame會幫我們做出反鋸齒 ( Anti-Aliasing ) ,也就能讓字體變的更柔順,更好看。 當然,如果你要做出那種像素感很重的復古遊戲,可以設定成False。 ::: ### 音樂、音效 :::success 好的音樂和音效能夠增加遊戲體驗,及讓遊戲變的更有趣。 ::: ```python= soundObj = pygame.mixer.Sound('fileName.mp3') soundObj.play() # 當不要播時 : soundObj.stop() ``` 是不是覺得比匯入圖片更簡單了呢? 如果有空的時候,可以多玩玩上述的這些功能。 ### 打包遊戲 :::success 為何要學會打包遊戲 ? 直接給使用者原始碼叫他自己編譯不就好了 ? 事實上大錯特錯。回想一下,在安裝這麼多遊戲中,哪次看到原始碼了。通常為了使用者方便以及保護好程式碼,通常是不會讓使用者直接看到程式在寫什麼。所以打包是一件非常重要的事情。 ::: 首先先在terminal輸入pip install auto-py-to-exe ![](https://i.imgur.com/WRzNySn.png) 然後再輸入auto-py-to-exe ![](https://i.imgur.com/gTEivgy.png) :::info Script Location是放遊戲的main One Directory / One File 是打包成一個資料夾或者是一個exe檔 Console Window是指要不要顯示CLI ( 如果你們覺得很醜的話就勾Window Based ) ::: 完成 : ![](https://i.imgur.com/RJaz6ST.png) 糟糕 怎麼出錯了XD :::danger 注意 ! 打包完成後如果直接打開,會出現錯誤,因為打包的檔案並不包含上面引入的圖片或者是音樂。 若要正常執行,請將輸出的檔案放回去原本的資料夾。 ::: 這樣才是正常的 : ![](https://i.imgur.com/5fjgze4.png) ### 總結 上述的這些功能只佔遊戲設計中的小小一環,要做出功能完整的遊戲需要學習的知識點遠遠不止這些。但當你們掌握今天上午的課程以及上述的這些指令後,就能做出小遊戲了。 今天學習到的概念只是製作遊戲的基礎,如果對於大型遊戲設計感到興趣的話,除了掌握今天所學外,還可以去接觸 Unity 或是 JavaScript,僅僅學習今天的東西還是不夠的XD。 ## 正式的遊戲設計 ### 打地鼠 ![](https://i.imgur.com/9juJztP.png) (不用你們說,我知道很醜) 資源包 : https://drive.google.com/drive/folders/1DNa6-j81sERV2FgpYOsZsCtFIO49jWmW?usp=sharing ```python= import pygame import time from random import randint #視窗大小 SCREEN_WIDTH = 400 SCREEN_HEIGHT = 400 #常用顏色 GREEN = (73,188,11) WHITE = (255,255,255) #地鼠座標 / 分數 /遊戲時間 / 開始時間 / 狀態 x,y = None,None score = 0 game_time = 20 start_time = 0 state = 0 #首頁0 遊戲中1 結束2 #建立視窗及頻率鐘 screen = pygame.display.set_mode((SCREEN_WIDTH,SCREEN_HEIGHT)) pygame.display.set_caption('打地鼠') clock = pygame.time.Clock() #載入遊戲圖片 mallet = pygame.image.load('mallet.png') down_mallet = pygame.image.load('down-mallet.png') mole = pygame.image.load('mole.png') grass = pygame.image.load('grass.png') #隱藏滑鼠座標顯示及初始化文字模組 pygame.mouse.set_visible(False) pygame.font.init() # FPS FPS = 60 # 歡迎畫面 def welcome_screen(): # 全部填滿草 screen.blit(grass,(0,0)) # 字體設定 font = pygame.font.SysFont('corbel',48) # 文字設定 text = font.render('Press ENTER to start',False,WHITE) # 畫出文字部分 screen.blit(text,((SCREEN_WIDTH - text.get_width()) / 2, 185 ) ) #畫出一個地鼠 screen.blit(mole,(120,50)) # 取得槌子的矩形範圍 mallet_position = mallet.get_rect() # 將槌子的中心點設在滑鼠點的位置 mallet_position.center = pygame.mouse.get_pos() if pygame.mouse.get_pressed()[0]: screen.blit(down_mallet, mallet_position) else: screen.blit(mallet, mallet_position) def play(): # 取用遊戲狀態、分數及開始時間資訊 global state, score, start_time # 設定遊戲開始時間 time.time() 會取得目前的時間 start_time = time.time() # 將分數歸 0 且狀態設定為 1 遊玩中 score = 0 state = 1 # 產生新的老鼠(這邊先立一個函式之後完成) new_mole() # 產生瞬間先檢查是否有被打到(這邊先立一個函式之後完成) whack() def end(): # 狀態改為 2 結束遊戲 global state state = 2 def new_mole(): # 隨機決定下一個老鼠產生的位置 global x, y # x 從螢幕最左到右邊扣掉老鼠的寬都能取, y 則向下移 30 到底部扣掉老鼠的高都能取 x = randint(0, SCREEN_WIDTH - mole.get_width()) y = randint(30, SCREEN_HEIGHT - mole.get_height()) # 判斷是否在方形區塊內 def isInRect(p,rect): # 先取得點座標 x1, y1 = p # 再取得方形座標 x2, y2, len, width = rect # 如果不在區域內 就 return false if(x1<x2 or x1 > x2+len) : return False elif (y1<y2 or y1>y2+width) : return False # else return true else: return True def whack(): global score # 取得滑鼠當前的位置 mx, my = pygame.mouse.get_pos() # 取得老鼠的寬及高 width, height = mole.get_size() # 將座標計算是不是點擊在老鼠的圖片上, 如果有的話要加分和產生下一隻新的 if isInRect((mx,my),(x,y,width,height)): score += 1 new_mole() # 遊戲畫面 def play_screen(): # 畫出草 screen.blit(grass,(0,0)) # 字體設定 font = pygame.font.SysFont('corbel',30) # 分數的文字 text_score = font.render(str(score),False,WHITE) # 現在的時間 current = game_time - (time.time() - start_time) # 如果時間結束 就跳到 end if current <= 0: end() # 時間的文字 text_time = font.render(str(int(current)),False,WHITE) # 如果按下了滑鼠 if pygame.mouse.get_pressed()[0]: # 就在鼠標位置顯示下降的槌子 screen.blit(down_mallet, pygame.mouse.get_pos()) # 如果不是的話 else: # 就在鼠標的位置顯示一般的槌子 screen.blit(mallet,pygame.mouse.get_pos()) # 顯示分數 screen.blit(text_score,(10,0)) #顯示時間 screen.blit(text_time,(370,0)) # 顯示地鼠 screen.blit(mole,(x,y)) # 結束話面 def end_screen(): # 背景填滿綠色 screen.fill(GREEN) # 設定字體樣板分別顯示遊戲結束、分數及重新開始按鈕 font = pygame.font.Font(None, 30) game_over = font.render("GAME OVER", False, WHITE) font = pygame.font.Font(None, 25) # 分數 points = font.render("Score: " + str(score), False, WHITE) font = pygame.font.Font(None, 22) restart = font.render("Press ENTER to play again", False, WHITE) # 將上述資訊顯示到螢幕上 screen.blit(game_over, (SCREEN_WIDTH / 2 - game_over.get_width() / 2, 100)) screen.blit(points, (SCREEN_WIDTH / 2 - points.get_width() / 2, 200)) screen.blit(restart, (SCREEN_WIDTH / 2 - restart.get_width() / 2, 300)) #遊戲執行 running=True while running: #事件處理 for event in pygame.event.get(): #當遊戲視窗被關閉 if event.type==pygame.QUIT:#當遊戲視窗被關閉 running=False elif state == 0:#遊戲還沒開始的事件 if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN: play() elif state == 1:#遊戲中的事件 # 如果按下滑鼠 就打 if event.type == pygame.MOUSEBUTTONDOWN: whack() elif state == 2:#遊戲結束的事件 if event.type == pygame.KEYDOWN and event.key ==pygame.K_RETURN: play() if state == 0:#還沒開始的畫面 welcome_screen() elif state == 1:#遊戲中的畫面 play_screen() elif state == 2:#遊戲結束的畫面 end_screen() clock.tick(FPS)#限制畫面最高更新 60 FPS pygame.display.update()#更新畫面 pygame.quit() ``` <!-- 將new mole whack play 拔掉 讓他們寫寫看 資源包 : --> 參考資源 : 1. Making Games with Python & Pygame ( https://inventwithpython.com/pygame/ ) 2. Python 功力提升的樂趣

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password
    or
    Sign in via Google Sign in via Facebook Sign in via X(Twitter) Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    By signing in, you agree to our terms of service.

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully