Heat Map
AI的Heat Map
void Map::SolidMapBFS( TileHeatMap& out_distanceField, IntVec2 startTileCoords )
{
for (int i = 0; i < out_distanceField.m_dimensions.x * out_distanceField.m_dimensions.y; i++)
{
out_distanceField.m_values[i] = HEAT_MAP_SPECIAL_VALUE;
m_isTileSearchedSolidMap[i] = false;
}
std::vector tileCoordinates;
int currentIndex = 0;
tileCoordinates.reserve( m_mapDef.m_dimensions.x * m_mapDef.m_dimensions.y );
tileCoordinates.push_back( startTileCoords );
out_distanceField.SetValue( GetTileIndexForTileCoords( startTileCoords ), 0.f );
while (currentIndex < tileCoordinates.size())
{
startTileCoords = tileCoordinates[currentIndex];
m_isTileSearchedSolidMap[GetTileIndexForTileCoords( startTileCoords )] = true;
int tempIndex = 0;
IntVec2 nextCoord;
nextCoord = startTileCoords + IntVec2( 1, 0 );
tempIndex = GetTileIndexForTileCoords( nextCoord );
if (!isTileOutOfBound( nextCoord ) && !m_isTileSearchedSolidMap[tempIndex] && !m_tiles[tempIndex].m_tileDefinition->m_isSolid)
{
m_isTileSearchedSolidMap[tempIndex] = true;
tileCoordinates.push_back( nextCoord );
float currentTileValue = out_distanceField.GetValue( startTileCoords );
out_distanceField.SetValue( tempIndex, currentTileValue + 1 );
}
nextCoord = startTileCoords + IntVec2( -1, 0 );
tempIndex = GetTileIndexForTileCoords( nextCoord );
if (!isTileOutOfBound( nextCoord ) && !m_isTileSearchedSolidMap[tempIndex] && !m_tiles[tempIndex].m_tileDefinition->m_isSolid)
{
m_isTileSearchedSolidMap[tempIndex] = true;
tileCoordinates.push_back( nextCoord );
float currentTileValue = out_distanceField.GetValue( startTileCoords );
out_distanceField.SetValue( tempIndex, currentTileValue + 1 );
}
nextCoord = startTileCoords + IntVec2( 0, 1 );
tempIndex = GetTileIndexForTileCoords( nextCoord );
if (!isTileOutOfBound( nextCoord ) && !m_isTileSearchedSolidMap[tempIndex] && !m_tiles[tempIndex].m_tileDefinition->m_isSolid)
{
m_isTileSearchedSolidMap[tempIndex] = true;
tileCoordinates.push_back( nextCoord );
float currentTileValue = out_distanceField.GetValue( startTileCoords );
out_distanceField.SetValue( tempIndex, currentTileValue + 1 );
}
nextCoord = startTileCoords + IntVec2( 0, -1 );
tempIndex = GetTileIndexForTileCoords( nextCoord );
if (!isTileOutOfBound( nextCoord ) && !m_isTileSearchedSolidMap[tempIndex] && !m_tiles[tempIndex].m_tileDefinition->m_isSolid)
{
m_isTileSearchedSolidMap[tempIndex] = true;
tileCoordinates.push_back( nextCoord );
float currentTileValue = out_distanceField.GetValue( startTileCoords );
out_distanceField.SetValue( tempIndex, currentTileValue + 1 );
}
currentIndex++;
}
EntityList &scorpios = m_entityListsByType[_EVIL_SCORPIO];
for (int i = 0; i < scorpios.size(); i++)
{
if (scorpios[i] != nullptr)
{
IntVec2 scorpioCoords = GetTileCoordsForWorldPos( scorpios[i]->m_position );
int scorpioTileIndex = GetTileIndexForTileCoords( scorpioCoords );
out_distanceField.SetValue( scorpioTileIndex, HEAT_MAP_SPECIAL_VALUE );
}
}
}
生成HeatMap的代码
碰撞
子弹碰撞是预防性碰撞,坦克碰撞是矫正性碰撞
Libra中的碰撞
void Map::EntityCollision( EntityType entityType1, EntityType entityType2 )
{
EntityList& typeEntity1 = m_entityListsByType[entityType1];
EntityList& typeEntity2 = m_entityListsByType[entityType2];
if (typeEntity1 == typeEntity2)
{
for (int i = 0; i < typeEntity1.size(); i++)
{
for (int j = i + 1 ; j < typeEntity2.size(); j++)
{
if (typeEntity1[i] != nullptr && typeEntity2[j] != nullptr)
{
if (typeEntity1[i]->m_isPushByOthers && typeEntity1[i]->m_isPushOthers && typeEntity2[j]->m_isPushByOthers && typeEntity2[j]->m_isPushOthers)
{
PushDiscsOutOfEachOther2D( typeEntity1[i]->m_position, typeEntity1[i]->m_physicsRadius, typeEntity2[j]->m_position, typeEntity2[j]->m_physicsRadius );
}
else if (typeEntity1[i]->m_isPushByOthers && typeEntity1[i]->m_isPushOthers && !typeEntity2[j]->m_isPushByOthers && typeEntity2[j]->m_isPushOthers)
{
PushDiscOutOfFixedDisc2D( typeEntity1[i]->m_position, typeEntity1[i]->m_physicsRadius, typeEntity2[j]->m_position, typeEntity2[j]->m_physicsRadius );
}
else if (!typeEntity1[i]->m_isPushByOthers && typeEntity1[i]->m_isPushOthers && typeEntity2[j]->m_isPushByOthers && typeEntity2[j]->m_isPushOthers)
{
PushDiscOutOfFixedDisc2D( typeEntity2[j]->m_position, typeEntity2[j]->m_physicsRadius, typeEntity1[i]->m_position, typeEntity1[i]->m_physicsRadius );
}
}
}
}
}
else
{
for (int i = 0; i < typeEntity1.size(); i++)
{
for (int j = 0; j < typeEntity2.size(); j++)
{
if (typeEntity1[i] != nullptr && typeEntity2[j] != nullptr)
{
if (typeEntity1[i]->m_isPushByOthers && typeEntity1[i]->m_isPushOthers && typeEntity2[j]->m_isPushByOthers && typeEntity2[j]->m_isPushOthers)
{
PushDiscsOutOfEachOther2D( typeEntity1[i]->m_position, typeEntity1[i]->m_physicsRadius, typeEntity2[j]->m_position, typeEntity2[j]->m_physicsRadius );
}
else if (typeEntity1[i]->m_isPushByOthers && typeEntity1[i]->m_isPushOthers && !typeEntity2[j]->m_isPushByOthers && typeEntity2[j]->m_isPushOthers)
{
PushDiscOutOfFixedDisc2D( typeEntity1[i]->m_position, typeEntity1[i]->m_physicsRadius, typeEntity2[j]->m_position, typeEntity2[j]->m_physicsRadius );
}
else if (!typeEntity1[i]->m_isPushByOthers && typeEntity1[i]->m_isPushOthers && typeEntity2[j]->m_isPushByOthers && typeEntity2[j]->m_isPushOthers)
{
PushDiscOutOfFixedDisc2D( typeEntity2[j]->m_position, typeEntity2[j]->m_physicsRadius, typeEntity1[i]->m_position, typeEntity1[i]->m_physicsRadius );
}
}
}
}
}
}
纠正性碰撞代码
void Bullet::BulletReflecStone( float deltaSeconds )
{
Vec2 currentPos = m_position;
m_position += m_velocity * deltaSeconds;
if (g_theGame->m_currentMap->IsPositionInSolidTile( m_position ))
{
if (m_entityType == _GOOD_BULLET)
{
if (m_bulletType == GOOD_BOLT || m_bulletType == GOOD_BULLET)
{
g_audio->StartSound( g_soundArray[bulletReflectionSound] );
IntVec2 currentTileCoords = g_theGame->m_currentMap->GetTileCoordsForWorldPos( currentPos );
IntVec2 nextFrameTileCoords = g_theGame->m_currentMap->GetTileCoordsForWorldPos( m_position );
Vec2 tanVec = Vec2( 0.f, 0.f );
tanVec.x = (float)(nextFrameTileCoords.x - currentTileCoords.x);
tanVec.y = (float)(nextFrameTileCoords.y - currentTileCoords.y);
Vec2 normal = (tanVec).GetRotated90Degrees();
m_velocity = -m_velocity.GetReflected( normal );
m_orientationDegrees = m_velocity.GetOrientationDegrees();
float offSetDegrees = rng->RollRandomFloatInRange( -5.f, 5.f );
m_orientationDegrees += offSetDegrees;
m_velocity = Vec2::MakeFromPolarDegrees( m_orientationDegrees, m_speed );
m_position = currentPos;
m_hitStoneTime++;
IntVec2 tileCoords = g_theGame->m_currentMap->GetTileCoordsForWorldPos( m_position );
int currentTileIndex = g_theGame->m_currentMap->GetTileIndexForTileCoords( currentTileCoords.x, currentTileCoords.y );
if (g_theGame->m_currentMap->m_tiles[currentTileIndex].m_tileDefinition->m_isDestructible)
{
g_theGame->m_currentMap->m_tiles[currentTileIndex].m_tileDefinition->m_health--;
if (g_theGame->m_currentMap->m_tiles[currentTileIndex].m_tileDefinition->m_health <= 0)
{
g_theGame->m_currentMap->m_tiles[currentTileIndex].m_tileDefinition = TileDefinition::GetDefByName( g_theGame->m_currentMap->m_tiles[currentTileIndex].m_tileDefinition->m_destroyedTileType );
}
}
}
}
}
预防性碰撞代码
截图


