python使用PyGame實(shí)現(xiàn)打磚塊游戲
效果
在設(shè)計(jì)游戲之前,先設(shè)置一些常量,供后續(xù)選用。
import pygame import random WIDTH, HEIGHT = 640, 400 # 游戲窗口尺寸 SIZE = 20 # 磚塊尺寸 # 顏色定義 C_PADDLE = (120, 120, 120) C_BRICK = (0, 128, 55) C_BALL = (233,233,233) BLACK = (25, 25, 25) RED = (255, 0, 0)
磚塊實(shí)現(xiàn)
可玩性比較高的打磚塊游戲,其磚塊有著不同的屬性,有一些磚塊打不掉,有些在打碎之后會(huì)掉落一些東西,接住之后可以發(fā)生裂變反應(yīng)??紤]到作為一個(gè)初學(xué)者小游戲,我們先讓所有磚塊有著相同的特質(zhì),但為了日后的擴(kuò)展,所以用類來實(shí)現(xiàn)磚塊。
作為一個(gè)磚塊來說,只有三個(gè)屬性,坐標(biāo)( x , y ) (x,y)(x,y)以及邊長size,又因?yàn)榇u塊不會(huì)動(dòng),所以這些參數(shù)僅作為傳入的參數(shù),而無需調(diào)用。而磚塊唯一的行為,就是與小球發(fā)生碰撞,所以需要有一個(gè)判定方法。最終,磚塊類實(shí)現(xiàn)如下
class Brick: def __init__(self, col, row, dy=50, size=SIZE, color=C_BRICK): x = col*size y = row*size + dy self.color = color self.rect = pygame.Rect(x, y, size, size) def hitRect(self, rect): return self.rect.colliderect(rect) def draw(self, screen): pygame.draw.rect(screen, self.color, self.rect)
在實(shí)際應(yīng)用中,顯然不可能只有一個(gè)磚塊,所以在Brick中設(shè)置一個(gè)靜態(tài)方法,用以生成隨機(jī)的磚塊,其生成邏輯是,隨機(jī)生成一個(gè)數(shù),如果這個(gè)數(shù)大于0.3,那么就在當(dāng)前位置生成一個(gè)磚塊,否則跳過。
@staticmethod def randBricks(dense=0.3, size=SIZE, xEdge=WIDTH): bricks = [] for row in range(5): col = 0 while (col+1)* size < xEdge: bricks.append(Brick(col, row)) col += 1 if random.random()>dense else 2 return bricks
小車
和磚塊相比,小車只多了一個(gè)左右移動(dòng)的功能,即點(diǎn)擊左箭頭,相左移動(dòng),點(diǎn)擊右箭頭,向右移動(dòng)。而且其移動(dòng)的范圍不能超出x軸的邊界,其小車類實(shí)現(xiàn)如下。
class Car: def __init__(self, width, height=10, speed = 10, color=C_PADDLE, xEdge=WIDTH, yEdge=HEIGHT): self.width, self.height = width, height self.xEdge = xEdge self.color = color self.x = (xEdge - width) // 2 self.y = yEdge - 30 self.vx = speed # 只有x方向的速度 def move(self, keys): if keys[pygame.K_LEFT] and self.x > 0: self.x -= self.vx if keys[pygame.K_RIGHT] and self.x < self.xEdge - self.width: self.x += self.vx def draw(self, screen): pygame.draw.rect(screen, self.color, (self.x, self.y, self.width, self.height))
小球
相比于不動(dòng)的磚塊,只需要左右移動(dòng)的小車,小球的行為會(huì)稍微復(fù)雜一點(diǎn),不僅需要考慮和墻壁以及小車的碰撞,也要考慮和磚塊的碰撞。在這個(gè)過程中,需要進(jìn)行諸多邊界的判斷,所以除了小球的半徑和位置之外,設(shè)置L,R,U,D四個(gè)函數(shù),用于計(jì)算其左右上下的邊界位置。小球類實(shí)現(xiàn)如下。
class Ball: # xEdge, yEdge分別是水平核垂直方向的邊緣 def __init__(self, radius, speed=5, xEdge=WIDTH, yEdge=HEIGHT, color=C_BALL): self.r = radius self.xEdge, self.yEdge = xEdge, yEdge self.color = color self.x = random.randint(radius, xEdge - radius) self.y = random.randint(yEdge//3, yEdge // 2) self.vx = self.vy = speed L = lambda self : self.x - self.r R = lambda self : self.x + self.r U = lambda self : self.y + self.r D = lambda self : self.y - self.r xy = lambda self : (self.x, self.y) def move(self): self.x += self.vx self.y += self.vy def rect(self): d = self.r * 2 return pygame.Rect(self.L(), self.D(), d, d) # 撞擊邊緣 def hitEdge(self): if self.L() < 0 or self.R() > self.xEdge: self.vx *= -1 if self.U() < 0: self.vy *= -1 elif self.U() > self.yEdge: return True return False # 撞擊car def hitCar(self, car): if self.y + self.r >= car.y and car.x <= self.x <= car.x + car.width: self.vy *= -1 def hitBricks(self, bricks): for brick in bricks[:]: if brick.hitRect(self.rect()): self.vy *= -1 bricks.remove(brick) return 1 return 0 def draw(self, screen): pygame.draw.circle(screen, self.color, (self.x, self.y), self.r)
其中,hitBricks的返回值為1時(shí),表示擊中了磚塊,否則表示未擊中。
初始化和主循環(huán)
在具體寫主循環(huán)之前,先設(shè)置一個(gè)GameOver的顯示函數(shù),這個(gè)函數(shù)的出鏡率很高,在之前的實(shí)戰(zhàn)中也用到過。
def drawGamerOver(screen, font, width=WIDTH, height=HEIGHT): w, h = font.size('GAME OVER') msg = font.render('GAME OVER', True, RED) screen.blit(msg, ((width - w) // 2, (height - h) // 2 - 40)) w, h = font.size('點(diǎn)擊任意位置,再來一局') msg = font.render('點(diǎn)擊任意位置,再來一局', True, RED) screen.blit(msg, ((width - w) // 2, (height - h) // 2 + 40))
然后是初始化,主要包括小球、小車、磚塊的初始化,以及PyGame的初始化。
def init(): ball = Ball(10) car = Car(100) bricks = Brick.randBricks() return ball, car, bricks # 初始化 Pygame pygame.init() window = pygame.display.set_mode((WIDTH, HEIGHT)) font = pygame.font.Font(r"SimHei.ttf", 30) pygame.display.set_caption("打磚塊") # 初始化彈球、板、磚塊的位置 ball, car, bricks = init() score, running, gameOver = 0, True, False
其running用于調(diào)控主循環(huán),gameOver則表示當(dāng)前游戲失敗,若失敗,則跳入游戲失敗的窗口。最后,主循環(huán)如下
while True: for event in pygame.event.get(): if event.type == pygame.QUIT: pygame.quit() running = False break if gameOver: ball, car, bricks = init() gameOver, score = False, 0 if not running: break if not gameOver: keys = pygame.key.get_pressed() car.move(keys) # 移動(dòng)小車 ball.move() # 移動(dòng)彈球 ball.hitCar(car) if ball.hitEdge(): bricks = Brick.randBricks() # 重新初始化游戲 gameOver = True # 游戲結(jié)束 score += ball.hitBricks(bricks) # 清空窗口 window.fill(BLACK) if not gameOver: car.draw(window) ball.draw(window) for brick in bricks: brick.draw(window) # 顯示分?jǐn)?shù) score_text = font.render(f"Score: {score}", True, C_BRICK) window.blit(score_text, (20, 20)) else: drawGamerOver(window, font) pygame.display.flip() # 更新屏幕顯示 pygame.time.delay(30) # 控制幀率
以上就是python使用PyGame實(shí)現(xiàn)打磚塊游戲的詳細(xì)內(nèi)容,更多關(guān)于python PyGame打磚塊游戲的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
Python使用PyMongo4.x操作MongoDB的教程分享
PyMongo是一個(gè)Python編程語言中用于連接和操作MongoDB數(shù)據(jù)庫的庫,它提供了豐富的功能和API,使開發(fā)者能夠在Python中輕松地進(jìn)行MongoDB的數(shù)據(jù)交互和管理,本文給大家總結(jié)了Python如何使用PyMongo4.x操作MongoDB,需要的朋友可以參考下2023-09-09(手寫)PCA原理及其Python實(shí)現(xiàn)圖文詳解
這篇文章主要介紹了Python來PCA算法,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧,希望能給你帶來幫助2021-08-08python 獲取sqlite3數(shù)據(jù)庫的表名和表字段名的實(shí)例
今天小編就為大家分享一篇python 獲取sqlite3數(shù)據(jù)庫的表名和表字段名的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2019-07-07深入探究Python中的多進(jìn)程模塊用法實(shí)例
多進(jìn)程是計(jì)算機(jī)編程中的一個(gè)概念,也可以說是一種可用于實(shí)現(xiàn)并行性和利用多個(gè) CPU 內(nèi)核或處理器并發(fā)執(zhí)行任務(wù)的技術(shù),在本文中,我們將學(xué)習(xí)有關(guān) python 中多進(jìn)程處理的所有知識(shí)、理論和實(shí)際使用代碼2024-01-01Python3.7實(shí)現(xiàn)驗(yàn)證碼登錄方式代碼實(shí)例
這篇文章主要介紹了Python3.7實(shí)現(xiàn)驗(yàn)證碼登錄方式代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-02-02PyTorch中的train()、eval()和no_grad()的使用
本文主要介紹了PyTorch中的train()、eval()和no_grad()的使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-04-04