Как определить, пересекает ли игрок ЧАСТЬ мира - PullRequest
0 голосов
/ 25 июля 2011

Извините, если название вопроса было неясным, но с моим дешевым английским я не могу найти способ задать его четко.

Но я могу объяснить это долго.

Поэтому я понял, что если я спроектирую свой мир (а под словом «мир» я имею в виду ВСЮ игру, это будет один уровень) 10.000x10.000 ... этого будет достаточно, кроме нескольких других спрайтов (и я имею в виду, как 4 или5 с максимумом 50x50, ничего большого.)

Итак, я подумал, почему я не делаю всю свою карту в виде 10.000x10.000 (или, скажем, тонн 512x512) изображения?Но у меня есть один вопрос, есть несколько вещей, которые вы можете «взаимодействовать».они будут (вместе с ними, я имею в виду материал, который находится в моем "world.jpg") всегда будут оставаться на одном месте, но игрок (который, как вы знаете, на самом деле является спрайтом) будет двигаться, поэтому моя 10.000x10.000 будет "move ".

Итак, посмотрите на картинку ниже, есть черная точка, которая является" игроком ", и красная точка, которая, скажем, дверь.

и мир всегда центрирован по черной точкеесли он не пойдет на конец света.как вы можете видеть, (посмотрите на часть изображения 1 и часть 2), когда он перемещается немного на восток, красная точка выглядит перемещенной.но я только что переместил свое изображение 10.000x10.000.То, что я имел в виду с материалом на картинке 10kx10k, будет двигаться.

В любом случае, но, как вы можете видеть в последней части рисунка, когда он приближается к красной точке, я хочу, чтобы мое «действие»

Как это сделать?

-часть ниже на самом деле не связана с основным вопросом

Полезно ли использовать картинку 10kx10 вместо других спрайтов, появляющихся в мире, когдаон двигается?но если я хочу сделать это, я не только проверю, находится ли он рядом, но я также проверю его точку зрения, чтобы понять, должен ли я показать ему спрайт или нет.

Будет ли полезнее, если я покажумои вещи, когда он приходит к координатам, которые я хочу, или использует одну большую картинку, это нормально?

Спасибо.

Ответы [ 3 ]

1 голос
/ 25 июля 2011

Если вы запрашиваете обнаружение столкновений в радиусе вашей красной точки.Вы можете просто использовать следующий тест (псевдокод, я не пишу C #: -)

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

Это позволит определить, находится ли ваш игрок в пределах определенного радиуса от вашей точки, затем вы можете выполнить любое действие, которое выпожелает.

Надеюсь, это поможет!:)

1 голос
/ 25 июля 2011

Я бы предложил структуру карты примерно так ...

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);
     }
0 голосов
/ 26 июля 2011

Хорошо, из того, что я понимаю по вашему вопросу, у вас есть большое изображение, которое содержит различные объекты, с которыми ваш проигрыватель взаимодействует, да?Я имею в виду, что в самом файле изображения есть двери, холмы или другие объекты, с которыми игрок может взаимодействовать.

Честно говоря, это плохая идея, поэтому я надеюсь, что меня неправильно поняли.Гораздо лучше, чтобы фоновое изображение было просто общим и создавало все классы интерактивных объектов в вашей игре.Если вы сделаете это, то ваши классы объектов могут содержать поведение, которое может пересекаться друг с другом, либо на основе их расстояния (столкновение окружности), либо на основе ограничительной рамки, которую вы для них определили.

Столкновение окружности:

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 10000 пикселей, следует понимать, что конвейер содержимого XNA не будет импортировать изображение размером более 4000 пикселей всторона.

Если вы настроили взаимодействие плеера с пикселями на заднем плане изображения, вы можете либо создать массив местоположений интерактивных объектов вручную, либо использовать метод Texture2D.GetData () длязагружайте цвета каждого пикселя в изображении для обработки, но имейте в виду, что это займет много времени, особенно для больших или многочисленных текстур.

...