pygame實現(xiàn)彈球游戲流程
一、事件
鼠標事件:
pygame.mouse.get_pos():獲取鼠標當前點的坐標
pygame.mouse.get_pressed()[0]:獲取鼠標左鍵是否為點擊
二、復習碰撞精靈
1、首先是3個球在窗口上移動的最基礎(chǔ)的版本:
import pygame, sys class MyBall(pygame.sprite.Sprite): def __init__(self, point, speed): self.image = pygame.image.load("beach_ball.png") self.rect = self.image.get_rect() self.rect.left = point[0] self.rect.top = point[1] self.speed = speed def move(self): self.rect = self.rect.move(self.speed) screen.blit(self.image, self.rect) pygame.init() size = width, height = 640, 480 screen = pygame.display.set_mode(size) screen.fill([255, 255, 255]) balls = [] for i in range(3): ball = MyBall([180+i*180, 200], [8, 8]) balls.append(ball) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.fill([255, 255, 255]) for i in range(len(balls)): balls[i].move() pygame.display.flip() pygame.time.delay(20)
這三個球有一個缺點,一旦移動到窗口外,就移不回來了,因此,我們要在移動時,進行窗口邊沿的判斷
2、增加上下左右邊框的判斷
這樣當球試圖超出邊界時,將對應(yīng)方向的速度取反,使得重新回到窗口中來:
def move(self): self.rect = self.rect.move(self.speed) if self.rect.right > width: # 新增右邊框判斷 self.speed[0] = -abs(self.speed[0]) if self.rect.left < 0: # 新增左邊框判斷 self.speed[0] = abs(self.speed[0]) if self.rect.bottom > height: # 新增下邊框判斷 self.speed[1] = -abs(self.speed[1]) if self.rect.top < 0: # 新增上邊框判斷 self.speed[1] = abs(self.speed[1]) screen.blit(self.image, self.rect)
進行到這一步,我們發(fā)現(xiàn)小球碰到一起時沒有發(fā)生碰撞事件,即碰到一起的小球沒有互相撤退,這時碰撞檢測就使用起來了:
通過pygame.sprite.spritecollide我們可以檢測當前小球與別的小球是否發(fā)生碰撞,如果發(fā)生碰撞,就將小球當前速度取反
3、碰撞處理
1)碰撞后的處理
def crash(self, balls): balls.remove(self) # 將自身從碰撞組中刪除 if pygame.sprite.spritecollide(self, balls, False): # 檢測碰撞發(fā)生,將自身的速度取反 self.speed[0] = -self.speed[0] self.speed[1] = -self.speed[1]
2)針對小球兩兩組合進行碰撞處理:
for i in range(len(balls)): for j in range(len(balls)): if i == j: continue balls[i].crash([balls[i], balls[j]])
這樣小球互相碰到就會向相反的方向彈去。
三、畫出球桿并擊打小球
我們可以設(shè)想當小球停止下來后才好進行擊打小球的動作,因此,可以針對小球做一個減速處理
然后當小球的x,y方向的速度都低于1時即認為小球靜止了
1、減速邏輯
def dec_speed(self): """減速""" self.speed[0] *= 0.995 self.speed[1] *= 0.995
2、畫出球桿
當小球靜時后,我們需要畫出一個球桿,畫法為小球中心點到當前鼠標的位置畫一條線段:
def wait_hit(self): if abs(self.speed[0]) > 1 or abs(self.speed[1]) > 1: # 在運動狀態(tài),退出,注意需要用abs,原因是速度有正和負 pass else: pos = pygame.mouse.get_pos() # 獲取鼠標坐標 pygame.draw.line(screen, [255, 0, 0], self.rect.center, pos, 5) # 畫出小球到鼠標的紅線 if pygame.mouse.get_pressed()[0]: # 按下鼠標左鍵 self.speed[0] = 0.1 * (self.rect.center[0] - pos[0]) # 給小球初始速度 self.speed[1] = 0.1 * (self.rect.center[1] - pos[1])
然后加上調(diào)用:
for i in range(len(balls)): if i == 0: balls[i].wait_hit() # 只有0號小球靜止時畫出球桿 balls[i].move() balls[i].dec_speed() # 減速,使得小球最終靜止下來
至此,一開始3個小球都會運動,運動過程中碰到一起也會發(fā)生碰撞反彈,隨著時間推移,小球越來越慢,最終停下來,然后在0號球處畫出了紅線,點擊鼠標左鍵,小球會向紅線的相反方向移動,就是存在一個問題,當小球碰到靜止的小球時,靜止的小球不會動
3、碰撞發(fā)生后,當發(fā)現(xiàn)自身沒有速度,使用對方的速度
def crash(self, groups): groups.remove(self) # 將自身從碰撞組中刪除 if pygame.sprite.spritecollide(self, groups, False): # 檢測碰撞發(fā)生,將自身的速度取反 if abs(self.speed[0]) > 1: # 運動狀態(tài)用自身的反速度 self.speed[0] = -self.speed[0] else: self.speed[0] = -groups[0].speed[0] # 靜止狀態(tài),用對方的反速度 if abs(self.speed[1]) > 1: self.speed[1] = -self.speed[1] else: self.speed[1] = -groups[0].speed[1]
至此一個簡單的彈球游戲就結(jié)束了
附完整源代碼:
import pygame, sys class MyBall(pygame.sprite.Sprite): def __init__(self, point, speed): self.image = pygame.image.load("beach_ball.png") self.rect = self.image.get_rect() self.rect.left = point[0] self.rect.top = point[1] self.speed = speed def move(self): self.rect = self.rect.move(self.speed) if self.rect.right > width: # 新增右邊框判斷 self.speed[0] = -abs(self.speed[0]) if self.rect.left < 0: # 新增左邊框判斷 self.speed[0] = abs(self.speed[0]) if self.rect.bottom > height: # 新增下邊框判斷 self.speed[1] = -abs(self.speed[1]) if self.rect.top < 0: # 新增上邊框判斷 self.speed[1] = abs(self.speed[1]) screen.blit(self.image, self.rect) def crash(self, groups): groups.remove(self) # 將自身從碰撞組中刪除 if pygame.sprite.spritecollide(self, groups, False): # 檢測碰撞發(fā)生,將自身的速度取反 if abs(self.speed[0]) > 1: # 運動狀態(tài)用自身的反速度 self.speed[0] = -self.speed[0] else: self.speed[0] = -groups[0].speed[0] # 靜止狀態(tài),用對方的反速度 if abs(self.speed[1]) > 1: self.speed[1] = -self.speed[1] else: self.speed[1] = -groups[0].speed[1] def dec_speed(self): """減速""" self.speed[0] *= 0.995 self.speed[1] *= 0.995 def wait_hit(self): if abs(self.speed[0]) > 1 or abs(self.speed[1]) > 1: # 在運動狀態(tài),退出,注意需要用abs,原因是速度有正和負 pass else: pos = pygame.mouse.get_pos() # 獲取鼠標坐標 pygame.draw.line(screen, [255, 0, 0], self.rect.center, pos, 5) # 畫出小球到鼠標的紅線 if pygame.mouse.get_pressed()[0]: # 按下鼠標左鍵 self.speed[0] = 0.1 * (self.rect.center[0] - pos[0]) # 給小球初始速度 self.speed[1] = 0.1 * (self.rect.center[1] - pos[1]) pygame.init() size = width, height = 640, 480 screen = pygame.display.set_mode(size) screen.fill([255, 255, 255]) balls = [] for i in range(3): ball = MyBall([180 + i * 180, 200], [8, 8]) balls.append(ball) while True: for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() screen.fill([255, 255, 255]) for i in range(len(balls)): if i == 0: balls[i].wait_hit() # 只有0號小球靜止時畫出球桿 balls[i].move() balls[i].dec_speed() # 減速,使得小球最終靜止下來 for i in range(len(balls)): for j in range(len(balls)): if i == j: continue balls[i].crash([balls[i], balls[j]]) pygame.display.flip() pygame.time.delay(10)
到此這篇關(guān)于pygame實現(xiàn)彈球游戲流程的文章就介紹到這了,更多相關(guān)pygame彈球游戲內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Pandas數(shù)據(jù)操作分析基本常用的15個代碼片段
這篇文章主要介紹了Pandas數(shù)據(jù)操作分析基本常用的15個代碼片段,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-09-09tensorflow實現(xiàn)打印ckpt模型保存下的變量名稱及變量值
今天小編就為大家分享一篇tensorflow實現(xiàn)打印ckpt模型保存下的變量名稱及變量值,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-01-01使用tensorflow根據(jù)輸入更改tensor shape
這篇文章主要介紹了使用tensorflow根據(jù)輸入更改tensor shape,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-06-06