4 回答

TA貢獻1803條經(jīng)驗 獲得超3個贊
回答
每次球彈過邊緣時,分數(shù)就會瞬間增加,每次球重生時分數(shù)都會回到 0。
分數(shù)在主循環(huán)中不斷初始化。您必須在循環(huán)之前初始化分數(shù):
def main():
# [...]
score_A = 0 # <--- INSERT
score_B = 0
while run:
# score_A = 0 <--- DELETE
# score_B = 0

TA貢獻1934條經(jīng)驗 獲得超2個贊
回答問題1:是的??隙ㄓ泻芏喔行У姆椒▉碜鍪?。沒有必要為方向制造那么多變數(shù)。簡單地說direction = [True, False],其中direction[0]代表not direction[0]x 軸的左,代表右。同樣,direction[1]代表 y 軸。這也解決了您在開始時隨機化方向的問題。您只需 direction = [random.randint(0, 1), random.randint(0, 1)]在 init 方法中執(zhí)行即可隨機化方向。同樣的方式,也列出速度清單。self.speed = [0.5, random.uniform(0.1, 1)]。這樣,左右方向的速度將始終相同,但 y 將根據(jù)所選的隨機數(shù)而變化,因此存在適當?shù)碾S機性,并且您也不必硬編碼隨機方向。這樣,移動變得非常簡單。
class Ball:
def __init__(self, x, y, color, size):
self.x = x
self.y = y
self.color = color
self.size = size
self.direction = [random.randint(0, 1), random.randint(0, 1)]
self.speed = [0.5, random.uniform(0.1, 1)]
def draw(self, display):
pygame.draw.rect(display, self.color, (self.x, self.y, self.size, self.size))
def move(self):
if self.direction[0]:
self.x += self.speed[0]
else:
self.x -= self.speed[0]
if self.direction[1]:
self.y += self.speed[0]
else:
self.y -= self.speed[0]
因為我們定義的方向方向是布爾值,所以改變狀態(tài)也變得非常容易。如果球擊中球拍,您可以簡單地切換direction[0] = not direction[0]x 中的布爾值并為 y 選擇一個新的隨機數(shù),而不是手動分配布爾值。
def switchDirection(self):
self.direction = not self.direction
self.speed[1] = random.uniform(0.1, 1)
move通過為 Paddle 類提供一個函數(shù)而不是在主循環(huán)中移動,Paddle 也可以稍微改進。這只是意味著您必須編寫更少的代碼。
def move(self, vel, up=pygame.K_UP, down=pygame.K_DOWN):
keys = pygame.key.get_perssed()
if keys[up]:
self.y -= vel
if keys[down]:
self.y += vel
對于碰撞,我建議使用pygame.Rect()andcolliderect因為它更強大并且可能也更有效。
例子:
import random
import pygame
WIN = pygame.display
D = WIN.set_mode((800, 500))
class Paddle:
def __init__(self, x, y, width, height, vel, color):
self.x = x
self.y = y
self.width = width
self.height = height
self.vel = vel
self.color = color
def move(self, vel, up=pygame.K_UP, down=pygame.K_DOWN):
keys = pygame.key.get_pressed()
if keys[up]:
self.y -= vel
if keys[down]:
self.y += vel
def draw(self, window):
pygame.draw.rect(window, self.color, (self.x, self.y, self.width, self.height), 0)
def getRect(self):
return pygame.Rect(self.x, self.y, self.width, self.height)
left_paddle = Paddle(20, 100, 10, 50, 5, (0, 0, 0))
right_paddle = Paddle(770, 350, 10, 50, 5, (0, 0, 0))
class Ball:
def __init__(self, x, y, color, size):
self.x = x
self.y = y
self.color = color
self.size = size
self.direction = [random.randint(0, 1), random.randint(0, 1)]
self.speed = [0.3, random.uniform(0.2, 0.2)]
def draw(self, window):
pygame.draw.rect(window, self.color, (self.x, self.y, self.size, self.size))
def switchDirection(self):
self.direction[0] = not self.direction[0]
self.direction[1] = not self.direction[1]
self.speed = [0.2, random.uniform(0.1, 0.5)]
def bounce(self):
self.direction[1] = not self.direction[1]
self.speed = [0.2, random.uniform(0.01, 0.2)]
def move(self):
if self.direction[0]:
self.x += self.speed[0]
else:
self.x -= self.speed[0]
if self.direction[1]:
self.y += self.speed[1]
else:
self.y -= self.speed[1]
def getRect(self):
return pygame.Rect(self.x, self.y, self.size, self.size)
def boundaries(self):
if ball.x <= 10:
self.switchDirection()
if ball.x + self.size >= 800:
self.switchDirection()
if ball.y + self.size >= 490:
self.bounce()
if ball.y <= 0:
self.bounce()
ball = Ball(400, 250, (255, 0, 0), 20)
while True:
pygame.event.get()
D.fill((255, 255, 255))
ball.draw(D)
ball.boundaries()
ball.move()
#print(ball.x, ball.y)
left_paddle.draw(D)
right_paddle.draw(D)
right_paddle.move(0.4)
left_paddle.move(0.4, down=pygame.K_s, up=pygame.K_w)
if left_paddle.getRect().colliderect(ball.getRect()):
ball.switchDirection()
if right_paddle.getRect().colliderect(ball.getRect()):
ball.switchDirection()
WIN.flip()

