クラスを使用してXNAでスプライトを移動する


7

こんにちは、このプログラミングラークの初心者で、本当にイライラします。クラスを使用している間、ヘビをあらゆる方向に動かそうとしています。私は速度のためにvector2を作成し、ヘビをヘビクラス内で移動するメソッドを作成しようとしました。

今、私は混乱しており、次に何をすべきかわかりません。

どんな助けにも感謝します。ありがとう

これは私がメソッドに関して行ったことです...

  public Vector2 direction()
        {
                Vector2 inputDirection = Vector2.Zero;

                if (Keyboard.GetState().IsKeyDown(Keys.Left)) inputDirection.X -= -1;
                if (Keyboard.GetState().IsKeyDown(Keys.Right)) inputDirection.X += 1;
                if (Keyboard.GetState().IsKeyDown(Keys.Up)) inputDirection.Y -= -1;
                if (Keyboard.GetState().IsKeyDown(Keys.Down)) inputDirection.Y += 1;

                return inputDirection * snakeSpeed;

        }

どんな助けにも感謝します。ありがとう

編集:
まあ私はすべてを明確にさせてください。割り当て用の小さな基本的なゲームを作っています。ゲームは、古いノキアの携帯電話での古いヘビゲームに似ています。私はスネーククラスを作成しました(ゲーム内で動くスプライトが1つだけになるため、これが必要かどうかはわかりません)。上記のコードを(snakeクラスで)作成した後、ゲームはエラーなしで実行されましたが、実際には画像を移動できませんでした:(

EDIT2:みんなの回答に感謝します!!

xna 

私のコードの悪い引用の

これは実行可能なアプローチのようですが、実際の質問はここには表示されません。「方向」関数の結果を使用して実際にオブジェクトを移動する方法を尋ねていますか?

この方向メソッドからの出力を実際に使用するコードを投稿していただければ、お役に立てるかもしれません。エラーはスプライトの位置を更新する方法にあると思います。
マイケルコールマン

回答の賛成と承認は別の方法です。GDは、目標の達成を支援してくれた開発者に感謝する方法です。=)
Will Marcouiller、2011

回答:


2

私はゲーム開発の初心者でもありますが、私のinputDirection変数は常に変数をに再初期化することになるでしょうVector2.Zero

ゲーム開発についてはあまり詳しくありませんが、オブジェクト指向プログラミングについては、これもまた別のことです!クラスについてのあなたのコメントを読んだ後、私はここに来ました。

public class Snake {
    private Texture2D _snake; // Represents your snake's sprite.
    private Vector2 _snakePos; // Field that determines your snake's position.
    private Vector2 _snakeSpeed = new Vector2(10.0f, 10.0f); // Field that determines the number of pixels your snake will move at once while moving.

    public Snake(Vector2 initialPosition) {
        _snakePos = initialPosition;
    }

    public void MoveDown() {
        _snakePos.Y += _snakeSpeed.Y;
    }

    public void MoveLeft() {
        _snakePos.X -= _snakeSpeed.X;
    }

    public void MoveRight() {
        _snakePos.X += _snakeSpeed.Y;
    }

    public void MoveUp() {
        _snakePos.Y -= _snakeSpeed.Y;
    }
}

public class Game Game1 {
    private Snake _snake = new Snake();

    protected override void Update(GameTime gameTime) {
        Keys[] keys = Keyboard.GetState().GetPressedKeys();

        if (keys != null && keys.Length > 0)
            switch (keys[0]) {
                case Keys.Escape:
                    Exit();
                    break;
                case Keys.Down:
                    _snake.MoveDown();
                    break;
                case Keys.Left:
                    _snake.MoveLeft();
                    break;
                case Keys.Right:
                    _snake.MoveRight();
                    break;
                case Keys.Up:
                    _snake.MoveUp();
                    break;
                default:
                    break;
            }
    }
}

これがお役に立てば幸いです。そして実行可能な解決策への正しい方向に進んでください。=)


