对角输入未显示在 Pygame 格斗游戏输入缓冲区中

问题描述 投票:0回答:1

我正在使用 Pygame 在 Python 中开发一个简单的格斗游戏输入缓冲区,并且我试图让它尽可能接近实际格斗游戏的工作方式。我在尝试添加对对角线输入的支持时遇到了问题。我有输入缓冲区的工作版本,并且我正在寻找有关如何将对角线输入集成到现有代码中的指导。这是到目前为止该程序的代码:

https://paste.pythondiscord.com/WWFQ

如您所见,我尝试将四个对角线同时映射到两个键,例如 wa、sd 等,但这不起作用,因为输入没有显示在缓冲区中,或者它只是在一个键之间进行选择基本方向和其他方向。任何帮助或建议将不胜感激

我尝试使用集合来检查组合键,如下所示:

elif event.type == pygame.KEYDOWN:
    key = pygame.key.name(event.key)
    if key in ['w', 'a', 's', 'd']:
        buffer.append(key)
    elif 'w' in buffer and 'a' in buffer:  # W + A (diagonal)
        buffer.append('wa')
    elif 'w' in buffer and 'd' in buffer:  # W + D (diagonal)
        buffer.append('wd')
    elif 's' in buffer and 'a' in buffer:  # S + A (diagonal)
        buffer.append('sa')
    elif 's' in buffer and 'd' in buffer:  # S + D (diagonal)
        buffer.append('sd')

但是对角线的图像不会显示在屏幕上。例如,如果我按下后退 (S+A),缓冲区只会显示彼此相邻的向上输入和后退输入,而不是向下后退的图像。

python pygame game-development
1个回答
0
投票

缓冲区检查需要在

KEYDOWN
事件处理程序之外进行。合理的地方是在缓冲区间隙检查中添加
else
条件。

类似:

    # Check if it's time to clear the buffer
    current_time = pygame.time.get_ticks()
    if current_time - last_input_time >= buffer_store_time * 1000:
        buffer.clear()
        special_move_executed = {move["name"]: False for move in special_moves}
    else:  # check the buffer for diagonals
        if 'w' in buffer and 'a' in buffer:  # W + A (diagonal)
            buffer.remove('w')
            buffer.remove('a')
            buffer.append('wa')

这还假设您想要删除缓冲区中组合起来形成对角线的移动。

您没有将

i
j
k
键添加到缓冲区,因此您需要添加这些键才能使特殊移动检测起作用。另请注意,您的某些特殊动作无法被检测到,例如,火焰拳需要
down
+
right
+
light attack
,但在检测到
down forward
down时,缓冲区处理将替换
right
 
。因此,我认为您需要对缓冲区进行两次检查,一次用于对角线替换,仅检查最后一个缓冲的键,另一次用于较长时间的不活动以清除缓冲区。

无需额外计时器即可检测浪涌热度

这是完整的代码清单,我用系统字体中包含的字母或箭头替换了您的图像。

import pygame
import sys

# Initialize Pygame
pygame.init()

# Set up display
screen_width, screen_height = 800, 600
screen = pygame.display.set_mode((screen_width, screen_height))
pygame.display.set_caption("Fighting Game Input Buffer")

# Set up fonts
# font = pygame.font.Font(None, 36)  # this doesn't include arrows
# grab the first installed font
font = pygame.font.SysFont(pygame.font.get_fonts()[0], 36)

# Load Input Images
if False:
    #Cardinal Directions
    up_image = pygame.image.load("up.png")
    down_image = pygame.image.load("down.png")
    left_image = pygame.image.load("left.png")
    right_image = pygame.image.load("right.png")

    #Diagonal Directions
    upback_image = pygame.image.load("upback.png")
    upforward_image = pygame.image.load("upforward.png")
    downback_image = pygame.image.load("downback.png")
    downforward_image = pygame.image.load("downforward.png")

    #Attack Buttons
    light_image = pygame.image.load("L.png")
    medium_image = pygame.image.load("M.png")
    heavy_image = pygame.image.load("H.png")
    special_image = pygame.image.load("S.png")
    
    
