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()