TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

905c7c275895c3e18a39223f5fdb1a01c9ce0629.svn-base (5861B)


      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 != ((Collider*)(act))->GetSpatCell()) //not sure about all this casting, might be causing troubles
     55 			{
     56 				mCells[i].GetActorTree()->Insert(id, NULL);
     57 				ClearActorCell(id); 
     58 				((Collider*)(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::DetectActorCollision(int id1, int id2)
     86 {
     87 	if (id1 != id2)
     88 	{	
     89 		//gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition());
     90 		return DetectRectIntersect(mAHM->GetActorAddress(id1)->GetPosition(), mAHM->GetActorAddress(id2)->GetPosition());
     91 	}
     92 	else
     93 	{
     94 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
     95 		return false;
     96 	}
     97 }
     98 
     99 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID)
    100 {
    101 	if (DetectorID != foreignID)
    102 	{
    103 		//gDiagDraw->LogDiagRect(*sensor);
    104 		//gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition());
    105 		return DetectRectIntersect(sensor, mAHM->GetActorAddress(foreignID)->GetPosition());
    106 	}
    107 	else
    108 	{
    109 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
    110 		return false;
    111 	}
    112 }
    113 
    114 bool SpatialMonitor::HandleCollisions(int CallerID)
    115 {
    116 	int CallerCell = GetActorCell(CallerID);
    117 	
    118 	Cell* AdjecentCellIndex[9];
    119 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    120 
    121 	for (int i = 0; i < 9; i++)
    122 	{	
    123 		if (AdjecentCellIndex[i] != NULL)
    124 		{
    125 			Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump();
    126 			if (ActorTreeArray != NULL)
    127 			{
    128 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    129 				{
    130 					if (DetectActorCollision(CallerID, ActorTreeArray[j]->GetItem()) == true)
    131 					{
    132 						mAHM->GetActorAddress(CallerID)->EventProcess(Event(ACTOR_COLLISION, ActorTreeArray[j]->GetItem()));
    133 					}
    134 				}
    135 			}
    136 			else
    137 			{
    138 				//gCons->ConsPrintf("Cell is empty/n");
    139 			}
    140 		}
    141 		else
    142 		{
    143 			//Cell does not exist. do nothing
    144 		}
    145 	}
    146 
    147 	return true;
    148 }
    149 
    150 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType)
    151 {
    152 	int CallerCell = GetActorCell(CallerID);
    153 
    154 	Cell* AdjecentCellIndex[9];
    155 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    156 
    157 	for (int i = 0; i < 9; i++)
    158 	{
    159 		if (AdjecentCellIndex[i] != NULL)
    160 		{
    161 			Node** ActorTreeArray = (AdjecentCellIndex[i]->GetActorTree())->Dump();
    162 
    163 			if (ActorTreeArray != NULL)
    164 			{
    165 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    166 				{
    167 					Node* debugtool = ActorTreeArray[j];
    168 					if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true)
    169 					{
    170 						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
    171 					}
    172 				}
    173 			}
    174 			else
    175 			{
    176 				//gCons->ConsPrintf("Cell is empty/n");
    177 			}
    178 		}
    179 		else
    180 		{
    181 			//Cell does not exist. do nothing
    182 		}
    183 	}
    184 	return true;
    185 }
    186 
    187 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID)
    188 {
    189 	int CallerCell = GetActorCell(CallerID);
    190 
    191 	Cell* AdjecentCellIndex[9];
    192 	GetAdjacentCells(CallerCell, AdjecentCellIndex);
    193 
    194 	for (int i = 0; i < 9; i++)
    195 	{
    196 		if (AdjecentCellIndex[i] != NULL)
    197 		{
    198 			Node** ActorTreeArray = ((AdjecentCellIndex[i]->GetActorTree())->Dump());
    199 			if (ActorTreeArray != NULL)
    200 			{
    201 				for (int j = 0; j < (AdjecentCellIndex[i]->GetActorTree())->Size(); j++)
    202 				{
    203 					if (DetectRectSensors(sensor, CallerID, ActorTreeArray[j]->GetItem()) == true)
    204 					{
    205 						if (mAHM->GetActorAddress(ActorTreeArray[j]->GetItem())->IsBlocking() == true)
    206 						{
    207 							return true;
    208 						}
    209 					}
    210 				}
    211 			}
    212 			else
    213 			{
    214 				//gCons->ConsPrintf("Cell is empty/n");
    215 			}
    216 		}
    217 		else
    218 		{
    219 			//Cell does not exist. do nothing
    220 		}
    221 	}
    222 	return false;
    223 }
    224 
    225 bool SpatialMonitor::EventProcess(Event eve)
    226 {
    227 	switch (*eve.GetEventType())
    228 	{
    229 	case MOVED_THIS_FRAME:
    230 		UpdateActorCell(eve.GetEventData()->i);
    231 		HandleCollisions(eve.GetEventData()->i);
    232 		return true;
    233 		break;
    234 	case CHECK_RECT_SENSOR:
    235 		HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id, eve.GetEventData()->sd.st);
    236 		return true;
    237 		break;
    238 	case CHECK_BLOCKERS:
    239 		return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.id);
    240 		break;
    241 	default:
    242 		gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n");
    243 		return false;
    244 		break;
    245 	}
    246 }