PyGame彈珠遊戲雙人改良版
阿新 • • 發佈:2018-12-19
# _*_ coding:utf-8 _*_ import pygame from pygame.locals import * from sys import exit __author__ = 'admin' ''' 彈珠遊戲設計擴充套件,改良版 ''' pygame.init() # 設定螢幕寬度 SCREEN_SIZE = (320, 400) # 初始化得分 score_playerA = 0 score_playerB = 0 # 顏色 WHITE = (255, 255, 255) BLUE = (0, 255, 255) GREEN = (0, 255, 0) BLACK = (0, 0, 0) RED = (255, 0, 0) # 初始化遊戲狀態:1/遊戲開始介面 2/遊戲進行中 3/遊戲結束 status = 1 # 初始化贏家 winner = '' screen = pygame.display.set_mode(SCREEN_SIZE, 0, 32) class Baffle(): def __init__(self): # 設定上擋板的大小 self.BAFFLE_SIZE_U = (40, 5) # 設定上擋板左上角初始位置 self.BAFFLE_POS_U = ((SCREEN_SIZE[0] / 2 - self.BAFFLE_SIZE_U[0] / 2), 0) # 獲取上擋板左上角座標初始值 self.BAFFLE_POS_U_x, self.BAFFLE_POS_U_y = self.BAFFLE_POS_U # 設定下擋板的大小 self.BAFFLE_SIZE_D = (40, 5) # 設定下擋板左上角初始位置 self.BAFFLE_POS_D = ((SCREEN_SIZE[0] / 2 - self.BAFFLE_SIZE_D[0] / 2), (SCREEN_SIZE[1] - self.BAFFLE_SIZE_D[1])) # 獲取下擋板左上角座標初始值 self.BAFFLE_POS_D_x, self.BAFFLE_POS_D_y = self.BAFFLE_POS_D # 設定擋板移速 self.BAFFLE_SPEED = 5 # 下檔位左移處理 def BAFFLE_D_move_left(self): self.BAFFLE_POS_D_x -= self.BAFFLE_SPEED self.BAFFLE_POS_D_x = max(0, self.BAFFLE_POS_D_x) # 下擋板右移處理 def BAFFLE_D_move_right(self): self.BAFFLE_POS_D_x += self.BAFFLE_SPEED self.BAFFLE_POS_D_x = min(SCREEN_SIZE[0] - self.BAFFLE_SIZE_D[0], self.BAFFLE_POS_D_x) # 上擋板左移處理 def BAFFLE_U_move_left(self): self.BAFFLE_POS_U_x -= self.BAFFLE_SPEED self.BAFFLE_POS_U_x = max(0, self.BAFFLE_POS_U_x) # 上擋板右移處理 def BAFFLE_U_move_right(self): self.BAFFLE_POS_U_x += self.BAFFLE_SPEED self.BAFFLE_POS_U_x = min(SCREEN_SIZE[0] - self.BAFFLE_SIZE_U[0], self.BAFFLE_POS_U_x) # 畫出擋板 def draw(self): # 畫出下擋板 pygame.draw.rect(screen, GREEN, pygame.Rect((self.BAFFLE_POS_D_x, self.BAFFLE_POS_D_y), self.BAFFLE_SIZE_D)) # 畫出上擋板 pygame.draw.rect(screen, BLUE, pygame.Rect((self.BAFFLE_POS_U_x, self.BAFFLE_POS_U_y), self.BAFFLE_SIZE_U)) def reset(self): self.BAFFLE_POS_U = ((SCREEN_SIZE[0] / 2 - self.BAFFLE_SIZE_U[0] / 2), 0) self.BAFFLE_POS_D = ((SCREEN_SIZE[0] / 2 - self.BAFFLE_SIZE_D[0] / 2), (SCREEN_SIZE[1] - self.BAFFLE_SIZE_D[1])) self.draw() baffle = Baffle() class Ball(): def __init__(self): # 設定彈珠的大小 self.BALL_SIZE = (10, 10) # 設定彈珠左上角初始位置 self.BALL_POS = ((SCREEN_SIZE[0] / 2 - self.BALL_SIZE[0] / 2), (SCREEN_SIZE[1] - baffle.BAFFLE_SIZE_D[1] - self.BALL_SIZE[1])) # 獲取彈珠左上角座標初始值 self.BALL_POS_x, self.BALL_POS_y = self.BALL_POS # 設定彈珠彈速 self.BALL_SPEED = 5 # 設定彈珠的座標位移量 self.BALL_x_mobility = -2 self.BALL_y_mobility = -3 def draw(self): # 延遲彈珠重新整理速度 pygame.time.delay(int(100 / self.BALL_SPEED)) # 畫出彈珠 pygame.draw.rect(screen, WHITE, pygame.Rect((self.BALL_POS_x, self.BALL_POS_y), self.BALL_SIZE)) def reset(self): self.BALL_POS = ((SCREEN_SIZE[0] / 2 - self.BALL_SIZE[0] / 2), (SCREEN_SIZE[1] - baffle.BAFFLE_SIZE_D[1] - self.BALL_SIZE[1])) self.draw() # 輸出結果 def CheckResult(self, score_A, score_B): global winner if score_A > score_B: winner = u"PlayerA Win!" print("PlayerA 勝利!") elif score_A == score_B: winner = u"It's a draw!" print("打成平局!") else: winner = u"PlayerB Win!" print("PlayerB 勝利!") def edge_detection(self): global score_playerA, score_playerB, status # 彈珠在螢幕內的左邊緣檢測 if self.BALL_POS_x <= 0: self.BALL_x_mobility = 2 # 彈珠在螢幕內的右邊緣檢測 if self.BALL_POS_x >= SCREEN_SIZE[0]: self.BALL_x_mobility = -2 # 彈珠在螢幕內的上邊緣檢測 # 獲取上擋板底部的縱座標 baffle.BAFFLE_U_bottom_y = baffle.BAFFLE_POS_U_y + baffle.BAFFLE_SIZE_U[1] if 0 <= ball.BALL_POS_y < baffle.BAFFLE_U_bottom_y: # 如果彈珠和座標在擋板長度內 if baffle.BAFFLE_POS_U_x - self.BALL_SIZE[0] <= self.BALL_POS_x <= (baffle.BAFFLE_POS_U_x + baffle.BAFFLE_SIZE_U[0]): self.BALL_y_mobility = 3 score_playerA += 1 print("score_playerA:", score_playerA) # 不符合以上情況,說明這個球你肯定接不住了 else: self.CheckResult(score_playerA, score_playerB) # exit() status = 3 # 彈珠在螢幕內的下邊緣檢測 # 獲取彈珠底部的縱座標 self.BALL_bottom_y = self.BALL_POS_y + self.BALL_SIZE[1] # 如果彈珠底部在擋板內部 if SCREEN_SIZE[1] >= self.BALL_bottom_y > baffle.BAFFLE_POS_D_y: # 如果彈珠和座標在擋板長度內 if baffle.BAFFLE_POS_D_x - self.BALL_SIZE[0] <= self.BALL_POS_x <= (baffle.BAFFLE_POS_D_x + baffle.BAFFLE_SIZE_D[0]): self.BALL_y_mobility = -3 score_playerB += 1 print("score_playerB:", score_playerB) # 不符合以上情況,說明這個球你肯定接不住了 else: self.CheckResult(score_playerA, score_playerB) # exit() status = 3 # 獲取彈珠新的位置 self.BALL_POS_x += ball.BALL_x_mobility self.BALL_POS_y += ball.BALL_y_mobility ball = Ball() def GameBody(): # 退出檢測函式 def checkForOut(): global status, ball, baffle, score_playerA, score_playerB for event in pygame.event.get(): # 點選× if event.type == 12: exit() if event.type == 2: # 按鍵為Esc if event.key == 27: exit() # 按鍵為Space if event.key == 32: # 當前狀態為遊戲開始介面 if status == 1: status = 2 # 當前狀態為遊戲結束介面 elif status == 3: # 初始化玩家分數以及擋板和彈珠的位置 score_playerA, score_playerB = (0, 0) ball = Ball() baffle = Baffle() status = 2 def divide(): font = pygame.font.SysFont("arial", 20) text_sur1 = font.render(u"A", True, BLUE) text_sur2 = font.render(u"B", True, GREEN) pos_A = (SCREEN_SIZE[0] / 2 - text_sur1.get_width() / 2, SCREEN_SIZE[1] / 4) pos_B = (SCREEN_SIZE[0] / 2 - text_sur1.get_width() / 2, SCREEN_SIZE[1] * 3 / 4) # 寫入文字"A"、"B" screen.blit(text_sur1, pos_A) screen.blit(text_sur2, pos_B) # 畫出區域中介線 pygame.draw.line(screen, WHITE, (0, SCREEN_SIZE[1] / 2), (SCREEN_SIZE[0], SCREEN_SIZE[1] / 2)) # 遊戲開始選單的設計 def start_menu(): font = pygame.font.SysFont("arial", 30) text_surWarn = font.render(u"START", True, BLUE) warn_width = text_surWarn.get_width() warn_height = text_surWarn.get_height() pos_warn = (SCREEN_SIZE[0] / 2 - warn_width / 2, SCREEN_SIZE[1] / 2 - warn_height / 2) screen.blit(text_surWarn, pos_warn) # 遊戲結束選單的設計 def end_menu(): font_winner = pygame.font.SysFont("arial", 30) font_warn = pygame.font.SysFont("arial", 30, 5) text_surWinner = font_winner.render(winner, True, RED) text_surWarn = font_warn.render(u"RESTART", True, RED) winner_width = text_surWinner.get_width() winner_height = text_surWinner.get_height() warn_width = text_surWarn.get_width() warn_height = text_surWarn.get_height() rect_width = max(winner_width, warn_width) rect_height = winner_height + warn_height rect_y = SCREEN_SIZE[1] / 2 - rect_height / 2 rect_x = SCREEN_SIZE[0] / 2 - rect_width / 2 pygame.draw.rect(screen, GREEN, pygame.Rect((rect_x, rect_y), (rect_width, rect_height))) # 顯示居中處理 winner_x = SCREEN_SIZE[0] / 2 - winner_width / 2 winner_y = rect_y screen.blit(text_surWinner, (winner_x, winner_y)) # 顯示居中處理 pos_warn_x = SCREEN_SIZE[0] / 2 - warn_width / 2 pos_warn_y = rect_y + winner_height screen.blit(text_surWarn, (pos_warn_x, pos_warn_y)) while True: checkForOut() if status == 1: # 彈出遊戲開始介面 start_menu() if status == 2: # 獲取按鍵情況 key_pressed = pygame.key.get_pressed() # 如果按下LEFT鍵,執行擋板左移 if key_pressed[276]: baffle.BAFFLE_D_move_left() # 如果按下RIGHT鍵,執行擋板右移 elif key_pressed[275]: baffle.BAFFLE_D_move_right() # 如果按下a鍵,執行擋板左移 elif key_pressed[97]: baffle.BAFFLE_U_move_left() # 如果按下d鍵,執行擋板右移 elif key_pressed[100]: baffle.BAFFLE_U_move_right() # 彈珠的邊緣檢測 ball.edge_detection() # 填充螢幕顏色,相當於重新整理介面 screen.fill((0, 0, 0)) # 劃分雙方區域 divide() # 畫出擋板 baffle.draw() # 畫出彈珠 ball.draw() if status == 3: # 彈出遊戲結束介面選單 end_menu() pygame.display.flip() GameBody()