Di chuyển sprite của tôi trong XNA bằng các lớp


7

Hey, tôi là một người mới tham gia chương trình này và nó thực sự làm tôi thất vọng. Tôi đang cố gắng di chuyển một con rắn theo mọi hướng trong khi sử dụng các lớp học. Ive đã tạo ra một vector2 cho tốc độ và ive đã cố gắng tạo ra một phương thức di chuyển con rắn trong lớp rắn.

Bây giờ tôi bối rối và không biết phải làm gì tiếp theo.

Đánh giá cao bất kỳ sự giúp đỡ. Cảm ơn: D

Đây là những gì tôi đã làm về phương pháp ...

  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;

        }

Đánh giá cao bất kỳ sự giúp đỡ. Cảm ơn: D

EDIT:
Vâng hãy để tôi làm cho mọi thứ rõ ràng. Tôi đang làm một trò chơi cơ bản nhỏ cho một bài tập. Trò chơi này giống với trò chơi rắn cũ trên điện thoại Nokia cũ. Tôi đã tạo ra một lớp rắn (mặc dù tôi không chắc liệu điều này có cần thiết hay không vì tôi sẽ chỉ có một sprite di chuyển trong trò chơi). Sau khi tôi viết mã ở trên (trong lớp con rắn), trò chơi đã chạy không có lỗi nhưng tôi thực sự không thể di chuyển hình ảnh :(

EDIT2: Cảm ơn rất nhiều vì phản hồi của mọi người !!

xna 

Lời xin lỗi cho đoạn trích xấu về mã của tôi: /

Đây có vẻ là một cách tiếp cận khả thi, nhưng tôi không thấy một câu hỏi thực sự ở đây. Bạn có hỏi làm thế nào để sử dụng kết quả của chức năng "hướng" của bạn để thực sự di chuyển một đối tượng?

Tôi nghĩ rằng nếu bạn đăng mã thực sự sử dụng đầu ra từ phương thức định hướng này, chúng tôi có thể giúp bạn. Tôi nghĩ lỗi là ở cách bạn đang cập nhật vị trí của sprite.
Michael Coleman

Nâng cao và chấp nhận câu trả lời là một cách khác, cách của GD để cảm ơn các nhà phát triển đồng nghiệp đã giúp bạn đạt được mục tiêu của mình. =)
Will Marcouiller

Câu trả lời:


2

Mặc dù tôi cũng là một người mới trong việc phát triển trò chơi, nhưng cá cược của tôi là bạn luôn luôn xác định lại inputDirectionbiến của mình Vector2.Zero.

Tôi không biết nhiều về phát triển trò chơi, nhưng đối với lập trình hướng đối tượng, đó là một điều khác! Đây là những gì tôi đã đi kèm sau khi đọc bình luận của bạn về các lớp học.

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

Tôi hy vọng điều này sẽ giúp, và để đi đúng hướng đến một giải pháp khả thi! =)


Đây có vẻ là một cách dài hơi để sử dụng một vài nút .. nhưng tôi biết gì về lol. Tôi thực sự không biết tôi đang làm gì trong các lớp học :(.

2
Trong thực tế, đây là Snakelớp học của bạn nên nhận thức được tốc độ và hướng của nó. Bên cạnh đó, đây là trò chơi nhận được đầu vào của người dùng. Vì vậy, trong sự hiểu biết của tôi, bạn phải làm cho con rắn bí quyết gì hướng thì đầu tiếp theo, đó là, tôi tin rằng bạn cần phải có, trong phạm vi của bạn Snakelớp, bốn phương pháp: MoveDown(), MoveLeft(), MoveRight()MoveUp(). Đó là con rắn biết phải làm gì để di chuyển bằng cách này hay cách khác, và vì nó cũng biết tốc độ của nó, nên nó sẽ di chuyển theo. Sau đó, trong Gamelớp của bạn , khởi tạo con rắn của bạn và nhập chỉ đường thông qua các phương thức của nó!
Will Marcouiller

1
Xin vui lòng, xem câu trả lời được chỉnh sửa của tôi vì tôi đã bao gồm một Snakelớp có thể phơi bày bốn Movephương thức. Con rắn không cần phải biết phím nào đã được nhấn, thay vào đó trò chơi của bạn sẽ nhận được các phím. Sau đó, trò chơi của bạn sẽ cho con rắn biết bạn sẽ đi đâu tùy thuộc vào các phím đã được người chơi nhấn. Sau đó, trò chơi của bạn cho biết _snaketrường hợp của bạn MoveLeft, MoveDownv.v. tùy thuộc vào các phím mà bạn đã nhấn. Hãy cho tôi biết nếu điều này sẽ giúp! Và hãy bình luận về những thứ bạn không làm việc hoặc vì vậy, tôi sẽ vui lòng giúp đỡ hết sức có thể.
Will Marcouiller

Cảm ơn bạn rất nhiều, đây chính xác là những gì tôi đang tìm kiếm về mặt câu trả lời. Bạn gọi cho mình một người mới nhưng đã cho thấy khác :). Tôi thực sự khủng khiếp với nhạc jazz mã hóa này. Sự nhầm lẫn của tôi là khi sử dụng các lớp cho tất cả mọi thứ (có lẽ là chìa khóa).

