TapestryEngine

A 2D Platformer Game Engine
Log | Files | Refs

1e9e815a80a89d81879d36b8f1bfd91a90c50357.svn-base (4625B)


      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 			SDL_Rect cell;
     13 			cell.w = cellW;
     14 			cell.h = cellH;
     15 			cell.x = cellW * j;
     16 			cell.y = cellH * i;
     17 
     18 			mCells[i*CELLS_X + j] = cell;
     19 
     20 		}
     21 	}
     22 	return true;
     23 }
     24 
     25 bool SpatialMonitor::LogActor(Actor& act)
     26 {
     27 	if (mActorCount < MAX_ACTORS)
     28 	{
     29 		mActors[mActorCount] = &act;
     30 		act.SetSpatID(mActorCount);
     31 		UpdateActorCell(mActorCount);
     32 		mActorCount += 1;
     33 		return true;
     34 	}
     35 	else
     36 	{
     37 		gCons->ConsPrintf("Failed to Log Actor. Spatial Monitor actor capacity reached! \n");
     38 		return false;
     39 	}
     40 }
     41 
     42 int SpatialMonitor::UpdateActorCell(int id)
     43 {
     44 	for (int i = 0; i < CELL_COUNT; i++)
     45 	{
     46 		if (DetectCenterPointIntersect(&mCells[i], mActors[id]->GetPosition()))
     47 		{
     48 			//gCons->ConsPrintf("Actor entering cell %i\n", i);
     49 			mActorCells[id] = i;
     50 			return i;
     51 		}
     52 	}
     53 	gCons->ConsPrintf("Could not find Actor cell\n");
     54 	return -1;
     55 }
     56 
     57 int* SpatialMonitor::GetAdjacentCells(int cellnum, int cells[9])
     58 {
     59 	cells[0] = (cellnum - CELLS_X - 1);
     60 	cells[1] = (cellnum - CELLS_X);
     61 	cells[2] = (cellnum - CELLS_X + 1);
     62 
     63 	cells[3] = (cellnum - 1);
     64 	cells[4] = (cellnum);
     65 	cells[5] = (cellnum + 1);
     66 
     67 	cells[6] = (cellnum + CELLS_X - 1);
     68 	cells[7] = (cellnum + CELLS_X);
     69 	cells[8] = (cellnum + CELLS_X + 1);
     70 
     71 	return cells;
     72 }
     73 
     74 bool SpatialMonitor::GetActorsInCell(int cellnum)
     75 {
     76 	for (int i = 0; i < MAX_ACTORS; i++)
     77 	{
     78 		if (mActorCells[i] == cellnum)
     79 		{
     80 			//gCons->ConsPrintf("Actor %i is in adjacent cell\n", i);
     81 			mAdjacentActorIDs[mAdjacentActorCount] = i;
     82 			mAdjacentActorCount++;
     83 		}
     84 	}
     85 	return true;
     86 }
     87 
     88 bool SpatialMonitor::GetAdjacentActors(int cellnum)
     89 {
     90 	mAdjacentActorCount = 0;
     91 	mAdjacentActorIDs[MAX_ACTORS] = { 0 };
     92 
     93 	int cells[9];
     94 	GetAdjacentCells(cellnum, cells);
     95 
     96 	for (int i = 0; i < 9; i++)
     97 	{
     98 		GetActorsInCell(cells[i]);
     99 		//gDiagDraw->LogDiagRect(mCells[cells[i]]);
    100 	}
    101 	return true;
    102 }
    103 
    104 bool SpatialMonitor::DetectActorCollision(int id1, int id2)
    105 {
    106 	if (id1 != id2)
    107 	{
    108 		//gDiagDraw->LogDiagRect(*mActors[id2]->GetPosition());
    109 		return DetectRectIntersect(mActors[id1]->GetPosition(), mActors[id2]->GetPosition());
    110 	}
    111 	else
    112 	{
    113 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
    114 		return false;
    115 	}
    116 }
    117 
    118 bool SpatialMonitor::DetectRectSensors(SDL_Rect* sensor, int DetectorID, int foreignID)
    119 {
    120 	if (DetectorID != foreignID)
    121 	{
    122 		//gDiagDraw->LogDiagRect(*sensor);
    123 		//gDiagDraw->LogDiagRect(*mActors[foreignID]->GetPosition());
    124 		return DetectRectIntersect(sensor, mActors[foreignID]->GetPosition());
    125 	}
    126 	else
    127 	{
    128 		//gCons->ConsPrintf("Attempted to check actor collision with itself\n");
    129 		return false;
    130 	}
    131 }
    132 
    133 bool SpatialMonitor::HandleCollisions(int CallerID)
    134 {
    135 	int CallerCell = GetActorCell(CallerID);
    136 	GetAdjacentActors(CallerCell);
    137 
    138 	for (int i = 0; i < mAdjacentActorCount; i++)
    139 	{
    140 		if (DetectActorCollision(CallerID, mAdjacentActorIDs[i]) == true) //i is the wrong value
    141 		{
    142 			mActors[CallerID]->EventProcess(Event(ACTOR_COLLISION, mActors[mAdjacentActorIDs[i]]));
    143 		}
    144 	}
    145 	return true;
    146 }
    147 
    148 bool SpatialMonitor::HandleRectSensors(SDL_Rect* sensor, int CallerID, SensorType SeType)
    149 {
    150 	int CallerCell = GetActorCell(CallerID);
    151 	GetAdjacentActors(CallerCell);
    152 
    153 	for (int i = 0; i < mAdjacentActorCount; i++)
    154 	{
    155 		if (DetectRectSensors(sensor, CallerID, mAdjacentActorIDs[i]) == true)
    156 		{
    157 			mActors[CallerID]->EventProcess(Event(SENSOR_COLLISION, SeType, mActors[mAdjacentActorIDs[i]]));
    158 		}
    159 	}
    160 	return true;
    161 }
    162 
    163 bool SpatialMonitor::TestBlockers(SDL_Rect* sensor, int CallerID)
    164 {
    165 	int CallerCell = GetActorCell(CallerID);
    166 	GetAdjacentActors(CallerCell);
    167 
    168 	for (int i = 0; i < mAdjacentActorCount; i++)
    169 	{
    170 		if (DetectRectSensors(sensor, CallerID, mAdjacentActorIDs[i]) == true)
    171 		{
    172 			if (mActors[mAdjacentActorIDs[i]]->IsBlocking() == true)
    173 			{
    174 				return true;
    175 			}
    176 			//mActors[CallerID]->EventProcess(Event(SENSOR_COLLISION, SeType, mActors[i]));
    177 		}
    178 	}
    179 	return false;
    180 }
    181 
    182 bool SpatialMonitor::EventProcess(Event eve)
    183 {
    184 	switch (*eve.GetEventType())
    185 	{
    186 	case MOVED_THIS_FRAME:
    187 		UpdateActorCell(eve.GetEventData()->i);
    188 		HandleCollisions(eve.GetEventData()->i);
    189 		return true;
    190 		break;
    191 	case CHECK_RECT_SENSOR:
    192 		HandleRectSensors(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.ID, eve.GetEventData()->sd.st);
    193 		return true;
    194 		break;
    195 	case CHECK_BLOCKERS:
    196 		return TestBlockers(eve.GetEventData()->sd.sensor, eve.GetEventData()->sd.ID);
    197 		break;
    198 	default:
    199 		gCons->ConsPrintf("Spatial Monitor Received Invalid Event Type\n");
    200 		return false;
    201 		break;
    202 	}
    203 }