public static Vector2 MovePos(Vector2 position, float width, float height, Vector2 velocity, Room room, out bool collided) { collided = false; if (velocity == Vector2.Zero) { return position; } while (velocity != Vector2.Zero) { Hitbox box = new Hitbox(position, width, height); CollideLine? collision = GetNextCollision(box, velocity, room); float distance = collision.HasValue ? collision.Value.distance : velocity.Length(); Vector2 move = velocity; move.Normalize(); move *= distance; position += move; velocity -= move; if (collision.HasValue) { switch (collision.Value.type) { case CollideType.X: velocity.X = 0f; break; case CollideType.Y: velocity.Y = 0f; break; } collided = true; } } return position; }
public void UpdateEnemy(Room room, Player player) { if (hurtCool > 0) { hurtCool--; } Update(room, player); }
public override void Initialize(Main main) { base.Initialize(main); player = new Player(); player.position = new Vector2(tileSize * 1.5f, tileSize * 1.5f); currentRoom = SetupLevel(player); camera = player.position; }
public override bool Update(Room room, Player player, ref Vector2 camera) { CameraEvent whichEvent = events[currentEvent]; if (currentEvent < events.Count - 1 && whichEvent.timer >= whichEvent.endAction) { currentEvent++; } return events[currentEvent].Update(room, player, ref camera); }
public override sealed bool UpdateBullet(Room room, Player player) { if (timeLeft < totalTime * 3 / 4) { this.collision = true; } timeLeft--; return timeLeft < 0; }
public void ChangeRoom(Room room, Vector2 position) { if (currentRoom != null) { currentRoom.ExitRoom(player); } currentRoom = room; player.position = position; room.EnterRoom(player); }
public override sealed bool Update(Room room, Player player) { if (UpdateBullet(room, player)) { return true; } if (Collides(player)) { player.TakeDamage(1); } return false; }
private static CollideLine? GetNextCollision(Hitbox box, Vector2 velocity, Room room) { CollideLine? xLine = NextXCollision(box, velocity, room); CollideLine? yLine = NextYCollision(box, velocity, room); if (!xLine.HasValue) { return yLine; } if (!yLine.HasValue) { return xLine; } return xLine.Value.distance < yLine.Value.distance ? xLine : yLine; }
public void Update(Room room) { if (Main.IsControlPressed(KeyControl.Debug)) { debug = !debug; } if (Attacking) { attackTimer--; } if (!Attacking && Main.IsControlPressed(KeyControl.Action)) { Action(room); } if (Attacking) { Attack(room); } else { Move(room); } Hitbox box = hitbox; int left = (int)Math.Floor(box.topLeft.X / Tile.tileSize); int right = (int)Math.Ceiling(box.topRight.X / Tile.tileSize); int top = (int)Math.Floor(box.topLeft.Y / Tile.tileSize); int bottom = (int)Math.Ceiling(box.bottomLeft.Y / Tile.tileSize); for (int x = left; x < right; x++) { for (int y = top; y < bottom; y++) { Puzzle puzzle = room.tiles[x, y].puzzle; if (puzzle != null) { puzzle.OnPlayerCollide(room, x, y, this); } } } if (invincible > 0) { invincible--; } }
public override sealed bool UpdateBullet(Room room, Player player) { Vector2 oldPos = position; UpdateVelocity(room, player); if (wallCollide) { bool collided; TopLeft = Collision.MovePos(TopLeft, size, size, velocity, room, out collided); if (collided) { return true; } } else { position += velocity; } PostUpdate(room, player); timeLeft--; return timeLeft < 0; }
public bool TakeDamage(int damage, Room room, Player player) { if (CanBeHit) { life -= damage; if (life <= 0) { Kill(room, player); return true; } if (boss) { hurtCool = 180; room.bullets.Clear(); } else { hurtCool = 60; } } return false; }
public virtual bool Update(Room room, Player player, ref Vector2 camera) { if (timer == 0 && camera != targetPos) { Vector2 offset = targetPos - camera; if (offset.Length() < speed) { camera = targetPos; } else { offset.Normalize(); offset *= speed; camera += offset; } } else if (timer < endAction) { timer++; if (timer >= 30 && timer < 30 + actionLength) { DoAction(room, player, timer - 30); } } else { Vector2 offset = player.position - camera; if (offset.Length() < speed) { camera = player.position; return true; } offset.Normalize(); offset *= speed; camera += offset; } return false; }
public MonsterRoom(Room room, CreateStartEvent createStart, Vector2 spawnEnemyCamera, CreateEnemiesEvent createEnemies, CreateEndEvent createEnd) { this.CreateStart = createStart; this.spawnEnemyCamera = spawnEnemyCamera; this.CreateEnemies = createEnemies; this.enemies = new List<Enemy>(); this.CreateEnd = createEnd; this.cleared = false; room.OnExit += (Room r, Player player) => this.enemies.Clear(); }
public virtual void Initialize(Room room, int x, int y) { }
public virtual void OnPlayerCollide(Room room, int x, int y, Player player) { }
public abstract void Update(Room room, Player player);
private static CollideLine? NextXCollision(Hitbox box, Vector2 velocity, Room room) { if (velocity.X > 0f) { int x = (int)Math.Ceiling(box.topRight.X / tileSize); x = Math.Max(x, 0); int end = (int)Math.Floor((box.topRight.X + velocity.X) / tileSize); while (x <= end && x < room.width) { float xDistance = tileSize * x - box.topRight.X; float yDistance = xDistance / velocity.X * velocity.Y; int y = (int)Math.Floor((box.topRight.Y + yDistance) / tileSize); y = Math.Max(y, 0); int yEnd = (int)Math.Ceiling((box.bottomRight.Y + yDistance) / tileSize) - 1; while (y <= yEnd && y < room.height) { if (SolidTile(room.tiles[x, y])) { return new CollideLine { type = CollideType.X, position = x * tileSize, start = y * tileSize, end = (y + 1) * tileSize, distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance) }; } y++; } x++; } } else if (velocity.X < 0f) { int x = (int)Math.Floor(box.topLeft.X / tileSize); x = Math.Min(x, room.width); int end = (int)Math.Ceiling((box.topLeft.X + velocity.X) / tileSize); while (x >= end && x > 0) { float xDistance = tileSize * x - box.topLeft.X; float yDistance = xDistance / velocity.X * velocity.Y; int y = (int)Math.Floor((box.topLeft.Y + yDistance) / tileSize); y = Math.Max(y, 0); int yEnd = (int)Math.Ceiling((box.bottomLeft.Y + yDistance) / tileSize) - 1; while (y <= yEnd && y < room.height) { if (SolidTile(room.tiles[x - 1, y])) { return new CollideLine { type = CollideType.X, position = x * tileSize, start = y * tileSize, end = (y + 1) * tileSize, distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance) }; } y++; } x--; } } return null; }
public virtual void PostUpdate(Room room, Player player) { }
public virtual void UpdateVelocity(Room room, Player player) { }
public void Kill(Room room, Player player) { if (OnDeath != null) { OnDeath(this, room, player); } room.enemies.Remove(this); }
public abstract bool UpdateBullet(Room room, Player player);
private static CollideLine? NextYCollision(Hitbox box, Vector2 velocity, Room room) { if (velocity.Y > 0f) { int y = (int)Math.Ceiling(box.bottomLeft.Y / tileSize); y = Math.Max(y, 0); int end = (int)Math.Floor((box.bottomLeft.Y + velocity.Y) / tileSize); while (y <= end && y < room.height) { float yDistance = tileSize * y - box.bottomLeft.Y; float xDistance = yDistance / velocity.Y * velocity.X; int x = (int)Math.Floor((box.bottomLeft.X + xDistance) / tileSize); x = Math.Max(x, 0); int xEnd = (int)Math.Ceiling((box.bottomRight.X + xDistance) / tileSize) - 1; while (x <= xEnd && x < room.width) { if (SolidTile(room.tiles[x, y])) { return new CollideLine { type = CollideType.Y, position = y * tileSize, start = x * tileSize, end = (x + 1) * tileSize, distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance) }; } x++; } y++; } } else if (velocity.Y < 0f) { int y = (int)Math.Floor(box.topLeft.Y / tileSize); y = Math.Min(y, room.height); int end = (int)Math.Ceiling((box.topLeft.Y + velocity.Y) / tileSize); while (y >= end && y > 0) { float yDistance = tileSize * y - box.topLeft.Y; float xDistance = yDistance / velocity.Y * velocity.X; int x = (int)Math.Floor((box.bottomLeft.X + xDistance) / tileSize); x = Math.Max(x, 0); int xEnd = (int)Math.Ceiling((box.bottomRight.X + xDistance) / tileSize) - 1; while (x <= xEnd && x < room.width) { if (SolidTile(room.tiles[x, y - 1])) { return new CollideLine { type = CollideType.Y, position = y * tileSize, start = x * tileSize, end = (x + 1) * tileSize, distance = (float)Math.Sqrt(xDistance * xDistance + yDistance * yDistance) }; } x++; } y--; } } return null; }
public virtual void Update(Room room, int x, int y, Player player) { }
public void Action(Room room) { Vector2 checkDirection = Helper.DirectionToVector2(direction); float checkPosOffset = size; if (checkDirection.X != 0f && checkDirection.Y != 0f) { checkPosOffset *= (float)Math.Sqrt(2); } Vector2 checkPos = position + checkPosOffset * checkDirection; checkPos /= Tile.tileSize; if (checkDirection.X > 0f && checkPos.X == (float)Math.Floor(checkPos.X)) { checkPos.X -= 1f; } if (checkDirection.Y > 0f && checkPos.Y == (float)Math.Floor(checkPos.Y)) { checkPos.Y -= 1f; } int x = (int)checkPos.X; int y = (int)checkPos.Y; Puzzle puzzle = room.tiles[x, y].puzzle; if (puzzle != null && puzzle.PlayerInteraction(room, x, y, this)) { return; } attackTimer = 15; }
public virtual bool PlayerInteraction(Room room, int x, int y, Player player) { return false; }
public void Attack(Room room) { if (!AttackCanDamage) { return; } float attackDir = Helper.DirectionToRotation(direction); float angle1 = attackDir - 0.25f * (float)Math.PI; float angle2 = attackDir + 0.25f * (float)Math.PI; float reach = radius + attackDistance; int i = 0; while (i < room.enemies.Count) { Enemy enemy = room.enemies[i]; if (Collision.SectorCollides(position, reach, angle1, angle2, enemy.position, enemy.radius)) { if (enemy.TakeDamage(1, room, this)) { i--; } } i++; } }
public void Move(Room room) { Vector2 velocity = Vector2.Zero; if (Main.IsControlHeld(KeyControl.Up)) { velocity.Y -= 1f; } if (Main.IsControlHeld(KeyControl.Down)) { velocity.Y += 1f; } if (Main.IsControlHeld(KeyControl.Left)) { velocity.X -= 1f; } if (Main.IsControlHeld(KeyControl.Right)) { velocity.X += 1f; } if (velocity != Vector2.Zero) { velocity.Normalize(); if (Main.IsControlHeld(KeyControl.Focus)) { velocity *= 1.5f; } else { velocity *= 4f; } Helper.GetDirection(velocity, ref direction); bool collided; TopLeft = Collision.MovePos(TopLeft, size, size, velocity, room, out collided); } }
public void DoAction(Room room, Player player) { List<CameraEvent> startEvents = CreateStart(room, player); List<CameraEvent> endEvents = CreateEnd(room, player); Enemy.DeathAction onDeath = (Enemy e, Room r, Player p) => { enemies.Remove(e); if (enemies.Count == 0) { r.cameraEvent = new CameraChainEvent(endEvents); cleared = true; } }; startEvents.Add(new CameraEvent(spawnEnemyCamera, (Room r, Player p, int time) => { CreateEnemies(r, p, enemies); foreach (Enemy e in enemies) { e.temporary = true; e.OnDeath += onDeath; r.enemies.Add(e); } })); room.cameraEvent = new CameraChainEvent(startEvents); }