1
Imo, Head First C # là một cuốn sách gọn gàng để có được một primer hướng đối tượng tốt trong khi thực sự tạo ra kết quả có thể nhìn thấy trong suốt quá trình.
Oskar Duveborn

2

Tôi sử dụng mã như thế này để di chuyển các họa tiết của mình, nó có xu hướng hoạt động khá tốt đối với tôi, nó cũng sử dụng "GameTime" để đảm bảo chuyển động được nhất quán trên tốc độ khung hình.

// 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());

Rõ ràng bạn có thể muốn cung cấp nhiều tham số hơn cho sprite trong quá trình cập nhật của nó, vì vậy bạn cũng có thể rất nhanh về tốc độ hoặc những thứ khác.


3
Cần có các nhãn dán màu đỏ khổng lồ trên mỗi hướng dẫn XNA để thông báo cho mọi người về việc sử dụng GameTime để sửa đổi tất cả các sự kiện theo từng khung hình mà bạn muốn được cập nhật ở tốc độ thời gian thực liên tục để cung cấp trải nghiệm người chơi nhất quán bất kể phần cứng .
Hóa đơn

@Bill: Tình cảm của tôi chính xác.
Michael Coleman

2

Câu hỏi này cần nhiều lambdas.

Lưu ý đây là từ WIP, vì vậy có một số tính năng chưa được sử dụng và ngụ ý nhưng chưa được thực hiện. Nơi bạn nhìn thấy () =>thêm của bạn inputDirection.X -= -1;. Tôi nhận ra điều này là dành cho một Tay chơi game và bạn đang sử dụng bàn phím, nhưng nguyên tắc nhóm hoặc ít nhất là khái niệm bản đồ hành động vẫn được áp dụng.

Đây có lẽ là quá mức cần thiết, nhưng rất nhiều niềm vui!

Chức năng thiết lập ánh xạ các điều khiển:

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!"));
}

Thành phần trò chơi giúp nó hoạt động (khởi tạo 1 cho mỗi người chơi):

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

Bây giờ tôi bối rối và không biết phải làm gì tiếp theo.

Điều này có nghĩa là mã của bạn không làm những gì bạn nghĩ nó nên làm hay bạn có một số tính năng mà bạn cần triển khai mà bạn không biết làm thế nào hoặc bạn muốn tư vấn về tính năng nào sẽ thực hiện tiếp theo?

Dù bằng cách nào ...

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

Bạn không muốn trừ đi một tiêu cực cho một hướng và thêm một hướng tích cực theo hướng khác. Hai người đánh giá cùng một điều.


Vâng hãy để tôi làm cho mọi thứ rõ ràng. Tôi đang làm một trò chơi cơ bản nhỏ cho một bài tập. Trò chơi này giống với trò chơi rắn cũ trên điện thoại Nokia cũ. Tôi đã tạo ra một lớp rắn (mặc dù tôi không chắc liệu điều này có cần thiết hay không vì tôi sẽ chỉ có một sprite di chuyển trong trò chơi). Sau khi tôi viết mã ở trên (trong lớp con rắn), trò chơi đã chạy không có lỗi nhưng tôi thực sự không thể di chuyển hình ảnh :(

1
@Tom, bạn nên đặt sự làm rõ trong chính câu hỏi.
Tetrad

1

Đây là cách tôi đang làm điều này trong một trong những trò chơi của mình trên Windows Phone. Hãy nhớ rằng tôi đã thực hiện một số đơn giản hóa cho ví dụ. Trong trò chơi của tôi, kẻ thù đi theo một nhóm các điểm mốc dọc theo một con đường.

Trong Updatephương thức bên trong Enemy.cslớp của tôi , tôi đánh giá Enemy.Waypoints.Peek() - Enemy.Position(chuẩn hóa) để xác định hướng kẻ địch sẽ di chuyển.

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

Sau đó, tôi tính toán vận tốc (hướng + tốc độ) cho khung hình hiện tại bằng cách sử dụng hướng.

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

Cuối cùng, tôi điều chỉnh vị trí thực tế của kẻ thù.

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

Nó giúp hiểu toán học liên quan, nhưng đây là cách bạn có thể di chuyển một đối tượng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.