public bool ApplyMove(GameObject gameObject, Vector2Int dest, bool checkObjects = true, bool collision = true) { if (gameObject.Room == null) { return(false); } if (gameObject.Room.Map != this) { return(false); } PositionInfo posInfo = gameObject.PosInfo; if (CanGo(dest, checkObjects) == false) { return(false); } if (collision) { // Remove { int x = posInfo.PosX - MinX; int y = MaxY - posInfo.PosY; if (_objects[y, x] == gameObject) { _objects[y, x] = null; } } { int x = dest.x - MinX; int y = MaxY - dest.y; _objects[y, x] = gameObject; } } // Zone GameObjectType type = ObjectManager.GetObjectTypeById(gameObject.Id); if (type == GameObjectType.Player) { Player player = (Player)gameObject; Zone now = gameObject.Room.GetZone(gameObject.CellPos); Zone after = gameObject.Room.GetZone(dest); if (now != after) { now.Players.Remove(player); after.Players.Add(player); } } else if (type == GameObjectType.Monster) { Monster monster = (Monster)gameObject; Zone now = gameObject.Room.GetZone(gameObject.CellPos); Zone after = gameObject.Room.GetZone(dest); if (now != after) { now.Monsters.Remove(monster); after.Monsters.Add(monster); } } else if (type == GameObjectType.Projectile) { Projectile projectile = (Projectile)gameObject; Zone now = gameObject.Room.GetZone(gameObject.CellPos); Zone after = gameObject.Room.GetZone(dest); if (now != after) { now.Projectiles.Remove(projectile); after.Projectiles.Add(projectile); } } // 실제 좌표 이동 posInfo.PosX = dest.x; posInfo.PosY = dest.y; return(true); }
// 오브젝트 룸에서 생성해욧 public void EnterGame(GameObject gameObject, bool randomPos = true) { if (gameObject == null) { return; } GameObjectType type = ObjectManager.GetObjectTypeById(gameObject.Id); if (randomPos) { Random _rand = new Random(); Vector2Int respawnPos; while (true) { respawnPos.x = _rand.Next(Map.MinX, Map.MaxX + 1); respawnPos.y = _rand.Next(Map.MinY, Map.MaxY + 1); if (Map.Find(respawnPos) == null) { gameObject.CellPos = respawnPos; break; } } } // 오브젝트 타입이 Player일때 if (type == GameObjectType.Player) { // 플레이어 룸 스폰 Player player = gameObject as Player; // 플레이어가 룸안에 들어옴 _players.Add(gameObject.Id, player); player.Room = this; player.RefreshAdditionalStat(); Map.ApplyMove(player, new Vector2Int(player.CellPos.x, player.CellPos.y)); GetZone(player.CellPos).Players.Add(player); // 클라이언트에게 Room 에서 처리하고 있는 맵을 로드하라! { S_ChangeMap changeMapPacket = new S_ChangeMap(); changeMapPacket.MapId = this.Map.MapID; player.Session.Send(changeMapPacket); } // 본인한테 Room 에 있던 player정보 전송 { S_EnterGame enterPacket = new S_EnterGame(); enterPacket.Player = player.Info; player.Session.Send(enterPacket); player.Vision.Update(); } } // 오브젝트 타입이 Monster else if (type == GameObjectType.Monster) { // 몬스터 룸 스폰 Monster monster = gameObject as Monster; _monsters.Add(gameObject.Id, monster); monster.Room = this; GetZone(monster.CellPos).Monsters.Add(monster); Map.ApplyMove(monster, new Vector2Int(monster.CellPos.x, monster.CellPos.y)); // 업데이트 한번실행 monster.Update(); } // 오브젝트 타입이 Projectile else if (type == GameObjectType.Projectile) { // 투사체 룸 스폰 Projectile projectile = gameObject as Projectile; _projectiles.Add(gameObject.Id, projectile); projectile.Room = this; GetZone(projectile.CellPos).Projectiles.Add(projectile); // 업데이트 한번실행 projectile.Update(); } // 타인에게 정보 전송 { S_Spawn spawnPacket = new S_Spawn(); spawnPacket.Objects.Add(gameObject.Info); Broadcast(gameObject.CellPos, spawnPacket); } }
public void EnterGame(GameObject gameObject) { if (gameObject == null) { return; } GameObjectType type = ObjectManager.GetObjectTypeById(gameObject.Id); // 각 오브젝트 타입별 처리 if (type == GameObjectType.Player) { Player player = gameObject as Player; _players.Add(gameObject.Id, player); // 해당하는 아이디와 플레이어를 딕셔너리에 삽입 player.Room = this; // 이거 안하고 스폰 후 가만히 있으면, 화살같은거 안박히는 버그남 Map.ApplyMove(player, new Vector2Int(player.CellPos.x, player.CellPos.y)); // 맵에다가 나를 이동시켜달라 요청 // 본인에게 스폰됐다는 정보 전송 { S_EnterGame enterPacket = new S_EnterGame(); // 패킷 보낼때마다 new 해서 Player 만들어줘도 되지만 // 받는쪽에서는 Player 자체가 아니라 그 플레이어의 정보만 궁금함 enterPacket.Player = player.Info; player.Session.Send(enterPacket); // 나에게 내 정보 전송 // 입장한 플레이어에게 // 접속중인 다른 플레이어뿐만 아니라 몬스터나 투사체들의 정보도 던져줘야 한다. S_Spawn spawnPacket = new S_Spawn(); foreach (Player p in _players.Values) { // 내 정보는 위에서 보냈으니, 내가 아닌 플레이어들의 정보만 담는다 if (player != p) { spawnPacket.Objects.Add(p.Info); } } foreach (Monster m in _monsters.Values) { spawnPacket.Objects.Add(m.Info); } foreach (Projectile p in _projectiles.Values) { spawnPacket.Objects.Add(p.Info); } player.Session.Send(spawnPacket); // 나에게 현재 게임에 있는 타인의 정보를 알린다. } } else if (type == GameObjectType.Monster) { Monster monster = gameObject as Monster; _monsters.Add(gameObject.Id, monster); monster.Room = this; Map.ApplyMove(monster, new Vector2Int(monster.CellPos.x, monster.CellPos.y)); // 맵에다가 나를 이동시켜달라 요청 } else if (type == GameObjectType.Projectile) // 투사체 { Projectile projectile = gameObject as Projectile; _projectiles.Add(gameObject.Id, projectile); projectile.Room = this; } // 타인에게 새로운 오브젝트가 스폰됐음을 알림 { S_Spawn spawnPacket = new S_Spawn(); spawnPacket.Objects.Add(gameObject.Info); // 신규유저의 정보를 기존에 접속중인 모두에게 알림 foreach (Player p in _players.Values) { // 본인의 정보 (MyPlayer)는 S_EnterGame 패킷으로 받기로 했기 때문이기도 하다. if (p.Id != gameObject.Id) // 위에서 생성한게 나 자신이 아닐때만 알림 -> 나 자신일때는 이미 위에서 알렸음 { p.Session.Send(spawnPacket); } } } }
// Id에 따른 오브젝트 룸에서 지워욧 public void LeaveGame(int objectId) { GameObjectType type = ObjectManager.GetObjectTypeById(objectId); Vector2Int cellPos; if (type == GameObjectType.Player) { Player player = null; if (_players.Remove(objectId, out player) == false) { return; } cellPos = player.CellPos; player.OnLeaveGame(); Map.ApplyLeave(player); player.Room = null; // 본인한테 정보 전송 { S_LeaveGame leavePacket = new S_LeaveGame(); player.Session.Send(leavePacket); } } else if (type == GameObjectType.Monster) { Monster monster = null; if (_monsters.Remove(objectId, out monster) == false) { return; } cellPos = monster.CellPos; Map.ApplyLeave(monster); monster.Room = null; } else if (type == GameObjectType.Projectile) { Projectile projectile = null; if (_projectiles.Remove(objectId, out projectile) == false) { return; } cellPos = projectile.CellPos; Map.ApplyLeave(projectile); projectile.Room = null; } else { return; } // 타인한테 정보 전송 { S_Despawn despawnPacket = new S_Despawn(); despawnPacket.ObjectIds.Add(objectId); Broadcast(cellPos, despawnPacket); } }