Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/296.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 像在Poké中那样移动精灵;周一_C#_Xna_Monogame - Fatal编程技术网

C# 像在Poké中那样移动精灵;周一

C# 像在Poké中那样移动精灵;周一,c#,xna,monogame,C#,Xna,Monogame,我有一个游戏,我想让我的角色在我的领域中一方一方地移动,就像在神奇宝贝里一样 根据我的代码,它是一个方块一个方块地移动的,只不过它会在每个按键上跳过大约4-5个方块。然后跳来跳去 有人能帮助我以类似于神奇宝贝的方式完成代码工作吗 我的代码如下 public class Map { private Map() { Position = new Vector2(0, 0); } public string Data { get; set; } p

我有一个游戏,我想让我的角色在我的领域中一方一方地移动,就像在神奇宝贝里一样

根据我的代码,它是一个方块一个方块地移动的,只不过它会在每个按键上跳过大约4-5个方块。然后跳来跳去

有人能帮助我以类似于神奇宝贝的方式完成代码工作吗

我的代码如下

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 Vector2 Speed = new Vector2(40, 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 x = this.ArrayPosition.X;
        var y = this.ArrayPosition.Y;
        switch (pdirection) {
            case Direction.Up:
                if (y > 0 && y < 16) {
                    direction = new Vector2(0, -1);
                }
                break;

            case Direction.Down:
                if (y < 16 && y >= 0) {
                    direction = new Vector2(0, 1);
                }
                break;

            case Direction.Left:
                if (x > 0 && x < 16) {
                    direction = new Vector2(-1, 0);
                }
                break;

            case Direction.Right:
                if (x < 16 && x >= 0) {
                    direction = new Vector2(1, 0);
                }
                break;
        }
        Position += direction * Speed;
    }

    private void drawPlayer() {
        var tile = Position / Speed;
        var x = tile.X;
        var y = tile.Y;
        drawTile((int)x, (int)y);
        var texture = Content.Load<Texture2D>("Sprites/player");
        this.SpriteBatch.Draw(texture, Position, 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);
    }
}
公共类映射{
私有地图(){
位置=新矢量2(0,0);
}
公共字符串数据{get;set;}
公共字符串[][]映射数据{get;set;}
公共ContentManager内容{get;set;}
公共SpriteBatch SpriteBatch{get;set;}
公共向量2位置{get;set;}
专用矢量2阵列位置;
私有只读矢量2速度=新矢量2(40,32);
公共静态映射解析(字符串路径){
var map=newmap();
var stream=TitleContainer.OpenStream(Path.Combine(“Content”,Path));
使用(var sr=新的StreamReader(stream)){
map.Data=sr.ReadToEnd();
}
var lines=map.Data.Split(新字符串[1]{Environment.NewLine},StringSplitOptions.None);
var mapHeight=lines.Count();
map.MapData=新字符串[mapHeight][];
对于(int i=0;i0&&y<16){
方向=新矢量2(0,-1);
}
打破
案例方向。向下:
如果(y<16&&y>=0){
方向=新矢量2(0,1);
}
打破
案例方向。左:
如果(x>0&&x<16){
方向=新矢量2(-1,0);
}
打破
案例说明。右:
如果(x<16&&x>=0){
方向=新矢量2(1,0);
}
打破
}
位置+=方向*速度;
}
私人玩家(){
var tile=位置/速度;
var x=tile.x;
var y=tile.y;
拉瓦((内部)x,(内部)y);
var texture=Content.Load(“精灵/玩家”);
这个.SpriteBatch.Draw(纹理、位置、颜色、白色);
}
私人无效付款人(整数x,整数y){
牵引瓦(x,y);
drawTexture(Content.Load(“精灵/敌人”),x,y);
}
专用空心绘图砖(整数x,整数y){
drawTexture(内容加载(“瓷砖/草”),x,y);
}
专用空心抽墙(内部x、内部y){
drawTexture(内容物荷载(“瓷砖/墙”),x,y);
}
私有void drawTexture(Texture2D纹理,int x,int y){
变量矩形=新矩形(x*40,y*32,40,32);
这个.SpriteBatch.Draw(纹理、矩形、颜色、白色);
}
}

在我看来,除了可能的累积移动增量误差外,您还使用了坐标系的混合来表示地图上的事物。考虑< <强> > <强>坐标系。我不确定你的地图有多大,所以我们假设它是10x10。因此,瓷砖;敌人;玩家的坐标应该在{0…9}x{0…9}之内

e、 g.在您的
DrawMap()
中,我看到您的平铺使用了一个坐标系0来表示您的
字符串[][]MapData
。在
drawTexture()
之前,请保持坐标的缩放,如下所示,我认为这是一个好主意:

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

提示:尽量避免代码中出现幻数。考虑将40和32定义为常量,或者更好地确定在<代码>加载内容()/<代码>运行时的瓦片大小。
但是,根据
方向
移动播放机的方法
Move()
,按
速度
缩放,定义如下:

private readonly Vector2 Speed = new Vector2(40, 32);
…我认为这不是一个好主意,因为你用玩家的速度来缩放瓷砖的大小,这导致玩家的坐标系与敌人的坐标系、墙壁和其他地图数据完全不同。因为它是按比例缩放的,所以每当你想与地图交互时,你都需要一直除以平铺大小来规范玩家的坐标

稍后,当你画玩家时,你有一条不寻常的线:

private void drawPlayer() {
    var tile = Position / Speed;
如果
p
是位置,
v
是速度
t
是时间;然后是
p=vt
,紧接着就是
t=p/v
,所以仅仅阅读上面这一行就有点奇怪了。但我知道你想做什么——根据瓷砖大小确定瓷砖的坐标

然而,如果你只是将玩家的位置标准化,使其始终保持在范围{0…MapData dimensions}内,而不按(40,32)缩放,这将使事情变得更简单

变化 在
Move()
方法中更改此行:

    Position += direction * Speed;
…致:

    Position += direction;
private void drawPlayer() {
    drawTile((int)Position.x, (int)Position.y);
    var texture = Content.Load<Texture2D>("Sprites/player");

    var p = Position * new Vector2 (40,32);
    this.SpriteBatch.Draw(texture, p, Color.White);
}
然后从以下位置更改
drawPlayer()

private void drawPlayer() {
    var tile = Position / Speed;
    var x = tile.X;
    var y = tile.Y;
    drawTile((int)x, (int)y);
    var texture = Content.Load<Texture2D>("Sprites/player");
    this.SpriteBatch.Draw(texture, Position, Color.White);
}
pr