动作非常快
Movement very fast
我有一个 monogame 项目,我想根据键盘输入移动玩家。但是我的代码只是让移动超快。
我尝试了不同的速度限制,并检查了如果使用不同的 GameTime
属性是否可行。
我的代码哪里有问题?
public class Map {
private Map() {
Position = new Vector2(0, 0);
}
public string Data { get; set; }
public string[][] MapData { get; set; }
public ContentManager Content { get; set; }
public SpriteBatch SpriteBatch { get; set; }
public Vector2 Position { get; set; }
private Vector2 ArrayPosition;
private readonly int Speed_X = 40;
private readonly int Speed_Y = 32;
public static Map Parse(string path) {
var map = new Map();
var stream = TitleContainer.OpenStream(Path.Combine("Content", path));
using (var sr = new StreamReader(stream)) {
map.Data = sr.ReadToEnd();
}
var lines = map.Data.Split(new string[1] { Environment.NewLine }, StringSplitOptions.None);
var mapHeight = lines.Count();
map.MapData = new string[mapHeight][];
for (int i = 0; i < lines.Count(); i++) {
var elements = lines[i].Split(';');
map.MapData[i] = elements;
}
return map;
}
public void DrawMap(SpriteBatch spriteBatch, ContentManager content, GameTime gametime) {
this.SpriteBatch = spriteBatch;
this.Content = content;
for (int y = 0; y < MapData.Count(); y++) {
var current = MapData[y];
for (int x = 0; x < current.Count(); x++) {
switch (current[x]) {
case "e":
drawEnemy(x, y);
break;
case "P":
case ".":
drawTile(x, y);
break;
case "w":
drawWall(x, y);
break;
}
}
}
drawPlayer();
}
public void Move(Direction pdirection, GameTime gametime) {
var direction = Vector2.Zero;
var speed = Vector2.Zero;
var y = Math.Floor(this.ArrayPosition.Y);
var x = Math.Floor(this.ArrayPosition.X);
switch (pdirection) {
case Direction.Up:
if (y > 0 && y < 16) {
direction = new Vector2(0, -1);
speed.Y = Speed_Y;
}
break;
case Direction.Down:
if (y < 16 && y >= 0) {
direction = new Vector2(0, 1);
speed.Y = Speed_Y;
}
break;
case Direction.Left:
if (x > 0 && x < 16) {
direction = new Vector2(-1, 0);
speed.X = Speed_X;
}
break;
case Direction.Right:
if (x < 16 && x >= 0) {
direction = new Vector2(1, 0);
speed.X = Speed_X;
}
break;
}
ArrayPosition = (this.Position + (direction * speed)) / new Vector2(Speed_X, Speed_Y);
var newPosition = this.Position + (direction * speed * gametime.ElapsedGameTime.Milliseconds);
if (this.MapData[(int)Math.Floor(ArrayPosition.Y)][(int)Math.Floor(ArrayPosition.X)] != "w") {
this.Position = newPosition;
}
}
private void drawPlayer() {
var x = Position.X;
var y = Position.Y;
drawTile((int)x, (int)y);
var texture = Content.Load<Texture2D>("Sprites/player");
this.SpriteBatch.Draw(texture, new Vector2(x, y), Color.White);
}
private void drawEnemy(int x, int y) {
drawTile(x, y);
drawTexture(Content.Load<Texture2D>("Sprites/enemy"), x, y);
}
private void drawTile(int x, int y) {
drawTexture(Content.Load<Texture2D>("Tiles/grass"), x, y);
}
private void drawWall(int x, int y) {
drawTexture(Content.Load<Texture2D>("Tiles/wall"), x, y);
}
private void drawTexture(Texture2D texture, int x, int y) {
var rectangle = new Rectangle(x * 40, y * 32, 40, 32);
this.SpriteBatch.Draw(texture, rectangle, Color.White);
}
}
在函数 Move:
中使用类似的东西
float deltatime=0;
public void Move(Direction pdirection, GameTime gametime) {
deltaTime= (float)gameTime.ElapsedGameTime.TotalSeconds;
//calculate your object position using deltatime
}
您应该使用 TotalSeconds
属性 而不是 GameTime.ElapsedGameTime
中的 Milliseconds
。后者是一个 int
,它对小数计算没有用,而前者是一个 double
,它是。由于它是 int
这也解释了为什么你的移动非常快。
在您的 Move() 方法中更改此行:
var newPosition = this.Position +
(direction * speed *
gametime.ElapsedGameTime.Milliseconds);
...至:
var newPosition = this.Position +
(direction * speed *
gametime.ElapsedGameTime.TotalSeconds);
然而与其他发帖人所说的相反,没有必要执行 deltatime=0;
因为 ElapsedGameTime
定义为:
The amount of elapsed game time since the last update - MSDN
你不想重置时间间隔,因为它们只会导致动画,不是,特别是光滑.
告诉我更多
我有一个 monogame 项目,我想根据键盘输入移动玩家。但是我的代码只是让移动超快。
我尝试了不同的速度限制,并检查了如果使用不同的 GameTime
属性是否可行。
我的代码哪里有问题?
public class Map {
private Map() {
Position = new Vector2(0, 0);
}
public string Data { get; set; }
public string[][] MapData { get; set; }
public ContentManager Content { get; set; }
public SpriteBatch SpriteBatch { get; set; }
public Vector2 Position { get; set; }
private Vector2 ArrayPosition;
private readonly int Speed_X = 40;
private readonly int Speed_Y = 32;
public static Map Parse(string path) {
var map = new Map();
var stream = TitleContainer.OpenStream(Path.Combine("Content", path));
using (var sr = new StreamReader(stream)) {
map.Data = sr.ReadToEnd();
}
var lines = map.Data.Split(new string[1] { Environment.NewLine }, StringSplitOptions.None);
var mapHeight = lines.Count();
map.MapData = new string[mapHeight][];
for (int i = 0; i < lines.Count(); i++) {
var elements = lines[i].Split(';');
map.MapData[i] = elements;
}
return map;
}
public void DrawMap(SpriteBatch spriteBatch, ContentManager content, GameTime gametime) {
this.SpriteBatch = spriteBatch;
this.Content = content;
for (int y = 0; y < MapData.Count(); y++) {
var current = MapData[y];
for (int x = 0; x < current.Count(); x++) {
switch (current[x]) {
case "e":
drawEnemy(x, y);
break;
case "P":
case ".":
drawTile(x, y);
break;
case "w":
drawWall(x, y);
break;
}
}
}
drawPlayer();
}
public void Move(Direction pdirection, GameTime gametime) {
var direction = Vector2.Zero;
var speed = Vector2.Zero;
var y = Math.Floor(this.ArrayPosition.Y);
var x = Math.Floor(this.ArrayPosition.X);
switch (pdirection) {
case Direction.Up:
if (y > 0 && y < 16) {
direction = new Vector2(0, -1);
speed.Y = Speed_Y;
}
break;
case Direction.Down:
if (y < 16 && y >= 0) {
direction = new Vector2(0, 1);
speed.Y = Speed_Y;
}
break;
case Direction.Left:
if (x > 0 && x < 16) {
direction = new Vector2(-1, 0);
speed.X = Speed_X;
}
break;
case Direction.Right:
if (x < 16 && x >= 0) {
direction = new Vector2(1, 0);
speed.X = Speed_X;
}
break;
}
ArrayPosition = (this.Position + (direction * speed)) / new Vector2(Speed_X, Speed_Y);
var newPosition = this.Position + (direction * speed * gametime.ElapsedGameTime.Milliseconds);
if (this.MapData[(int)Math.Floor(ArrayPosition.Y)][(int)Math.Floor(ArrayPosition.X)] != "w") {
this.Position = newPosition;
}
}
private void drawPlayer() {
var x = Position.X;
var y = Position.Y;
drawTile((int)x, (int)y);
var texture = Content.Load<Texture2D>("Sprites/player");
this.SpriteBatch.Draw(texture, new Vector2(x, y), Color.White);
}
private void drawEnemy(int x, int y) {
drawTile(x, y);
drawTexture(Content.Load<Texture2D>("Sprites/enemy"), x, y);
}
private void drawTile(int x, int y) {
drawTexture(Content.Load<Texture2D>("Tiles/grass"), x, y);
}
private void drawWall(int x, int y) {
drawTexture(Content.Load<Texture2D>("Tiles/wall"), x, y);
}
private void drawTexture(Texture2D texture, int x, int y) {
var rectangle = new Rectangle(x * 40, y * 32, 40, 32);
this.SpriteBatch.Draw(texture, rectangle, Color.White);
}
}
在函数 Move:
中使用类似的东西float deltatime=0;
public void Move(Direction pdirection, GameTime gametime) {
deltaTime= (float)gameTime.ElapsedGameTime.TotalSeconds;
//calculate your object position using deltatime
}
您应该使用 TotalSeconds
属性 而不是 GameTime.ElapsedGameTime
中的 Milliseconds
。后者是一个 int
,它对小数计算没有用,而前者是一个 double
,它是。由于它是 int
这也解释了为什么你的移动非常快。
在您的 Move() 方法中更改此行:
var newPosition = this.Position +
(direction * speed *
gametime.ElapsedGameTime.Milliseconds);
...至:
var newPosition = this.Position +
(direction * speed *
gametime.ElapsedGameTime.TotalSeconds);
然而与其他发帖人所说的相反,没有必要执行 deltatime=0;
因为 ElapsedGameTime
定义为:
The amount of elapsed game time since the last update - MSDN
你不想重置时间间隔,因为它们只会导致动画,不是,特别是光滑.