public BaddyGenerator(Map _map, Point2 mapPos) { m_growingIndex = -1; m_pixelPos = new Point2( mapPos.X * _map.getTileWidth() + _map.getTileWidth() / 2, mapPos.Y * _map.getTileWidth() + _map.getTileWidth() / 2); m_baddyArray = new Baddy[GameConstants.baddyGeneratorMaxBaddies]; for (int i = 0; i < m_baddyArray.Length; i++) { m_baddyArray[i] = new Baddy(); m_baddyArray[i].SetStartPosition(m_pixelPos); } }
public void update(float frameTime, Map _map, Character[] _characterArray) { if (m_growingIndex == -1) { for (int i = 0; i < m_baddyArray.Length; i++) { if (m_baddyArray[i].m_inGenerator) { m_baddyArray[i].m_position = m_pixelPos; m_growingIndex = i; break; } } } if (m_growingIndex != -1) { m_baddyArray[m_growingIndex].m_age += frameTime / GameConstants.baddyGenerateTime; if (m_baddyArray[m_growingIndex].m_age >= 1.0) { m_baddyArray[m_growingIndex].m_health = GameConstants.baddyInitialHealth; m_baddyArray[m_growingIndex].m_age = 1.0f; m_baddyArray[m_growingIndex].m_inGenerator = false; m_baddyArray[m_growingIndex].randomlyAssignDirection(); m_growingIndex = -1; } } for(int i = 0; i < m_baddyArray.Length; i++) { if (m_baddyArray[i].IsAlive()) { if (m_baddyArray[i].movePosition(frameTime, _map, _characterArray, false, false)) { m_baddyArray[i].randomlyAssignDirection(); } } } }
void preprocessMapData() { m_mapExtraData = new int[m_numTilesWide * m_numTilesHigh]; m_mapDataSpecial = new SpecialType[m_numTilesWide * m_numTilesHigh]; m_baddyArray = new ArrayList(); m_turretArray = new ArrayList(); m_ogreActiveOnMap = false; // Find player positions for (int i = 0; i < m_mapData.Length; i++) { TileType tileType = (TileType)m_mapData[i]; m_mapDataSpecial[i] = SpecialType.NONE; if (tileType == TileType.PLAYER_1) { m_playerOneStartPos = getPosition(i); m_mapData[i] = TileType.FLOOR; } if (tileType == TileType.PLAYER_2) { m_playerTwoStartPos = getPosition(i); m_mapData[i] = TileType.FLOOR; } if (tileType == TileType.OGRE) { m_ogreStartPos = getPosition(i); m_mapData[i] = TileType.FLOOR; m_ogreActiveOnMap = true; } } // Map borders for(int i = 0; i < m_numTilesWide; i++) { Instantiate(Prefabs[(int)TileType.WALL], new Vector3(i, 0, -1), Quaternion.identity, transform); Instantiate(Prefabs[(int)TileType.WALL], new Vector3(i, 0, m_numTilesHigh), Quaternion.identity, transform); } for (int i = 0; i < m_numTilesHigh; i++) { Instantiate(Prefabs[(int)TileType.WALL], new Vector3(-1, 0, i), Quaternion.identity, transform); Instantiate(Prefabs[(int)TileType.WALL], new Vector3(m_numTilesWide, 0, i), Quaternion.identity, transform); } // Find special types for (int y = 0; y < m_numTilesHigh; y++) { for (int x = 0; x < m_numTilesWide; x++) { TileType tileType = getMapTileType(x,y); switch(tileType) { case TileType.WALL: case TileType.BREAKABLE_RED: case TileType.BREAKABLE_YELLOW: case TileType.BREAKABLE_WALL: case TileType.USABLE_BOLDER: case TileType.DOOR_VERTICAL: case TileType.DOOR_HORIZONTAL: { Instantiate(Prefabs[(int)tileType], new Vector3(x, 0, y), Quaternion.identity, transform); } break; } if (tileType == TileType.BADDY_SPAWN) { // m_baddyArray.Add(new BaddyGenerator(this, new Point2(x, y))); } // if destructable state hit points m_mapExtraData[x + y * m_numTilesWide] = 100; // if teleporter state index // if key door or Point2 pos = new Point2(x, y); /* if (tileType == TileType.TURRET_RANDOM) { m_turretArray.Add(new TurretRandom(this, pos)); } if (tileType == TileType.TURRET_ROOK) { m_turretArray.Add(new TurretRook(this, pos)); } if (tileType == TileType.WALL_MOVING_START) { m_movingWallsList.Add(new Point2(x, y)); }*/ } } m_staticMapInstance = this; }
bool TestPositionAgainDiagonalWalls(Map _theMap, int minX, int minY, int maxX, int maxY, ref bool environmentCollision, ref Point2 newPos) { bool collidedOnDiagonal = false; Point2 result = new Point2(); Point2 slideBlockCentre = new Point2(); Point2 localNewPos = new Point2(newPos); bool localEnvironmentCollision = environmentCollision; for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { if (x >= _theMap.getWidth() / _theMap.getTileWidth() && y >= _theMap.getHeight() / _theMap.getTileHeight()) { continue; } TileType tileType = _theMap.getMapTileType(x, y); Point2 pixel = new Point2( x * _theMap.getTileWidth(), y * _theMap.getTileHeight()); int pixelCenX = pixel.X + _theMap.getTileWidth() / 2; int pixelCenY = pixel.Y + _theMap.getTileHeight() / 2; m_boundingTileCircle.Center = new Vector3(pixelCenX, pixelCenY, 0); m_boundingTileCircle.Radius = _theMap.getTileWidth() / 2; if (Map.isTileTypeDiagonalWall(tileType) && _theMap.isTileTypePixelCollision(tileType)) { TileType pixelCheckType = _theMap.GetTileTypePixelCollision(tileType); Point2 topLeft = new Point2( localNewPos.X - m_tileSet.getTileWidth() / 2, localNewPos.Y - m_tileSet.getTileHeight() / 2); bool localIntersects = m_tileSet.checkForCollision(_theMap.getTileSet(), m_frameIndexCollision, topLeft, (int)pixelCheckType, pixel); if (localIntersects) { if (Map.isTileTypeDiagonalWall(tileType)) { if (localEnvironmentCollision || collidedOnDiagonal) { localNewPos = new Point2(m_position); } else { if (GetSlidePositionOffDiagonalBlock(tileType, m_position, localNewPos, ref result, pixel)) { localNewPos = new Point2(result); } else { slideBlockCentre = new Point2(pixelCenX, pixelCenY); GetSlidePositionOffBlock(m_position, localNewPos, slideBlockCentre, _theMap.getTileWidth(), m_characterRadius, ref localNewPos); } collidedOnDiagonal = true; } localEnvironmentCollision = true; } } } // if diagonal wall } // for loop } // for loop environmentCollision = localEnvironmentCollision; newPos.X = localNewPos.X; newPos.Y = localNewPos.Y; return collidedOnDiagonal; }
bool isAnyCharacterOnTile(Map _theMap, Point2 tilePos) { for(int i = 0; i < _theMap.m_baddyArray.Count; i++) { if (((BaddyGenerator)_theMap.m_baddyArray[i]).isAnyBaddieOnTile(tilePos)) { return true; } } for(int c = 0; c < Game.m_characters.Length; c++) { if (Game.m_characters[c].isCharacterOnTile(tilePos)) { return true; } } for (int p = 0; p < Game.m_npcs.Length; p++) { if (Game.m_npcs[p].isCharacterOnTile(tilePos)) { return true; } } return false; }
protected bool moveBolder(Map _theMap, int _pixelX, int _pixelY) { // First find out where we want to push the block to int tileX = _theMap.getTileNumFromPixelX(_pixelX); int tileY = _theMap.getTileNumFromPixelY(_pixelY); int newTileX = tileX; int newTileY = tileY; int diffX = _pixelX - m_position.X; int diffY = _pixelY - m_position.Y; float angle = 20.0f * Angles.DEG_1; float rotationMod = m_rotation; while (rotationMod > Angles.DEG_45) { rotationMod -= Angles.DEG_90; } if (Math.Abs(rotationMod) < angle) { if (Math.Abs(diffX) > Math.Abs(diffY)) { newTileX = tileX + diffX / Math.Abs(diffX); } else { newTileY = tileY + diffY / Math.Abs(diffY); } } else { if (Math.Abs(diffX) > Math.Abs(diffY)) { if (Math.Abs(diffY) != 0) { newTileY = tileY + diffY / Math.Abs(diffY); } } else { if (Math.Abs(diffX) != 0) { newTileX = tileX + diffX / Math.Abs(diffX); } } } // Secondly now we need to check if the way if blocked TileType destination = _theMap.getMapTileType(newTileX, newTileY); if(destination == TileType.FLOOR) { if (!isAnyCharacterOnTile(_theMap, new Point2(newTileX, newTileY))) { _theMap.setMapTileType(tileX, tileY, TileType.FLOOR); _theMap.setMapTileType(newTileX, newTileY, TileType.USABLE_BOLDER); return true; } } return false; }
public bool movePosition(float frameTime, Map _theMap, Character[] _characterArray, bool slideAgainstWalls, bool canUseSlides) { bool movingOnSlide = false; bool slideAgainstDiagonalWalls = slideAgainstWalls && true; bool environmentCollision = false; // todo this shouldnt be assigned here each frame m_characterRadius = m_tileSet.getTileWidth() / 2 * 8 / 10; Point2 change = new Point2(); int tileIndexX = m_position.X / _theMap.getTileWidth(); int tileIndexY = m_position.Y / _theMap.getTileHeight(); TileType tileTypeStoodOn = _theMap.getMapTileType(tileIndexX, tileIndexY); Boolean onSlide = Map.isTileTypeSlide(tileTypeStoodOn) && canUseSlides; int SLIDE_EXIT_LENGTH = 10; // If not sliding (on slide exit) then allow movement if (!onSlide) { float moveSpeed = m_moveSpeedPerSecond * frameTime; float cos = (float)Math.Cos(m_rotation); float sin = (float)Math.Sin(m_rotation); change.X = (int)( sin * moveSpeed); change.Y = (int)(-cos * moveSpeed); } Point2 newPos = new Point2(); // Velocity is only for slide movement if (m_velocity.Length() > MAX_VELOCITY) { m_velocity.Normalize(); m_velocity *= MAX_VELOCITY; } change.X += (int)(m_velocity.X * frameTime); newPos.X = m_position.X + change.X; change.Y += (int)(m_velocity.Y * frameTime); newPos.Y = m_position.Y + change.Y; if (Map.isTileTypeSlide(tileTypeStoodOn) && canUseSlides) { Vector2 targetPoint = new Vector2(); Vector2 charPoint = new Vector2(m_position.X, m_position.Y); targetPoint.X = tileIndexX * _theMap.getTileWidth() + m_tileSet.getTileWidth() / 2; targetPoint.Y = tileIndexY * _theMap.getTileHeight() + m_tileSet.getTileHeight() / 2; if (tileTypeStoodOn == TileType.SLIDE_DOWN) { targetPoint.Y += m_tileSet.getTileHeight(); } else if (tileTypeStoodOn == TileType.SLIDE_UP) { targetPoint.Y -= m_tileSet.getTileHeight(); } else if (tileTypeStoodOn == TileType.SLIDE_LEFT) { targetPoint.X -= m_tileSet.getTileWidth(); } else if (tileTypeStoodOn == TileType.SLIDE_RIGHT) { targetPoint.X += m_tileSet.getTileWidth(); } Vector2 vector = targetPoint - charPoint; // Its important this is high to keep the player in the center of the slide // So they dont come out off-center and get stuck in collision const float VELOCITY_INCREASE = 200.0f; m_velocity += vector * VELOCITY_INCREASE * frameTime; movingOnSlide = true; } else if (m_velocity.Length() > 0) { // dubious code to reduce velocity m_velocity *= (25 * frameTime); change.X += (int)(m_velocity.X * frameTime); change.Y += (int)(m_velocity.Y * frameTime); newPos.X = m_position.X + change.X; newPos.Y = m_position.Y + change.Y; if (m_velocity.Length() < SLIDE_EXIT_LENGTH) { m_velocity.X = 0; m_velocity.Y = 0; stopMovement(); } } else { newPos.X = m_position.X + change.X; newPos.Y = m_position.Y + change.Y; } Point2 lastPos = new Point2(newPos); // check per tile here if (Map.isTileTypeSlide(tileTypeStoodOn) == false && BuildConstants.COLLISION_OFF == false)// && onSlide == false)// && m_teleporting == false) { // Check against the very boundarys of the map newPos.X = capValue(newPos.X, m_characterRadius, _theMap.getWidth() - m_characterRadius); newPos.Y = capValue(newPos.Y, m_characterRadius, _theMap.getHeight() - m_characterRadius); if (lastPos.X != newPos.X || lastPos.Y != newPos.Y) { environmentCollision = true; } int minX = capValue(tileIndexX - 1, 0, _theMap.getWidth() / _theMap.getTileWidth()); int maxX = capValue(tileIndexX + 2, 0, _theMap.getWidth() / _theMap.getTileWidth()); int minY = capValue(tileIndexY - 1, 0, _theMap.getHeight() / _theMap.getTileHeight()); int maxY = capValue(tileIndexY + 2, 0, _theMap.getHeight() / _theMap.getTileHeight()); m_boundingCharCircle.Center = new Vector3(newPos.X, newPos.Y, 0); m_boundingCharCircle.Radius = m_characterRadius; for (int y = minY; y < maxY; y++) { for (int x = minX; x < maxX; x++) { if (x >= _theMap.getWidth() / _theMap.getTileWidth() && y >= _theMap.getHeight() / _theMap.getTileHeight()) { continue; } TileType tileType = _theMap.getMapTileType(x, y); Point2 pixel = new Point2( x * _theMap.getTileWidth(), y * _theMap.getTileHeight()); bool intersects = false; int pixelCenX = pixel.X + _theMap.getTileWidth() / 2; int pixelCenY = pixel.Y + _theMap.getTileHeight() / 2; m_boundingTileCircle.Center = new Vector3(pixelCenX, pixelCenY, 0); m_boundingTileCircle.Radius = _theMap.getTileWidth() / 2; if (Map.isTileTypeSquareBlock(tileType, m_frameIndexRendering) || (canUseSlides == false && Map.isTileTypeSlide(tileType))) { m_boundingTileBox = BoundingBox.CreateFromSphere(m_boundingTileCircle); bool localIntersects = m_boundingCharCircle.Intersects(m_boundingTileBox); if(localIntersects) { if (slideAgainstWalls) { if (GetSlidePositionOffBlock(m_position, newPos, new Point2(pixelCenX, pixelCenY), _theMap.getTileWidth(), m_characterRadius, ref newPos)) { environmentCollision = true; } } else { intersects = true; } } } else if (Map.isTileTypeCircle(tileType)) { intersects = m_boundingCharCircle.Intersects(m_boundingTileCircle); } else if (_theMap.isTileTypePixelCollision(tileType)) { TileType pixelCheckType = _theMap.GetTileTypePixelCollision(tileType); Point2 topLeft = new Point2( newPos.X - m_tileSet.getTileWidth() / 2, newPos.Y - m_tileSet.getTileHeight() / 2); bool localIntersects = m_tileSet.checkForCollision(_theMap.getTileSet(), m_frameIndexCollision, topLeft, (int)pixelCheckType, pixel); if (localIntersects && (!Map.isTileTypeDiagonalWall(tileType) || slideAgainstDiagonalWalls == false)) { intersects = localIntersects; } } if (intersects) { environmentCollision = true; newPos = new Point2(m_position); } } } // 2nd pass for diagonal walls if (slideAgainstDiagonalWalls) { TestPositionAgainDiagonalWalls(_theMap, minX, minY, maxX, maxY, ref environmentCollision, ref newPos); } m_boundingCharCircle.Center = new Vector3(newPos.X, newPos.Y, 0); m_boundingCharCircle.Radius = m_characterRadius; if (_characterArray != null) { // Check against other characters for (int c = 0; c < _characterArray.Length; c++) { if (_characterArray[c] == this || _characterArray[c].m_health <= 0 || _characterArray[c].m_finishedLevel) { continue; } BoundingSphere otherCharBounding = new BoundingSphere(); otherCharBounding.Center = new Vector3(_characterArray[c].m_position.X, _characterArray[c].m_position.Y, 0); otherCharBounding.Radius = m_characterRadius; if (m_boundingCharCircle.Intersects(otherCharBounding)) { if (m_frameIndexRendering == (int)CharacterTile.BADDY) { _characterArray[c].applyDamageDrain(frameTime, GameConstants.baddyDrainAmountPerSec); continue; } // characters are facing each other // This means if characters do occupy the same space (via resurrection or teleport) then they can still move appart else if (IsFacing(_characterArray[c])) { newPos = new Point2(m_position); } } } } } if (slideAgainstWalls) { m_position.X = newPos.X; m_position.Y = newPos.Y; } else { int realChangeX = newPos.X - m_position.X; int percentageX = 100; // This will let user get stuck on things instead of just sliding around if (change.X * change.X > realChangeX * realChangeX) { percentageX = 100 * realChangeX / change.X; } int realChangeY = newPos.Y - m_position.Y; int percentageY = 100; // This will let user get stuck on things instead of just sliding around if (change.Y * change.Y > realChangeY * realChangeY) { percentageY = 100 * realChangeY / change.Y; } int lowestPercentage = percentageX < percentageY ? percentageX : percentageY; // Calculate final position m_position.X += change.X * lowestPercentage / 100; m_position.Y += change.Y * lowestPercentage / 100; } SetMovingOnSlideState(movingOnSlide); return environmentCollision; }