TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

34a277129fa2017d1255f92a059217545915c49a.svn-base (6652B)


      1 #include "ActorCollision.h"
      2 
      3 bool SpatialMonitor::PartitionCells(int worldH, int worldW)
      4 {
      5 	int cellW = (worldW / CELLS_X);
      6 	int cellH = (worldH / CELLS_Y);
      7 
      8 	for (int i = 0; i < CELLS_Y; i++)
      9 	{
     10 		for (int j = 0; j < CELLS_X; j++)
     11 		{
     12 			Cell new_cell;
     13 			new_cell.GetCellRect()->w = cellW;
     14 			new_cell.GetCellRect()->h = cellH;
     15 			new_cell.GetCellRect()->x = cellW * j;
     16 			new_cell.GetCellRect()->y = cellH * i;
     17 
     18 			mCells[i*CELLS_X + j] = new_cell;
     19 
     20 		}
     21 	}
     22 	return true;
     23 }
     24 
     25 bool SpatialMonitor::LogActor(int id)
     26 {
     27 	//mActors[mActorCount] = &act;
     28 	//mActors.Insert(act.GetHandle(), &act);
     29 	//act.SetSpatID(mActorCount);
     30 	UpdateActorCell(id);
     31 	return true;
     32 }
     33 
     34 bool SpatialMonitor::ClearActorCell(int id)
     35 {
     36 	if (GetActorCell(id) != -1)
     37 	{
     38 		mCells[GetActorCell(id)].GetActorTree()->Search(id)->Delete();
     39 		return true;
     40 	}
     41 	return false;
     42 }
     43 
     44 
     45 int SpatialMonitor::UpdateActorCell(int id)
     46 {
     47 	Actor* act = (mAHM->GetActorAddress(id));
     48 	for (int i = 0; i < CELL_COUNT; i++)
     49 	{
     50 		if (DetectCenterPointIntersect( mCells[i].GetCellRect(),  act->GetPosition() ) )
     51 		{
     52 			//gCons->ConsPrintf("Actor entering cell %i\n", i);
     53 			
     54 			if (i != act->GetSpatCell())
     55 			{
     56 				mCells[i].GetActorTree()->Insert(id, NULL);
     57 				ClearActorCell(id); //this is causing the crash, delete function sucks.
     58 				//mCells[GetActorCell(id)].GetActorTree()->Search(id)->Delete();
     59 				act->SetSpatCell(i);
     60 			}
     61 
     62 			return i;
     63 		}
     64 	}
     65 	gCons->ConsPrintf("Could not find Actor cell\n");
     66 	return -1;
     67 }
     68 
     69 int SpatialMonitor::GetAdjacentCells(int cellnum, Cell* cells[9])
     70 {
     71 	cells[0] = GetCell((cellnum - CELLS_X - 1));
     72 	cells[1] = GetCell((cellnum - CELLS_X));
     73 	cells[2] = GetCell((cellnum - CELLS_X + 1));
     74 
     75 	cells[3] = GetCell((cellnum - 1));
     76 	cells[4] = GetCell((cellnum));
     77 	cells[5] = GetCell((cellnum + 1));
     78 	
     79 	cells[6] = GetCell((cellnum + CELLS_X - 1));
     80 	cells[7] = GetCell((cellnum + CELLS_X));
     81 	cells[8] = GetCell((cellnum + CELLS_X + 1));
     82 	
     83 	return 0;
     84 }
     85 
     86 //bool SpatialMonitor::GetActorsInCell(int cellnum) //uneeded now. Use Cell.GetActorTree()
     87 //{
     88 //	for (int i = 0; i < MAX_ACTORS; i++) //this is very bad. Basically defeats the function of cells by check each actor
     89 //	{
     90 //		if (mActorCells[i] == cellnum)
     91 //		{
     92 //			//gCons->ConsPrintf("Actor %i is in adjacent cell\n", i);
     93 //			mAdjacentActorIDs[mAdjacentActorCount] = i;
     94 //			mAdjacentActorCount++;
     95 //		}
     96 //	}
     97 //	return true;
     98 //}
     99 
    100 //bool SpatialMonitor::GetAdjacentActors(int cellnum)
    101 //{
    102 //	mAdjacentActorCount = 0;
    103 //	mAdjacentActorIDs[MAX_ACTORS] = { 0 };
    104 //
    105 //	int cells[9];
    106 //	GetAdjacentCells(cellnum, cells);
    107 //
    108 //	for (int i = 0; i < 9; i++)
    109 //	{
    110 //		GetActorsInCell(cells[i]);
    111 //		//gDiagDraw->LogDiagRect(mCells[cells[i]]);
    112 //	}
    113 //	return true;
    114 //}
    115 
    116 bool SpatialMonitor::DetectActorCollision(int id1, int id2)
    117 {
    118 	if (id1 != id2)
    119 	{	
    120 		//gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition());
    121 		return DetectRectIntersect(mAHM->GetActorAddress(id1)->GetPosition(), mAHM->GetActorAddress(id2)->GetPosition());
    122 	}
    123 	else
    124 	{
    125 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
    126 		return false;
    127 	}
    128 }
    129 
    130 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID)
    131 {
    132 	if (DetectorID != foreignID)
    133 	{
    134 		//gDiagDraw->LogDiagRect(*sensor);
    135 		//gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition());
    136 		return DetectRectIntersect(sensor, mAHM->GetActorAddress(foreignID)->GetPosition());
    137 	}
    138 	else
    139 	{
    140 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
    141 		return false;
    142 	}
    143 }
    144 
    145 bool SpatialMonitor::HandleCollisions(int CallerID)
    146 {
    147 	int CallerCell = GetActorCell(CallerID);
    148 	
    149 	Cell* AdjecentCellIndex[9];
    150 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    151 
    152 	for (int i = 0; i < 9; i++)
    153 	{	
    154 		if (AdjecentCellIndex[i] != NULL)
    155 		{
    156 			Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump();
    157 			if (ActorTreeArray != NULL)
    158 			{
    159 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    160 				{
    161 					if (DetectActorCollision(CallerID, ActorTreeArray[j]->GetItem()) == true)
    162 					{
    163 						mAHM->GetActorAddress(CallerID)->EventProcess(Event(ACTOR_COLLISION, ActorTreeArray[j]->GetItem()));
    164 					}
    165 				}
    166 			}
    167 			else
    168 			{
    169 				//gCons->ConsPrintf("Cell is empty/n");
    170 			}
    171 		}
    172 		else
    173 		{
    174 			//Cell does not exist. do nothing
    175 		}
    176 	}
    177 
    178 	return true;
    179 }
    180 
    181 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType)
    182 {
    183 	int CallerCell = GetActorCell(CallerID);
    184 
    185 	Cell* AdjecentCellIndex[9];
    186 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    187 
    188 	for (int i = 0; i < 9; i++)
    189 	{
    190 		if (AdjecentCellIndex[i] != NULL)
    191 		{
    192 			Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump();
    193 
    194 			if (ActorTreeArray != NULL)
    195 			{
    196 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    197 				{
    198 					Node* debugtool = ActorTreeArray[j];
    199 					if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true)
    200 					{
    201 						mAHM->GetActorAddress(CallerID)->EventProcess(Event(SENSOR_COLLISION, SeType, ActorTreeArray[j]->GetItem())); //Used to pass actor* now passed ID number. receiver functions need to be updated
    202 					}
    203 				}
    204 			}
    205 			else
    206 			{
    207 				//gCons->ConsPrintf("Cell is empty/n");
    208 			}
    209 		}
    210 		else
    211 		{
    212 			//Cell does not exist. do nothing
    213 		}
    214 	}
    215 	return true;
    216 }
    217 
    218 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID)
    219 {
    220 	int CallerCell = GetActorCell(CallerID);
    221 
    222 	Cell* AdjecentCellIndex[9];
    223 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    224 
    225 	for (int i = 0; i < 9; i++)
    226 	{
    227 		if (AdjecentCellIndex[i] != NULL)
    228 		{
    229 			Node** ActorTreeArray = ((AdjecentCellIndex[i]->GetActorTree())->Dump());
    230 			if (ActorTreeArray != NULL)
    231 			{
    232 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    233 				{
    234 					if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true)
    235 					{
    236 						if (mAHM->GetActorAddress(ActorTreeArray[j]->GetItem())->IsBlocking() == true)
    237 						{
    238 							return true;
    239 						}
    240 					}
    241 				}
    242 			}
    243 			else
    244 			{
    245 				//gCons->ConsPrintf("Cell is empty/n");
    246 			}
    247 		}
    248 		else
    249 		{
    250 			//Cell does not exist. do nothing
    251 		}
    252 	}
    253 	return false;
    254 }
    255 
    256 bool SpatialMonitor::EventProcess(Event eve)
    257 {
    258 	switch (*eve.GetEventType())
    259 	{
    260 	case MOVED_THIS_FRAME:
    261 		UpdateActorCell(eve.GetEventData()->i);
    262 		HandleCollisions(eve.GetEventData()->i);
    263 		return true;
    264 		break;
    265 	case CHECK_RECT_SENSOR:
    266 		HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id, eve.GetEventData()->sd.st);
    267 		return true;
    268 		break;
    269 	case CHECK_BLOCKERS:
    270 		return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id);
    271 		break;
    272 	default:
    273 		gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n");
    274 		return false;
    275 		break;
    276 	}
    277 }