2014-02-15 7 views
1

모든 코드는 유감이지만 Visual C# 및 XNA는 완전히 새로운 기능입니다.XNA 4.0 적의 산란, 벽에서 튀어 오름

이 프로그램은 Aaron Reed의 XNA 4.0 학습에서 제외되었습니다. 교수님이해야 할 물건 중 일부를 수정했습니다.이 책은 일부 내용을 다루지 만 전체 내용은 다루지 않습니다. 대부분의 코드는 책에서 복사됩니다.

완성 된 제품에 대한 최소 요구 사항은 다음과 같습니다

  1. 당신은 3 반지와 해골 볼의 위치에있는이 개 이미지를 사용 (또는 원하는 경우 당신은 여전히 ​​동일하게 사용할 수 있습니다) - 하나가되는
  2. 플레이어 스프라이트는 화살표 키 (마우스가 활성화되지 않음)를 사용하여 이동할 수 있습니다.
  3. 참가자 스프라이트는 자동으로 움직이며 자유롭게 움직입니다 (당신은 바란다.) 그리고 그들은 경계로부터 튀어 나온다. (어떤 방식 으로든 당신이 선택한다)
  4. 게임 시작시 1 명의 플레이어와 5 개의 참가자 스프라이트가 있습니다.
  5. 플레이어 스프라이트가 화면의 모든 참가자 (적의 스프라이트)를 파괴 한 경우 게임이 끝날 때까지 정확히 120 초 동안 게임이 지속됩니다. 플레이어가 승리하는 것을 나타내는 메시지; 그렇지 않으면 플레이어가 잃어버린 메시지를 인쇄하십시오.
  6. 매 10 초마다 적의 스프라이트의 새로운 화신이 어느 위치에 나옵니다.
  7. 플레이어 스프라이트는 충돌 할 때만 적의 스프라이트를 파괴 할 수 있고, "A"키를 누르면 같은 시간. 충돌없이 "A"키를 누르면 적의 2 화신이 발생합니다.
  8. 게임이 의미있는 의미로 적의 스피리트가 합리적인 속도로 움직여야합니다 (의미는 없습니다)
  9. 프로그램의 일부 사운드 - 항상 재생되는 배경 사운드, 적을 파괴 할 때 재생되는 사운드, 플레이어가 발동 할 때 다른 소리가 들리지만 충돌이 없었기 때문에 적을 파괴하지 않음, 새로운 적을 발견 할 때 소리가납니다. (매 10 초마다)

나는 적이 (스켈링)를 피하려하지만 적들은 모든면에서 반응하지 않습니다. (플레이어가 오른쪽이나 왼쪽에 있고 이자형 플레이어가 위 또는 아래가 될 때까지 회피하지 못함), 적들이 회피 할 때, 그들은 화면 떨림에서 사라집니다 (갑자기 위아래로 똑바로 움직이며 빠르게 흔들리고 있습니다).

새로운 적을 10 초 후에 생성하면 왼쪽 상단 모서리부터 시작하여 바닥 벽에서 튀어 나와 다시 올라갈 때 화면 밖으로 사라집니다.

10 초 후에도 두개골이 화면 주위에 무작위로 생성되지 않습니다.

또한 충돌이없는 A 버튼을 누르면 2 개의 적을 생성하는 방법을 알지 못합니다.

SpriteManager.당신의 충돌 코드에 대한 CS

namespace Assignment_2 
{ 
    public class SpriteManager : Microsoft.Xna.Framework.DrawableGameComponent 
    { 
     //SpriteBatch for drawing 
     SpriteBatch spriteBatch; 

     //A sprite for the player and a list of automated sprites 
     UserControlledSprite player; 
     List<Sprite> spriteList = new List<Sprite>(); 

     int enemySpawnMinMilliseconds = 10000; 
     int enemySpawnMaxMilliseconds = 10000; 
     int enemyMinSpeed = 10; 
     int enemyMaxSpeed = 10; 
     int nextSpawnTime = 0; 

     public SpriteManager(Game game) 
      : base(game) 
     { 
      // TODO: Construct any child components here 
     } 

     public override void Initialize() 
     { 
      // TODO: Add your initialization code here 
      ResetSpawnTime(); 
      base.Initialize(); 
     } 

