Pygame迷宫游戏二级关卡碰撞报错:IndexError: pixel index out of range
Hey Brady, let's break down why your game is crashing with that IndexError: pixel index out of range and fix it step by step.
What's Causing the Error?
That error pops up when you call DISPLAYSURF.get_at((x, y)) with coordinates that are outside the bounds of the screen (or the surface you're checking). Here's how it happens in your code:
- When you hold down a movement key (like left), your
spritexorspriteycan go negative, or exceed the screen's width/height (e.g.,spritexbecomes 1085 when the screen is only 1080 pixels wide). - When you check collision with
spritex + 10orspritey + 12in Level 2, even if the base coordinates are valid, adding those offsets can push the pixel check outside the screen. - You're checking pixels from the main display surface (
DISPLAYSURF), which has your sprite drawn on top—this means you might be checking the sprite's pixels instead of the maze's, leading to incorrect collision checks and accidental out-of-bounds calls.
Step-by-Step Fixes
1. Add Boundary Checks for Movement
First, make sure your character can never move outside the screen. You'll need to use the sprite's actual size to avoid cutting off the sprite at the edges:
# Add these lines right after loading your sprites sprite_w, sprite_h = sprite.get_size() sprite2_w, sprite2_h = sprite2.get_size()
Then update your movement logic to clamp the coordinates:
keys_pressed = pygame.key.get_pressed() if keys_pressed[K_LEFT]: if clevel == 1: spritex = max(0, spritex - 5) # Don't go left of the screen else: spritex = max(0, spritex - 5) elif keys_pressed[K_RIGHT]: if clevel == 1: # Don't go right past the screen minus sprite width spritex = min(width - sprite_w, spritex + 5) else: spritex = min(width - sprite2_w, spritex + 5) elif keys_pressed[K_UP]: if clevel == 1: spritey = max(0, spritey - 5) else: spritey = max(0, spritey - 5) elif keys_pressed[K_DOWN]: if clevel == 1: spritey = min(height - sprite_h, spritey + 5) else: spritey = min(height - sprite2_h, spritey + 5) elif keys_pressed[K_t]: spritex = 950 spritey = 20
2. Check Collisions Directly on the Maze Images
Instead of checking pixels from the main display (which has your sprite on it), check directly on the level1 or level2 surfaces. This is more accurate, and we'll add a check to ensure we never ask for a pixel outside the maze image:
# Level 1 collision fix if clevel == 1: # First, make sure coordinates are within the maze image bounds if 0 <= spritex < level1.get_width() and 0 <= spritey < level1.get_height(): # Check top-left and bottom-right corners of the sprite pixel_top_left = level1.get_at((spritex, spritey)) pixel_bottom_right = level1.get_at((spritex + sprite_w - 1, spritey + sprite_h - 1)) if pixel_top_left == (0, 0, 0, 255) or pixel_bottom_right == (0, 0, 0, 255): spritex = 7 spritey = 520 # Level 2 collision fix if clevel == 2: if 0 <= spritex < level2.get_width() and 0 <= spritey < level2.get_height(): pixel_top_left = level2.get_at((spritex, spritey)) pixel_bottom_right = level2.get_at((spritex + sprite2_w - 1, spritey + sprite2_h - 1)) if pixel_top_left == (0, 0, 0, 255) or pixel_bottom_right == (0, 0, 0, 255): spritex = 505 spritey = 4
3. Clean Up Unused Code
You can delete the empty sprite lines in your KEYDOWN event handler—they don't do anything, since you're already handling continuous movement with keys_pressed.
Why This Works
- Boundary clamping ensures your character never moves outside the screen, so you never try to access a pixel that doesn't exist.
- Checking the maze image directly avoids collision checks being messed up by your character sprite covering the maze pixels.
- Pre-checking coordinates before calling
get_at()guarantees you never ask for a pixel outside the maze image's bounds.
内容的提问来源于stack exchange,提问作者Brady

