我正在开发的游戏有问题。游戏的重点是用木板击球,以使球不会掉落。代码中有很多错误,但是我认为我应该先解决这个问题。基本上,一旦球从木板反弹,我就会增加速度增量。但是,一旦增量变得过高,您将看到球“跳跃”,而不是在屏幕上平稳移动。我尝试增加FPS并减小速度增量,但是速度太慢。下面是我的代码:
import pygame
pygame.init()
win = pygame.display.set_mode((750, 750))
pygame.display.set_caption('Ball Plank')
clock = pygame.time.Clock()
x = 305
y = 650
width = 150
height = 10
vel = 30
score = 0
lives = 3
radius = 35
ball_x = 377
ball_y = 297
ball_vely = 10
ball_velx = 10
font = pygame.font.SysFont('comicsans', 40, True)
def drawing():
win.fill((0, 0, 0))
text_score = font.render('Score: ' + str(score), 1, (255, 255, 255))
text_lives = font.render('Lives: ' + str(lives), 1, (255, 255, 255))
win.blit(text_score, (570, 20))
win.blit(text_lives, (30, 20))
circle = pygame.draw.circle(win, (0, 255, 0), (int(ball_x), int(ball_y)), radius)
rect = pygame.draw.rect(win, (255, 0, 0), (x, y, width, height))
pygame.display.update()
run = True
while run:
clock.tick(40)
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and x > vel:
x -= vel
if keys[pygame.K_RIGHT] and x < 750 - width - vel:
x += vel
ball_y += ball_vely
ball_x += ball_velx
if ball_y - radius - 10 <= 0:
ball_vely *= -1
elif ball_y + radius + 8 > y and ball_y <= y and ball_x > x - radius and ball_x < x + width + radius:
ball_velx = 10
if ball_vely > 0:
ball_vely += 0.5
else:
ball_vely -= 0.5
ball_vely *= -1
score += 1
if ball_x > x + 75:
ball_velx *= 1 + (ball_x - x + 75)/150
elif ball_x < x + 75:
ball_velx *= -(1 + (ball_x - x + 75)/150)
if ball_x - radius - 10 <= 0 or ball_x + radius + 10 >= 750:
ball_velx *= -1
if ball_y > 760 + radius:
lives -= 1
if lives == 0:
run = False
drawing()
pygame.display.quit()
pygame.quit()
不确定到底出了什么问题,对不起,代码太多了。
答案 0 :(得分:0)
您必须根据帧速率计算每帧的移动。
pygame.time.Clock.tick
返回自上次调用以来的毫秒数。当您在应用程序循环中调用它时,这是自上一帧以来经过的毫秒数。将物体速度乘以每帧经过的时间,无论 FPS 多少,都可以获得持续运动。
以像素为单位定义玩家每秒应移动的距离 (ball_move_per_second
, paddle_move_per_second
)。计算应用程序循环中每帧的距离 (ball_move_per_frame
, paddle_move_per_frame
)。为球的运动添加一个 pygame.math.Vector2
类型的方向向量:
clock = pygame.time.Clock()
ball_dir = pygame.math.Vector2(1, 1).normalize()
ball_move_per_second = 500
paddle_move_per_second = 500
run = True
while run:
ms_frame = clock.tick(300)
ball_move_per_frame = ball_move_per_second * ms_frame / 1000
paddle_move_per_frame = paddle_move_per_second * ms_frame / 1000
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x = max(0, x - paddle_move_per_frame)
if keys[pygame.K_RIGHT]:
x = min(x + paddle_move_per_frame, win.get_width() - width)
ball_x += ball_dir.x * ball_move_per_frame
ball_y += ball_dir.y * ball_move_per_frame
此外,您的碰撞测试存在一些问题。有关解决方案,请参阅 Pong 和 Sometimes the ball doesn't bounce off the paddle in pong game。
完整示例:
import pygame
pygame.init()
win = pygame.display.set_mode((750, 750))
pygame.display.set_caption('Ball Plank')
clock = pygame.time.Clock()
x, y = 305, 650
width, height = 150, 10
score = 0
lives = 3
radius = 35
ball_x, ball_y = 377, 297
ball_dir = pygame.math.Vector2(1, 1).normalize()
ball_move_per_second = 500
paddle_move_per_second = 500
def drawing():
win.fill((0, 0, 0))
text_score = font.render('Score: ' + str(score), 1, (255, 255, 255))
text_lives = font.render('Lives: ' + str(lives), 1, (255, 255, 255))
win.blit(text_score, (570, 20))
win.blit(text_lives, (30, 20))
circle = pygame.draw.circle(win, (0, 255, 0), (round(ball_x), round(ball_y)), radius)
rect = pygame.draw.rect(win, (255, 0, 0), (round(x), round(y), width, height))
pygame.display.update()
font = pygame.font.SysFont('comicsans', 40, True)
run = True
while run:
ms_frame = clock.tick(300)
ball_move_per_frame = ball_move_per_second * ms_frame / 1000
paddle_move_per_frame = paddle_move_per_second * ms_frame / 1000
for event in pygame.event.get():
if event.type == pygame.QUIT:
run = False
if event.type == pygame.KEYDOWN and event.key == pygame.K_r:
x, y = 305, 650
ball_x, ball_y = 377, 297
ball_dir = pygame.math.Vector2(1, 1).normalize()
ball_move_per_second = 500
paddle_move_per_second = 500
score = 0
lives = 3
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT]:
x = max(0, x - paddle_move_per_frame)
if keys[pygame.K_RIGHT]:
x = min(x + paddle_move_per_frame, win.get_width() - width)
ball_x += ball_dir.x * ball_move_per_frame
ball_y += ball_dir.y * ball_move_per_frame
if ball_x < radius:
ball_x = radius
ball_dir.x *= -1
if ball_x > win.get_width() - radius:
ball_x = win.get_width() - radius
ball_dir.x *= -1
if ball_y < radius:
ball_y = radius
ball_dir.y *= -1
if ball_dir.y > 0 and y - radius < ball_y < y - radius + height and x - radius < ball_x < x + width + radius:
ball_y = y - radius
ball_dir.y *= -1
ball_move_per_second += 10
score += 1
elif ball_y > win.get_height() - radius:
ball_y = win.get_height() - radius
ball_dir.y *= -1
lives -= 1
drawing()
pygame.display.quit()
pygame.quit()