     protected override void LoadContent() 
     { 
      spriteBatch = new SpriteBatch(Game.GraphicsDevice); 

      //Load the player sprite 
      player = new UserControlledSprite(
       Game.Content.Load<Texture2D>(@"Images/threerings"), 
       Vector2.Zero, new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(6, 6)); 

      //Load several different automated sprites into the list to test 
      //spriteList.Add(new AutomatedSprite(
      // Game.Content.Load<Texture2D>(@"Images/skullball"), 
      // new Vector2(150, 150), new Point(75, 75), 10, new Point(0, 0), 
      // new Point(6, 8), new Vector2(3, 0), "skullcollision")); 
      //spriteList.Add(new AutomatedSprite(
      // Game.Content.Load<Texture2D>(@"Images/skullball"), 
      // new Vector2(300, 150), new Point(75, 75), 10, new Point(0, 0), 
      // new Point(6, 8), new Vector2(-2, 0), "skullcollision")); 
      ////spriteList.Add(new AutomatedSprite(
      //// Game.Content.Load<Texture2D>(@"Images/skullball"), 
      //// new Vector2(150, 300), new Point(75, 75), 10, new Point(0, 0), 
      //// new Point(6, 8), new Vector2(3, 4), "skullcollision")); 
      ////spriteList.Add(new AutomatedSprite(
      //// Game.Content.Load<Texture2D>(@"Images/skullball"), 
      //// new Vector2(300, 400), new Point(75, 75), 10, new Point(0, 0), 
      //// new Point(6, 8), new Vector2(0, -3), "skullcollision")); 
      ////spriteList.Add(new AutomatedSprite(
      //// Game.Content.Load<Texture2D>(@"Images/skullball"), 
      //// new Vector2(200, 300), new Point(75, 75), 10, new Point(0, 0), 
      //// new Point(6, 8), new Vector2(-3, 7), "skullcollision")); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(150, 150), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(3, 0), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(300, 150), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(-2, 0), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(150, 300), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(3, 4), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(300, 400), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(0, -3), "skullcollision", this, .75f, 150)); 
      spriteList.Add(new EvadingSprite(
       Game.Content.Load<Texture2D>(@"Images/skullball"), 
       new Vector2(200, 300), new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(-3, 7), "skullcollision", this, .75f, 150)); 
      base.LoadContent(); 
     } 

     public override void Update(GameTime gameTime) 
     { 
      nextSpawnTime -= gameTime.ElapsedGameTime.Milliseconds; 
      if (nextSpawnTime < 0) 
      { 
       SpawnEnemy(); 

       //reset spawn timer 
       ResetSpawnTime(); 
      } 
      // Update player 
      player.Update(gameTime, Game.Window.ClientBounds); 

      // Update all sprites 
      for (int i = 0; i < spriteList.Count; ++i) 
      { 
       Sprite s = spriteList[i]; 

       s.Update(gameTime, Game.Window.ClientBounds); 

       // Check for collisions 
       if (s.collisionRect.Intersects(player.collisionRect) && (Keyboard.GetState().IsKeyDown(Keys.A))) 
       { 
        // Play collision sound 
        if (s.collisionCueName != null) 
         ((Game1)Game).PlayCue(s.collisionCueName); 

        // Remove collided sprite from the game 
        spriteList.RemoveAt(i); 
        --i; 
       } 
      } 

      base.Update(gameTime); 
     } 

     public override void Draw(GameTime gameTime) 
     { 
      spriteBatch.Begin(SpriteSortMode.FrontToBack, BlendState.AlphaBlend); 

      // Draw the player 
      player.Draw(gameTime, spriteBatch); 

      // Draw all sprites 
      foreach (Sprite s in spriteList) 
       s.Draw(gameTime, spriteBatch); 

      spriteBatch.End(); 
      base.Draw(gameTime); 
     } 
     // Return current position of the player sprite 
     public Vector2 GetPlayerPosition() 
     { 
      return player.GetPosition; 
     } 

     private void SpawnEnemy() 
     { 
      Vector2 speed = Vector2.Zero; 
      Vector2 position = Vector2.Zero; 

      // Default frame size 
      Point frameSize = new Point(75, 75); 
      // Create the sprite. NOTE: This sprite bounces off the bottom wall then goes back and disappears offscreen 
      spriteList.Add(
       new EvadingSprite(Game.Content.Load<Texture2D>(@"images\skullball"), 
       position, new Point(75, 75), 10, new Point(0, 0), 
       new Point(6, 8), new Vector2(3, 4), "skullcollision", this, .75f, 150)); 

     } 

     private void ResetSpawnTime() 
     { 
      nextSpawnTime = ((Game1)Game).rnd.Next(
      enemySpawnMinMilliseconds, 
      enemySpawnMaxMilliseconds); 
     } 
    } 
} 

EvadingSprite는

class EvadingSprite : Sprite 
{ 
    // Save a reference to the sprite manager to 
    // use to get the player position 
    SpriteManager spriteManager; 

