开发者

How to detect if player intersects PART of the world

开发者 https://www.devze.com 2023-03-22 10:17 出处:网络
I\'m sorry if question title was unclear, but with my cheap english, I cant find away to ask it clearly.

I'm sorry if question title was unclear, but with my cheap english, I cant find a way to ask it clearly.

But I can explain it in long way.

So I have realized if I design my world(and with world, I mean ENTIRE game, it will be one level) 10.000x10.000... it will be very enough, other than few another sprite(and I mean like 4 or 5 with maximum of 50x50, nothing big.)

So I thought, why dont I make my entire map as 10.000x10.000(or lets say tons of 512x512) picture ? But I have one question, there is few things 开发者_开发知识库you can "interact". they will(with they, I mean the stuff that is in my "world.jpg") be always stay at same place, but player(which is actually a sprite as you know) will move, therefore my 10.000x10.000 will "move".

So look at picture below, there is black dot which is "player" and red dot, which is lets say, a door.

and world is always centered to black dot unless he goes to end of the world. as you can see, (look at picture part 1 and part 2) when he moves a little bit to east, red dot looks moved. but I just moved my 10.000x10.000 image. Thats what I meant with the stuff on 10kx10k pic will move.

Anyway, but as you can see in last part of pic, when he goes near red dot, I want to my "action"

How to do it ?

-part below is not really related to main question

Is it useful to use 10kx10 pic instead of another sprites appearing on world when he moves ? but If I want to do that, not just I will check if he is nearby, but I will also check his point to realize if I should or shouldnt show him sprite.

Will it be more useful if I show my stuff when he comes to coordinates I want, or is using one big picture is OK ?

Thanks.

How to detect if player intersects PART of the world


I would suggest a structure of the map somewhat like this..

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

how i draw inside the MapPoint Class...

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


If you are asking for collision detection within a radius of your red dot. You can simply use the following test (pseudocode, I don't write C# :-)

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

This will detect if your player is within a certain radius of your dot, you can then perform whatever action you wish.

Hope this helps! :)


Ok, from what I understand of your question, you have a large image which contains different objects you want your player to interact with, yes? By which I mean, the image file itself has doors or hills or other things which the player would interact with.

This is a bad idea, honestly, so I hope I misunderstood. It is far better to have your background image just be something generic and make all interactive objects classes within your game. If you do this, then you can have your object classes contain behavior to intersect with each other either based on their distance (circle collision) or based on a bounding box you define for them.

Circle Collision:

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

Rectangle Collision:

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

Also, if you are planning on making a 10,000 x 10,000 pixel image, understand that the XNA Content Pipeline will not import an image greater than 4,000 pixels to a side.

If you are set on having the player interact with pixels in the background of the image, you can either make an array of interactive object locations manually or you can use the Texture2D.GetData() method to load in the colors of every single pixel in the image for processing-- but be aware that this will take a long time, especially for large or numerous textures.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号