pygame 中的加速和减速
Acceleration and Deceleration in pygame
我没有太多的编码经验,我一直在尝试让我的角色在按住键时加速到恒定速度,在松开键时减速。我在网上找到了一些代码,但我似乎无法将其正确实施到我的代码中。如果您不介意,如果您彻底解释了答案,那将会很有帮助,这样我才能正确理解我做错了什么。
这是我的代码
"""Dot Game"""
#Imports
import pygame, sys
#Constants
WIDTH, HEIGHT = 1000, 1000
TITLE = "Dot."
#pygame initialization
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
#fps
FPS = 60
fpsclock = pygame.time.Clock()
#colors
bgc = (247, 226, 222)
pc = (152, 193, 217)
pc2 = (61, 90, 128)
ec = (119, 2, 26)
ec2 = (220, 66, 73)
#accel
x_change = 0
y_change = 0
accel_x = 0
accel_y = 0
max_speed = 6
display_width, display_height = pygame.display.get_surface().get_size()
x = display_width * 0.45
y = display_height * 0.8
#Player Class
class Player:
def __init__(self, x, y):
self.x = int(x)
self.y = int(y)
self.radius = 32
self.width = 2
self.color = pc
self.color2 = pc2
self.velX = 0
self.velY = 0
self.left_pressed = False
self.right_pressed = False
self.up_pressed = False
self.down_pressed = False
self.speed = 3
self.hitbox = (self.x -20, self.y -20, 40, 40)
def draw(self, win):
pygame.draw.circle(win, self.color2, (self.x,self.y), 20)
pygame.draw.circle(win, self.color, (self.x,self.y), 14)
self.hitbox = (self.x -20, self.y -20, 40, 40)
#pygame.draw.rect(win,(255,0,0), self.hitbox,2)
def update(self):
self.velX = 0
self.velY = 0
if self.left_pressed:
self.velX = -self.speed
if self.right_pressed:
self.velX = self.speed
if self.up_pressed:
self.velY = -self.speed
if self.down_pressed :
self.velY = self.speed
self.x += self.velX
self.y += self.velY
self.rect = pygame.Rect(int(self.x), int(self.y), 32, 32)
def collide(self):
print('hit')
pass
#Player Initialization
player = Player(WIDTH/2, HEIGHT/2)
#Main Loop
collide = False
while not collide:
for event in pygame.event.get():
if event.type == pygame.QUIT:
collide == True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
accel_x = -.2
player.left_pressed = True
elif event.key == pygame.K_RIGHT:
accel_x = .2
player.right_pressed = True
elif event.key == pygame.K_UP:
accel_y = -.2
player.up_pressed = True
elif event.key == pygame.K_DOWN:
accel_y = .2
player.down_pressed = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
accel_x = 0
accel_y = 0
player.left_pressed = False
elif event.key == pygame.K_RIGHT:
accel_x = 0
accel_y = 0
player.right_pressed = False
elif event.key == pygame.K_UP:
accel_x = 0
accel_y = 0
player.up_pressed = False
elif event.key == pygame.K_DOWN:
accel_x = 0
accel_y = 0
player.down_pressed = False
x_change += accel_x # Accelerate.
if abs(x_change) >= max_speed: # If max_speed is exceeded.
# Normalize the x_change and multiply it with the max_speed.
x_change = x_change/abs(x_change) * max_speed
y_change += accel_y # Accelerate.
if abs(y_change) >= max_speed: # If max_speed is exceeded.
# Normalize the x_change and multiply it with the max_speed.
y_change = y_change/abs(y_change) * max_speed
# Decelerate if no key is pressed.
if accel_x == 0:
if x_change > 0:
x_change -= 0.2
if x_change < 0.2:
x_change = 0
elif x_change < 0:
x_change += 0.2
if x_change > -0.2:
x_change = 0
if accel_y == 0:
if y_change > 0:
y_change -= 0.2
if y_change < 0.2:
y_change = 0
elif y_change < 0:
y_change += 0.2
if y_change > -0.2:
y_change = 0
x += x_change # Move the object.
y += y_change
#Draw
win.fill((bgc))
player.draw(win)
#update
player.update()
pygame.display.update()
fpsclock.tick(FPS)
运动本身起作用,但没有加减速
在您的代码中,速度始终是恒定的,因为您在 update
的开头设置了 self.velX = 0
和 self.velY = 0
。因此,速度的数量始终为 0 或 3。
不要重置 self.velX
和 self.velY
。随加速度改变速度,但限制在最大速度。加速度必须是一个小值。只要按下一个键,这个小值就会每帧添加一次速度。这样慢慢地把速度提高到最大。
通过将速度乘以摩擦力来改进物理学。摩擦值必须小于 1,或者 1 表示没有摩擦:
class Player:
def __init__(self, x, y):
# [...]
self.acceleration = 0.1
self.friction = 0.99 # = 1 if you don't want any friction
def update(self):
if self.left_pressed:
if self.velX > -max_speed:
self.velX -= self.acceleration
if self.right_pressed:
if self.velX < max_speed:
self.velX += self.acceleration
if self.up_pressed:
if self.velY > -max_speed:
self.velY -= self.acceleration
if self.down_pressed :
if self.velY < max_speed:
self.velY += self.acceleration
self.x += self.velX
self.y += self.velY
self.velX *= self.friction
self.velY *= self.friction
self.rect = pygame.Rect(int(self.x), int(self.y), 32, 32)
我没有太多的编码经验,我一直在尝试让我的角色在按住键时加速到恒定速度,在松开键时减速。我在网上找到了一些代码,但我似乎无法将其正确实施到我的代码中。如果您不介意,如果您彻底解释了答案,那将会很有帮助,这样我才能正确理解我做错了什么。
这是我的代码
"""Dot Game"""
#Imports
import pygame, sys
#Constants
WIDTH, HEIGHT = 1000, 1000
TITLE = "Dot."
#pygame initialization
pygame.init()
win = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption(TITLE)
#fps
FPS = 60
fpsclock = pygame.time.Clock()
#colors
bgc = (247, 226, 222)
pc = (152, 193, 217)
pc2 = (61, 90, 128)
ec = (119, 2, 26)
ec2 = (220, 66, 73)
#accel
x_change = 0
y_change = 0
accel_x = 0
accel_y = 0
max_speed = 6
display_width, display_height = pygame.display.get_surface().get_size()
x = display_width * 0.45
y = display_height * 0.8
#Player Class
class Player:
def __init__(self, x, y):
self.x = int(x)
self.y = int(y)
self.radius = 32
self.width = 2
self.color = pc
self.color2 = pc2
self.velX = 0
self.velY = 0
self.left_pressed = False
self.right_pressed = False
self.up_pressed = False
self.down_pressed = False
self.speed = 3
self.hitbox = (self.x -20, self.y -20, 40, 40)
def draw(self, win):
pygame.draw.circle(win, self.color2, (self.x,self.y), 20)
pygame.draw.circle(win, self.color, (self.x,self.y), 14)
self.hitbox = (self.x -20, self.y -20, 40, 40)
#pygame.draw.rect(win,(255,0,0), self.hitbox,2)
def update(self):
self.velX = 0
self.velY = 0
if self.left_pressed:
self.velX = -self.speed
if self.right_pressed:
self.velX = self.speed
if self.up_pressed:
self.velY = -self.speed
if self.down_pressed :
self.velY = self.speed
self.x += self.velX
self.y += self.velY
self.rect = pygame.Rect(int(self.x), int(self.y), 32, 32)
def collide(self):
print('hit')
pass
#Player Initialization
player = Player(WIDTH/2, HEIGHT/2)
#Main Loop
collide = False
while not collide:
for event in pygame.event.get():
if event.type == pygame.QUIT:
collide == True
if event.type == pygame.KEYDOWN:
if event.key == pygame.K_LEFT:
accel_x = -.2
player.left_pressed = True
elif event.key == pygame.K_RIGHT:
accel_x = .2
player.right_pressed = True
elif event.key == pygame.K_UP:
accel_y = -.2
player.up_pressed = True
elif event.key == pygame.K_DOWN:
accel_y = .2
player.down_pressed = True
elif event.type == pygame.KEYUP:
if event.key == pygame.K_LEFT:
accel_x = 0
accel_y = 0
player.left_pressed = False
elif event.key == pygame.K_RIGHT:
accel_x = 0
accel_y = 0
player.right_pressed = False
elif event.key == pygame.K_UP:
accel_x = 0
accel_y = 0
player.up_pressed = False
elif event.key == pygame.K_DOWN:
accel_x = 0
accel_y = 0
player.down_pressed = False
x_change += accel_x # Accelerate.
if abs(x_change) >= max_speed: # If max_speed is exceeded.
# Normalize the x_change and multiply it with the max_speed.
x_change = x_change/abs(x_change) * max_speed
y_change += accel_y # Accelerate.
if abs(y_change) >= max_speed: # If max_speed is exceeded.
# Normalize the x_change and multiply it with the max_speed.
y_change = y_change/abs(y_change) * max_speed
# Decelerate if no key is pressed.
if accel_x == 0:
if x_change > 0:
x_change -= 0.2
if x_change < 0.2:
x_change = 0
elif x_change < 0:
x_change += 0.2
if x_change > -0.2:
x_change = 0
if accel_y == 0:
if y_change > 0:
y_change -= 0.2
if y_change < 0.2:
y_change = 0
elif y_change < 0:
y_change += 0.2
if y_change > -0.2:
y_change = 0
x += x_change # Move the object.
y += y_change
#Draw
win.fill((bgc))
player.draw(win)
#update
player.update()
pygame.display.update()
fpsclock.tick(FPS)
运动本身起作用,但没有加减速
在您的代码中,速度始终是恒定的,因为您在 update
的开头设置了 self.velX = 0
和 self.velY = 0
。因此,速度的数量始终为 0 或 3。
不要重置 self.velX
和 self.velY
。随加速度改变速度,但限制在最大速度。加速度必须是一个小值。只要按下一个键,这个小值就会每帧添加一次速度。这样慢慢地把速度提高到最大。
通过将速度乘以摩擦力来改进物理学。摩擦值必须小于 1,或者 1 表示没有摩擦:
class Player:
def __init__(self, x, y):
# [...]
self.acceleration = 0.1
self.friction = 0.99 # = 1 if you don't want any friction
def update(self):
if self.left_pressed:
if self.velX > -max_speed:
self.velX -= self.acceleration
if self.right_pressed:
if self.velX < max_speed:
self.velX += self.acceleration
if self.up_pressed:
if self.velY > -max_speed:
self.velY -= self.acceleration
if self.down_pressed :
if self.velY < max_speed:
self.velY += self.acceleration
self.x += self.velX
self.y += self.velY
self.velX *= self.friction
self.velY *= self.friction
self.rect = pygame.Rect(int(self.x), int(self.y), 32, 32)