    // Variables to delay evasion until player is close 
    float evasionSpeedModifier; 
    int evasionRange; 
    bool evade = false; 

    public EvadingSprite(Texture2D textureImage, Vector2 position, 
     Point frameSize, int collisionOffset, Point currentFrame, 
     Point sheetSize, Vector2 speed, string collisionCueName, 
     SpriteManager spriteManager, float evasionSpeedModifier, 
     int evasionRange) 
     : base(textureImage, position, frameSize, collisionOffset, 
     currentFrame, sheetSize, speed, collisionCueName) 
    { 
     this.spriteManager = spriteManager; 
     this.evasionSpeedModifier = evasionSpeedModifier; 
     this.evasionRange = evasionRange; 
    } 

    public EvadingSprite(Texture2D textureImage, Vector2 position, 
     Point frameSize, int collisionOffset, Point currentFrame, 
     Point sheetSize, Vector2 speed, int millisecondsPerFrame, 
     string collisionCueName, SpriteManager spriteManager, 
     float evasionSpeedModifier, int evasionRange) 
     : base(textureImage, position, frameSize, collisionOffset, 
     currentFrame, sheetSize, speed, millisecondsPerFrame, 
     collisionCueName) 
    { 
     this.spriteManager = spriteManager; 
     this.evasionSpeedModifier = evasionSpeedModifier; 
     this.evasionRange = evasionRange; 
    } 

    public override Vector2 direction 
    { 
     get { return speed; } 
    } 

    public override void Update(GameTime gameTime, Rectangle clientBounds) 
    { 
     // First, move the sprite along its direction vector 
     position += speed; 

     // Use the player position to move the sprite closer in 
     // the X and/or Y directions 
     Vector2 player = spriteManager.GetPlayerPosition(); 

     if (evade) 
     { 
      // Move away from the player horizontally 
      if (player.X < position.Y) 
       position.X += Math.Abs(speed.Y); 
      else if (player.X > position.X) 
       position.X -= Math.Abs(speed.Y); 

      // Move away from the player vertically 
      if (player.Y < position.Y) 
       position.Y += Math.Abs(speed.X); 
      else if (player.Y > position.Y) 
       position.Y -= Math.Abs(speed.X); 

     } 
     else 
     { 
      if (Vector2.Distance(position, player) < evasionRange) 
      { 
       // Player is within evasion range, 
       // reverse direction and modify speed 
       speed *= -evasionSpeedModifier; 
       evade = true; 
      } 
     } 

     //make them bounce off walls 
     if (position.X > clientBounds.Width - frameSize.X || 
      position.X < 0) 
      speed *= -1; 

     if (position.Y > clientBounds.Height - frameSize.Y || 
      position.Y < 0) 
      speed *= -1; 
     base.Update(gameTime, clientBounds); 
    } 
} 
+0

나는 귀하의 질문이 광범위하고 많은 코드 작성 방법을 포함하고 있다고 생각합니다. 문제가있는 곳과 최종 결과가 어떠해야하는지 구체적으로 명확히하십시오. "나는 스프라이트를 피하려고 노력하고있다." 매우 유익하지 않습니다. 회피 코드는 어디에 있습니까? 뭐 할 계획 이니? – Measuring

+0

@ 계측 조금 줄였습니다. 지금은 더 명확한가요? – user3313728

+0

예, 이제 좋습니다. 그러므로 적의 업데이트에서 evade = true로 설정할 수있는 루프가있는 것 같습니다. 실제로는 false로 설정하지 않았습니다 (적을 흔들어 볼 수 있으므로이 또한 의미가 있습니다). 그 부분을 디버깅 해 보셨습니까? – Measuring

답변

1

:

if (position.Y > clientBounds.Height - frameSize.Y || 
     position.Y < 0) 
     speed *= -1; 

는 당신은 갈 올라갈 스프라이트를 말하고있다. 기본적으로 y가 -1 일 때 양의 방향으로 이동하여 양수가 될 때까지 양의 방향으로 이동합니다. 따라서 화면에서 양수와 음수를 전환 할 수 있습니다. 제 권고는 당신이 당신을 회피하지 않을 때 벽에서 정확하게 튀어 오르는 것처럼 그 진술을 두 가지로 나눌 것입니다.

if (position.X > clientBounds.Width - frameSize.X) 
     speed *= -1; 
    else if (position.X<=0) 
     speed*=1; 
    if (position.Y > ClientBounds.Height - frameSize.Y) 
      speed *= -1; 
    else if(position.Y > 0) 
      speed *= 1;