Results 1 to 12 of 12

Thread: [resolved] collision detection (2d array, sprite)

  1. #1

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802

    [resolved] collision detection (2d array, sprite)

    I'm writing a game but I can't get the collision detection to work quite right...

    I have a map of tiles, each tile is 20x20 pixels and I have the map stored in a 2d array iMap[20][20] so my whole map is 400x400 pixels on the screen.

    If I move my sprite 20 pixels at a time the collision detection works because then I can just go: sprite.x/20 to find out where in the array the player is and then chek to see if the next spot in the array is walkable or not.

    The problem is that I want to move my sprite 5 pixels at a time so the method mentioned above won't work. I can partually move through walls and that is not the way I want it.

    How can I get the collision detection to work even if I move 5 pixels at a time?
    Last edited by McCain; Dec 3rd, 2002 at 04:35 AM.
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  2. #2
    Lively Member
    Join Date
    May 2002
    Location
    Oregon
    Posts
    64
    First off, let me say I'm not qualified to answer this so I'm probably a little off on this. But couldn't you just check if sprite.x+5/20 is walkable?

  3. #3

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    No, that wouldn't work...
    I'll give you some code and try to explain why it doesn't work...
    PHP Code:
    if(key == "right")
    {
        if(
    iMap[player.x/20 1][player.y/20] == '0')
            
    player.+= 20;

    The above code will work but the sprite moves 20 pixels at a time and that is too much, I want it to move 5 pixels every time.
    PHP Code:
    if(key == "right")
    {
        if(
    iMap[player.x/20 1][player.y/20] == '0')
            
    player.+= 5;

    This code will only work when player.x is 0, 20, 40, 60, 80, 100 and so on...
    Let's say that player.x == 25 then it would be iMap[25/20+1][player.y/20] and that is not a valid coordinate in the iMap array...
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  4. #4
    transcendental analytic kedaman's Avatar
    Join Date
    Mar 2000
    Location
    0x002F2EA8
    Posts
    7,221
    you'd have to go with the traditional collision detection method, test each object that you can collide with. If you have a large amount of objects that can collide with each other and you're worried about peformance you can use a quadtree to narrow down the object count to test.
    Use
    writing software in C++ is like driving rivets into steel beam with a toothpick.
    writing haskell makes your life easier:
    reverse (p (6*9)) where p x|x==0=""|True=chr (48+z): p y where (y,z)=divMod x 13
    To throw away OOP for low level languages is myopia, to keep OOP is hyperopia. To throw away OOP for a high level language is insight.

  5. #5
    Frenzied Member
    Join Date
    Jul 2002
    Posts
    1,370
    You have two choices:
    1. use an array[80][80], ie., 5 pixel tiles- which is probably a terrible idea, since your sprites would occupy more territiry than that.
    2. round .x and .y (up or down) to the nearest value of 20, put in temp variables then test collision.

    You cannot have two granularities and expect them to compare directly without compensating.... somehow

  6. #6
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by McCain

    Let's say that player.x == 25 then it would be iMap[25/20+1][player.y/20] and that is not a valid coordinate in the iMap array...
    Yes, it is a valid coordinate. 25/20 is 1 (integer division), plus 1 is 2. However, you get an incorrect result, because you are checking the next cell in the map, but you arent actually to that cell yet (youd be halfway across the current cell, after the move). What you want to do is add 5 BEFORE the division to get the correct cell.

    Z.

  7. #7

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    Actually I might not be halfway to the next cell as I have to move 4 times to get to a new cell (I only move 5 pixels at a time and each tile (cell) is 20 pixels x 20 pixels)

    Let's say player.x == 45 then I'm only 1/4 in the next cell and if I add 5 I'm halfway... So sometimes I'd have to add 5, sometimes 10 and sometime 15, how do I know when to add what?
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  8. #8
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    What about this: check for each of the 4 corners of the sprite in what tile they would be in after the move. Then test each of these tiles for passability.
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  9. #9
    Frenzied Member Zaei's Avatar
    Join Date
    Jul 2002
    Location
    My own little world...
    Posts
    1,710
    Originally posted by McCain
    Actually I might not be halfway to the next cell as I have to move 4 times to get to a new cell (I only move 5 pixels at a time and each tile (cell) is 20 pixels x 20 pixels)

    Let's say player.x == 45 then I'm only 1/4 in the next cell and if I add 5 I'm halfway... So sometimes I'd have to add 5, sometimes 10 and sometime 15, how do I know when to add what?
    If moving 5 pixels, add 5 to the .x position before divding by 20. If 10, add 10, 15, add 15.

    CB's suggestion is a better solution, however, sicne it allows any granularity in movement.

    Z.

  10. #10

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    2. round .x and .y (up or down) to the nearest value of 20, put in temp variables then test collision.
    How would I do that? How do I know how much I need to add or subtract to get to a number that is dividible by 20

    What about this: check for each of the 4 corners of the sprite in what tile they would be in after the move. Then test each of these tiles for passability.
    If I'm given any x-coordinate or y-coordinate, how can I know what cell that coord is in? will it work if I just integer devide it by 20?
    Last edited by McCain; Nov 29th, 2002 at 04:10 PM.
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

  11. #11
    Kitten CornedBee's Avatar
    Join Date
    Aug 2001
    Location
    In a microchip!
    Posts
    11,594
    Yes.

    And to find the nearest integer divisible by 20:
    Code:
    inline int findNearestDivisible(int divisor, int number)
    {
      int diff = number % divisor;
      return (diff < divisor/2) ?
        (number - diff) : (number + (divisor-diff));
    }
    All the buzzt
    CornedBee

    "Writing specifications is like writing a novel. Writing code is like writing poetry."
    - Anonymous, published by Raymond Chen

    Don't PM me with your problems, I scan most of the forums daily. If you do PM me, I will not answer your question.

  12. #12

    Thread Starter
    Fanatic Member McCain's Avatar
    Join Date
    Jan 2002
    Location
    Sweden/Denmark
    Posts
    802
    Thank you guys for all your help!
    The collision detection now works perfect.

    Here is the code if you're interested:
    Code:
    if(g_pacInfo.x % 20 == 0)
    	g_pacInfo.arrayx = g_pacInfo.x / 20;
    if(g_pacInfo.y % 20 == 0)
    	g_pacInfo.arrayy = g_pacInfo.y / 20;
    
    //Left
    if(GetAsyncKeyState(VK_LEFT)<0) 
    {
    	if(g_pacInfo.x % 20 == 0)
    	{
    		if(iMap[g_pacInfo.arrayx - 1][g_pacInfo.y / 20] == '0')
    		{
    			if(iMap[g_pacInfo.arrayx - 1][(g_pacInfo.y + 19) / 20] == '0')
    			{
    				g_pacInfo.x -= 5;
    			}
    		}
    	}
    	else
    	{
    		g_pacInfo.x -= 5;
    	}
    }
    
    //Right
    if(GetAsyncKeyState(VK_RIGHT)<0)
    {
    	if(g_pacInfo.x % 20 == 0)
    	{
    		if(iMap[g_pacInfo.arrayx + 1][g_pacInfo.y / 20] == '0')
    		{
    			if(iMap[g_pacInfo.arrayx + 1][(g_pacInfo.y + 19) / 20] == '0')
    			{
    				g_pacInfo.x += 5;
    			}
    		}
    	}
    	else
    	{
    		g_pacInfo.x += 5;
    	}
    }
    
    //Up
    if(GetAsyncKeyState(VK_UP)<0)
    {
    	if(g_pacInfo.y % 20 == 0)
    	{
    		if(iMap[g_pacInfo.x / 20][g_pacInfo.arrayy - 1] == '0')
    		{
    			if(iMap[(g_pacInfo.x + 19) / 20][g_pacInfo.arrayy - 1] == '0')
    			g_pacInfo.y -= 5;
    		}
    	}
    	else
    	{
    		g_pacInfo.y -= 5;
    	}
    }
    
    //down
    if(GetAsyncKeyState(VK_DOWN)<0)
    {
    	if(g_pacInfo.y % 20 == 0)
    	{
    		if(iMap[g_pacInfo.x / 20][g_pacInfo.arrayy + 1] == '0')
    		{
    			if(iMap[(g_pacInfo.x + 19) / 20][g_pacInfo.arrayy + 1] == '0')
    			g_pacInfo.y += 5;
    		}
    	}
    	else
    	{
    		g_pacInfo.y += 5;
    	}
    }
    Never argue with fools, they will only drag you down to their level, and beat you with experience.

    Q: How do you tell an experienced hacker from a novice?
    A: The latter thinks there's 1000 bytes in a kilobyte, while the former is sure there's 1024 meters in a kilometer

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width