【问题标题】:Game object not saving state in MonoGame游戏对象未在 MonoGame 中保存状态
【发布时间】:2015-04-11 08:00:01
【问题描述】:

在我的游戏的游戏逻辑部分,您检查输入,为什么我的对象之前的状态没有被用于进一步评估我的函数?

我的游戏课:

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
using System.Diagnostics;

namespace MonoRPG
{
    public class Game1 : Game
    {

        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch;


        public Game1()
            : base()
        {
            graphics = new GraphicsDeviceManager(this);
            Content.RootDirectory = "Content";

        }

        protected override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
        }

        protected override void UnloadContent()
        {
        }


        protected override void Update(GameTime gameTime)
        {
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed || Keyboard.GetState().IsKeyDown(Keys.Escape))
                Exit();

            Player playerObject = new Player(this, this.Content, this.spriteBatch);
            KeyboardState oldState;
            KeyboardState newState = Keyboard.GetState();

            if (newState.IsKeyDown(Keys.Right))
            {
                Debug.WriteLine("right key pressed");
            }

            oldState = newState;


            base.Update(gameTime);
        }

        protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.CornflowerBlue);

            renderMap createMap = new renderMap(this, this.Content, this.spriteBatch);
            Player playerObject = new Player(this, this.Content, this.spriteBatch);

            createMap.RenderMap();
            playerObject.drawPlayer();
            playerObject.positionX = playerObject.positionX + 10;

            base.Draw(gameTime);
        }
    }
}

还有我的播放器类:

using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using Microsoft.Xna.Framework.GamerServices;
using System.Diagnostics;

namespace MonoRPG
{
    public class Player
    {
        public int positionX = 0;
        public int positionY = 0;

        Game1 draw = new Game1();
        ContentManager gameContent;
        SpriteBatch playerSprites;
        KeyboardState oldState;


        public Player(Game1 canvas, ContentManager content, SpriteBatch spriteBatch)
        {
            draw = canvas;
            gameContent = content;
            playerSprites = spriteBatch;
        }

        public Player()
        {

        }


        public void drawPlayer()
        {
            Texture2D playerTexture = gameContent.Load<Texture2D>("player/player.png");

            playerSprites.Begin();
            playerSprites.Draw(playerTexture, new Vector2(positionX, positionY), Color.Red);
            playerSprites.End();
        }

        public void playerMove(KeyboardState keyState, KeyboardState oldState)
        {
            positionX = positionX + 1;
        }

    }
}

绘图工作正常,但我用于播放器的矩形精灵的位置不会改变。问题与我创建对象的方式有关吗?我尝试在函数之外声明,但后来我不能使用 this 关键字。如何调用现有对象的函数?

【问题讨论】:

    标签: c# monogame


    【解决方案1】:

    您应该在InitializeLoadContent 方法中初始化(创建)对象。该对象应该只创建一次,而不是游戏的每次更新。 InitializeLoadContent 仅在游戏启动时出现一次(Initialize 首先是 LoadContent,当您调用 base.Initialize() 时)。

    当您将代码放入Update 方法时,它会在游戏的每次更新(通常是每一帧)时执行。您的代码应该看起来更像这样

    Player player;
    KeyboardState oldState; // player and oldState belongs to the whole game
    
    protected override void Initialize() {
        // remember that spriteBatch is still null here
        player = new Player(this, Content, spriteBatch);
        // the line below initializes the spriteBatch
        // check the comments to see why this exact code won't work
        base.Initialize();
    }
    
    protected override void Update(GameTime gameTime) {
        KeyboardState newState = Keyboard.GetState(); // newState belongs to this exact update only
    
        if (newState.IsKeyDown(Keys.Right) && oldState.IsKeyUp(Keys.Right)) {
            player.playerMove(newState, oldState); // not sure why you wish to pass these arguments?
        }
    
        oldState = newState;
    }
    
    protected override void Draw(GameTime gameTime) {
        GraphicsDevice.Clear(Color.CornflowerBlue);
    
        renderMap createMap = new renderMap(this, this.Content, this.spriteBatch);
    
        createMap.RenderMap();
    
        // the player here is the same player in the Update method
        player.drawPlayer();
    
        base.Draw(gameTime);
    }
    

    【讨论】:

    • 当我在初始化函数中初始化它们时,我开始在 Player.cs 中收到 nullreference 异常,说 playerSprites 没有设置为对象的实例?
    • @user3585434 正如我所说,LoadContentInitialize 之后执行。您可以在创建播放器之前将new Player()LoadContentnew SpriteBatch() 移动到Initialize 以创建精灵批处理。无论如何,在创建新游戏对象时传递精灵批次是非常糟糕的做法(仅在 Draw 方法中传递它们)。
    • 这正是我所需要的,非常感谢,我会记住的!
    猜你喜欢
    • 2021-06-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多