In my test game I made using pygame, I have 2 main characters you can choose from the start, an apple pie (ranged attack) and a pumpkin pie (Melee attack), and each one of these can use a "Special Attack", and the apple pie's special fires 1 projectile in each direction. This projectile uses the same image as the normal attack, which is loading correctly, but the super, although all of their collisions function correctly, they are completely invisible. Here's the function:
Variables
pie_projectile_image = pygame.image.load('Pie_projectile.png')
print("pie_projectile_image:", pie_projectile_image, pie_projectile_image.get_size())
pie_projectile_image = pygame.transform.scale(pie_projectile_image, (100, 100))
# Resize to 100x100 pixels
pie_projectile_rect = pie_projectile_image.get_rect()
Func List to store active super projectiles
super_projectiles = []
def SuperAttack(Pietype):
global SuperTimer, super_projectiles, isinvincible
if Pietype == "apple":
# Fire a barrage of projectiles in all directions
directions = ['left', 'right', 'up', 'down']
for direction in directions:
temp_projectile_rect = pie_projectile_image.get_rect()
temp_projectile_rect.center = pie_rect.center
super_projectiles.append((temp_projectile_rect, direction))
print("Super projectiles:", super_projectiles)
pygame.mixer.Sound.play(sound_attack_pie)
#In the main while loop...
if keys[pygame.K_e] and SuperTimer >= MaxSuperTimer:
SuperAttack(pie_type)
# Increment SuperTimer
if SuperTimer < MaxSuperTimer:
SuperTimer += 1
#More code...
# Update and render super projectiles
for projectile in super_projectiles[:]:
rect, direction = projectile
if direction == 'left':
rect.x -= 10
elif direction == 'right':
rect.x += 10
elif direction == 'up':
rect.y -= 10
elif direction == 'down':
rect.y += 10
# Check for collisions with MouthToFeed
for MouthToFeed_image, MouthToFeed_rect in MouthToFeed_list:
if rect.colliderect(MouthToFeed_rect):
pygame.mixer.Sound.play(sound_damage_MouthToFeed)
score += 1
MouthToFeed_rect.x = random.randint(0, width - 100)
MouthToFeed_rect.y = random.randint(0, height - 100)
distance = math.sqrt((MouthToFeed_rect.x - pie_rect.x) ** 2 +
(MouthToFeed_rect.y - pie_rect.y) ** 2)
while distance < min_distance:
MouthToFeed_rect.x = random.randint(0, width - 100)
MouthToFeed_rect.y = random.randint(0, height - 100)
distance = math.sqrt((MouthToFeed_rect.x - pie_rect.x) ** 2 +
(MouthToFeed_rect.y - pie_rect.y) ** 2)
super_projectiles.remove(projectile)
break
# Remove projectiles that leave the screen
if rect.x < 0 or rect.x > width or rect.y < 0 or rect.y > height:
super_projectiles.remove(projectile)
else:
# Render the projectile on the screen
screen.blit(pie_projectile_image, rect)
print("pie_projectile_image:", pie_projectile_image,
pie_projectile_image.get_size())
print("Rendering super projectile at:", rect)
I don't know why it doesn't work, and all the other code works like a charm. What's going on?
In my test game I made using pygame, I have 2 main characters you can choose from the start, an apple pie (ranged attack) and a pumpkin pie (Melee attack), and each one of these can use a "Special Attack", and the apple pie's special fires 1 projectile in each direction. This projectile uses the same image as the normal attack, which is loading correctly, but the super, although all of their collisions function correctly, they are completely invisible. Here's the function:
Variables
pie_projectile_image = pygame.image.load('Pie_projectile.png')
print("pie_projectile_image:", pie_projectile_image, pie_projectile_image.get_size())
pie_projectile_image = pygame.transform.scale(pie_projectile_image, (100, 100))
# Resize to 100x100 pixels
pie_projectile_rect = pie_projectile_image.get_rect()
Func List to store active super projectiles
super_projectiles = []
def SuperAttack(Pietype):
global SuperTimer, super_projectiles, isinvincible
if Pietype == "apple":
# Fire a barrage of projectiles in all directions
directions = ['left', 'right', 'up', 'down']
for direction in directions:
temp_projectile_rect = pie_projectile_image.get_rect()
temp_projectile_rect.center = pie_rect.center
super_projectiles.append((temp_projectile_rect, direction))
print("Super projectiles:", super_projectiles)
pygame.mixer.Sound.play(sound_attack_pie)
#In the main while loop...
if keys[pygame.K_e] and SuperTimer >= MaxSuperTimer:
SuperAttack(pie_type)
# Increment SuperTimer
if SuperTimer < MaxSuperTimer:
SuperTimer += 1
#More code...
# Update and render super projectiles
for projectile in super_projectiles[:]:
rect, direction = projectile
if direction == 'left':
rect.x -= 10
elif direction == 'right':
rect.x += 10
elif direction == 'up':
rect.y -= 10
elif direction == 'down':
rect.y += 10
# Check for collisions with MouthToFeed
for MouthToFeed_image, MouthToFeed_rect in MouthToFeed_list:
if rect.colliderect(MouthToFeed_rect):
pygame.mixer.Sound.play(sound_damage_MouthToFeed)
score += 1
MouthToFeed_rect.x = random.randint(0, width - 100)
MouthToFeed_rect.y = random.randint(0, height - 100)
distance = math.sqrt((MouthToFeed_rect.x - pie_rect.x) ** 2 +
(MouthToFeed_rect.y - pie_rect.y) ** 2)
while distance < min_distance:
MouthToFeed_rect.x = random.randint(0, width - 100)
MouthToFeed_rect.y = random.randint(0, height - 100)
distance = math.sqrt((MouthToFeed_rect.x - pie_rect.x) ** 2 +
(MouthToFeed_rect.y - pie_rect.y) ** 2)
super_projectiles.remove(projectile)
break
# Remove projectiles that leave the screen
if rect.x < 0 or rect.x > width or rect.y < 0 or rect.y > height:
super_projectiles.remove(projectile)
else:
# Render the projectile on the screen
screen.blit(pie_projectile_image, rect)
print("pie_projectile_image:", pie_projectile_image,
pie_projectile_image.get_size())
print("Rendering super projectile at:", rect)
I don't know why it doesn't work, and all the other code works like a charm. What's going on?
Share Improve this question asked Mar 25 at 9:35 solder _prosolder _pro 12 Answers
Reset to default -1The pie_projectile_image
might have an alpha transparency or be fully transparent, causing it to be invisible when rendered. Even though the image is loaded and scaled correctly, if the image itself has transparency (e.g., a PNG with an alpha channel), it can be invisible depending on how it's handled in Pygame.
Ensure the image is not fully transparent. You can also check the alpha channel using pie_projectile_image.get_at()
for specific pixels to see if they are fully transparent.
Alternative Solution: If you suspect the transparency might be the issue, you can try setting the alpha value manually or ensure the image is fully opaque by using convert()
or convert_alpha()
(the latter if it has an alpha channel):
# If your image has transparency, make sure it's handled properly
pie_projectile_image = pygame.image.load('Pie_projectile.png').convert_alpha()
This ensures the image is loaded with transparency handling (if it exists) and should be rendered correctly. If the image doesn't have transparency and still doesn't show up, the problem might lie elsewhere in how it's being rendered.
Bonus: You could also try a simple test: temporarily replace pie_projectile_image with a solid color to verify if the issue is related to the image or something else:
# Test with a solid red rectangle instead of an image
pygame.draw.rect(screen, (255, 0, 0), rect)
If the red rectangle shows up, it confirms that the issue lies with how the image is being loaded or rendered.
The problem seems to be with how you're storing and updating the super_projectiles
.
In your code, you are appending tuples to super_projectiles
:
super_projectiles.append((temp_projectile_rect, direction))
And then you're modifying rect inside your loop:
rect, direction = projectilerect.x += 10 # or other direction
However, pygame.Rect
is a mutable object, so the position does update, but you're not updating the tuple itself. Even though it seems to work because collisions are using the rect, your rendering logic is likely failing to update because you're storing and updating rects in-place without re-wrapping or tracking the changes properly.
But the most likely actual cause is this: you’re reusing the same image (pie_projectile_image
) for both normal and super projectiles — which is totally fine — but you're not scaling it before blitting, or the surface might be corrupted in memory if transformations were chained improperly.
Here's a clean and safer version of how you could handle this:
Fix
Make sure pie_projectile_image
is only loaded and transformed once, and stored properly. Ensure screen.blit()
is called after filling or updating the screen
(e.g., after screen.fill()
). Use a small class or dictionary to store projectile data for clarity. Example fix using a dict:
# Initialization
pie_projectile_image = pygame.transform.scale(pygame.image.load('Pie_projectile.png'), (100, 100))
# In SuperAttack()
super_projectiles.append({'rect': temp_projectile_rect, 'direction': direction})
# In main loop
for projectile in super_projectiles[:]:
rect = projectile['rect']
direction = projectile['direction']
# Move
if direction == 'left':
rect.x -= 10
elif direction == 'right':
rect.x += 10
elif direction == 'up':
rect.y -= 10
elif direction == 'down':
rect.y += 10
# Render
screen.blit(pie_projectile_image, rect)
Also, double-check that your screen.fill()
or background rendering isn't drawing after the blit
call, which would overwrite the projectile visuals.
Debug Tips:
Make sure nothing is blitting over your projectiles after rendering. Try temporarily changing the image color or drawing a red rectangle as a placeholder:
pygame.draw.rect(screen, (255, 0, 0), rect)
If that shows up, the issue is with the image rendering
发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744206308a4563119.html
评论列表(0条)