2013-06-04 3 views
2

XNA 4.0을 처음 접했을 때 플레이어가 적에게 점프하여 죽일 수있는 슈퍼 마리오 브라더스 유형의 게임을 만들려고합니다. 그러나 나는 적을 죽이는 것에 문제가있다. 내 캐릭터 (rectangleBox) 아래에 15px 직사각형을 만들어 적의 사각형과 교차하면 enemy.alive = false이 발생합니다. 이 경우 enemy.alive = false 적을 뽑지 않습니다. 그러나 이것은 직사각형이 교차하는 때에 만 적용됩니다. 적군이 rectangleBox의 경계를 떠나면 다시 나타납니다. 적을 영구히 삭제하여 게임을 다시 시작할 때까지 다시 부활시키지 않으려면 어떻게합니까?XNA에서 적의 스프라이트를 영구히 삭제하는 방법

적 클래스 코드 :

using System; 
using System.Collections.Generic; 
using System.Linq; 
using Microsoft.Xna.Framework; 
using Microsoft.Xna.Framework.Audio; 
using Microsoft.Xna.Framework.Content; 
using Microsoft.Xna.Framework.GamerServices; 
using Microsoft.Xna.Framework.Graphics; 
using Microsoft.Xna.Framework.Input; 
using Microsoft.Xna.Framework.Media; 

namespace notDMIG 
{ 
    class Enemy 
    { 
     public Texture2D texture; 
     public Rectangle bounds; 
     public Vector2 position; 
     public Vector2 velocity; 
     public float timer = 0.0f; 
     public int spriteNum = 1; 
     public int maxSpriteNum; 
     public bool alive; 

     public Enemy(Texture2D Texture, Vector2 Position, Vector2 Velocity, int maxsprites) 
     { 
      texture = Texture; 
      position = Position; 
      velocity = Velocity; 
      maxSpriteNum = maxsprites; 
      alive = false; 
     } 
    } 
} 

은 Game1.cs 적 관련 코드

protected override void Update(GameTime gameTime) 
{ 
    foreach (Enemy enemy in Enemies) 
    { 
     enemy.alive = true; 

     Rectangle rectangleBox = new Rectangle((int)player.position.X, (int)player.position.Y + player.sprite.Height + 15, player.sprite.Width, 1); 
     Rectangle enemyBox = new Rectangle((int)enemy.position.X, (int)enemy.position.Y, enemy.texture.Width, enemy.texture.Height); 

     if (enemy.alive == true) 
     { 
      if (rectangleBox.Intersects(enemyBox)) 
      { 
       enemy.alive = false; 

       continue; 
      } 
     } 
    } 
} 

protected override void Draw(GameTime gameTime) 
{ 
    foreach (Enemy enemy in Enemies) 
    { 
     if (enemy.alive == true) 
     { 
      spriteBatch.Draw(enemy.texture, enemy.position, Color.White); 
     } 
    } 
} 

답변

3

대신 Update 메서드에서 enemy.alive = true를 사용하는 대신이 메서드를 initialize 메서드에 배치하는 것이 좋습니다. initialize 메서드는 업데이트 메서드가 초당 수백 번 호출되는 동안 프로그램의 시작 부분 (모든 적을 기술적으로 살아 있어야 함)에서만 호출됩니다. 그래서 당신의 프로그램이하는 것은 "적과 플레이어가 교차합니다, 적군은 죽었습니다, 다음 업데이트 루프, 적들은 다시 살아 있습니다"입니다.

그래서 저는 대신 업데이트 대신 초기화 메소드에 배치합니다.

+0

조언 해 주셔서 감사합니다. Enemy.cs에서 Alive = true로 설정 한 다음 Game1.cs에서 초기화하지 않고 올바른 방향으로 이끌어주었습니다. – FLAVAred

2

당신은 전혀 살아 속성을 사용하지 않는 것을 고려하고 원수 같은 목록에있는 개체를 치료한다 살아있다. 이 염두에, 나는 다음에 코드를 리팩토링 것 : 내 코드에서

protected override void Update(GameTime gameTime) 
{ 
    for (int i = 0; i < Enemies.Count; i++) 
    { 
     //If player intersects enemy 
     if (player.Bounds.Intersects(Enemies[i].Bounds)) 
     { 
      Enemies.RemoveAt(i); 
      i--; 
      continue; 
     }    
    } 
} 


protected override void Draw(GameTime gameTime) 
{ 
    foreach (Enemy enemy in Enemies) 
    { 
     spriteBatch.Draw(enemy.texture, enemy.position, Color.White); 
    } 
} 

, 우리 지금 루프를 교차 확인 각 적 통해. 교차점이 발견되면 목록에서 해당 적을 제거합니다. 이것은 그를 영원히 제거하고 코드를 크게 단순화합니다.

일반적으로 .Alive와 같은 속성을 사용하는 경우 풀 데이터 구조를 사용하게됩니다.

+0

존 감사합니다. 나는이 제안을 시도하고 그것에 대해 좀 더 연구를했지만 너무 많은 오류가 발생하여 나를 압도했다. 나는 내일 교수님과 함께 가져다가 더 밝힐 수 있는지 알아 보겠다. – FLAVAred

+0

나는 일반적으로 적 개체의 풀을 유지하고 그들을 처분하기보다는 재사용하려고한다. 많은 물체가있는 게임을 만들면 GC와 관련된 문제를 예방할 수 있습니다 –

+0

하지만 목록에서 제거해도 적 자체는 삭제되지 않습니다. Dispose()를 호출하거나 Game.Components에서 제거하지 않아도됩니까? – Kokodoko

관련 문제