python 使暂停按钮只执行一次[重复]

kknvjkwl  于 2023-09-29  发布在  Python
关注(0)|答案(1)|浏览(90)

此问题已在此处有答案

How to create a pause button in Pygame?(1个答案)
Making a pause screen(1个答案)
pausing/ Unpausing in Pygame(3个答案)
11小时前关闭

import sys
import math
import random
import pygame
from svglib.svglib import svg2rlg
from reportlab.graphics import renderPDF
from io import BytesIO

# Initialize Pygame
pygame.init()

# Constants for the game window
WINDOW_WIDTH = 800
WINDOW_HEIGHT = 600
WINDOW_TITLE = "Zombie Survival Game"

# Constants for the player
PLAYER_WIDTH = 64
PLAYER_HEIGHT = 36
PLAYER_INITIAL_X = (WINDOW_WIDTH - PLAYER_WIDTH) // 2
PLAYER_INITIAL_Y = WINDOW_HEIGHT - PLAYER_HEIGHT - 10

# Constants for the bullet
BULLET_SIZE = 10
BULLET_RADIUS = BULLET_SIZE // 2
BULLET_SPEED = 10

# Customizations
BASE_PLAYER_SPEED = 3  # Base speed of the player
RECOIL = 10  # Recoil caused by each bullet
GUN_TIP_OFFSET = 5  # Offset from the center to the tip of the gun
BULLET_FIRE_RATE = 15  # Time between each bullet (in frames)
DASH_COOLDOWN = 60  # Cooldown for the dash in frames

# Modify the apply_bullet_knockback function to call update_player_money when a zombie dies
def apply_bullet_knockback(zombie, angle, knockback_distance):
    zombie[0] += knockback_distance * math.cos(angle)
    zombie[1] += knockback_distance * math.sin(angle)
    
    # Check if the zombie is dead (health <= 0)
    if zombie[2] <= 0:
        update_player_money(zombie[6])  # Pass the zombie damage to update player money

# Modify the update_player_money function to properly update player money
def update_player_money(zombie_damage):
    global player_money
    # Define the money value for each zombie damage
    zombie_money_values = {
        10: 5,  # Example: 10 damage zombie gives 5 money
        20: 30,  # Adjust these values based on your game's balance
        5: 10,
        30: 250
    }
   
    # Check if the zombie damage is valid
    if zombie_damage in zombie_money_values:
        player_money += zombie_money_values[zombie_damage]