これは、いくつかのボタンを使用するための長い方法のように思われます。私は実際にクラスの面で私がやっている見当がつかない:(。

2
実際、これはSnakeその速度と方向を認識しているクラスです。さて、これはユーザー入力を取得しているゲームです。だから、私の理解では、あなたがあること、それは次のヘッドばならない何方向ヘビのノウハウを行う必要があり、私はあなたの中に、あなたが持っているべきであると信じているSnake:4つのメソッド、クラスMoveDown()MoveLeft()MoveRight()MoveUp()。移動する方法を知っているのはヘビであり、その速度も知っているため、それに応じて移動します。次に、Gameクラスで蛇をインスタンス化し、そのメソッドを使用して方向を入力します。
Marcouiller氏、2011

1
Snake4つのMoveメソッドを公開する可能なクラスを含めたので、編集した回答を参照してください。ヘビはどのキーが押されたかを知る必要はなく、ゲームはキーを取得します。次に、プレイヤーが押したキーに応じてヘビにどこに行くべきかを指示するのはあなたのゲームです。次に、ゲームは、押されたキーに応じて_snakeインスタンスをMoveLeftMoveDown通知します。これが役立つかどうか教えてください!そして、あなたがうまく動かないようなことについて気軽にコメントしてください、私はできる限りのことを喜んでお手伝いします。
Marcouiller、2011

どうもありがとう、これはまさに私が答えに関して探していたものです。あなたは自分を新人と呼びましたが、それ以外は:) 私はこのコーディングジャズに文字通りひどいです。私の混乱は、すべてにクラスを使用するときです(これはおそらくキーです)。

1
Imo、Head First C#は、オブジェクト指向の優れた入門書を入手しながら、実際に目に見える結果を生成するための素晴らしい本です。
Oskar Duveborn、2011

2

私はこのようなコードを使用してスプライトを移動します。これは私にとって非常にうまく機能する傾向があります。また、「GameTime」を使用して、フレームレート全体で移動が一貫していることを確認します。

// Sprite Protecteds
Vector2 direction;
Vector2 position;
float speed;

// Sprite Code
void Update(GameTime time, KeyboardState kb)
{
    // reset to zero for no keys pressed
    direction = Vector2.Zero;

    if (Keyboard.GetState().IsKeyDown(Keys.Left)) direction.X = -1;
    if (Keyboard.GetState().IsKeyDown(Keys.Right)) direction.X = 1;
    if (Keyboard.GetState().IsKeyDown(Keys.Up)) direction.Y = -1;
    if (Keyboard.GetState().IsKeyDown(Keys.Down)) direction.Y = 1;

    position += direction * speed * time. Milliseconds;
}

// Game "Update" method (not sure of exact code here)
sprite.Update(gameTime, Keyboard.GetState());

明らかに、更新プロセス中にスプライトにより多くのパラメータを提供したい場合があるかもしれません。そのため、速度やその他の事柄も非常に重要な場合があります。


3
ハードウェアに関係なく一貫したプレーヤーエクスペリエンスを提供するために一定のリアルタイムレートで更新するすべてのフレームごとのイベントを変更するためのGameTimeの使用を人々に知らせるために、すべてのXNAチュートリアル全体に巨大な赤いステッカーが必要です。 。
ビル

@ビル:私の感情は正確に。
マイケルコールマン、

2

この質問にはもっとラムダが必要です。

これはWIPからのものであるため、未使用で暗黙的に実装されていない機能がいくつかあることに注意してください。あなたが() =>追加を見るところinputDirection.X -= -1;。これはゲームパッド用であり、キーボードを使用していることがわかりますが、グループ化の原則、または少なくともアクションマップの概念は引き続き適用されます。

これはおそらくやり過ぎですが、とても楽しいです!

コントロールをマップするセットアップ機能:

