Can you check collisions/overlaps without counting transparent squares?

Started by bx83, Tue 29/06/2021 09:17:53

Previous topic - Next topic

bx83

I want to check a collision (or overlap) between my character and the 'borders' of the maze (ie. the walls). I've run out of objects (40 used) so I must use the object that represents the maze 'board' - with transparencies to move through.
How is this possible?
My main character has hardly any transparency around edges, but obviously the maze image has lots through and around it.
Would I better of using and detecting walkable areas drawn where the 'solid' bits of the maze are?

Crimson Wizard

Assuming you are speaking of the pac-man like game idea you mentioned previously, the big question is - whether your map is grid based. That is - if everything, or at least the static objects such as walls, is aligned to a grid.
If it is then you may simply make an array of ints defining what lies in a grid, and check for cells when you move your player and other movable objects.

If it's not grid based, one solution I used in my racing game where I would draw walkable areas and test an area at few player's edge point(s). When the player moves, I'd project its position in the direction of movement and test if there is any "wall" area detected under one of the edge points' future position. In case there were I'd stop or calculate "bounce" from the wall, but latter may be not necessary for your game.
This is not an ultimate solution, but it works so long as a) there's no walls thinner than the player, b) player's speed is not fast enough to "jump" over the wall in one go.

There may be other solutions, but the selection must depend on what kind of map and game movement you have.

For example, if your game is based on rectangles (even if not grid-based), there's an algorithm known as AABB collisions (AABB stands for axis-aligned bound box, which is basically a non-rotated rectangle).
Just because I used this before, here's the LUA library that does such collision detection: https://github.com/kikito/bump.lua
It's not too big, but will require a good effort to transfer to AGS due to the differences in language.

Maybe someone else already did similar thing for AGS. You may try searching for the platformer arcade game "Art of Dying" which is open source.

bx83

Oh I’ve grabbed art of dying code; now there’s the fun of interpreting it :/  will check for collision code.
Do you see any hope in artificial transplant of aabb code on to character sprites?
(As opposed to objects)

Crimson Wizard

Quote from: bx83 on Tue 29/06/2021 13:09:07
Do you see any hope in artificial transplant of aabb code on to character sprites?

You calculate the rectangle sprite position and pass it into aabb collision code.

If you need a pixel-perfect collision, then you first find out if aabb collision occurs, then take the sprite and check pixels, although that may be slow.

In any case I'd recommend to first find the overall kind of collision check that works for you, then go into such details.

bx83

Do you happen to know the function name/asc file where The Art of Dying has the AABB code? Found the source.

bx83

Too late - found it, broke my brain.
It's a doing a simple vector collission line-by-line. Or something.

I found this easier algorithm here (https://www.geeksforgeeks.org/find-two-rectangles-overlap/) which sees if two rectangles are overlapping, and returns true if they are. I converted to this:

Code: ags
function IsOverlappingCO(Character *ch, Object *ob)
{
  int v = ch.View;  
  ViewFrame* frame = Game.GetViewFrame(v, 0, 0);
  int wC = Game.SpriteWidth[frame.Graphic];
  int hC = Game.SpriteHeight[frame.Graphic];
  
  // +---^---+
  // |   |   |
  // |   |   |
  // <---X--->
  //character measures from bottom-centre corner up
  
  //actual coords +/- dimensions  
  int TLCharX = (ch.x - (wC/2));
  int TLCharY = (ch.y - (hC));
  int BRCharX  = TLCharX + wC;
  int BRCharY  = TLCharY + hC;
  
  //==
  
  int wO = Game.SpriteWidth[ob.Graphic];
  int hO = Game.SpriteHeight[ob.Graphic];
  
  // ^-------+
  // |       |
  // |       |
  // X------->
  //object measures from bottom-left corner up
  
  //actual coords +/- dimensions
  int TLObjX = ob.X;
  int TLObjY = ob.Y - hO;
  int BRObjX = ob.X + wO;
  int BRObjY = ob.Y;
  
  //             l2
  //             tlobj
  //             +---------+
  //             | obj     |
  //      l1     |         |
  //      tlchar |         |
  //      +-----------+    |
  //      | char |    |    |
  //      |      |    |    |
  //      |      +----|----+r2
  //      |           |     brobj
  //      +-----------+r1
  //                   brchar
  //
  
  // the line cannot have positive overlap
  if (TLCharX == BRCharX || TLCharY == BRCharY || TLObjX == BRObjX || TLObjY == BRObjY) return false;

  // If one rectangle is on left side of other
  if (TLCharX >= BRObjX || TLObjX >= BRCharX) return false;

  // If one rectangle is above other
  if (TLCharY >= BRObjY || TLObjY >= BRCharY) return false;

  return true; 
}


Pending glaring errors, this means I can compare the whole of a character, to the whole of an object - without worrying about their points of origin or that a character must be 'standing on a object', etc. etc.

Can anyone see anything wrong with it? Calculation's, logic?
1. It figures out width, height of the Character, and then absolute top-left and bottom-right corners of it's sprite in real coords (not just 0+length,0+height, but their position on screen)
2. Same for Object
3. Checks if they are not touching - return false
4. Checks if there are off to eachother's right or left - return false
5. Checks if there are above or below one another - return false
6. Otherwise, they have some part overlapping - return true

??

Khris

The code is very basic.

Assuming you have .x and .y for the top-left corner and .w and .h for the dimensions:

Code: ags
function areOverlapping(Rect r1, Rect r2) {
  if (r1.x + r1.w < r2.x || r1.x > r2.x + r2.w) return false; // no horizontal overlap
  if (r1.y + r1.h < r2.y || r1.y > r2.y + r2.h) return false;  // no vertical overlap
  return true;  // overlap
}


Khris

It gets a bit longer if you include the conversions from AGS chars/objs to rectangles :)

SMF spam blocked by CleanTalk