gpt4 book ai didi

python - Pygame - 接地时平台跳转无响应

转载 作者:行者123 更新时间:2023-12-04 03:39:58 30 4
gpt4 key购买 nike

我最近在用 pygame(Python 版本:3.8.5,Pygame 版本:2.0.1)制作平台游戏。

我实现了一个跳转功能,只要按下 “a” 键或 up 键,播放器就会停止

问题

但这太没有反应了:

  • 在跳跃发生之前,我必须按 2 到 3 次按键。

代码

下面是整个项目的代码(诚然有点乱):

import os
import sys
import pygame
from pygame.locals import *

# utility functions

# for drawing the collision box
def draw_collision_box(screen, rect):
pygame.draw.rect(screen, (0, 255, 0), rect, 1)

# getting collisions
def get_collisions(rect, tiles):
collisions = []

for tile in tiles:
if rect.colliderect(tile):
collisions.append(tile)

return collisions

# moving the player
def move(rect, movement, tiles):
collision_types = {"top": False, "bottom": False, "right": False, "left": False}

rect.x += movement[0]
collisions = get_collisions(rect, tiles)

for collision in collisions:
if movement[0] > 0:
rect.right = collision.left
collision_types["right"] = True
elif movement[0] < 0:
rect.left = collision.right
collision_types["left"] = True

rect.y += movement[1]
collisions = get_collisions(rect, tiles)

for collision in collisions:
if movement[1] > 0:
rect.bottom = collision.top
collision_types["bottom"] = True
elif movement[1] < 0:
rect.top = collision.bottom
collision_types["top"] = True

return rect, collision_types

# constants
FPS = 60
TILE_SIZE = 32
MAX_GRAVITY_SCL = 3

# initialize pygame
pygame.init()

# initializing the game window
WINDOW_SIZE = (400, 400)
screen = pygame.display.set_mode(WINDOW_SIZE)
pygame.display.set_caption("Platformer")

# clock
clock = pygame.time.Clock()

# player
player_image = pygame.image.load(os.path.join(
"assets", "platformer", "player.png")) # loading the player image
player_image = pygame.transform.scale(player_image, (16, 32)) # resizing the player image
player_image.set_colorkey((255, 255, 255)) # making the bg of the player transparent by setting the color key

moving_right = False # checking if the player is moving right
moving_left = False # checking if the player is moving left

player_xspeed = 4 # player speed on horizontal axis

player_ymomentum = 0 # initial momentum on vertical axis
gravitational_acc = 0.5 # constant gravitation acceleration
jump_force = 10 # jump force of the player
grounded = False # checking if the player is grounded

player_rect = pygame.Rect(
50, 50, player_image.get_width(), player_image.get_height()) # player rect for managing collisions

# tiles
grass_image = pygame.image.load(os.path.join(
"assets", "platformer", "grass.png")) # loading the grass image
dirt_image = pygame.image.load(os.path.join(
"assets", "platformer", "dirt.png")) # loading the dirt image

# resizing the tile images
grass_image = pygame.transform.scale(grass_image, (TILE_SIZE, TILE_SIZE))
dirt_image = pygame.transform.scale(dirt_image, (TILE_SIZE, TILE_SIZE))

# game map
game_map = [["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "2", "2", "2", "0", "0", "2", "2", "2", "0", "0", "0", "0", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "2", "2", "2", "0", "0", "0", "0", "0"],
["0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "0", "1", "1", "1", "0", "0", "0", "0", "0"],
["2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "1", "1", "1", "2", "2", "2", "2", "2"],
["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"],
["1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1"]]

# game loop
while True:
# frames per second
clock.tick(FPS)

# filling the background with a solid color so that images doesn't make on top of each other
screen.fill((146, 244, 255))

# rendering images
screen.blit(player_image, (player_rect.x, player_rect.y))

# rendering the map
tiles = []

for y in range(len(game_map)):
for x in range(len(game_map[y])):
if game_map[y][x] == "1":
screen.blit(dirt_image, (x * TILE_SIZE, y * TILE_SIZE))
if game_map[y][x] == "2":
screen.blit(grass_image, (x * TILE_SIZE, y * TILE_SIZE))
if game_map[y][x] != "0":
tiles.append(pygame.Rect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE))

# drawing the collision boxes for the tiles
# for tile in tiles:
# draw_collision_box(screen, tile)

# updating the game
movement = [0, 0]

if moving_right == True:
movement[0] += player_xspeed
if moving_left == True:
movement[0] -= player_xspeed

# gravity for the player
player_ymomentum += gravitational_acc
player_ymomentum = min(player_ymomentum, MAX_GRAVITY_SCL)
movement[1] += player_ymomentum

# updating player's position
player_rect, collision_types = move(player_rect, movement, tiles)
if collision_types["top"] or collision_types["bottom"]:
player_ymomentum = 0

grounded = collision_types["bottom"]

# drawing the collision rect of the player
# draw_collision_box(screen, player_rect)

# listening for events
for event in pygame.event.get():
if event.type == QUIT: # quit event
pygame.quit() # stop pygame
sys.exit() # quit the program

if event.type == KEYDOWN: # key input event
if (event.key == K_RIGHT or event.key == K_d):
moving_right = True
if (event.key == K_LEFT or event.key == K_a):
moving_left = True
if (event.key == K_UP or event.key == K_w) and grounded:
player_ymomentum = -jump_force

if event.type == KEYUP: # keyup input event
if (event.key == K_RIGHT or event.key == K_d):
moving_right = False
if (event.key == K_LEFT or event.key == K_a):
moving_left = False

# updating the display
pygame.display.update()

有人可以帮助我吗?

最佳答案

通过阅读您的代码,会发生以下情况:

在这行代码中

player_ymomentum += gravitational_acc

player_ymomentum 设置为 0.5;因此 movement[1] 也设置为 0.5。

move 函数中,您运行这行代码:

rect.y += movement[1]

因为 movement[1] 是 < 1 并且 Rect.y 是/必须是一个整数值,rect.y 不是实际上改变。

因为 rect.y 没有改变,所以在接下来对 get_collisions 的调用中没有检测到碰撞。

条件 if movement[1] > 0True,但由于未检测到碰撞,collision_types["bottom"] 将永远不要设置为 True;因此 grounded 不会是 True 并且你不能跳。


在下一帧中,行

player_ymomentum += gravitational_acc

再次运行。这次,player_ymomentum 设置为 1;因此 movement[1] 也设置为 1。

move 函数中,行

rect.y += movement[1]

这次实际上会移动矩形。将检测到碰撞,collision_types["bottom"] 将设置为 Truegrounded 将设置为 True,让你跳跃。

player_ymomentum 将被重置为 0,并且这个循环再次开始。

因此,每当您尝试站立跳跃时,grounded 实际上是 False 的几率为 50/50,因此按跳跃键将不起作用。


要解决此问题,请删除此部分:

if collision_types["top"] or collision_types["bottom"]:
player_ymomentum = 0

player_ymomentum 将在仍站在地面上时向 MAX_GRAVITY_SCL 生长,但这应该不是问题。

或者在尝试检测玩家与地面之间的碰撞时使用更大的Rect,如下所示:

...
rect.y += movement[1]
collisions = get_collisions(rect.inflate(1, 1), tiles)

for collision in collisions:
...

关于python - Pygame - 接地时平台跳转无响应,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66221121/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com