-1

The figure moves in different directions: left, right, up, and down. While moving, it should also fire in the direction it's moving when the space bar is pressed. In this code, when moving to the right, the figure fires backwards, but should fire forwards. When moving to the left, the figure fires sideways, but should fire forwards. Could you please tell me how to fix this error? Here's the Python code. Images of the background and different positions of the figures are included. enter image description here enter image description here enter image description here enter image description here enter image description hereenter enter image description here enter image description here

import pygame, sys
import math # To calculate angles
 

pygame.init()
win = pygame.display.set_mode((400, 400))  # Window size 400x400 pixels
pygame.display.set_caption("Turning towards the target and shooting at it")
 
clock = pygame.time.Clock()
 
# Player's initial coordinates
x = 50
y = 50
 
# Player dimensions
width = 35
height = 35
 
# Speed ​​of movement
speed = 5
 
# List of all active bullets
bullets = []
 
# Bullet speed constant
bullet_speed = 8
 
# The current direction of the player's movement (for animation and movement)
player_move_direction = None # 'right', 'left', 'up', 'down', None
 
# The player's gaze direction (where the character is looking, orienting towards the target)
player_look_direction = None # 'right', 'left', 'up', 'down' (упрощенно)
 
# Target coordinates
target_x = 350
target_y = 350
target_radius = 15
 
# --- Sprites ---
# To make things simple, we'll use walkRight and walkLeft.
# In a real game, you would need sprites for each viewing direction.
# or a rotation mechanism.
try:
    walkRight = [pygame.image.load('Dan_Right1.png'), pygame.image.load('Dan_Right2.png'), pygame.image.load('Dan_Right3.png'), pygame.image.load('Dan_Right4.png'), pygame.image.load('Dan_Right5.png')]
    walkLeft = [pygame.image.load('Dan_Left1.png'), pygame.image.load('Dan_Left2.png'), pygame.image.load('Dan_Left3.png'), pygame.image.load('Dan_Left4.png'), pygame.image.load('Dan_Left5.png')]
    bg = pygame.image.load('Picture.jpg')  # Фон игры
    playerStand = pygame.image.load('Dan_Another.png')  # Изображение стоящего персонажа
 
    # --- Optional: sprites for other viewing directions ---
    # player_up_sprite = pygame.image.load('Dan_Up.png')
    # player_down_sprite = pygame.image.load('Dan_Down.png')
 
except pygame.error as e:
    print(f"Error loading image:{e}")
    print("Make sure the image files are present.")
    pygame.quit()
    sys.exit()
 
animCount = 0
 
# Function for determining the direction of gaze on a target
def get_look_direction(player_x, player_y, target_x, target_y):
    dx = target_x - player_x
    dy = target_y - player_y
 
    # We check whether the target is level or vertical
    if abs(dx) < 10: # If the player and the target are almost on the same vertical line
        if dy > 0: return 'down'
        elif dy < 0: return 'up'
        else: return player_look_direction if player_look_direction else 'right' # If at one point, we maintain the direction
    elif abs(dy) < 10: # If the player and the target are almost on the same horizontal line
        if dx > 0: return 'right'
        elif dx < 0: return 'left'
        else: return player_look_direction if player_look_direction else 'right'
 
    # A simplified definition: If the target is to the right, look right. If it's to the left, look left.
    # For more precise turning, you need to use angles and more sprites.
    if dx > 0:
        return 'right'
    elif dx < 0:
        return 'left'
    else: # If the target is straight, look in the current direction of gaze
        return player_look_direction if player_look_direction else 'right'
 
