如何检测球员是否与世界的一部分相交

时间:2011-07-25 00:40:16

标签: c# xna intersection intersect

如果问题标题不清楚,我很抱歉,但凭借我便宜的英语,我无法找到一种方法来清楚地问清楚。

但我可以解释它。

所以我已经意识到,如果我设计我的世界(和世界,我的意思是整个游戏,它将是一个级别)10.000x10.000 ......它将是足够的,除了少数另一个精灵(我的意思是像4或5,最大50x50,没什么大的。)

所以我想,为什么我不把我的整张地图制作成10.000x10.000(或者说是512x512吨)的图片? 但我有一个问题,你可以“互动”的东西很少。他们(与他们一起,我的意思是“world.jpg”中的东西)总是停留在同一个地方,但是玩家(实际上是一个精灵)会移动,因此我的10.000x10.000会“移动”。

所以看下面的图片,有黑点是“玩家”和红点,也就是说,一扇门。

除非他走向世界末日,否则世界总是以黑点为中心。你可以看到,(看图片第1部分和第2部分)当他向东移动一点点时,红点看起来很动人。但我刚刚移动了我的10.000x10.000图像。多数民众赞成在10kx10k图片中我的意思将会移动。

无论如何,但正如你在pic的最后部分所看到的那样,当他走近红点时,我想要我的“行动”

怎么做?

下面的

-part与主要问题

无关

使用10kx10 pic而不是移动时出现在世界上的其他精灵是否有用?但是如果我想这样做,不仅仅是我会检查他是否在附近,但我也会检查他的观点,以确认我是否应该向他展示精灵。

如果我在找到我想要的坐标时展示我的东西,或者使用一张大图片是否可以,它会更有用吗?

感谢。

3 个答案:

答案 0 :(得分:1)

我会建议地图的结构有点像这样..

public class Map
{
     public MapPoint[,] mapPoints;       //the map
     public Player player;               //the player/user object
     public Vector2 DrawHeroPosition;    
     //where at the screen the player is going to be drawn
     public Vector2 RangeStart;          
     //what part of the map who is going to be drawn
     public int SizeX;     //number of mapPoints the screen can contain at one time 
     public int SizeY;     //number of mapPoints the screen can contain at one time 

     //MapPoint represents a specific 512x512 point (mapPoint) its position at
     //the map but also includes the sprite that is going to be drawn and objects
     //that the player can interact with at that place (like the door)

     //the player object includes reference to where in the world it is place

     public Map(ContentManager theContentManager, int x, int y)
     {
        MapSizeX = x;
        MapSizeY = y;
        int ScreenSizeX = 9;
        int ScreenSizeY = 9;
        mapPoints = new MapPoint[MapSizeX , MapSizeY];

        //ad code for generating/creating map...
        //important that you store the MapPoints position inside each mapPoint

        player = new Player(mapPoints[0,0]);  //crate a player who knows where he is
    }