else:  # render fonts
    color = pygame.Color("turquoise")
    #Cardinal Directions
    up_image = font.render("↑", True, color)
    down_image = font.render("↓", True, color)
    left_image = font.render("←", True, color)
    right_image = font.render("→", True, color)

    #Diagonal Directions - 
    upback_image = pygame.transform.rotate(up_image, 45)  # ↖ isn't in the font.
    upforward_image = pygame.transform.rotate(up_image, -45)
    downback_image = pygame.transform.rotate(down_image, -45)
    downforward_image = pygame.transform.rotate(down_image, 45)

    #Attack Buttons
    attack_color = pygame.Color("firebrick")
    light_image = font.render("L", True, attack_color)
    medium_image = font.render("M", True, attack_color)
    heavy_image = font.render("H", True, attack_color)
    special_image = font.render("S", True, attack_color)

# Dictionary to Map Keys to Images
key_to_image = {
    'w': up_image,
    'a': left_image,
    's': down_image,
    'd': right_image,
    'u': light_image,
    'i': medium_image,
    'j': heavy_image,
    'k': special_image,
    'wa': upback_image,   # W + A (diagonal)
    'wd': upforward_image,  # W + D (diagonal)
    'sa': downback_image, # S + A (diagonal)
    'sd': downforward_image,# S + D (diagonal)
}

# Input buffer parameters
buffer = []
buffer_store_time = 0.4  # in seconds
max_buffer_size = 10
last_input_time = pygame.time.get_ticks()

# List of special moves
special_moves = [
    {"name": "Flame Punch", "sequence": ['s', 'd', 'u']},
    {"name": "Tornado Kick", "sequence": ['s', 'a', 'u']},
    {"name": "Rising Uppercut", "sequence": ['d', 's', 'd', 'k']},
    {"name": "Surging Heat", "sequence": ['s', 's', 'k']}
    # Add more special moves here
]

# Flags to track if special moves are executed
special_move_executed = {move["name"]: False for move in special_moves}

# Main game loop
while True:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()
            sys.exit()
        elif event.type == pygame.KEYDOWN:
            # Add the key to the buffer
            key = pygame.key.name(event.key)
            # if key in ['w', 'a', 's', 'd']:
            if key in ['w', 'a', 's', 'd', 'i', 'j', 'k']:
              buffer.append(key)

            # Check if the buffer is full and replace the oldest input
            if len(buffer) > max_buffer_size:
                buffer.pop(0)

            # Update the last input time
            last_input_time = pygame.time.get_ticks()

    # Check if it's time to clear the buffer
    current_time = pygame.time.get_ticks()
    if current_time - last_input_time >= buffer_store_time * 1000:
        buffer.clear()
        special_move_executed = {move["name"]: False for move in special_moves}
    else:  # check the buffer for diagonals
        if 'w' in buffer and 'a' in buffer:  # W + A (diagonal)
            buffer.remove('w')
            buffer.remove('a')
            buffer.append('wa')
        if 'w' in buffer and 'd' in buffer:  # W + D (diagonal)
            buffer.remove('w')
            buffer.remove('d')
            buffer.append('wd')
        if 's' in buffer and 'a' in buffer:  # S + A (diagonal)
            buffer.remove('s')
            buffer.remove('a')
            buffer.append('sa')
        if 's' in buffer and 'd' in buffer:  # S + D (diagonal)
            buffer.remove('s')
            buffer.remove('d')
            buffer.append('sd')
        # Check for special moves
        for move in special_moves:
            if buffer[-len(move["sequence"]):] == move["sequence"]:
                special_move_executed[move["name"]] = True


    # Draw the buffer and special move messages on the screen
    screen.fill("white")

    # Render the images for each key in the buffer
    x_position = 20
    for key in buffer:
        if key in key_to_image:
            key_image = key_to_image[key]
            screen.blit(key_image, (x_position, 20))
            x_position += key_image.get_width() + 5  # Adjust the spacing

    y_position = 60
    for move in special_moves:
        if special_move_executed[move["name"]]:
            special_move_text = font.render(move["name"] + " Executed!", True, "red")
            screen.blit(special_move_text, (20, y_position))
            y_position += 40

    pygame.display.flip()
© www.soinside.com 2019 - 2024. All rights reserved.