# The function of drawing a character taking into account the direction of view
def draw_player(player_x, player_y, look_direction):
    global animCount
 
    # Determine which sprite to use for rendering
    if look_direction == 'right':
        # If we look to the right, we use the walkRight sprites.
        # If the character moves to the right and looks to the right, it's a walking animation.
        # If the character is standing and looking to the right, ignore animCount and use playerStand
        if player_move_direction == 'right':
            win.blit(walkRight[animCount // 6], (player_x, player_y))
            animCount += 1
            if animCount >= len(walkRight) * 6: animCount = 0
        else:
            win.blit(playerStand, (player_x, player_y)) # Standing, but looking to the right
            animCount = 0 # Resetting the animation
 
    elif look_direction == 'left':
        # If we look to the left, we use the walkLeft sprites.
        if player_move_direction == 'left':
            win.blit(walkLeft[animCount // 6], (player_x, player_y))
            animCount += 1
            if animCount >= len(walkLeft) * 6: animCount = 0
        else:
            win.blit(playerStand, (player_x, player_y)) # Standing, but looking to the left
            animCount = 0 # Resetting the animation
 
   
    elif look_direction == 'up':
         # Draw a sprite looking up
        # If the player moves up, we use animation
        if player_move_direction == 'up':
            win.blit(player_up_walk[animCount // 6], (player_x, player_y))
            animCount += 1
            if animCount >= len(player_up_walk) * 6: animCount = 0
        else:
            win.blit(player_up_sprite, (player_x, player_y))
            animCount = 0
    elif look_direction == 'down':
        # Draw a sprite looking down
         if player_move_direction == 'down':
            win.blit(player_down_walk[animCount // 6], (player_x, player_y))
            animCount += 1
            if animCount >= len(player_down_walk) * 6: animCount = 0
         else:
             win.blit(player_down_sprite, (player_x, player_y))
             animCount = 0
 
    else: # If the player is standing and the facing direction is undefined (or None)
        win.blit(playerStand, (player_x, player_y))
        animCount = 0 # Resetting the animation
 
# Window drawing function
def drawWindow():
    win.blit(bg, (0, 0)) # Drawing the background
 
    # Let's draw a target
    pygame.draw.circle(win, (255, 0, 0), (target_x, target_y), target_radius)
 
    # Draw a character based on the direction of the gaze
    draw_player(x, y, player_look_direction)
 
    # Drawing all existing bullets
    for bullet in bullets[:]:
        # The bullet fires in the direction of the player's look (player_look_direction)
        if bullet['direction'] == 'right':
            pygame.draw.rect(win, (255, 255, 255), (bullet['x'], bullet['y'], 10, 5))
            bullet['x'] += bullet_speed
        elif bullet['direction'] == 'left':
            pygame.draw.rect(win, (255, 255, 255), (bullet['x'], bullet['y'], 10, 5))
            bullet['x'] -= bullet_speed
        elif bullet['direction'] == 'up':
            pygame.draw.rect(win, (255, 255, 255), (bullet['x'], bullet['y'], 5, 10))
            bullet['y'] -= bullet_speed
        elif bullet['direction'] == 'down':
            pygame.draw.rect(win, (255, 255, 255), (bullet['x'], bullet['y'], 5, 10))
            bullet['y'] += bullet_speed
 
        # Removing bullets that go beyond the screen
        if (bullet['x'] < 0 or bullet['x'] > 400 or bullet['y'] < 0 or bullet['y'] > 400):
            bullets.remove(bullet)
 
    pygame.display.update() # Refreshing the screen
 
run = True
while run:
    clock.tick(30)
 
    moved_this_frame = False # Flag indicating whether the player was moving in this frame
 
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            run = False
        elif event.type == pygame.KEYDOWN:
            if event.key == pygame.K_SPACE:
                # --- СТРЕЛЬБА В НАПРАВЛЕНИИ ВЗГЛЯДА ---
                # The bullet is fired from the front of the character looking at the target.
                if player_look_direction == 'right':
                    # We start the bullet from the right side of the character
                    bullets.append({'x': x + width, 'y': y + (height // 2) - 2, 'direction': 'right'})
                elif player_look_direction == 'left':
                    # We start the bullet from the left of the character
                    bullets.append({'x': x - 10, 'y': y + (height // 2) - 2, 'direction': 'left'})
                elif player_look_direction == 'up':
                    # We start the bullet from the top of the character
                    bullets.append({'x': x + (width // 2) - 2, 'y': y - 10, 'direction': 'up'})
                elif player_look_direction == 'down':
                    # We start the bullet from below the character
                    bullets.append({'x': x + (width // 2) - 2, 'y': y + height, 'direction': 'down'})
                else: # If the player is standing and the direction of view is not defined
                    # Стреляем по умолчанию вправо
                    bullets.append({'x': x + width, 'y': y + (height // 2) - 2, 'direction': 'right'})
 
    keys = pygame.key.get_pressed()
 
    # --- Updating the player's MOVEMENT direction---
    # This only affects where the sprite moves and what walking animation to show.
    if keys[pygame.K_RIGHT]:
        player_move_direction = 'right'
        x += speed
        moved_this_frame = True
    elif keys[pygame.K_LEFT]:
        player_move_direction = 'left'
        x -= speed
        moved_this_frame = True
    elif keys[pygame.K_UP]:
        player_move_direction = 'up'
        y -= speed
        moved_this_frame = True
    elif keys[pygame.K_DOWN]:
        player_move_direction = 'down'
        y += speed
        moved_this_frame = True
 
    # If the player has not moved, reset the direction of movement
    if not moved_this_frame:
        player_move_direction = None
 
    # --- Updating the direction of the LOOK at the target ---
    # This always happens, regardless of movement.
    player_look_direction = get_look_direction(x, y, target_x, target_y)
 
    drawWindow() 
 
pygame.quit()
sys.exit()
0

1 Answer 1

-1

i think the problem is not in the bullet code, it's in the function get_look_direction()

try remove this part entirely:

player_look_direction = get_look_direction(x, y, target_x, target_y)

replace it with:

if player_move_direction is not None:
    player_look_direction = player_move_direction
else:
    player_look_direction = get_look_direction(x, y, target_x, target_y)
New contributor
ov4u is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.
Sign up to request clarification or add additional context in comments.

1 Comment

Thank you for answer! Unfortunately, it didn't help. I followed your advice and replaced the piece of code you recommended. But when I run the program, I now only get a black window with no background or shape.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.