public void ApplyGravity() { if (Owner.IsWorldFrozen) { return; } // Compute Gravity step for all objects affected by physics for (int i = 0; i < PlumberOwner.GameObjects.Count; i++) { if (PlumberOwner.GameObjects[i] is MovableGameObject) { GameObject obj = Owner.GameObjects[i]; MovableGameObject mobj = obj as MovableGameObject; if (mobj.IsAffectedByGravity) { mobj.Velocity.Y += GravityAcc * Owner.Time; // Apply gravity to vertical velocity if (mobj.Velocity.Y > MaximumFallSpeed) { mobj.Velocity.Y = MaximumFallSpeed; } } } } }
public void MoveAgent(MovableGameObject a, float[] controls) { a.Velocity.X = a.Velocity.Y = 0; if (!Owner.IsWorldFrozen) { if (controls[0] > 0) { a.Velocity.X += 4; } if (controls[1] > 0) { a.Velocity.X += -4; } if (Owner.DegreesOfFreedom == 2) { if (controls[2] > 0) { a.Velocity.Y += 4; } if (controls[3] > 0) { a.Velocity.Y += -4; } } } //int futureX = a.X + (int)a.vX; //a.X = futureX; //int futureY = a.Y + (int)a.vY; //a.Y = futureY; }
public void Update(GameObject gameObject, GameTime gameTime) { MovableGameObject movableGameObject = gameObject as MovableGameObject; movableGameObject.VelocityX = 0; if (!movableGameObject.Dead) { foreach (Keys key in Keyboard.GetState().GetPressedKeys()) { switch (key) { case Keys.A: movableGameObject.VelocityX = -MoveSpeed; break; case Keys.D: movableGameObject.VelocityX = MoveSpeed; break; case Keys.Space: Jump(movableGameObject); break; default: break; } } } }
public static (int, int) GetObjectDirections(MovableGameObject movableObject) { // Если двигались вправо, направление 1 // Если двигались влево, направление -1 var directionX = movableObject.Position.X - movableObject.OldPosition.X; if (directionX != 0) { directionX /= Math.Abs(directionX); } // Если двигались вверх, направление 1 // Если двигались вниз, направление -1 var directionY = movableObject.Position.Y - movableObject.OldPosition.Y; if (directionY != 0) { directionY /= Math.Abs(directionY); } // Если изначально стояли на месте, стреляем вправо if (directionX == 0 && directionY == 0) { directionX = 1; } return((int)directionX, (int)directionY); }
private void ReverseDirectionOnEndRoad(MovableGameObject movableGameObject) { if (movableGameObject.VelocityX != 0) { Vector2 position = movableGameObject.Position; position += movableGameObject.MoveAmount; Rectangle bounds = new Rectangle((int)position.X, (int)position.Y, movableGameObject.Width, movableGameObject.Height); int floorCollisionWidth = 0; foreach (GameObject gameObject in _collisionObjects) { Rectangle gameObjectBounds = gameObject.Bounds; if (bounds.Intersects(gameObjectBounds)) { floorCollisionWidth += Rectangle.Intersect(bounds, gameObjectBounds).Width; } } if (floorCollisionWidth > 0 && floorCollisionWidth < bounds.Width) { movableGameObject.VelocityX = 0; } } }
private void VerticalCollision(MovableGameObject movableGameObject) { if (movableGameObject.MoveAmountY != 0) { Vector2 position = movableGameObject.Position; position += movableGameObject.MoveAmount; Rectangle bounds = new Rectangle((int)position.X, (int)position.Y, movableGameObject.Width, movableGameObject.Height); foreach (GameObject collisionObject in _collisionObjects) { if (bounds.Intersects(collisionObject.Bounds)) { if (movableGameObject.MoveAmountY > 0) { movableGameObject.OnGround = true; } movableGameObject.VelocityY = 0; movableGameObject.MoveAmountY = 0; return; } } movableGameObject.OnGround = false; } }
public override void PresentNewTrainingUnit() { m_stepCount = 0; // Scale the noise in the world base on randomness_level { float randomness = TSHints[RANDOMNESS_LEVEL]; WrappedWorld.ImageNoiseStandardDeviation = 7 * randomness * randomness; } int noObjects = (int)TSHints[TSHintAttributes.NUMBER_OF_DIFFERENT_OBJECTS]; // Generate an artificial invisible agent m_agent = WrappedWorld.CreateNonVisibleAgent(); PointF agentPos = m_agent.GetGeometry().Location; m_agent.GameObjectStyle = GameObjectStyleType.None; // Prevent reseting movement vector when colliding with something from the top (default style is Platformer) // Generate shapes around the agent CreateTargets(noObjects, agentPos); // Pick one target and duplicate it in the pow center m_pickIdx = m_rndGen.Next(noObjects); var pick = m_targets[m_pickIdx]; Color color = TSHints[TSHintAttributes.IS_VARIABLE_COLOR] > 0 ? LearningTaskHelpers.RandomVisibleColor(m_rndGen) : pick.ColorMask; m_question = WrappedWorld.CreateShape((Shape.Shapes)m_shapeIdcs[m_pickIdx], color, agentPos, pick.Size); }
public bool IsCollisionPossible(GunBullet bullet, MovableGameObject movableGameObject) { return(IsCollisionPossible(bullet, movableGameObject.NewPosition) || IsCollisionPossible(bullet, new Vector2( movableGameObject.NewPosition.X - movableGameObject.Size, movableGameObject.NewPosition.Y - movableGameObject.Size)) || IsCollisionPossible((MovableGameObject)bullet, movableGameObject)); }
private void Jump(MovableGameObject movableGameObject) { if (movableGameObject.OnGround) { movableGameObject.OnGround = false; movableGameObject.VelocityY = JumpPower; } }
public bool ResolveCollision(GameObject go, MovableGameObject mover) { // If the bot's ID has already been removed from the world, the bot is dead, return the alive state as false if (!worldStateService.GameObjectIsInWorldState(mover.Id)) { return(false); } // If the colliding GO has already been removed from the world, but we reached here, the bot is alive but need not process the GO collision if (!worldStateService.GameObjectIsInWorldState(go.Id)) { return(true); } if (mover.Size > engineConfig.WorldFood.MaxConsumptionSize) { return(true); } if (mover is BotObject botObject) { var superFoodEffect = worldStateService.GetActiveEffectByType(botObject.Id, Effects.Superfood); if (superFoodEffect != null && superFoodEffect.EffectDuration > 0) { botObject.Size += go.Size * (int)engineConfig.ConsumptionRatio[GameObjectType.Superfood]; } else { botObject.Size += go.Size; } go.Size = 0; botObject.Score += engineConfig.ScoreRates[GameObjectType.Food]; worldStateService.RemoveGameObjectById(go.Id); worldStateService.UpdateBotSpeed(mover); } else { var moverStartingSize = mover.Size; mover.Size -= go.Size; go.Size -= moverStartingSize; if (go.Size <= 0) { go.Size = 0; worldStateService.RemoveGameObjectById(go.Id); } if (mover.Size <= 0) { mover.Size = 0; worldStateService.RemoveGameObjectById(mover.Id); } return(mover.Size > 0); } return(true); }
public override void PresentNewTrainingUnit() { /*if (WrappedWorld.GetType() == typeof(PlumberWorld)) * { * m_agent = new MovableGameObject(@"Plumber24x28.png", new PointF(24, 28), type: GameObjectType.Agent); * PlumberWorld world = WrappedWorld as PlumberWorld; * m_target = new GameObject(@"Coin16x16.png", new PointF(200, 200), type: GameObjectType.NonColliding); * world.AddGameObject(m_target); * * GameObject obj1 = new GameObject(@"Block60x10.png", new PointF(10, 260)); * GameObject obj2 = new GameObject(@"Block60x10.png", new PointF(100, 250)); * GameObject obj3 = new GameObject(@"Block5x120.png", new PointF(200, 100)); * GameObject obj4 = new GameObject(@"Block60x10.png", new PointF(300, 200)); * * world.AddGameObject(obj1); * world.AddGameObject(obj2); * world.AddGameObject(obj3); * world.AddGameObject(obj4); * } * else*/if (WrappedWorld.GetType() == typeof(RoguelikeWorld)) { RoguelikeWorld world = WrappedWorld as RoguelikeWorld; world.DegreesOfFreedom = 2; // create agent m_agent = world.CreateAgent(); // get grid Grid g = world.GetGrid(); // place objects according to the grid world.CreateWall(g.GetPoint(12, 17)); m_agent.Position = g.GetPoint(15, 16); world.CreateWall(g.GetPoint(15, 17)); world.CreateWall(g.GetPoint(16, 17)); world.CreateWall(g.GetPoint(17, 17)); world.CreateWall(g.GetPoint(17, 18)); // place new wall with random position and size (1 - 3 times larger than default) GameObject wall = world.CreateWall(g.GetPoint(0, 0), (float)(1 + m_rndGen.NextDouble() * 2)); // GetRandomPositionInsidePow avoids covering agent PointF randPosition = world.RandomPositionInsideViewport(m_rndGen, wall.GetGeometry().Size); wall.Position = randPosition; // create target m_target = world.CreateTarget(g.GetPoint(18, 18)); // create shape world.CreateShape(// position // Type determine interactions // uses texture shape as mask Shape.Shapes.Star, Color.Cyan, g.GetPoint(11, 13), new SizeF(30, 30), 60, GameObjectType.Obstacle); // you can resize choosen shape RogueDoor door = (RogueDoor)world.CreateDoor(g.GetPoint(13, 17), size: 2f); world.CreateLever(g.GetPoint(13, 13), door); } }
private void UpdateAnimationState(MovableGameObject movableGameObject) { AnimationState animationState = _animationState; if (movableGameObject.OnGround) { if (movableGameObject.Velocity == Vector2.Zero) { animationState = AnimationState.Idle; _loopAnimation = true; } if (movableGameObject.VelocityX > 0) { animationState = AnimationState.Walk; _effects = SpriteEffects.None; _loopAnimation = true; } if (movableGameObject.VelocityX < 0) { animationState = AnimationState.Walk; _effects = SpriteEffects.FlipHorizontally; _loopAnimation = true; } } else { if (movableGameObject.VelocityX > 0) { _effects = SpriteEffects.None; } if (movableGameObject.VelocityX < 0) { _effects = SpriteEffects.FlipHorizontally; } if (movableGameObject.VelocityY < 0) { animationState = AnimationState.Jump; _loopAnimation = false; } } if (movableGameObject.Dead) { animationState = AnimationState.Dead; _loopAnimation = false; } if (_animationState != animationState) { _frameIndex = 0; _animationState = animationState; } }
public override void MoveWorldObjects() { ApplyGravity(); // Updates agent's speed vector based on input // Updates game objects by gravity MovableGameObject magent = (PlumberOwner.GameObjectInControl as MovableGameObject); //Create reference to the GameObject currently under User control, we need to know its OnGround value if (magent == null) { return; } if (PlumberOwner.moveUpAction == 1.0f && magent.OnGround == true) { magent.OnGround = false; // If the jump command request was detected, give boost to the Y velocity of the Object in control (jump) magent.Velocity.Y = JumpBoost; } if (PlumberOwner.moveRightAction == 1.0f) { magent.Velocity.X += Acceleration; // Apply acceleration while "right button" is pressed if (magent.Velocity.X > MaximumAgentSpeed) // Limit Max velocity { magent.Velocity.X = MaximumAgentSpeed; } } if (PlumberOwner.moveLeftAction == 1.0f) { magent.Velocity.X -= Acceleration; // Apply acceleration while "left button" is pressed if (magent.Velocity.X < -MaximumAgentSpeed) // Limit Max velocity { magent.Velocity.X = -MaximumAgentSpeed; } } if (PlumberOwner.moveLeftAction == 0.0f && PlumberOwner.moveRightAction == 0.0f) { magent.Velocity.X *= (1 - Deceleration); // Decelerate when no corresponding directional button is not pressed } base.MoveWorldObjects(); /* * MyLog.DEBUG.WriteLine("==============================="); * MyLog.DEBUG.WriteLine("previousX: " + magent.previousX); * MyLog.DEBUG.WriteLine("previousY: " + magent.previousY); * MyLog.DEBUG.WriteLine("X: " + PlumberOwner.GameObjectInControl.X); * MyLog.DEBUG.WriteLine("Y: " + PlumberOwner.GameObjectInControl.Y); * MyLog.DEBUG.WriteLine("previousVelocityX: " + magent.previousvX); * MyLog.DEBUG.WriteLine("previousVelocityY: " + magent.previousvY); * MyLog.DEBUG.WriteLine("VelocityX: " + magent.vX); * MyLog.DEBUG.WriteLine("VelocityY: " + magent.vY); * MyLog.DEBUG.WriteLine("OnGround: " + magent.OnGround); */ }
protected void createNewItem(GameObject track) { if (track != null) { GameObject temp = (GameObject)Instantiate(track); currentObject = new MovableGameObject(temp, moveSpeed, rotationSpeed); list.Add(temp); } }
private void CalculateNextMove(MovableGameObject movableGameObject, GameTime gameTime) { movableGameObject.Position += movableGameObject.MoveAmount; float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds; Vector2 moveAmount = movableGameObject.Velocity * elapsedTime; movableGameObject.MoveAmount = moveAmount; movableGameObject.VelocityY += FreeFallSpeed; }
protected void createNewItem(GameObject track) { if(track != null){ GameObject temp = (GameObject)Instantiate(track); currentObject = new MovableGameObject(temp, moveSpeed, rotationSpeed); list.Add(temp); } }
public bool ResolveCollision(GameObject go, MovableGameObject mover) { var currentEffect = new ActiveEffect { Bot = mover, Effect = Effects.GasCloud }; if (mover is BotObject bot) { if (worldStateService.GetActiveEffectByType(bot.Id, Effects.GasCloud) != default) { if (bot.Size < engineConfig.MinimumPlayerSize) { worldStateService.RemoveGameObjectById(bot.Id); } return(bot.Size >= engineConfig.MinimumPlayerSize); } worldStateService.AddActiveEffect(currentEffect); bot.Size -= engineConfig.GasClouds.AffectPerTick; if (bot.Size < engineConfig.MinimumPlayerSize) { worldStateService.RemoveGameObjectById(bot.Id); } return(bot.Size >= engineConfig.MinimumPlayerSize); } else { var moverStartingSize = mover.Size; mover.Size -= go.Size; go.Size -= moverStartingSize; if (go.Size <= 0) { go.Size = 0; worldStateService.RemoveGameObjectById(go.Id); } if (mover.Size <= 0) { mover.Size = 0; worldStateService.RemoveGameObjectById(mover.Id); } return(mover.Size > 0); } }
public void Update(GameObject gameObject, GameTime gameTime) { MovableGameObject movableGameObject = gameObject as MovableGameObject; Rectangle bounds = movableGameObject.Bounds; foreach (GameObject collisionObject in _collisionObjects) { if (bounds.Intersects(collisionObject.Bounds)) { if (Algorithm.PixelCollision(movableGameObject, collisionObject)) { (gameObject as MovableGameObject).Dead = true; } } } }
public void Update(GameObject gameObject, GameTime gameTime) { MovableGameObject movableGameObject = gameObject as MovableGameObject; if (movableGameObject.VelocityX == 0) { if (_lastVelocityX != movableGameObject.VelocityX) { movableGameObject.VelocityX = -_lastVelocityX; } else { movableGameObject.VelocityX = Game1.Random.Next(2) == 0 ? -MoveSpeed : MoveSpeed; } _lastVelocityX = movableGameObject.VelocityX; } }
private void HorizontalCollision(MovableGameObject movableGameObject) { if (movableGameObject.MoveAmountX != 0) { Vector2 position = movableGameObject.Position; position.X += movableGameObject.MoveAmountX; Rectangle bounds = new Rectangle((int)position.X, (int)position.Y, movableGameObject.Width, movableGameObject.Height); foreach (GameObject collisionObject in _collisionObjects) { if (bounds.Intersects(collisionObject.Bounds)) { movableGameObject.MoveAmountX = 0; break; } } } }
protected void removeItem() { if (list.Count > 1) { GameObject obj = list[list.Count - 1]; Destroy(obj); list.Remove(obj); GameObject latest = list[list.Count - 1]; currentObject = new MovableGameObject(latest, moveSpeed, rotationSpeed); } else if (list.Count == 1) { GameObject obj = list[list.Count - 1]; Destroy(obj); list.Remove(obj); currentObject = null; } }
protected void removeItem() { if( list.Count > 1){ GameObject obj = list[list.Count - 1]; Destroy (obj); list.Remove(obj); GameObject latest = list[list.Count - 1]; currentObject = new MovableGameObject(latest, moveSpeed, rotationSpeed); }else if(list.Count == 1){ GameObject obj = list[list.Count - 1]; Destroy (obj); list.Remove(obj); currentObject = null; } }
public bool ResolveCollision(GameObject go, MovableGameObject mover) { if (!(mover is BotObject bot)) { return(false); } if (!(go is TorpedoGameObject torpedo)) { return(false); } var moverStartingSize = bot.Size; var destructiveSize = go.Size; bot.Size -= go.Size; go.Size -= Math.Max(moverStartingSize, go.Size); if (go.Size <= 0) { go.Size = 0; worldStateService.RemoveGameObjectById(go.Id); } if (mover.Size <= 0) { mover.Size = 0; worldStateService.RemoveGameObjectById(mover.Id); } var firingPlayer = worldStateService.GetBotById(torpedo.FiringPlayerId); if (firingPlayer != null) { firingPlayer.Size += destructiveSize; } worldStateService.UpdateBotSpeed(firingPlayer); worldStateService.UpdateBotSpeed(bot); return(mover.Size >= engineConfig.MinimumPlayerSize); }
public bool ResolveCollision(GameObject go, MovableGameObject mover) { var currentEffect = new ActiveEffect { Bot = mover, Effect = Effects.AsteroidField }; if (mover is BotObject bot) { /* If the effect is not registered, add it to the list. */ if (worldStateService.GetActiveEffectByType(mover.Id, Effects.AsteroidField) == default) { worldStateService.AddActiveEffect(currentEffect); worldStateService.UpdateBotSpeed(mover); } } else { var moverStartingSize = mover.Size; mover.Size -= go.Size; go.Size -= moverStartingSize; if (go.Size <= 0) { go.Size = 0; worldStateService.RemoveGameObjectById(go.Id); } if (mover.Size <= 0) { mover.Size = 0; worldStateService.RemoveGameObjectById(mover.Id); } return(mover.Size > 0); } return(true); }
private GamePhysicalObject GetNearestObjectInPath(MovableGameObject movableObject, int directionX, int directionY) { var gameObjectsInLine = gameRepository.GetAllGamePhysicalObjects(movableObject); var positionX = movableObject.NewPosition.X; var positionY = movableObject.NewPosition.Y; if (directionX == 0) { gameObjectsInLine = gameObjectsInLine .Where(q => q.Position.X >= positionX && positionX >= q.Position.X - q.Size) .Where(q => { return((directionY > 0 ? positionY <q.Position.Y : positionY> q.Position.Y) || IsCollisionPossible(movableObject, q)); }) .OrderBy(q => Math.Abs(positionY - q.Position.Y)) .ToList(); } else { gameObjectsInLine = gameObjectsInLine .Where(q => q.Position.Y >= positionY && positionY >= q.Position.Y - q.Size).ToList(); gameObjectsInLine = gameObjectsInLine .Where(q => { return((directionX > 0 ? positionX <q.Position.X : positionX> q.Position.X) || IsCollisionPossible(movableObject, q)); }) .OrderBy(q => Math.Abs(positionX - q.Position.X)) .ToList(); } return(gameObjectsInLine.FirstOrDefault()); }
public bool ResolveCollision(GameObject gameObject, MovableGameObject mover) { if (gameObject.Size < mover.Size) { return(true); } Tuple <GameObject, GameObject> wormholePair = worldStateService.GetWormholePair(gameObject.Id); if (wormholePair.Equals(null)) { // Lol how? We found a wormhole in state that did not exist in the known wormhole pairs throw new InvalidOperationException("Invalid Wormhole"); } var counterpartWormhole = wormholePair.Item1.Id == gameObject.Id ? wormholePair.Item2 : wormholePair.Item1; var resultingPosition = vectorCalculatorService.GetPositionFrom( counterpartWormhole.Position, counterpartWormhole.Size + mover.Size, mover.CurrentHeading); mover.Position = resultingPosition; if (mover is BotObject botObject) { botObject.Score = engineConfig.ScoreRates[GameObjectType.Wormhole]; } var newSize = (int)Math.Ceiling(wormholePair.Item1.Size * engineConfig.ConsumptionRatio[GameObjectType.Wormhole]); wormholePair.Item1.Size = newSize < engineConfig.Wormholes.MinSize ? engineConfig.Wormholes.MinSize : newSize; wormholePair.Item2.Size = wormholePair.Item1.Size; worldStateService.UpdateGameObject(wormholePair.Item1); worldStateService.UpdateGameObject(wormholePair.Item2); return(true); }
public bool IsApplicable(GameObject gameObject, MovableGameObject mover) => gameObject.GameObjectType == GameObjectType.Food;
public void SetPlattformerReaction(MovableGameObject mgo1, GameObject o2) { int collideResult = CheckCollision(mgo1, o2); PointF lastUntouchingPosition = GetLastUntouchingPosition(mgo1, o2, ref collideResult); //finds the X,Y position of "source" in the closest point to "o2" before collision) if (collideResult == 4 || collideResult == 1) // If it collided at the bottom or top { mgo1.Position.Y = lastUntouchingPosition.Y; // Reposition Y position to the last position where there was no collision mgo1.Velocity.Y = 0; // and reset Y velocity } if (collideResult == 2 || collideResult == 3) // If it collided at the right or left reset X velocity to 0 { mgo1.Position.X = lastUntouchingPosition.X; // Reposition X position to the last position where there was no collision mgo1.Velocity.X = 0; // and reset X velocity } if (mgo1.PositionPrevious.Y == mgo1.Position.Y && collideResult == 4) // Remember if object is on ground, collision on the bottom { mgo1.OnGround = true; } }
public bool ResolveCollision(GameObject gameObject, MovableGameObject mover) { if (!(gameObject is BotObject go)) { throw new ArgumentException("Non player in player collision"); } if (!(mover is BotObject botObject)) { throw new ArgumentException("Non player in player collision"); } // If the bot's ID has already been removed from the world, the bot is dead, return the alive state as false if (!worldStateService.GameObjectIsInWorldState(botObject.Id)) { return(false); } // If the colliding GO has already been removed from the world, but we reached here, the bot is alive but need not process the GO collision if (!worldStateService.GameObjectIsInWorldState(go.Id)) { return(true); } var botsAreEqualSize = botObject.Size == go.Size; if (botsAreEqualSize) { BounceBots(go, botObject, 1); return(true); } var botIsBigger = botObject.Size > go.Size; var consumer = (botIsBigger ? botObject : go) as BotObject; var consumee = (!botIsBigger ? botObject : go) as BotObject; var consumedSize = collisionService.GetConsumedSizeFromPlayer(consumer, consumee); consumee.Size -= consumedSize; consumer.Size += consumedSize; consumer.Score += engineConfig.ScoreRates[GameObjectType.Player]; worldStateService.UpdateBotSpeed(consumer); BounceBots(consumee, consumer, (int)Math.Ceiling((consumedSize + 1d) / 2)); if (consumee.Size < engineConfig.MinimumPlayerSize) { consumer.Size += consumee.Size; // After the previous consumptionSize has already been removed consumee.Size = 0; worldStateService.RemoveGameObjectById(consumee.Id); } worldStateService.UpdateBotSpeed(consumee); if (mover.Size > engineConfig.MinimumPlayerSize) { return(true); } Logger.LogInfo("BotDeath", "Bot Consumed"); worldStateService.RemoveGameObjectById(mover.Id); return(false); }
public bool IsCollisionPossible(MovableGameObject movableObject, NotMovableGameObject notMovableObject) { return(IsCollisionPossible(movableObject, (GameObject)notMovableObject)); }
public bool IsApplicable(GameObject gameObject, MovableGameObject mover) => gameObject.GameObjectType == GameObjectType.TorpedoSalvo;
public bool IsApplicable(GameObject gameObject, MovableGameObject mover) => gameObject.GameObjectType == GameObjectType.Player && mover is BotObject;
protected void CreateAgent() { m_agent = WrappedWorld.CreateAgent(); }
public void SetPinballReaction(MovableGameObject mgo1, GameObject o2) { int collideResult = 0; PointF lastUntouchingPosition = GetLastUntouchingPosition(mgo1, o2, ref collideResult); //finds the X,Y position of "source" in the closest point to "o2" before collision) if (collideResult == 4 || collideResult == 1) // If it collided at the bottom or top, reposition and invert Y velocity { mgo1.Position.Y = lastUntouchingPosition.Y; mgo1.Velocity.Y = -mgo1.Velocity.Y; } if (collideResult == 2 || collideResult == 3) // If it collided at the right or left, reposition and invert X velocity { mgo1.Position.X = lastUntouchingPosition.X; mgo1.Velocity.X = -mgo1.Velocity.X; } if (mgo1.IsAffectedByGravity == true) //If it's affected by gravity, add deceleration effect { mgo1.Velocity.X *= 0.93f; //TODO: replace 0.93f constant with a variable mgo1.Velocity.Y *= 0.93f; } }
public void MoveAgent(MovableGameObject a, float[] controls) { a.Velocity.X = a.Velocity.Y = 0; if (!Owner.IsWorldFrozen) { if (controls[0] > 0) a.Velocity.X += 4; if (controls[1] > 0) a.Velocity.X += -4; if (Owner.DegreesOfFreedom == 2) { if (controls[2] > 0) a.Velocity.Y += 4; if (controls[3] > 0) a.Velocity.Y += -4; } } //int futureX = a.X + (int)a.vX; //a.X = futureX; //int futureY = a.Y + (int)a.vY; //a.Y = futureY; }
/* * This method is called when 2 GameObjects collide, it finds the point of contact by applying a binary search where the lower side is Source's X,Y previous position and the higher side is * Source's X,Y current position, and the middle (needed by the binary search) is found by returning the middle position between the 2 points. */ public PointF GetLastUntouchingPosition(MovableGameObject source, GameObject target, ref int lastCollideResult) { int currentCollisionResult = 0; // The collision result used while iteratively repositioning the Source PointF lowerSide = new PointF(source.PositionPrevious.X, source.PositionPrevious.Y); // Initialise the lower side for the binary search to the coordinates of the source's previous position PointF higherSide = new PointF(source.Position.X, source.Position.Y); // Initialise the higher side for the binary search to the coordinates of the source's current position PointF currentMiddle = new PointF(-10, -10); // Declares the middle PointF, which will be used for the binary search PointF previousMiddle = new PointF(0, 0); // Declares the previous middle PointF, which will be used to decide when the binary search can't divide anymore PointF originalSourcePosition = new PointF(source.Position.X, source.Position.Y); PointF lastUntouchingPosition = new PointF(source.PositionPrevious.X, source.PositionPrevious.Y); //It will be used to remember the last position encountered where there was no contact (collision) in order to apply repositioning int counter = 0; //Stop the loop when the function can't divide anymore by half the distance between lowerSide and higherSide while (previousMiddle != currentMiddle) // If the previous middle point and the current one are equivalent, it means that distance can't be divided anymore by half, exit { previousMiddle = currentMiddle; // Update the previous value of the middle point, it is used to check if they are equivalent, if they are, the loop should stop currentMiddle = ReturnCoordinatesBetweenTwoPoints(lowerSide.X, lowerSide.Y, higherSide.X, higherSide.Y, 0.5f); // Find the middle point between lowerSide and higherSide //MyLog.DEBUG.WriteLine("Recomputed middle between : " + lowerSide.x + "," + lowerSide.y + " | " + higherSide.x + "," + higherSide.y + " : = " + currentMiddle.x + ", " + currentMiddle.y); source.Position.X = currentMiddle.X; // Position source's x to the point in exam source.Position.Y = currentMiddle.Y; // Position source's y to the point in exam currentCollisionResult = CheckCollision(source, target); // Check if there is a collision using the point in exam //MyLog.DEBUG.WriteLine("Collision result: " + currentCollisionResult); if (currentCollisionResult > 0) // If there is a collision reposition higherSide for the binary search { higherSide = currentMiddle; lastCollideResult = currentCollisionResult; } else // If there is no collision reposition the lowerSide for the binary search { lowerSide = currentMiddle; lastUntouchingPosition.X = currentMiddle.X; // Update the last encountered position where there was no collision lastUntouchingPosition.Y = currentMiddle.Y; } if (counter > 20) // Additional check { MyLog.ERROR.WriteLine("Too many iterations during repositioning, this should never happen, exiting.."); break; } counter++; } source.Position.X = originalSourcePosition.X; source.Position.Y = originalSourcePosition.Y; return lastUntouchingPosition; }
public void Resolve(MovableGameObject mgo1, GameObject o2) { MovableGameObject mgo2 = o2 as MovableGameObject; if (mgo1.Subtype != null || o2.Subtype != null) { if (ResolveSubtype(mgo1, o2)) { return; } } // both objects are movable if (mgo2 != null) { // TODO : Recheck this code (cases where both objects are movable) for future functionality SetPinballReaction(mgo1, o2); if (mgo2.Type == GameObjectType.Enemy) { } return; } else // only one object is movable { // other object interactions ISwitchable switcher = o2 as ISwitchable; if (switcher != null && switcher.SwitchOnCollision() && (o2 as MovableGameObject) == null) // prevents from switching twice per turn { switcher.Switch(); } if (!( o2.Type == GameObjectType.Agent || o2.Type == GameObjectType.ClosedDoor || o2.Type == GameObjectType.Obstacle || o2.Type == GameObjectType.Teacher || o2.Type == GameObjectType.None)) { return; } if (mgo1.GameObjectStyle == GameObjectStyleType.Platformer) // Collision outcome depends on the GameObjectStyleType { SetPlattformerReaction(mgo1, o2); } else if (mgo1.GameObjectStyle == GameObjectStyleType.Pinball) { SetPinballReaction(mgo1, o2); } else if (mgo1.GameObjectStyle == GameObjectStyleType.None) { } return; } throw new ArgumentException("For given objects doesn't exist confict resolution. " + "Did you forget to implement overriding class for StandardConflictResolver?"); }