public void SetController(MyGamePad controller)
{
    controller.ClearActions();

    controller.BindAction(Buttons.Start, ButtonGroup.FullyExclusive, () => sine.play());

    controller.BindAction(Buttons.A,
        ButtonGroup.FaceButtons, () => showText("A!"));
    controller.BindAction(Buttons.A | Buttons.B,
        ButtonGroup.FaceButtons, () => showText("A and B!"));
    controller.BindAction(Buttons.B,
        ButtonGroup.FaceButtons, () => showText("B"));
    controller.BindAction(Buttons.B | Buttons.Y,
        ButtonGroup.FaceButtons, () => showText("B and Y!"));
    controller.BindAction(Buttons.Y,
        ButtonGroup.FaceButtons, () => showText("Y!"));
    controller.BindAction(Buttons.Y | Buttons.X,
        ButtonGroup.FaceButtons, () => showText("Y and X!"));
    controller.BindAction(Buttons.X,
        ButtonGroup.FaceButtons, () => showText("X!"));
    controller.BindAction(Buttons.X | Buttons.A,
        ButtonGroup.FaceButtons, () => showText("X n A, I made a funny!"));
    controller.BindAction(0x0,
        ButtonGroup.FaceButtons, () => showText("Nothing on the face buttons."));

    controller.BindAction(0x0,
        ButtonGroup.ShoulderButtons, () => showText("No shoulder buttons"));
    controller.BindAction(Buttons.LeftShoulder,
        ButtonGroup.ShoulderButtons, () => showText("Left shoulder button!"));
    controller.BindAction(Buttons.RightShoulder,
        ButtonGroup.ShoulderButtons, () => showText("Right shoulder button!"));

    controller.BindAction(0x0,
        ButtonGroup.DirectionalPad, () => showText("Nothin' on the dpad!"));
    controller.BindAction(Buttons.DPadUp,
        ButtonGroup.DirectionalPad, () => showText("DPAD UP!"));
    controller.BindAction(Buttons.DPadDown,
        ButtonGroup.DirectionalPad, () => showText("DPAD DOWN!"));
}

機能させるゲームコンポーネント(1人のプレイヤーにつき1つをインスタンス化):

using System;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System.Collections.Generic;

namespace MyGame
{
    [Flags]
    public enum ButtonGroup
    {
        NonExclusive            = 0x00,
        FaceButtons             = 0x01,
        DirectionalPad          = 0x02,
        ShoulderButtons         = 0x04,
        LeftSide                = 0x08,
        RightSide               = 0x10,
        FullyExclusive          = 0xFF,
    }

    class MyGamePad : GameComponent
    {
        private Buttons FaceButtons;
        private Buttons DirectionalButtons;
        private Buttons ShoulderButtons;
        private Buttons LeftSideButtons;
        private Buttons RightSideButtons;
        private Buttons AllButtons;

        private PlayerIndex playerIndex;
        private Dictionary<KeyValuePair<Buttons, ButtonGroup>, Action> actionMap = new Dictionary<KeyValuePair<Buttons, ButtonGroup>, Action>();

        public InstrumentPad(Game game, PlayerIndex playerIndex) : base(game)
        {
            this.playerIndex = playerIndex;
        }

        public void ClearActions()
        {
            actionMap.Clear();
        }

        public override void Update(GameTime gameTime)
        {
            base.Update(gameTime);

            updateButtons();

            foreach (KeyValuePair<Buttons, ButtonGroup> pair in actionMap.Keys)
            {
                switch (pair.Value)
                {
                    case ButtonGroup.DirectionalPad:
                        if (DirectionalButtons == pair.Key)
                            actionMap[pair].Invoke();
                        break;
                    case ButtonGroup.FaceButtons:
                        if (FaceButtons == pair.Key)
                            actionMap[pair].Invoke();
                        break;
                    case ButtonGroup.ShoulderButtons:
                        if (ShoulderButtons == pair.Key)
                            actionMap[pair].Invoke();
                        break;
                    case ButtonGroup.LeftSide:
                        if (LeftSideButtons == pair.Key)
                            actionMap[pair].Invoke();
                        break;
                    case ButtonGroup.RightSide:
                        if (RightSideButtons == pair.Key)
                            actionMap[pair].Invoke();
                        break;
                    case ButtonGroup.FullyExclusive:
                        if (AllButtons == pair.Key)
                            actionMap[pair].Invoke();
                        break;
                    case ButtonGroup.NonExclusive:
                        if ((AllButtons & pair.Key) == pair.Key)
                            actionMap[pair].Invoke();
                        break;
                }
            }
        }

        public void BindAction(Buttons buttonCombo, ButtonGroup buttonGrouping, Action action)
        {
            KeyValuePair<Buttons, ButtonGroup> pair = new KeyValuePair<Buttons, ButtonGroup>(buttonCombo, buttonGrouping);
            if (!actionMap.ContainsKey(pair))
                actionMap.Add(pair, action);
            else
                actionMap[pair] = action;
        }

