如何将现有逐像素碰撞代码适配为支持敌人类列表?
No problem at all! Your existing IntersectPixels method is already generic enough to work with any two objects—we just need to wrap it in a loop to check against every enemy in your list. Here's a step-by-step breakdown of how to adjust your code:
Step 1: First, Ensure You Have an Enemy Class (If You Don't Already)
Assuming you're using a class to represent your enemies, it should hold all the properties your single enemy used to have:
public class Enemy { public Vector2 Position; public Texture2D Texture; public Color[] PixelData; // Initialize this with Texture.GetData() when creating the enemy }
Step 2: Modify Your Collision Detection Method to Accept an Enemy List
Instead of checking against one enemy, we'll loop through every enemy in the list and run your pixel collision check for each. You have two options here depending on your needs:
Option 1: Check if the Player Collides With Any Enemy (Return bool)
Use this if you just need to know if the player is touching at least one enemy:
public bool CheckPlayerEnemyCollision(Matrix playerTransform, Texture2D playerTexture, Color[] playerPixelData, List<Enemy> enemies) { foreach (var enemy in enemies) { // Create the transformation matrix for the current enemy Matrix enemyTransform = Matrix.CreateTranslation(new Vector3(enemy.Position, 0.0f)); // Run your existing pixel collision check if (game.IntersectPixels( playerTransform, playerTexture.Width, playerTexture.Height, playerPixelData, enemyTransform, enemy.Texture.Width, enemy.Texture.Height, enemy.PixelData)) { // Collision found—return immediately return true; } } // No collisions detected return false; }
Option 2: Get All Enemies the Player Is Colliding With (Return List<Enemy>)
Use this if you need to interact with all enemies the player is touching (e.g., deal damage to multiple enemies at once):
public List<Enemy> GetCollidingEnemies(Matrix playerTransform, Texture2D playerTexture, Color[] playerPixelData, List<Enemy> enemies) { List<Enemy> collidingEnemies = new List<Enemy>(); foreach (var enemy in enemies) { Matrix enemyTransform = Matrix.CreateTranslation(new Vector3(enemy.Position, 0.0f)); if (game.IntersectPixels( playerTransform, playerTexture.Width, playerTexture.Height, playerPixelData, enemyTransform, enemy.Texture.Width, enemy.Texture.Height, enemy.PixelData)) { collidingEnemies.Add(enemy); } } return collidingEnemies; }
Step 3: Optional (But Recommended) Performance Optimization
Pixel-perfect collision is expensive, especially with lots of enemies. Add a quick rectangle collision check first to skip pixel checks for enemies that aren't even close to the player:
public List<Enemy> GetCollidingEnemies(Matrix playerTransform, Texture2D playerTexture, Color[] playerPixelData, List<Enemy> enemies) { List<Enemy> collidingEnemies = new List<Enemy>(); // Create the player's bounding rectangle Rectangle playerBounds = new Rectangle( (int)playerTransform.Translation.X, (int)playerTransform.Translation.Y, playerTexture.Width, playerTexture.Height); foreach (var enemy in enemies) { // Create the enemy's bounding rectangle Rectangle enemyBounds = new Rectangle( (int)enemy.Position.X, (int)enemy.Position.Y, enemy.Texture.Width, enemy.Texture.Height); // Skip pixel check if rectangles don't overlap if (!playerBounds.Intersects(enemyBounds)) continue; // Only run pixel check if rectangles overlap Matrix enemyTransform = Matrix.CreateTranslation(new Vector3(enemy.Position, 0.0f)); if (game.IntersectPixels( playerTransform, playerTexture.Width, playerTexture.Height, playerPixelData, enemyTransform, enemy.Texture.Width, enemy.Texture.Height, enemy.PixelData)) { collidingEnemies.Add(enemy); } } return collidingEnemies; }
Important Notes
- Your original
IntersectPixelsmethod stays exactly the same—it's already designed to work with any two objects, so we don't need to change it at all. - Make sure each
Enemyinstance'sPixelDatais initialized correctly (callenemy.Texture.GetData(enemy.PixelData)when you create the enemy, just like you did for your single enemy before).
内容的提问来源于stack exchange,提问作者Elie Jamous