# Function to display damage indicator on a zombie
def display_damage_indicator(zombie_x, zombie_y, damage, zombie_size):
    font = pygame.font.Font(None, 24)
    text = font.render("-" + str(damage), True, (255, 0, 0))
    screen.blit(text, (zombie_x + zombie_size[0] // 4, zombie_y - 10))  # Adjusted position for damage indicator

# Constants for colors
LIGHT_GREY = (200, 200, 200)

# Add a new variable to track the change in brightness
brightness_change = 0

# Load player image
player_image = pygame.image.load('player.svg')  # Make sure the path is correct
player_image = pygame.transform.scale(player_image, (PLAYER_WIDTH, PLAYER_HEIGHT))

# Load different zombie images and their attributes
zombie_attributes = {
    "normal": {"image": pygame.image.load('zombie_normal.svg'), "size": (PLAYER_WIDTH, PLAYER_HEIGHT),
               "health": 50, "speed": 2, "damage": 10},
    "strong": {"image": pygame.image.load('zombie_strong.svg'), "size": (PLAYER_WIDTH + 20, PLAYER_HEIGHT + 20),
               "health": 100, "speed": 1, "damage": 20},
    "fast": {"image": pygame.image.load('zombie_fast.svg'), "size": (PLAYER_WIDTH - 20, PLAYER_HEIGHT - 20),
             "health": 30, "speed": 3, "damage": 5},
    "boss": {"image": pygame.image.load('zombie_boss.svg'), "size": (PLAYER_WIDTH + 50, PLAYER_HEIGHT + 50),
             "health": 200, "speed": 0.5, "damage": 30}
}

# Change bullet properties
BULLET_RADIUS = BULLET_SIZE // 2

# Bullet list to store active bullets
bullets = []

# List to store zombie attributes [x, y, health, speed, image, size, damage]
zombies = []

# Variable to track whether the game is paused
game_paused = False

# Initialize bullet fire timer
bullet_fire_timer = 0

# Constants for health and damage
PLAYER_INITIAL_HEALTH = 100
BULLET_DAMAGE = 5

# Add a global variable for bullet knockback distance
BULLET_KNOCKBACK_DISTANCE = 5  # Adjust this value as needed

# Initialize player attributes
player_x = PLAYER_INITIAL_X
player_y = PLAYER_INITIAL_Y
player_health = PLAYER_INITIAL_HEALTH

# Initialize player money
player_money = 0

# Load the higher-resolution shop image
shop_image = pygame.image.load("shop.svg")
shop_image = pygame.transform.scale(shop_image, (600, 600))  # Adjust size as needed

# Adjust the shop position to the right
shop_x = (WINDOW_WIDTH - shop_image.get_width()) // 2 + 50  # Shifted 50 pixels to the right
shop_y = (WINDOW_HEIGHT - shop_image.get_height()) // 2

# Variables for shop animation
shop_y = WINDOW_HEIGHT  # Starting position off-screen
shop_target_y = (WINDOW_HEIGHT - 600) // 2  # Target position at the center of the screen
shop_speed = 10  # Speed of the shop animation

# Variable to track whether the shop is currently displayed
shop_displayed = False

# Add a new variable to track if the shop is currently moving
shop_moving = False

# Create the game window
screen = pygame.display.set_mode((WINDOW_WIDTH, WINDOW_HEIGHT))
pygame.display.set_caption(WINDOW_TITLE)

# Dictionary to store zombie type percentages
ZOMBIE_PERCENTAGES = {}

# Function to spawn a random zombie based on percentages
def spawn_random_zombie():
    global zombie_spawn_timer

    if not ZOMBIE_PERCENTAGES:
        return

    total_percentage = sum(ZOMBIE_PERCENTAGES.values())
    rand_num = random.randint(1, total_percentage)
    cumulative_percentage = 0

    for zombie_type, percentage in ZOMBIE_PERCENTAGES.items():
        cumulative_percentage += percentage
        if rand_num <= cumulative_percentage:
            attributes = zombie_attributes[zombie_type]
            spawn_zombie(zombie_type, attributes)
            break

# Function to modify the spawn rate
def modify_spawn_rate(spawn_rate_change):
    global ZOMBIE_SPAWN_INTERVAL
    ZOMBIE_SPAWN_INTERVAL = max(1, ZOMBIE_SPAWN_INTERVAL + spawn_rate_change)  # Ensure it's at least 1

# Initialize zombie spawn interval
ZOMBIE_SPAWN_INTERVAL = 250  # Increase this value to reduce spawn rate
zombie_spawn_timer = 0  # Initialize zombie spawn timer

# Modify zombie spawn rate
modify_spawn_rate(-10)  # Call after defining ZOMBIE_SPAWN_INTERVAL

# Function to modify zombie percentages
def modify_zombie_percentages(zombie_type, new_percentage):
    global ZOMBIE_PERCENTAGES
    new_percentage = max(0.0, min(100.0, float(new_percentage)))  # Ensure percentage is in valid range
    ZOMBIE_PERCENTAGES[zombie_type] = new_percentage

# Modify zombie percentages (adjust as needed)
modify_zombie_percentages("normal", 100.0)
modify_zombie_percentages("strong", 80.0)
modify_zombie_percentages("fast", 60.0)
modify_zombie_percentages("boss", 15.0)

# Function to move zombies towards the player
def move_zombies_towards_player():
    for zombie in zombies:
        if zombie[2] <= 0:
            # Zombie is dead, don't move it
            continue

        # Calculate the angle between the zombie and the player
        angle = math.atan2(player_y - zombie[1], player_x - zombie[0])

        # Move the zombie towards the player
        zombie[0] += math.cos(angle) * zombie[3]  # Update x position
        zombie[1] += math.sin(angle) * zombie[3]  # Update y position

# Function to handle player being hit by a zombie
def player_hit_by_zombie():
    global player_health
    global invincible_timer
    if invincible_timer <= 0:
        # Check collision with zombies
        player_rect = pygame.Rect(player_x, player_y, PLAYER_WIDTH, PLAYER_HEIGHT)
        zombie_dealt_damage = False  # Track if a zombie has dealt damage

        for zombie in zombies:
            if zombie[2] <= 0:
                # Zombie is dead, skip
                continue
            zombie_rect = pygame.Rect(zombie[0], zombie[1], zombie[5][0], zombie[5][1])

            if player_rect.colliderect(zombie_rect):
                # Reduce player health if a zombie is in contact
                if not zombie_dealt_damage:
                    player_health -= zombie[6]
                    invincible_timer = 5 * 60  # 5 seconds at 60 FPS
                    zombie_dealt_damage = True

# Timer to control dash animation
dash_timer = 0
DASH_DURATION = 10
dash_cooldown = 0

# Function to handle player dash
def player_dash():
    global player_x, player_y, dash_timer, dash_cooldown

    if dash_cooldown <= 0 and dash_timer > 0:
        dash_distance = 10
        angle_deg = math.degrees(dash_angle)
        if 180 <= angle_deg <= 360:
            # Adjust the angle for dashing up
            player_x -= dash_distance * math.cos(dash_angle)
            player_y -= dash_distance * math.sin(dash_angle)
        else:
            # Adjust the angle for dashing down
            player_x += dash_distance * math.cos(dash_angle)
            player_y += dash_distance * math.sin(dash_angle)
        # Limit the player position within the window
        player_x = max(0, min(player_x, WINDOW_WIDTH - PLAYER_WIDTH))
        player_y = max(0, min(player_y, WINDOW_HEIGHT - PLAYER_HEIGHT))
        dash_timer -= 1
        if dash_timer == 0:
            dash_cooldown = DASH_COOLDOWN

# Function to check if a point is inside a rectangle
def is_point_inside_rect(point_x, point_y, rect_x, rect_y, rect_width, rect_height):
    return rect_x <= point_x <= rect_x + rect_width and rect_y <= point_y <= rect_y + rect_height

# Function to spawn a specific type of zombie
def spawn_zombie(zombie_type, attributes):
    # Randomly spawn the zombie off-screen
    if random.choice([True, False]):
        zombie_x = random.choice([-attributes["size"][0], WINDOW_WIDTH])
        zombie_y = random.randint(0, WINDOW_HEIGHT - attributes["size"][1])
    else:
        zombie_x = random.randint(0, WINDOW_WIDTH - attributes["size"][0])
        zombie_y = random.choice([-attributes["size"][1], WINDOW_HEIGHT])

    zombies.append([zombie_x, zombie_y, attributes["health"], attributes["speed"],
                    attributes["image"], attributes["size"], attributes["damage"]])
    
# Add a new variable to track if the shop is currently moving
shop_moving = False

# Main game loop
running = True
clock = pygame.time.Clock()

# Game over font
game_over_font = pygame.font.Font(None, 100)

# Initialize invincibility timer
invincible_timer = 0

# Initialize zombie spawn timer
zombie_spawn_timer = 0

# Stamina bar constants
MAX_STAMINA = 200
STAMINA_REGEN_RATE = 1  # Stamina regenerated per frame when not sprinting
STAMINA_DEPLETION_RATE = 2  # Stamina depleted per frame when sprinting
STAMINA_DASH_COST = 50  # Stamina cost for dashing
stamina = MAX_STAMINA  # Initial stamina

# Add this variable to ignore 'P' key during shop animation
ignore_p_key = False

while running:
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            running = False
            
    # Check if the game is paused
    if not game_paused:
        # Clear the screen with light grey
        screen.fill(LIGHT_GREY)

        keys = pygame.key.get_pressed()

        # Get the mouse position
        mouse_x, mouse_y = pygame.mouse.get_pos()
    
        # Update zombie spawn timer and spawn zombies
        zombie_spawn_timer -= 1
        if zombie_spawn_timer <= 0:
            spawn_random_zombie()
            zombie_spawn_timer = ZOMBIE_SPAWN_INTERVAL

        # Calculate the angle between the player and the cursor
        angle = math.atan2(mouse_y - (player_y + PLAYER_HEIGHT / 2), mouse_x - (player_x + PLAYER_WIDTH / 2))
        angle = math.degrees(angle)

        # Rotate the player image
        rotated_player = pygame.transform.rotate(player_image, -angle)
        rotated_rect = rotated_player.get_rect(center=(player_x + PLAYER_WIDTH / 2, player_y + PLAYER_HEIGHT / 2))

        # Get the keys pressed (WASD for movement)
        keys = pygame.key.get_pressed()
        if keys[pygame.K_a]:
            player_x -= BASE_PLAYER_SPEED
        if keys[pygame.K_d]:
            player_x += BASE_PLAYER_SPEED
        if keys[pygame.K_w]:
            player_y -= BASE_PLAYER_SPEED
        if keys[pygame.K_s]:
            player_y += BASE_PLAYER_SPEED

        # Limit the player position within the window
        player_x = max(0, min(player_x, WINDOW_WIDTH - PLAYER_WIDTH))
        player_y = max(0, min(player_y, WINDOW_HEIGHT - PLAYER_HEIGHT))

        # Dash mechanic
        global dash_angle
        if keys[pygame.K_SPACE] and stamina >= STAMINA_DASH_COST and dash_cooldown <= 0:
            # Dash towards the cursor
            dash_angle = math.atan2(mouse_y - (player_y + PLAYER_HEIGHT / 2), mouse_x - (player_x + PLAYER_WIDTH / 2))
            dash_timer = DASH_DURATION
            stamina -= STAMINA_DASH_COST
        else:
            # Regenerate stamina if not dashing
            stamina = min(MAX_STAMINA, stamina + STAMINA_REGEN_RATE)

        # Update cooldowns
        if dash_cooldown > 0:
            dash_cooldown -= 1

        # Update and draw bullets
        new_bullets = []
        for bullet in bullets:
            bullet[0] += math.cos(math.radians(bullet[2])) * BULLET_SPEED
            bullet[1] += math.sin(math.radians(bullet[2])) * BULLET_SPEED

            # Check if bullet is off-screen or hits a zombie
            bullet_rect = pygame.Rect(bullet[0] - BULLET_RADIUS, bullet[1] - BULLET_RADIUS, BULLET_SIZE, BULLET_SIZE)
            bullet_hit_zombie = False

            for zombie in zombies:
                if zombie[2] <= 0:
                    # Zombie is dead, skip
                    continue

                zombie_rect = pygame.Rect(zombie[0], zombie[1], zombie[5][0], zombie[5][1])

                if bullet_rect.colliderect(zombie_rect):
                    # Reduce zombie health
                    zombie[2] -= BULLET_DAMAGE
                    if zombie[2] <= 0:
                        zombies.remove(zombie)
                    bullet_hit_zombie = True

                    # Apply knockback to zombie
                    apply_bullet_knockback(zombie, math.radians(bullet[2]), RECOIL)
                
                    # Display damage indicator on zombie
                    display_damage_indicator(bullet[0], bullet[1], BULLET_DAMAGE, (BULLET_SIZE, BULLET_SIZE))

            if not bullet_hit_zombie and 0 <= bullet[0] < WINDOW_WIDTH and 0 <= bullet[1] < WINDOW_HEIGHT:
                # Draw the bullet image only if it didn't hit a zombie and is on-screen
                bullet_image = pygame.image.load('bullet.svg')  # Make sure the path is correct
                bullet_image = pygame.transform.scale(bullet_image, (BULLET_SIZE, BULLET_SIZE))
                screen.blit(bullet_image, (bullet[0] - BULLET_RADIUS, bullet[1] - BULLET_RADIUS))
   
            # Remove bullets that are off-screen or hit a zombie
            if 0 <= bullet[0] < WINDOW_WIDTH and 0 <= bullet[1] < WINDOW_HEIGHT and not bullet_hit_zombie:
                new_bullets.append(bullet)
        bullets = new_bullets

        # Fire bullets based on the fire rate
        bullet_fire_timer += 1
        if bullet_fire_timer >= BULLET_FIRE_RATE:
            mouse_click = pygame.mouse.get_pressed()
            if mouse_click[0] == 1:
                # Fire a bullet from the tip of the gun
                bullet_x = player_x + PLAYER_WIDTH / 2 + GUN_TIP_OFFSET * math.cos(math.radians(-angle))
                bullet_y = player_y + PLAYER_HEIGHT / 2 + GUN_TIP_OFFSET * math.sin(math.radians(-angle))
                bullets.append([bullet_x, bullet_y, angle])
                bullet_fire_timer = 0

        # Move zombies towards the player
        move_zombies_towards_player()
    
        # Check if the "p" key is pressed to toggle the shop display
        if keys[pygame.K_p] and not shop_moving:  # Only toggle when shop is not moving
            shop_moving = True
            shop_displayed = not shop_displayed
            shop_speed = -shop_speed if shop_displayed else shop_speed

        # Update the shop animation
        if shop_moving:
            if shop_displayed:
                if shop_y > shop_target_y:
                    shop_y -= shop_speed
                    if shop_y <= shop_target_y:
                        shop_y = shop_target_y
                        shop_moving = False  # Stop the shop movement
            else:
                if shop_y < WINDOW_HEIGHT:
                    shop_y += shop_speed
                    if shop_y >= WINDOW_HEIGHT:
                        shop_y = WINDOW_HEIGHT
                        shop_moving = False  # Stop the shop movement

        # Update and draw zombies
        for zombie in zombies:
            if zombie[2] <= 0:
                # Zombie is dead, don't add it to the new zombie list
                continue

            # Calculate the angle between the zombie and the player
            angle = math.atan2(player_y - zombie[1], player_x - zombie[0])
            angle = math.degrees(angle)

            # Rotate the zombie image
            rotated_zombie = pygame.transform.rotate(zombie[4], -angle)
            zombie_rect = rotated_zombie.get_rect(center=(zombie[0] + zombie[5][0] / 2, zombie[1] + zombie[5][1] / 2))

            # Draw the rotated zombie
            screen.blit(rotated_zombie, zombie_rect.topleft)

        # Check if player is hit by a zombie
        player_hit_by_zombie()

        # Display player health
        font = pygame.font.Font(None, 36)
        text = font.render("Player Health: {}".format(player_health), True, (255, 0, 0))
        screen.blit(text, (10, 10))

        # Display stamina bar
        pygame.draw.rect(screen, (0, 255, 0), (10, 50, stamina, 20))
        pygame.draw.rect(screen, (255, 0, 0), (10 + stamina, 50, MAX_STAMINA - stamina, 20))
    
        # Display player money
        font = pygame.font.Font(None, 36)
        money_text = font.render("Money: ${}".format(player_money), True, (0, 0, 255))
        screen.blit(money_text, (10, 80))
    
        # Draw the player
        screen.blit(rotated_player, rotated_rect.topleft)
    
    # Draw the higher-resolution shop icon
    screen.blit(shop_image, (shop_x, shop_y))
    if shop_moving or shop_displayed:
        # Update the shop position based on the movement speed
        shop_y += shop_speed
        # Check if the shop has reached its target position or gone off-screen
        if shop_speed > 0 and shop_y >= WINDOW_HEIGHT:
            shop_y = WINDOW_HEIGHT
            shop_moving = False  # Stop the shop movement
        elif shop_speed < 0 and shop_y <= shop_target_y:
            shop_y = shop_target_y
            shop_moving = False  # Stop the shop movement

    # Check if the game is paused and adjust brightness
    if game_paused:
        # Create a transparent surface to darken the screen
        darken_surface = pygame.Surface((WINDOW_WIDTH, WINDOW_HEIGHT), pygame.SRCALPHA)
        darken_surface.fill((35, 35, 35, 35))  # Adjust alpha for desired darkness
        screen.blit(darken_surface, (0, 0))

    # Update the display
    pygame.display.flip()
    clock.tick(60)

    # Check for key presses to toggle pause
    keys = pygame.key.get_pressed()
    if keys[pygame.K_p]:
        # Toggle the game pause state and handle game state accordingly
        game_paused = not game_paused

    # Check if player is alive
    if player_health <= 0:
        # If the game is paused, start the 3-second timer
        if game_paused:
            game_over_timer = 3 * 60  # 3 seconds at 60 FPS
        else:
            # Restart the game after 3 seconds
            pygame.display.flip()
            pygame.time.wait(3000)

            # Reset game
            bullets = []
            zombies = []
            player_health = PLAYER_INITIAL_HEALTH
            player_x = PLAYER_INITIAL_X
            player_y = PLAYER_INITIAL_Y
            stamina = MAX_STAMINA
            invincible_timer = 0
            zombie_spawn_timer = 0
            bullet_fire_timer = 0

    # Update the invincibility timer
    if invincible_timer > 0:
        invincible_timer -= 1

    # Handle player dash
    player_dash()
    
    zombie_spawn_timer -= 1

# Quit Pygame and close the window when the game loop ends
pygame.quit()
sys.exit()

在上面的代码中,我希望它在商店动画期间,我不按任何“p”键,当商店在中间出现时,然后当我们按“p”时,商店离开,在商店离开的动画期间,忽略任何“p”键。问题是,我可以举行的p按钮和游戏只是暂停游戏来回和商店来在慢动作。主要目的是当玩家按下“P”按钮时,商店出现并使游戏暂停,以便玩家可以购买物品,并且在他完成购买之后,他可以再次按下“P”按钮再次玩游戏。如果可能的话,在玩家离开商店后,一个3秒的计时器会出现在屏幕上,然后重新开始游戏,让玩家看到他周围的环境。请我需要的答案快,我必须提交此代码的竞争。
我试过很多方法,但都不管用

nkhmeac6

nkhmeac61#

您正在多次检查P键。在这里检查p时,您还需要检查您的商店标志:

# Check for key presses to toggle pause
keys = pygame.key.get_pressed()
if keys[pygame.K_p]:

比如说

if keys[pygame.K_p] and not shop_displayed:

相关问题