TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

025f21115e78bc401075b7aeb47067e9ea4a933c.svn-base (6532B)


      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); 
     58 				act->SetSpatCell(i);
     59 			}
     60 
     61 			return i;
     62 		}
     63 	}
     64 	gCons->ConsPrintf("Could not find Actor cell\n");
     65 	return -1;
     66 }
     67 
     68 int SpatialMonitor::GetAdjacentCells(int cellnum, Cell* cells[9])
     69 {
     70 	cells[0] = GetCell((cellnum - CELLS_X - 1));
     71 	cells[1] = GetCell((cellnum - CELLS_X));
     72 	cells[2] = GetCell((cellnum - CELLS_X + 1));
     73 
     74 	cells[3] = GetCell((cellnum - 1));
     75 	cells[4] = GetCell((cellnum));
     76 	cells[5] = GetCell((cellnum + 1));
     77 	
     78 	cells[6] = GetCell((cellnum + CELLS_X - 1));
     79 	cells[7] = GetCell((cellnum + CELLS_X));
     80 	cells[8] = GetCell((cellnum + CELLS_X + 1));
     81 	
     82 	return 0;
     83 }
     84 
     85 //bool SpatialMonitor::GetActorsInCell(int cellnum) //uneeded now. Use Cell.GetActorTree()
     86 //{
     87 //	for (int i = 0; i < MAX_ACTORS; i++) //this is very bad. Basically defeats the function of cells by check each actor
     88 //	{
     89 //		if (mActorCells[i] == cellnum)
     90 //		{
     91 //			//gCons->ConsPrintf("Actor %i is in adjacent cell\n", i);
     92 //			mAdjacentActorIDs[mAdjacentActorCount] = i;
     93 //			mAdjacentActorCount++;
     94 //		}
     95 //	}
     96 //	return true;
     97 //}
     98 
     99 //bool SpatialMonitor::GetAdjacentActors(int cellnum)
    100 //{
    101 //	mAdjacentActorCount = 0;
    102 //	mAdjacentActorIDs[MAX_ACTORS] = { 0 };
    103 //
    104 //	int cells[9];
    105 //	GetAdjacentCells(cellnum, cells);
    106 //
    107 //	for (int i = 0; i < 9; i++)
    108 //	{
    109 //		GetActorsInCell(cells[i]);
    110 //		//gDiagDraw->LogDiagRect(mCells[cells[i]]);
    111 //	}
    112 //	return true;
    113 //}
    114 
    115 bool SpatialMonitor::DetectActorCollision(int id1, int id2)
    116 {
    117 	if (id1 != id2)
    118 	{	
    119 		//gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition());
    120 		return DetectRectIntersect(mAHM->GetActorAddress(id1)->GetPosition(), mAHM->GetActorAddress(id2)->GetPosition());
    121 	}
    122 	else
    123 	{
    124 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
    125 		return false;
    126 	}
    127 }
    128 
    129 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID)
    130 {
    131 	if (DetectorID != foreignID)
    132 	{
    133 		//gDiagDraw->LogDiagRect(*sensor);
    134 		//gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition());
    135 		return DetectRectIntersect(sensor, mAHM->GetActorAddress(foreignID)->GetPosition());
    136 	}
    137 	else
    138 	{
    139 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
    140 		return false;
    141 	}
    142 }
    143 
    144 bool SpatialMonitor::HandleCollisions(int CallerID)
    145 {
    146 	int CallerCell = GetActorCell(CallerID);
    147 	
    148 	Cell* AdjecentCellIndex[9];
    149 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    150 
    151 	for (int i = 0; i < 9; i++)
    152 	{	
    153 		if (AdjecentCellIndex[i] != NULL)
    154 		{
    155 			Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump();
    156 			if (ActorTreeArray != NULL)
    157 			{
    158 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    159 				{
    160 					if (DetectActorCollision(CallerID, ActorTreeArray[j]->GetItem()) == true)
    161 					{
    162 						mAHM->GetActorAddress(CallerID)->EventProcess(Event(ACTOR_COLLISION, ActorTreeArray[j]->GetItem()));
    163 					}
    164 				}
    165 			}
    166 			else
    167 			{
    168 				//gCons->ConsPrintf("Cell is empty/n");
    169 			}
    170 		}
    171 		else
    172 		{
    173 			//Cell does not exist. do nothing
    174 		}
    175 	}
    176 
    177 	return true;
    178 }
    179 
    180 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType)
    181 {
    182 	int CallerCell = GetActorCell(CallerID);
    183 
    184 	Cell* AdjecentCellIndex[9];
    185 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    186 
    187 	for (int i = 0; i < 9; i++)
    188 	{
    189 		if (AdjecentCellIndex[i] != NULL)
    190 		{
    191 			Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump();
    192 
    193 			if (ActorTreeArray != NULL)
    194 			{
    195 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    196 				{
    197 					Node* debugtool = ActorTreeArray[j];
    198 					if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true)
    199 					{
    200 						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
    201 					}
    202 				}
    203 			}
    204 			else
    205 			{
    206 				//gCons->ConsPrintf("Cell is empty/n");
    207 			}
    208 		}
    209 		else
    210 		{
    211 			//Cell does not exist. do nothing
    212 		}
    213 	}
    214 	return true;
    215 }
    216 
    217 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID)
    218 {
    219 	int CallerCell = GetActorCell(CallerID);
    220 
    221 	Cell* AdjecentCellIndex[9];
    222 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    223 
    224 	for (int i = 0; i < 9; i++)
    225 	{
    226 		if (AdjecentCellIndex[i] != NULL)
    227 		{
    228 			Node** ActorTreeArray = ((AdjecentCellIndex[i]->GetActorTree())->Dump());
    229 			if (ActorTreeArray != NULL)
    230 			{
    231 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    232 				{
    233 					if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true)
    234 					{
    235 						if (mAHM->GetActorAddress(ActorTreeArray[j]->GetItem())->IsBlocking() == true)
    236 						{
    237 							return true;
    238 						}
    239 					}
    240 				}
    241 			}
    242 			else
    243 			{
    244 				//gCons->ConsPrintf("Cell is empty/n");
    245 			}
    246 		}
    247 		else
    248 		{
    249 			//Cell does not exist. do nothing
    250 		}
    251 	}
    252 	return false;
    253 }
    254 
    255 bool SpatialMonitor::EventProcess(Event eve)
    256 {
    257 	switch (*eve.GetEventType())
    258 	{
    259 	case MOVED_THIS_FRAME:
    260 		UpdateActorCell(eve.GetEventData()->i);
    261 		HandleCollisions(eve.GetEventData()->i);
    262 		return true;
    263 		break;
    264 	case CHECK_RECT_SENSOR:
    265 		HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id, eve.GetEventData()->sd.st);
    266 		return true;
    267 		break;
    268 	case CHECK_BLOCKERS:
    269 		return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id);
    270 		break;
    271 	default:
    272 		gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n");
    273 		return false;
    274 		break;
    275 	}
    276 }