TA貢獻1804條經(jīng)驗 獲得超8個贊
我基本上對球在邊緣彈跳時的每一種可能的運動進行了編碼。我花了幾個小時的時間來研究它,并且讓它工作起來,我只是想知道是否有一種更有效的方法可以用我的代碼產(chǎn)生類似的輸出(因為我知道這應該是一個初學者項目)?
和
如何使球在隨機方向上產(chǎn)生?在每輪開始(和重新開始)時?
您可以使用浮動坐標,而不是實現(xiàn)球的“每個”方向。這些變量通常稱為 dx 和 dy。通過這種方式獲得球的隨機或反向方向很簡單,只需使用 dx 和 dy 的隨機或反向值即可。
你的球的更新應該如下所示:
def?update(self.?dt): ????self.x?+=?self.dx?*?self.speed?*?time_elapsed ????self.y?+=?self.dy?*?self.speed?*?time_elapsed?#?Time?elasped?is?often?called?dt.
每次球彈過邊緣時,分數(shù)就會瞬間增加,每次球重生時分數(shù)都會回到 0。
理想情況下,您應該有一個 GameState 對象,其中包含分數(shù)、生命和其他內(nèi)容作為屬性。

TA貢獻1796條經(jīng)驗 獲得超4個贊
關(guān)于如何減少所有球運動/碰撞代碼并提高可重用性的一些值得思考的地方:
import pygame
class Ball:
def __init__(self, bounds, color):
from random import randint, choice
self.bounds = bounds
self.position = pygame.math.Vector2(
randint(self.bounds.left, self.bounds.left+self.bounds.width),
randint(self.bounds.top, self.bounds.top+self.bounds.height)
)
self.velocity = pygame.math.Vector2(choice((-1, 1)), choice((-1, 1)))
self.color = color
self.size = 8
def draw(self, window):
pygame.draw.rect(
window,
self.color,
(
self.position.x-self.size,
self.position.y-self.size,
self.size*2,
self.size*2
),
0
)
def update(self):
self.position.x += self.velocity.x
self.position.y += self.velocity.y
if not self.bounds.left+self.size < self.position.x < self.bounds.left+self.bounds.width-self.size:
self.velocity.x *= -1
if not self.bounds.top+self.size < self.position.y < self.bounds.top+self.bounds.height-self.size:
self.velocity.y *= -1
def main():
from random import randint
window_width, window_height = 800, 500
window = pygame.display.set_mode((window_width, window_height))
pygame.display.set_caption("Pong")
clock = pygame.time.Clock()
black = (0, 0, 0)
white = (255, 255, 255)
padding = 20
bounds = pygame.Rect(padding, padding, window_width-(padding*2), window_height-(padding*2))
ball = Ball(bounds, white)
def redraw_window():
window.fill(black)
pygame.draw.rect(
window,
white,
(
padding,
padding,
window_width-(padding*2),
window_height-(padding*2)
),
1
)
ball.draw(window)
pygame.display.update()
while True:
clock.tick(60)
ball.update()
for event in pygame.event.get():
if event.type == pygame.QUIT:
break
else:
redraw_window()
continue
break
pygame.quit()
return 0
if __name__ == "__main__":
import sys
sys.exit(main())
這不是一個完整的替代品,我只是重新實現(xiàn)了該類Ball。沒有槳。本質(zhì)上,在實例化一個球時,您傳遞一個pygame.Rect,它描述了允許球彈跳的邊界。您還傳遞一個顏色元組。然后,球在邊界內(nèi)選擇一個隨機位置(該位置是 a pygame.math.Vector2,而不是存儲x和y作為單獨的實例變量)。球也有速度,它也是pygame.math.Vector2,因此您可以擁有獨立的速度分量 - 一個用于x(水平速度),一個用于y(垂直速度)。球size的 簡單地描述了球的尺寸。例如,如果size設(shè)置為8,則球?qū)?16x16 像素。
該類Ball還有一個update方法,每個游戲循環(huán)迭代都會調(diào)用該方法。它將球移動到速度決定的下一個位置,并檢查球是否與邊界碰撞。如果是,則反轉(zhuǎn)相應的速度分量。
添加回答
舉報