1

すべてのコードについて申し訳ありませんが、Visual C# と XNA はまったく初めてです。

このプログラムは、Aaron Reed による Learning XNA 4.0 から外れています。私の教授は、それが行うべきことのいくつかを変更しました(本はこれの一部をカバーしていますが、すべてではありません). ほとんどのコードは本からコピーされています。

完成品の最小要件は次のとおりです。

  1. 3 つのリングとスカル ボールの代わりに任意の 2 つの画像を使用できます (または、必要に応じて同じものを使用することもできます)。1 つはプレイヤー (3 つのリング) で、もう 1 つは参加者 (敵とも呼ばれます) です。
  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);
         }
    }
}

回避スプライト

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);
    }
}
4

1 に答える 1

1

衝突コードの場合:

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

あなたはスプライトに上に行くように言っています。基本的に、y で -1 にヒットすると、正の方向に移動するまで正の方向に移動し、正の場合は負の方向に移動します。そのため、画面外で正と負を切り替え続けます。私の推奨は、これらのステートメントを2つに分割することです。そうすれば、回避していないときは、正確に壁に跳ね返っています.

    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;
于 2014-08-16T14:13:56.243 に答える