        private void updateButtons()
        {
            GamePadState padState = GamePad.GetState(playerIndex);
            LeftSideButtons = 0x0;
            RightSideButtons = 0x0;

            FaceButtons = 0x0;
            if (padState.Buttons.A == ButtonState.Pressed)
                FaceButtons |= Buttons.A;
            if (padState.Buttons.B == ButtonState.Pressed)
                FaceButtons |= Buttons.B;
            if (padState.Buttons.X == ButtonState.Pressed)
                FaceButtons |= Buttons.X;
            if (padState.Buttons.Y == ButtonState.Pressed)
                FaceButtons |= Buttons.Y;

            RightSideButtons |= FaceButtons;

            DirectionalButtons = 0x0;
            if (padState.DPad.Up == ButtonState.Pressed)
                DirectionalButtons |= Buttons.DPadUp;
            if (padState.DPad.Down == ButtonState.Pressed)
                DirectionalButtons |= Buttons.DPadDown;
            if (padState.DPad.Left == ButtonState.Pressed)
                DirectionalButtons |= Buttons.DPadLeft;
            if (padState.DPad.Right == ButtonState.Pressed)
                DirectionalButtons |= Buttons.DPadRight;

            LeftSideButtons |= DirectionalButtons;

            ShoulderButtons = 0x0;
            if (padState.Buttons.LeftShoulder == ButtonState.Pressed)
            {
                ShoulderButtons |= Buttons.LeftShoulder;
                LeftSideButtons |= Buttons.LeftShoulder;
            }
            if (padState.Buttons.RightShoulder == ButtonState.Pressed)
            {
                ShoulderButtons |= Buttons.RightShoulder;
                RightSideButtons |= Buttons.RightShoulder;
            }

            AllButtons = LeftSideButtons | RightSideButtons;

            if (padState.Buttons.Start == ButtonState.Pressed)
                AllButtons |= Buttons.Start;
            if (padState.Buttons.Back == ButtonState.Pressed)
                AllButtons |= Buttons.Back;
        }
    }
}

1

今、私は混乱しており、次に何をすべきかわかりません。

これは、コードが意図したとおりに動作していないことを意味しますか、または実装方法がわからない、または実装する必要がある機能について、次に実装する機能に関するアドバイスが必要ですか?

どちらにしても...

if (Keyboard.GetState().IsKeyDown(Keys.Left)) inputDirection.X -= -1;
if (Keyboard.GetState().IsKeyDown(Keys.Right)) inputDirection.X += 1;

一方の方向に負の値を差し引き、もう一方の方向に正の値を加算する必要はありません。これら2つは同じことを評価します。


さて、すべてを明確にしましょう。割り当てのための小さな基本的なゲームを作っています。このゲームは、古いノキアの携帯電話での古いヘビゲームに似ています。私はスネーククラスを作成しました(ゲーム内で動くスプライトが1つしかないため、これが必要かどうかはわかりません)。上記のコードを(snakeクラスで)作成した後、ゲームはエラーなしで実行されましたが、実際に画像を移動できませんでした:(

1
@トム、あなたは質問自体に説明を入れるべきです。
Tetrad

1

これは、Windows Phoneのゲームの1つでこれを実行している方法です。例として、いくつかの簡略化を行ったことを覚えておいてください。私のゲームでは、敵はパスに沿って一連のウェイポイントをたどります。

クラスUpdate内のメソッドではEnemy.cs、評価Enemy.Waypoints.Peek() - Enemy.Position(正規化)して、敵が移動する方向を決定します。

this.Direction = this.Waypoints.Peek() - this.Position;
this.Direction.Normalize();

次に、方向を使用して現在のフレームの速度(方向+速度)を計算します。

this.Velocity = Vector2.Multiply(this.Direction, Settings.Speed * this.Speed);

最後に、敵の実際の位置を調整します。

// Adjust the position according to the velocity.
this.Position += this.Velocity;

関連する数学を理解するのに役立ちますが、これはオブジェクトを移動する方法です。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.