我正在制作一款新游戏(在 Visual Studio 中,使用 MonoGame 模板),我认为类使一切变得更加整洁并且更易于查找/使用 - 我的一个问题是我不知道如何将一个类链接到另一个类.
让我更深入地了解一下 - 我只是按照 WASD 键对应的方向移动玩家。我的代码在普通 Game1 类中运行良好,但我希望它位于专门用于键盘输入的类中。
注意 - 我没有触及课程顶部的任何“使用”内容。
这是我的代码:
键盘输入类:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace rpg_game
{
internal class KeyboardInput
{
public int player_X;
public int player_Y;
KeyboardState keyboardState = Keyboard.GetState();
public void Update(GameTime gameTime)
{
if (keyboardState.IsKeyDown(Keys.W)) { player_Y -=1; }
if (keyboardState.IsKeyDown(Keys.A)) { player_X -= 1; }
if (keyboardState.IsKeyDown(Keys.S)) { player_Y += 1; }
if (keyboardState.IsKeyDown(Keys.D)) { player_X += 1; }
}
}
}
只是澄清一下,如果类中存在 /* ... */,则仅意味着我没有添加或从其中获取任何内容 - 这些类未受影响:)
游戏1类:
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
namespace rpg_game
{
public class Game1 : Game
{
private GraphicsDeviceManager _graphics;
private SpriteBatch _spriteBatch;
private Texture2D player;
private int player_X = 100;
private int player_Y = 38;
KeyboardInput input = new KeyboardInput();
public Game1() { /* ... */ }
protected override void Initialize() { /* ... */ }
protected override void LoadContent()
{
player = Content.Load<Texture2D>("player");
}
protected override void Update(GameTime gameTime)
{
input.player_X = player_X;
input.player_Y = player_Y;
input.Update(gameTime);
}
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
_spriteBatch.Begin();
_spriteBatch.Draw(player, new Rectangle(player_X, player_Y, 25, 25), Color.White);
_spriteBatch.End();
base.Draw(gameTime);
}
}
}
我已经在每个类中提供了几乎所有内容,但在 Game1 类中,问题(我认为)在于更新中。
简而言之,我的问题是如何获得它,以便键盘输入位于另一个类中,但其工作方式与全部位于 Game1 类中时相同?
现在它位于不同的位置,当我运行代码时,玩家不会移动。 我需要做什么才能使用类并仍然让代码执行它应该执行的操作??
在键盘类中,您定义了一个新变量
player_X
和 player_Y
。
player_X
中使用的 player_Y
和 Game1
不同,因此它们之间没有联系。
向
KeyboardInput.Update()
添加参数可能有效,但只有在使用 ref 时才会更新,如下所示:
public void Update(GameTime gameTime, ref int Player_Y, ref int Player_X)
此外,如果你带一个类作为参数,你也可以更新变量,你仍然可以使用
ref
作为一个简单的方法,但我认为这会因为很多ref
参数而变得混乱。
我认为您使用类的方法是正确的,但我也建议创建一个
Player
类。并将 player_X
和 player_Y
放在那里。
从那里,您可以将 Player
类添加到 KeyboardInput.Update()
的参数,或者可以将 Update()
代码放在 Player 类中。 (后者是我的偏好)
Player 类示例:
namespace rpg_game
{
public class Player
{
public int X;
public int Y;
private Texture2D playerSprite;
KeyboardState keyboardState = Keyboard.GetState();
public void Update()
{
if (keyboardState.IsKeyDown(Keys.W)) { Y -=1; }
if (keyboardState.IsKeyDown(Keys.A)) { X -= 1; }
if (keyboardState.IsKeyDown(Keys.S)) { Y += 1; }
if (keyboardState.IsKeyDown(Keys.D)) { X += 1; }
}
//While at it, you could also add a draw Method, and call the player.Draw in the Game1.cs
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(playerSprite, new Rectangle(X, Y, 25, 25), Color.White);
}
}
}
然后,在 Game1.cs 中,您可以在那里定义 Player 类:
//right underneath the KeyboardInput input = new KeyboardInput(); You'll need to remove the player_X, player_Y and Texture2D variables afterwards
Player player = new Player() {X = 100, Y = 38}
//In the Update()
player.Update(); //gameTime parameter is only necessary if you're going to use it.
//In the Draw(), should still be between the spritebatch.Begin and spritebatch.End
player.Draw(_spriteBatch); //replaces the _spriteBatch.Draw(player /*...*/ );
(您需要删除
如果您仍然希望使用 KeyboardInput.Update 而不是 Player.Update,那么您可以删除
Player.Update()
方法,并将参数添加到 KeyboardInput.Update (player_x
/player_Y
需要更改为好吧):
public void Update(GameTime gameTime, Player player)
{
if (keyboardState.IsKeyDown(Keys.W)) { player.Y -=1; }
if (keyboardState.IsKeyDown(Keys.A)) { player.X -= 1; }
if (keyboardState.IsKeyDown(Keys.S)) { player.Y += 1; }
if (keyboardState.IsKeyDown(Keys.D)) { player.X += 1; }
}