/// <summary> /// Update all objects associated with this manager. /// </summary> /// <param name="timeElapsed"></param> public void UpdateAll(int timeElapsed, GameState gameRunState) { //asdf.Update(); int collisionState = 0; if (ninja.drawRect.Intersects(goalregion.drawRect) && (ninja.positionMask == PositionState.OnFloor) && ninja.ninjaLifeState == LifeState.Alive) { WOMstate = WOMState.LevelComplete; thoughts.setDialogueNumber(thoughts.getDialogueNumber() + 1); return; } //case where we just pressed the start button if (WOMstate == WOMState.RunningLevel) { //cancel the ninja warping animation ninja.EndWarpAnimation(); } commandMenu.Update(); commandMenu.UpdateAnimations(timeElapsed); if (gameRunState == GameState.StateRunning && timeElapsed != 0) { commandMenu.CommandCollisions(ninja, listOfWorldPlatforms); firstTimeHint = false; thoughts.Update(timeElapsed); } else { if (!firstTimeHint) { thoughts.showDialog(false); } thoughts.Update(timeElapsed); } ninja.Update(timeElapsed); if (ninja.drawRect.Y > Spotlight.stageCorner.Y) ninja.fallDeath(); faketimer++; backgroundLayers[2].Update(faketimer); backgroundLayers[1].Update(faketimer); backgroundLayers[0].Update(faketimer); foreach (Enemy e in listOfWorldEnemies) e.Update(timeElapsed, ninja); foreach (Platform p in listOfWorldPlatforms) p.Update(timeElapsed); if (gameRunState != GameState.StateRunning) return; List<Platform> ninjaCollisions = new List<Platform>(); //List of platforms that the ninja collides with List<int> collisionStates = new List<int>(); //List of corresponding collisionStates //NOTE: Platform collisions will have the same "wall clinging" problem until we create collisionLists for //those as well. These cases would only happen when platforms moving diagonally. foreach (Rope r in listOfHangingRopes) r.Update(timeElapsed); foreach (SuspendRope s in listOfSuspendRopes) s.Update(timeElapsed); foreach (Item item in listOfWorldItems) item.Update(timeElapsed); //Tests for collision between ninja and all platforms, and also all platforms against all other platforms //Also, tests to see if there are any obstructions in the areas where the ninja might wall climb from the top //right or left sides foreach (Platform p in listOfWorldPlatforms) { collisionState = Collision.checkCollisions(ninja, p); if (collisionState != 0) { if (p.isHazardous) { ninja.death(); // thoughts.showDialog(true); } collisionStates.Add(collisionState); ninjaCollisions.Add(p); //store the platform object in a List } // Don't check collisions if this platform isn't moving. if ((p.velocity == Vector2.Zero && p.triggers.Count == 0) || p.goThrough) continue; foreach (Platform q in listOfWorldPlatforms) { // Don't check collisions against itself if (p == q) continue; if (q.goThrough) continue; collisionState = Collision.checkCollisions(p, q); if (collisionState != 0) Collision.collisionResolution(collisionState, p, q); } } foreach (Trigger t in listOfTriggers) { if (ninja.drawRect.Intersects(t.drawRect)) t.attachedTo.StartPatrol(timeElapsed); foreach (Enemy e in listOfWorldEnemies) { if (e.drawRect.Intersects(t.drawRect)) { t.attachedTo.StartPatrol(timeElapsed); } } } /* //Test for collision between ropes and ninja foreach (Rope r in listOfHangingRopes) { collisionState = Collision.checkCollisions(ninja, r); r.setHasNinja(collisionState != 0); if (collisionState != 0) { r.resolveCollisionWithObject(collisionState, ninja); } else if (collisionState == 0) { r.setRotationAngle(0.0f); } r.Update(timeElapsed); }*/ #region Items to WorldObjects foreach (Item item in listOfWorldItems) { if (ninja.drawRect.Intersects(item.drawRect) && ninja.HeldItem == null && item.isUsed == false) { ninja.HeldItem = item; ninja.HeldItem.isHeld = true; } if (!item.isUsed) continue; //Check if item hits platform, and if so, then bind item to platform foreach (Platform p in listOfWorldPlatforms) { collisionState = Collision.checkCollisions(p, item); item.isHeld = false; if (collisionState != 0) { item.setVelocity(0, 0); item.setGravity(false); switch (item.type) { case ItemType.Shuriken: if(item.isBoundToAnotherPlatform == false) p.bindObject(item); item.setBind(); item.isUsed = false; break; case ItemType.Sword: Rectangle r = item.drawRect; swordPlatform = new Platform(r, item.drawTex, false, false, false, false, false); swordPlatform.drawStyle = WorldObjectDrawStyle.Rotating; if (collisionState == 1) swordPlatform.rotationAngle = (float)(180*Item.radian); else if (collisionState == 2) swordPlatform.rotationAngle = (float)(270* Item.radian); else if(collisionState == 3) swordPlatform.rotationAngle = 0; else if (collisionState == 4) swordPlatform.rotationAngle = (float)(90 * Item.radian); removedItem = item; if (!item.isBoundToAnotherPlatform) p.bindObject(swordPlatform); swordPlatform.setBind(); swordToPlatform = true; break; } item.platformCheck(p); } //Test collision between shuriken and rope if (item.type == ItemType.Shuriken) { List<SuspendRope> ropes = p.suspendRopes; for (int j = 0; j < ropes.Count; j++) { if (item.drawRect.Intersects(ropes[j].drawRect)) { MusicManager.PlaySoundEffect(SoundEffects.cutRope); p.cutRope(ropes[j]); } } } } foreach (Enemy e in listOfWorldEnemies) { collisionState = Collision.checkCollisions(item, e); if (collisionState != 0) { item.enemyCheck(e); } } } if (swordToPlatform) { MusicManager.PlaySoundEffect(SoundEffects.swordCollide); listOfWorldPlatforms.AddLast(swordPlatform); listOfWorldItems.Remove(removedItem); swordToPlatform = false; } #endregion #region Enemy collisions foreach (Enemy e in listOfWorldEnemies) { if (!e.IsAlive()) continue; //Tests for collision between ninja and all enemies collisionState = Collision.checkCollisions(ninja, e); if (collisionState != 0) { if (ninja.HeldItem != null && ninja.HeldItem.type == ItemType.Sword) { ninja.Action_SwingSword(); MusicManager.PlaySoundEffect(SoundEffects.deathsound1); e.death(); } else { e.attack(); if (ninja.ninjaLifeState == LifeState.Alive) { ninja.villainDeath(); thoughts.showDialog(true); } } } //enemy-platform collision foreach (Platform p in listOfWorldPlatforms) { collisionState = Collision.checkCollisions(e, p); if (collisionState == 3) { if (gameRunState == GameState.StateRunning && e.positionMask == PositionState.OnFloor) e.WorldObjectMove((int)p.velocity.X, (int)e.velocity.Y); } if (collisionState != 0) Collision.collisionResolution(collisionState, e, p); } } #endregion //If ninja collided with nothing except for the screen boundries, set its state to InAir if (ninjaCollisions.Count == 0 /*&& ninja.drawRect.Height != 400*/) ninja.positionMask = PositionState.InAir; //If the ninja hits multiple objects from the same side, make sure that the resolution only happens once <-- BAD //Its bad because it prevents platforms from going through other platforms while the ninja is on one bool c1 = false, c2 = false, c3 = false, c4 = false; //This area resolves the ninja->platform collisions //We need to resolve left/right collisions first //NOTE: In a foreach loop, you can't delete elements of a list you are iterating through for (int i = 0; i < ninjaCollisions.Count; ++i) { switch(collisionStates[i]) { case 2: Collision.collisionResolution(collisionStates[i], ninja, ninjaCollisions[i]); c2 = true; break; case 4: Collision.collisionResolution(collisionStates[i], ninja, ninjaCollisions[i]); c4 = true; break; } } //Recheck for collisions and see if there are any top/down cases left //If so, then resolve them for (int i = 0; i < ninjaCollisions.Count; ++i) { collisionState = Collision.checkCollisions(ninja, ninjaCollisions[i]); if (collisionState != 0) { switch (collisionState) { case 1: Collision.collisionResolution(collisionStates[i], ninja, ninjaCollisions[i]); c1 = true; break; case 3: Collision.collisionResolution(collisionStates[i], ninja, ninjaCollisions[i]); //Only move the ninja with his "bound" platform if if (gameRunState == GameState.StateRunning && ninja.positionMask == PositionState.OnFloor) { Platform p = ninjaCollisions[i]; if (p.velocity.Y > 0) ninja.WorldObjectMove((int)ninjaCollisions[i].velocity.X, (int)(ninjaCollisions[i].velocity.Y - 1)); else if (p.velocity.Y < 0) ninja.WorldObjectMove((int)ninjaCollisions[i].velocity.X, (int)ninja.velocity.Y/*(int)ninjaCollisions[index].velocity.Y*/); //if (p2.velocity.Y >= 0) //ninja.setVelocity(ninja.velocity.X, ninja.velocity.Y + p2.velocity.Y); } c3 = true; break; } } } ninja.squishCheck(c1, c2, c3, c4); }