    public void Update()
    {
       //in the update method you do a lot of things like movement and so
       //set what part of the map the game should draw if the game for example
       //can show 9x9 512points at a single time

       //give range value from the players position
        RangeStart.X = player.PositionX;

        //test if the maps position is in the left corner of the map
        //if it is draw the map from the start..(RangeStart.X = 0)
        if (player.PositionX - (ScreenSizeX / 2) < 0) { RangeStart.X = 0; }
        //if not draw the hero in the mitle of the screen
        else
        {
            RangeStart.X = player.PositionX - (ScreenSizeX / 2);
        }
        //if the hero is in the right corer, fix his position
        while (RangeStart.X + ScreenSizeX > MapSizeX)
        {
            RangeStart.X--;
        }

        //the same thing for the Y axle
        RangeStart.Y = player.PositionY;
        if (player.PositionY - (ScreenSizeY / 2) < 0) { RangeStart.Y = 0; }
        else
        {
            RangeStart.Y = player.PositionY - (ScreenSizeY / 2);
        }
        while (RangeStart.Y + ScreenSizeY > MapSizeY)
        {
            RangeStart.Y--;
        }

        //time to set the position of the hero...
        //he works like the opposite of the range, if you move what part of the map
        //you draw you dont change the heros draw position, if you dont move the range
        //you have to move the hero to create the illusion of "moment"

        //if you are in the left part you have to move the heros draw position..
        if (player.PositionX - (ScreenSizeX / 2) < 0) 
        { DrawHeroPosition.X = player.PositionX; }

        //if you are in the right part
        else if (player.PositionX+1 > MapSizeX - (ScreenSizeX / 2))
        {
            DrawHeroPosition.X = player.PositionX - (MapSizeX - ScreenSizeX);
        }

        //if you aint in a corner, just place the hero in the middle of the map
        else
        {
            DrawHeroPosition.X = (ScreenSizeX / 2);
        }


        //the same thing for Y
        if (player.PositionY - (ScreenSizeY / 2) < 0) 
        { DrawHeroPosition.Y = player.PositionY; }
        else if (player.PositionY+1 > MapSizeY - (ScreenSizeY / 2))
        {
            DrawHeroPosition.Y = player.PositionY - (MapSizeY - ScreenSizeY);
        }
        else
        {
            DrawHeroPosition.Y = (ScreenSizeY / 2);
        }

    }

    public void Draw()
    {

        int x = (int)RangeStart.X;
        int y = (int)RangeStart.Y;

        for(int counterX = 0; x < ((MapSizeX)); x++, counterX++)
        {
            for (int counterY = 0; y < (MapSizeY); y++, counterY++)
            {
               if (mapPoints[x, y] != null)
               {
                 mapPoints[x, y].Draw(spriteBatch, mapPoints[counterX,counterY].positonInMatrix);
                 //mapPoints[counterX,counterY] = where to draw
                 //mapPoints[x, y] = what to draw
               }
            }
            y = (int)RangeStart.Y;
        }
    }
}

我如何在MapPoint类中绘制...

public void Draw(SpriteBatch theSpriteBatch, Vector2 positonOnScreen)
    {
        positonOnScreen = new Vector2(positonOnScreen.X * base.Scale * 16,
        positonOnScreen.Y * base.Scale * 16);

        //base.Scale is just a variable for have the ability to zoom in/out
        //16 represents the original size of the picture (16x16 pixels)

        theSpriteBatch.Draw(mSpriteTexture, new Rectangle((int)positonOnScreen.X,
        (int)(positonOnScreen.Y), 64, 64),new Rectangle(0, 0, 16, 16), Color.White);
     }

答案 1 :(得分:1)

如果要求在红点范围内进行碰撞检测。您可以简单地使用以下测试(伪代码,我不写C#: - )

if( (player.GetPosition() - point.GetPosition()).length() < radius )
{ /* Do code here */ }

这将检测您的玩家是否在您的点的某个半径范围内,然后您可以执行您希望的任何操作。

希望这有帮助! :)

答案 2 :(得分:0)

好的,根据我对你的问题的理解,你有一个大图像,其中包含你希望玩家与之交互的不同对象,是吗?我的意思是,图像文件本身有门或山丘或玩家可以与之互动的其他东西。

老实说,这是一个坏主意,所以我希望我误解了。最好让你的背景图像成为通用的,并在游戏中制作所有交互式对象类。如果这样做,那么您可以让对象类包含基于它们的距离(圆形碰撞)或基于您为它们定义的边界框相互交叉的行为。

圆形碰撞:

if (Math.Abs(Vector2.Distance(player.Position - obj.Position)) < player.Radius + obj.Radius)
    //do the action

矩形碰撞:

if (player.Bounds.Intersects(obj.Bounds))
   //do the action

此外,如果您计划制作10,000 x 10,000像素的图像,请了解XNA内容管道不会将大于4,000像素的图像导入到一侧。

如果你让玩家与图像背景中的像素进行交互,你可以手动创建一个交互式对象位置数组,也可以使用Texture2D.GetData()方法加载每个颜色的颜色。图像中的单个像素用于处理 - 但要注意这将花费很长时间,特别是对于大型或多种纹理。