--- tags: 開源社 title: pygame - 打磚塊(一) --- # Pygame 教學 (一) 共筆:https://hackmd.io/LuheTD_SQwWYa2wMwiv65g [匿名提問](https://app.sli.do/event/18mhx5qs) [前情提要](https://hackmd.io/@andy010629/r103KC6Iv) # 我們今天要來做打磚塊! >在這之前 我們來把遊戲的流程釐清一下 ## 我們會用到的物件 - ### 磚塊 生成 / 消失 / 反彈 - ### 球 反彈 (物理碰撞) - ### 反彈球ㄉ板子 反彈 (物理碰撞) ## 遊戲的基本流程 ![](https://i.imgur.com/AAmrUcD.png) ### CODING 邏輯 - [ ] pygame 初始化 - [ ] 把物件做出來 -- init -- - [ ] 球的生成 -- 位置 及 速度 - [ ] 反射板的生成 -- 位置 - [ ] 遊戲初始化 ( ) -- 將該歸位的的東西歸位 參數重設 -- loop start -- - [ ] 判斷遊戲狀態(按下右鍵開始) ( ) -- bool 開始參數 - [ ] 球給我動起來 - 球的碰撞>變更移動方向 -------------------------------------------------- ## 第一步 - Pygame 及 遊戲參數的初始化 ``` python= import sys import pygame from pygame.locals import QUIT SCREEN_SIZEX = 800 SCREEN_SIZEY = 600 SCREEN_COLOR = (0,0,0) clock = pygame.time.Clock() pygame.init() window_surface = pygame.display.set_mode((SCREEN_SIZEX,SCREEN_SIZEY)) window_surface.fill(SCREEN_COLOR) pygame.display.update() # 鼠標 鎖定 和 隱藏 pygame.event.set_grab(True) pygame.mouse.set_visible(False) while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pygame.quit() sys.exit() window_surface.fill(SCREEN_COLOR) pygame.display.update() #設定畫面貞數 clock.tick(60) ``` ## 第二步 物件的製作 > 我們的目標是 把物件包好 然後我們只要 call 他就可以生成了 > 今天的進度 我們會需要用到 "球" 和 "發射板" 這兩個物件 Object.py-- ```python= import pygame # 球 class Ball(object): def __init__(self,canvas,pos, radius): #一個pygame物件 self.pygame = pygame #畫布(物件繪製在哪邊) self.canvas = canvas #設置圓心位置 self.pos = pos #球的半徑 self.radius = radius #球的顏色 self.color = (100,200,200) #實/空 心 self.visible = True self.rect = self.pygame.draw.circle(self.canvas, self.color, self.pos, self.radius) def update(self): if(self.visible): self.rect = self.pygame.draw.circle(self.canvas, self.color, self.pos, self.radius) # 發射板 class Paddle(object): def __init__(self,canvas, rect): self.pygame = pygame self.canvas = canvas self.rect = rect self.color = (255, 255, 255) self.visible = True def update(self): if(self.visible): self.pygame.draw.rect(self.canvas, self.color, self.rect) ``` 寫完之後 我們把它匯入主程式吧! 我們只要在主程式前面加上 `` from Object import * `` 就可以把他們匯進去了 然後我們就可以在主程式裡面呼叫他們測試看看 - 像這樣 ```python= # Paddle(要繪製的圖層,[繪製位置,長跟寬]) paddle = Paddle(window_surface, [SCREEN_SIZEX/2 - 50, SCREEN_SIZEY - 48, 100, 24]) # Ball(要繪製的圖層,[繪製位置],半徑) ball = Ball(window_surface, [int(paddle.rect[0] + ((paddle.rect[2] - 10)//2)), paddle.rect[1] - 10], 10) ``` 然後記得在 while 裡面更新 讓他一直繪圖 ```python= paddle.update() ball.update() ``` ## 第三步 物件的生成和設定 ### 一些常數 ```python= BALL_SPEED = 8 dx = BALL_SPEED dy = -BALL_SPEED ``` ### 生成物件 > 這邊只是生成而已 一樣要記得在 loop 裡面 update 喔! ```python= paddle_x = 0 paddle_y = (SCREEN_SIZEY - 48) paddle = Paddle(window_surface, [paddle_x, paddle_y, 100, 24]) ball_x = paddle_x ball_y = paddle_y ball = Ball(window_surface, [ball_x, ball_y], 8) ``` ### 遊戲重設 ```python= def resetGame(): global game_mode,dx, dy game_mode = 0 dx = BALL_SPEED dy = -BALL_SPEED ``` ## 第四步 - 遊戲狀態設定 及 初始化 > 我們要在loop 一開始的 for event 裡面加上條件 判斷是否按下右鍵 ```python= for event in pygame.event.get(): ...... 以上省略 ..... if event.type == pygame.MOUSEBUTTONDOWN: if(game_mode == 0): game_mode = 1 ``` > 背景塗滿 ```python window_surface.fill(SCREEN_COLOR) ``` > 反射板 歸位 ```python paddle.rect[0] = paddle_x ``` ### 第五步 - 遊戲開始! ```python= if(game_mode == 0): ball.pos[0] = ball_x = paddle.rect[0] + ((paddle.rect[2] - ball.radius)//2) ball.pos[1] = ball_y = paddle.rect[1] - ball.radius else: ball_x += dx ball_y += dy #判斷死亡. if(ball_y + dy > SCREEN_SIZEY - ball.radius): resetGame() # 右牆或左牆碰撞. if(ball_x + dx > SCREEN_SIZEX - ball.radius or ball_x + dx < ball.radius): dx = -dx # 上牆碰撞 if(ball_y + dy < -ball.radius): dy = -dy ball.pos[0] = ball_x ball.pos[1] = ball_y ``` ### 完整程式碼 main.py-- ```python= import sys import pygame from pygame.locals import QUIT from Object import * SCREEN_SIZEX = 800 SCREEN_SIZEY = 600 SCREEN_COLOR = (0,0,0) BALL_SPEED = 8 dx = BALL_SPEED dy = -BALL_SPEED clock = pygame.time.Clock() def Update(): ball.update() paddle.update() pygame.display.update() def isCollision(Rect1, Rect2): if(pygame.Rect.colliderect(Rect1, Rect2)): return True return False def resetGame(): global game_mode, dx, dy game_mode = 0 dx = BALL_SPEED dy = -BALL_SPEED pygame.init() window_surface = pygame.display.set_mode((SCREEN_SIZEX,SCREEN_SIZEY)) window_surface.fill(SCREEN_COLOR) paddle_x = 0 paddle_y = (SCREEN_SIZEY - 48) paddle = Paddle(window_surface, [paddle_x, paddle_y, 100, 24]) ball_x = paddle_x ball_y = paddle_y ball = Ball(window_surface, [ball_x, ball_y], 8) resetGame() pygame.display.update() # 鼠標 鎖定 和 隱藏 pygame.event.set_grab(True) pygame.mouse.set_visible(False) while True: for event in pygame.event.get(): if event.type == QUIT: pygame.quit() sys.exit() elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: pygame.quit() sys.exit() if event.type == pygame.MOUSEMOTION: paddle_x = pygame.mouse.get_pos()[0] - 50= pygame.MO if event.type == pygame.MOUSEMOTION: paddle_x = pygame.mouse.get_pos()[0] - 50 if event.type == pygame.MOUSEBUTTONDOWN: if(game_mode == 0): game_mode = 1 window_surface.fill(SCREEN_COLOR) paddle.rect[0] = paddle_x if(isCollision(ball.rect, paddle.rect)): dy = -dy # 遊戲流程控制 if(game_mode == 0): ball.pos[0] = ball_x = paddle.rect[0] + ((paddle.rect[2] - ball.radius) // 2) ball.pos[1] = ball_y = paddle.rect[1] - ball.radius else: ball_x += dx ball_y += dy #判斷死亡. if(ball_y + dy > SCREEN_SIZEY - ball.radius): game_mode = 0 # 右牆或左牆碰撞. if(ball_x + dx > SCREEN_SIZEX - ball.radius or ball_x + dx < ball.radius): dx = -dx # 上牆碰撞 if(ball_y + dy < -ball.radius): dy = -dy ball.pos[0] = ball_x ball.pos[1] = ball_y Update() clock.tick(60) ``` Object.py-- ```python= import pygame class Ball(object): def __init__(self,canvas,pos, radius): self.pygame = pygame self.canvas = canvas self.pos = pos self.radius = radius self.color = (100,200,200) self.visible = True self.rect = self.pygame.draw.circle(self.canvas, self.color, self.pos, self.radius) def update(self): if(self.visible): self.rect = self.pygame.draw.circle(self.canvas, self.color, self.pos, self.radius) class Paddle(object): def __init__(self,canvas, rect): self.pygame = pygame self.canvas = canvas self.rect = rect self.color = (255, 255, 255) self.visible = True def update(self): if(self.visible): self.pygame.draw.rect(self.canvas, self.color, self.rect) ``` Git && GitHub 教學操作筆記 https://hackmd.io/@andy010629/BJB6pdg5w