【问题标题】:How to automatically implement gravity when key is released? How to allow for continuous jumping?释放键时如何自动实现重力?如何允许连续跳跃?
【发布时间】:2017-09-06 21:46:54
【问题描述】:

在我的代码中,当玩家的化身跳到某个点时,重力会使其回落。但是,这仅在按住向上和空格按钮直到达到特定点时才有效。在释放按钮的情况下,我想使用这段代码将鸭子重力送回:

player.rect.move_ip(0, (player.speed) * -player.y_direction)

不知道怎么做检查,看是否释放,然后自动执行。

另外一个我需要帮助的问题是,当鸭子回到地板上时,必须松开按钮然后重新敲击。我想更新代码,只要按下按钮,头像就会跳回地面,然后在按住空格和向上按钮的情况下自动返回跳跃。

以下是完整代码: 类播放器(pygame.sprite.Sprite): """玩家控制的鸭子"""

    def __init__(self, x, y, width, height):
        super(Player, self).__init__(x, y, width, height)

        # How many pixels the Player duck should move on a given frame.
        self.y_change = 0
        # How many pixels the spaceship should move each frame a key is pressed.
        self.y_dist = 150
        self.x_change = 0
        # How many pixels the spaceship should move each frame a key is pressed.
        self.x_dist = 30
        self.x_direction = 1
        # Positive = down, negative = up
        self.y_direction = -1
        # Current speed.
        self.speed = 13

duck = pygame.image.load('walkingduck.png')
player = Player(0, (window_height)-125, 120, 160) #Making player object(duck)

all_sprites_list = pygame.sprite.Group()
all_sprites_list.add(player)
move = False

while True:  # the main game loop
    if move: #Jumping process
        key_pressed = pygame.key.get_pressed()
        if key_pressed[pygame.K_UP] or key_pressed[pygame.K_SPACE]:
            if player.rect.y<=320:
                move=False
            else:
                player.rect.move_ip(0, player.speed * player.y_direction)
    if move==False and player.rect.y<=(window_height)-115:
        player.rect.move_ip(0, (player.speed) * -player.y_direction)

    for event in pygame.event.get(): #Closes game
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == KEYDOWN:
            move=True

            #Adds images and text
    screen.blit(BackGround.image, BackGround.rect)

    all_sprites_list.draw(screen)
    pygame.display.flip()
    pygame.display.update()
    clock.tick(FPS)

【问题讨论】:

  • 所以如果按下键,鸭子应该向上飞,否则向下?
  • 它已经做到了。然而,在释放鸭子时,它会停留在空中,除非它在下降时飞到某个点(按住键)。所以我想让它在任何时候释放钥匙然后将它放回地面。

标签: pygame python-3.5


【解决方案1】:

我会这样做:如果玩家正在飞行,请将y_change 设置为负数,否则将 GRAVITY 值添加到它以使其向下加速。然后移动矩形并夹住它。 (我实际上将移动代码放入Player 类的update 方法中。)

import sys
import pygame


class Player(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height):
        super(Player, self).__init__()
        self.image = pygame.Surface((width, height))
        self.image.fill((230, 200, 40))
        self.rect = self.image.get_rect(center=(x, y))
        self.y_change = 0


pygame.init()
GRAVITY = .9
window_height = 600
screen = pygame.display.set_mode((800, window_height))
player = Player(200, 50, 40, 30)
all_sprites_list = pygame.sprite.Group(player)
clock = pygame.time.Clock()
move = False
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            move = True
        if event.type == pygame.KEYUP:
            move = False

    if move:  # Fly upwards.
        player.y_change = -9
    else:  # Add the gravity to the y-velocity.
        player.y_change += GRAVITY
    player.rect.move_ip(0, player.y_change)
    # Clamp the rect.y value to the range 50 to 450-rect.h.
    # You could also use rect.clamp_ip((0, 50, 800, 450)).
    if player.rect.y < 50:
        player.rect.y = 50
        player.y_change = 0
    elif player.rect.bottom >= window_height-150:
        player.rect.bottom = window_height-150
        player.y_change = 0

    screen.fill((30, 100, 140))
    all_sprites_list.draw(screen)
    pygame.display.flip()
    pygame.display.update()
    clock.tick(30)

pygame.quit()
sys.exit()

这是update 方法和rect.clamp_ip 的变体。

import sys
import pygame


class Player(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height):
        super(Player, self).__init__()
        self.image = pygame.Surface((width, height))
        self.image.fill((230, 200, 40))
        self.rect = self.image.get_rect(center=(x, y))
        self.y_change = 0
        self.flying = False

    def update(self):
        if self.flying:
            self.y_change = -9
        self.y_change += GRAVITY
        self.rect.move_ip(0, self.y_change)
        self.rect.clamp_ip((0, 50, 800, 450))
        if self.rect.y <= 50:
            self.y_change = 1


pygame.init()
GRAVITY = .5
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
player = Player(200, 50, 40, 30)
all_sprites_list = pygame.sprite.Group(player)
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            player.flying = True
        if event.type == pygame.KEYUP:
            player.flying = False

    all_sprites_list.update()
    screen.fill((30, 100, 140))
    all_sprites_list.draw(screen)
    pygame.display.flip()
    clock.tick(30)

pygame.quit()
sys.exit()

编辑:这是连续跳跃的版本,而不是平滑的向上运动。

import sys
import pygame


class Player(pygame.sprite.Sprite):

    def __init__(self, x, y, width, height):
        super(Player, self).__init__()
        self.image = pygame.Surface((width, height))
        self.image.fill((230, 200, 40))
        self.rect = self.image.get_rect(center=(x, y))
        self.y_change = 0
        self.flying = False

    def update(self):
        if self.flying:
            # If the y_change is getting too big,
            # reset it to -13 to fly upwards again.
            if self.y_change > 5:
                self.y_change = -13
        # Accelerate downwards each frame.
        self.y_change += GRAVITY
        self.rect.move_ip(0, self.y_change)
        self.rect.clamp_ip((0, 50, 800, 450))
        if self.rect.y <= 50:
            self.y_change = 1


pygame.init()
GRAVITY = .9
screen = pygame.display.set_mode((800, 600))
clock = pygame.time.Clock()
player = Player(200, 50, 40, 30)
all_sprites_list = pygame.sprite.Group(player)
running = True

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
        if event.type == pygame.KEYDOWN:
            player.flying = True
        if event.type == pygame.KEYUP:
            player.flying = False

    all_sprites_list.update()
    screen.fill((30, 100, 140))
    all_sprites_list.draw(screen)
    pygame.display.flip()
    clock.tick(30)

pygame.quit()
sys.exit()

【讨论】:

  • 非常感谢。这完美地帮助我解决了所有的跳跃问题。
  • 你知道如何做到这一点,按住按钮时它不能停留在空中,而是重力将它拉下来?
  • 我不太确定你的意思。玩家是否应该在按下按钮时只跳一次而不是不断向上飞?
  • 它不应该一直向上飞。它应该在跳跃后下降,然后如果仍然按住按钮,则可以返回。
  • 如果我理解正确,您希望它看起来像一只会飞或扑腾的鸟。按住键时,它应该上升,然后下降一点,再上升等等,对吗?
猜你喜欢
  • 2018-02-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-06-10
相关资源
最近更新 更多