public override void update(TileMap map, TimeSpan elapsed) { if (SlatedToRemove) return; tElapsed = elapsed; isOnFloor = map.isRectOnFloor(EBounds.StandRect); if (attackDelay > 0) attackDelay -= elapsed.Milliseconds; if (showHpTicks > 0) showHpTicks -= elapsed.Milliseconds; // ### Update entity State if (!Alive) { DidMove = false; if (State == EntityState.Dead) return; else if (State != EntityState.Dying) die(); else if (!isOnFloor) EBounds.moveY(2); else { setState(EntityState.Dead); dropItems(); } return; } isOnFloor = map.isRectOnFloor(EBounds.StandRect); // ### Run the entities customizable AI if (ai != null) ai(this, map); else runAI(map); // ### Update movement State based on movement if (msVel.X != 0 && State != EntityState.Jumping) { setState(EntityState.Moving); if (msVel.X < 0) facing = Direction.Left; else facing = Direction.Right; } else if (State == EntityState.Moving) { // If State still 'Moving' but not moving, change State setState(EntityState.Standing); } // ### Update X position int currXSpeed = (int) (getRealXSpeed() * speedMultiplier); if (attackDelay > ATTACK_DELAY_MS * 0.625f && speedMultiplier > 0.25f) // If attacked recently while jumping, move slower speedMultiplier *= 0.93f; else if (speedMultiplier < MAX_SPEED) speedMultiplier += 0.033f; else speedMultiplier = MAX_SPEED; // Don't overshoot int oldX = EBounds.X; EBounds.moveX(currXSpeed); if (bounds.Right > map.getPixelWidth()) { EBounds.moveX((map.getPixelWidth() - bounds.Width) - bounds.X); // msVel.X = 0; } else if (bounds.Left <= 0) { EBounds.moveX(-bounds.X); // msVel.X = 0; } else if (msVel.X > 0) { int newX = map.checkBoundsXRight(bounds.Rect); updateBoundsX(map, newX); } else if (msVel.X < 0) { int newX = map.checkBoundsXLeft(bounds.Rect); updateBoundsX(map, newX); } if (oldX != EBounds.X) DidMove = true; else DidMove = false; // ### Update Y Position if (State == EntityState.Jumping) { // Gravity msVel.Y -= GRAVITY_PER_MS; } else if(jumpDelay > 0) { // Tick jump delay jumpDelay -= elapsed.Milliseconds; } // Subtract so everything else doesn't have to be switched (0 is top) EBounds.moveY((int) -getRealYSpeed()); if (bounds.Top >= map.getPixelHeight() - bounds.Height / 2) { EBounds.moveY((int) getRealYSpeed()); // Undo the move fallWithGravity(); } else if (bounds.Bottom <= 0) { EBounds.moveY((int) getRealYSpeed()); // Undo the move hitGround(); } else if (getRealYSpeed() > 0) { int newY = map.checkBoundsYUp(bounds.Rect); if (newY != bounds.Y) { // Hit something EBounds.moveY(newY - bounds.Y); // Move down correct amount (+) fallWithGravity(); } } else if (getRealYSpeed() < 0) { int newY = map.checkBoundsYDown(bounds.Rect); if (newY != bounds.Y) { // Hit something EBounds.moveY(newY - bounds.Y); // Move up correct amount (-) hitGround(); } } }
public void update(TileMap map, TimeSpan elapsed) { if (alive) { lastElapsed = elapsed; if (horizontal) { drawRect.X += getRealSpeed(); collRect.X += getRealSpeed(); } else { drawRect.Y += getRealSpeed(); collRect.Y += getRealSpeed(); } distTraveled += Math.Abs(getRealSpeed()); if (distTraveled > maxdist || drawRect.Right < 0 || drawRect.Left >= map.getPixelWidth()) { alive = false; } else { // Test walls based on direction (left, right) if (horizontal) { int x; if (msSpeed > 0) x = map.shrinkX(collRect.Right, false); else x = map.shrinkX(collRect.Left, false); int maxY = map.shrinkY(collRect.Bottom, true); for (int y = map.shrinkY(collRect.Top, false); y <= maxY; y++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } else { int y; if (msSpeed > 0) y = map.shrinkX(collRect.Bottom, false); else y = map.shrinkX(collRect.Top, false); int maxX = map.shrinkX(collRect.Left, true); for (int x = map.shrinkX(collRect.Right, false); x <= maxX; x++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } // Test collision with entites foreach (Entity e in map.entityIterator()) { if (!e.Alive) continue; EntityHit eHit; if (horizontal) { eHit = e.EBounds.collide(new Point(collRect.Right, collRect.Center.Y)); // If not hit in front, check back if (eHit.Part == EntityPart.None) eHit = e.EBounds.collide(new Point(collRect.Left, collRect.Center.Y)); } else { int y; if (msSpeed > 0) y = collRect.Bottom; else y = collRect.Top; eHit = e.EBounds.collide(new Point(collRect.Left, y)); // If not hit on left, check right if (eHit.Part == EntityPart.None) eHit = e.EBounds.collide(new Point(collRect.Right, y)); } if (eHit.Part != EntityPart.None) { alive = false; if (eHit.Part != EntityPart.Miss) { float dmgReducer = ((eHit.PercFromCenter < 0.6) ? 1 - eHit.PercFromCenter : 0.4f); int realDmg = e.hitInThe(eHit.Part, dmg, dmgReducer); map.addHitText(e, realDmg); if (!e.Alive) xp += e.XPValue; } return; } } } } }
public void update(TileMap map, TimeSpan elapsed) { if (alive) { lastElapsed = elapsed; int vel = getRealSpeed(); if (horizontal) { drawRect.X += vel; bounds.moveX(vel); } else { drawRect.Y += vel; bounds.moveY(vel); } distTraveled += Math.Abs(vel); if (distTraveled > maxdist || drawRect.Right < 0 || drawRect.Left >= map.getPixelWidth()) { alive = false; } else { // Test walls based on direction (left, right) if (horizontal) { int oldX = bounds.X, newX; if (vel > 0) { newX = map.checkBoundsXRight(bounds, Direction.Right); } else { newX = map.checkBoundsXLeft(bounds, Direction.Left); } if (newX != oldX || bounds.Y != drawRect.Y) { alive = false; return; } } else { int oldY = bounds.Y, newY; if (vel > 0) { newY = map.checkBoundsYDown(bounds, Direction.Right); } else { newY = map.checkBoundsYUp(bounds, Direction.Right); } if (newY != oldY) { alive = false; return; } } // Test collision with entites foreach (Entity e in map.entityIterator()) { if (!e.Alive) { continue; } EntityHit eHit; if (horizontal) { eHit = e.EBounds.collide(new Point(bounds.Right, bounds.Center.Y)); // If not hit in front, check back if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(bounds.Left, bounds.Center.Y)); } } else { int y; if (msSpeed > 0) { y = bounds.Bottom; } else { y = bounds.Top; } eHit = e.EBounds.collide(new Point(bounds.Left, y)); // If not hit on left, check right if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(bounds.Right, y)); } } if (eHit.Part != EntityPart.None) { alive = false; if (eHit.Part != EntityPart.Miss) { float dmgReducer = 0; if (eHit.PercFromCenter >= 0.75) { dmgReducer = 0.25f; } else if (eHit.PercFromCenter >= 0) { dmgReducer = 1 - eHit.PercFromCenter; } int realDmg = e.hitInThe(eHit.Part, dmg, dmgReducer); realDmg += e.slide(eHit.KnockBack); map.addHitText(e, realDmg); if (!e.Alive) { xp += e.XPValue; } } return; } } } } }
public void update(TileMap map, TimeSpan elapsed) { if (alive) { lastElapsed = elapsed; if (horizontal) { drawRect.X += getRealSpeed(); collRect.X += getRealSpeed(); } else { drawRect.Y += getRealSpeed(); collRect.Y += getRealSpeed(); } distTraveled += Math.Abs(getRealSpeed()); if (distTraveled > maxdist || drawRect.Right < 0 || drawRect.Left >= map.getPixelWidth()) { alive = false; } else { // Test walls based on direction (left, right) if (horizontal) { int x; if (msSpeed > 0) { x = map.shrinkX(collRect.Right, false); } else { x = map.shrinkX(collRect.Left, false); } int maxY = map.shrinkY(collRect.Bottom, true); for (int y = map.shrinkY(collRect.Top, false); y <= maxY; y++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } else { int y; if (msSpeed > 0) { y = map.shrinkX(collRect.Bottom, false); } else { y = map.shrinkX(collRect.Top, false); } int maxX = map.shrinkX(collRect.Left, true); for (int x = map.shrinkX(collRect.Right, false); x <= maxX; x++) { Rectangle wallRect = map.getRect(x, y); if (map.checkCollision(collRect, wallRect)) { alive = false; return; } } } // Test collision with entites foreach (Entity e in map.entityIterator()) { if (!e.Alive) { continue; } EntityHit eHit; if (horizontal) { eHit = e.EBounds.collide(new Point(collRect.Right, collRect.Center.Y)); // If not hit in front, check back if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(collRect.Left, collRect.Center.Y)); } } else { int y; if (msSpeed > 0) { y = collRect.Bottom; } else { y = collRect.Top; } eHit = e.EBounds.collide(new Point(collRect.Left, y)); // If not hit on left, check right if (eHit.Part == EntityPart.None) { eHit = e.EBounds.collide(new Point(collRect.Right, y)); } } if (eHit.Part != EntityPart.None) { alive = false; if (eHit.Part != EntityPart.Miss) { float dmgReducer = ((eHit.PercFromCenter < 0.6) ? 1 - eHit.PercFromCenter : 0.4f); int realDmg = e.hitInThe(eHit.Part, dmg, dmgReducer); map.addHitText(e, realDmg); if (!e.Alive) { xp += e.XPValue; } } return; } } } } }