pygame中的加速和减速 [英] Acceleration and Deceleration in pygame

查看:65
本文介绍了pygame中的加速和减速的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在编码方面没有太多经验,我一直试图让我的角色在按住键时加速到恒定速度并在松开键时减速.我在网上找到了一些代码,但我似乎无法正确地将它实现到我的中.如果你不介意的话,如果你彻底解释了答案会很有帮助,这样我就可以正确地理解我做错了什么.

I do not have much experience in coding, and I have been stuck on trying to make my character accelerate to a constant speed when key is held and decelerate when key is let go of. I found some code online on it but I cannot seem to properly implement it into mine. If you don't mind it would be helpful if you thoroughly explained the answer so I can properly understand what I am doing wrong.

这是我的代码

"""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)

运动本身有效,但没有加速和减速

The movement itself works, however there is no acceleration and deceleration

推荐答案

在你的代码中,速度总是恒定的,因为你设置了 self.velX = 0 self.velY = 0update 的开头.因此速度的大小总是 0 或 3.不要重置self.velXself.velY.用加速度改变速度,但限制在最大速度.加速度必须是一个小值.只要按下一个键,这个小值就会被添加到每帧一次的速度上.这会慢慢将速度提高到最大.
通过将速度乘以摩擦来提高物理性能.摩擦的值必须小于 1,或者 1 表示没有摩擦:

In your code the speed is always constant because you set self.velX = 0 and self.velY = 0 at the beginning of update. Therefore the amount of the speed is always 0 or 3. Do not reset self.velX and self.velY. Change the speed with the acceleration, but limit it at the maximum speed. The acceleration must be a small value. As long as a key is pressed, this small value is added to the speed once per frame. This slowly increases the speed to the maximum.
Improve physics by multiplying speed by friction. The value for the friction must be less than 1, or 1 for no friction:

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)

这篇关于pygame中的加速和减速的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