This commit is contained in:
dvaer 2024-08-20 17:53:00 +03:00
commit 7b1b04fdb3
74 changed files with 1094 additions and 460 deletions

View file

@ -18,6 +18,7 @@ namespace MonogameLibrary.UI.Base
public string textureName = "";
public Rectangle rectangle = new Rectangle(0, 0, 10, 10);
public Color mainColor = Color.White;
public bool sus = true;
public DrawableUIElement(UIManager manager, int layerIndex = 0, string textureName = "")
{
@ -29,6 +30,7 @@ namespace MonogameLibrary.UI.Base
{
if (textureName == "")
{
sus = false;
texture = new Texture2D(Manager.GraphicsDevice, 1, 1);
texture.SetData<Color>(new Color[] { mainColor });
}

View file

@ -18,7 +18,7 @@ public class Bar : DrawableUIElement
public float percent = 0.5f;
private DrawableUIElement barInside;
public Color inColor;
public string inTextureName;
public string inTextureName = "";
public Bar(UIManager manager, int layerIndex = 0, string textureName = "") : base(manager, layerIndex, textureName)
{
@ -30,8 +30,7 @@ public class Bar : DrawableUIElement
{
rectangle = new Rectangle(rectangle.X + rectangle.Height / 8, rectangle.Y + rectangle.Height / 8,
(int)((rectangle.Width - rectangle.Height / 4) * percent), rectangle.Height / 8 * 7),
mainColor = inColor,
textureName = inTextureName
mainColor = inColor
};
}

View file

@ -44,6 +44,9 @@
#begin MapData/TileMaps/main.tmj
/copy:MapData/TileMaps/main.tmj
#begin MapData/TileSets/bonfire.tsj
/copy:MapData/TileSets/bonfire.tsj
#begin MapData/TileSets/IconSet.tsj
/copy:MapData/TileSets/IconSet.tsj
@ -56,6 +59,30 @@
#begin MapData/TileSets/TilesetNature.tsj
/copy:MapData/TileSets/TilesetNature.tsj
#begin sounds/Background menu music.wav
/importer:WavImporter
/processor:SoundEffectProcessor
/processorParam:Quality=Best
/build:sounds/Background menu music.wav
#begin sounds/Background music.wav
/importer:WavImporter
/processor:SoundEffectProcessor
/processorParam:Quality=Best
/build:sounds/Background music.wav
#begin sounds/Button click.wav
/importer:WavImporter
/processor:SoundEffectProcessor
/processorParam:Quality=Best
/build:sounds/Button click.wav
#begin sounds/Craft sound.wav
/importer:WavImporter
/processor:SoundEffectProcessor
/processorParam:Quality=Best
/build:sounds/Craft sound.wav
#begin sounds/Loot.wav
/importer:WavImporter
/processor:SoundEffectProcessor
@ -98,6 +125,18 @@
/processorParam:Quality=Best
/build:sounds/Zombi stoit.wav
#begin sounds/zombie sound 2.wav
/importer:WavImporter
/processor:SoundEffectProcessor
/processorParam:Quality=Best
/build:sounds/zombie sound 2.wav
#begin sounds/zombie sound.wav
/importer:WavImporter
/processor:SoundEffectProcessor
/processorParam:Quality=Best
/build:sounds/zombie sound.wav
#begin Textures/Animations/player_down_idle.animation
/copy:Textures/Animations/player_down_idle.animation
@ -185,6 +224,33 @@
#begin Textures/Animations/player_right_idle.animation
/copy:Textures/Animations/player_right_idle.animation
#begin Textures/Animations/player_run_down.animation
/copy:Textures/Animations/player_run_down.animation
#begin Textures/Animations/player_run_left_down.animation
/copy:Textures/Animations/player_run_left_down.animation
#begin Textures/Animations/player_run_left_up.animation
/copy:Textures/Animations/player_run_left_up.animation
#begin Textures/Animations/player_run_left.animation
/copy:Textures/Animations/player_run_left.animation
#begin Textures/Animations/player_run_right_down.animation
/copy:Textures/Animations/player_run_right_down.animation
#begin Textures/Animations/player_run_right_up.animation
/copy:Textures/Animations/player_run_right_up.animation
#begin Textures/Animations/player_run_right.animation
/copy:Textures/Animations/player_run_right.animation
#begin Textures/Animations/player_run_right.zip
/copy:Textures/Animations/player_run_right.zip
#begin Textures/Animations/player_run_up.animation
/copy:Textures/Animations/player_run_up.animation
#begin Textures/Animations/player_running_top_rotate.animation
/copy:Textures/Animations/player_running_top_rotate.animation
@ -328,8 +394,20 @@
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/AnimationTextures/Zombie/zombie_spritesheet_v2.png
#begin Textures/GUI/back.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/GUI/back.png
#begin Textures/GUI/back.png
#begin Textures/Effects/explosion.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
@ -339,7 +417,7 @@
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/GUI/back.png
/build:Textures/Effects/explosion.png
#begin Textures/GUI/background/base.png
/importer:TextureImporter
@ -677,18 +755,6 @@
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/Ammo.png
#begin Textures/icons/Collectables/Ammo.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/Ammo.png
#begin Textures/icons/Collectables/BottleOfWater.png
/importer:TextureImporter
/processor:TextureProcessor
@ -701,30 +767,6 @@
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/BottleOfWater.png
#begin Textures/icons/Collectables/BottleOfWater.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/BottleOfWater.png
#begin Textures/icons/Collectables/Peeble.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/Peeble.png
#begin Textures/icons/Collectables/Peeble.png
/importer:TextureImporter
/processor:TextureProcessor
@ -749,30 +791,6 @@
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/PureBottleOfWater.png
#begin Textures/icons/Collectables/PureBottleOfWater.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/PureBottleOfWater.png
#begin Textures/icons/Collectables/RottenFlesh.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/RottenFlesh.png
#begin Textures/icons/Collectables/RottenFlesh.png
/importer:TextureImporter
/processor:TextureProcessor
@ -797,30 +815,6 @@
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/Steel.png
#begin Textures/icons/Collectables/Steel.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/Steel.png
#begin Textures/icons/Collectables/Wood.png
/importer:TextureImporter
/processor:TextureProcessor
/processorParam:ColorKeyColor=255,0,255,255
/processorParam:ColorKeyEnabled=True
/processorParam:GenerateMipmaps=False
/processorParam:PremultiplyAlpha=True
/processorParam:ResizeToPowerOfTwo=False
/processorParam:MakeSquare=False
/processorParam:TextureFormat=Color
/build:Textures/icons/Collectables/Wood.png
#begin Textures/icons/Collectables/Wood.png
/importer:TextureImporter
/processor:TextureProcessor

View file

@ -0,0 +1 @@
{"id":"player_run_down","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":528,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

View file

@ -0,0 +1 @@
{"id":"player_run_left","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":792,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

View file

@ -0,0 +1 @@
{"id":"player_run_left_down","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":660,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

View file

@ -0,0 +1 @@
{"id":"player_run_left_up","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":924,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

View file

@ -0,0 +1 @@
{"id":"player_run_right","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":264,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

Binary file not shown.

View file

@ -0,0 +1 @@
{"id":"player_run_right_down","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":396,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

View file

@ -0,0 +1 @@
{"id":"player_run_right_up","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":132,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

View file

@ -0,0 +1 @@
{"id":"player_run_up","textureName":"Textures/AnimationTextures/Character/hr-level1_running","startSpriteRectangle":{"X":0,"Y":0,"Width":88,"Height":132},"frameSecond":[{"Item1":0,"Item2":2}],"textureFrameInterval":0,"framesCount":22,"isCycle":true,"offset":"0, 0"}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -22,8 +22,9 @@ using System.Linq;
using System.Web;
using ZoFo.GameCore.GUI;
using ZoFo.GameCore.GameObjects.Entities.Interactables.Collectables;
using ZoFo.GameCore.GameObjects.MapObjects.StopObjects;
using ZoFo.GameCore.Graphics;
using ZoFo.GameCore.GameObjects.MapObjects.StopObjects;
using ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO;
using ZoFo.GameCore.Graphics;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using ZoFo.GameCore.GameManagers.CollisionManager;
@ -41,7 +42,6 @@ namespace ZoFo.GameCore
public Client()
{
networkManager = new ClientNetworkManager();
networkManager.GetDataSent += OnDataSend;
// Подписка на действия инпутменеджера.
// Отправляются данные апдейтса с обновлением инпута
@ -49,8 +49,8 @@ namespace ZoFo.GameCore
{
networkManager.AddData(new UpdateInput()
{
InputMovementDirection = AppManager.Instance.InputManager.InputMovementDirection,
InputAttackDirection = AppManager.Instance.InputManager.InputAttackDirection
InputMovementDirection = AppManager.Instance.InputManager.InputMovementDirection.Serialize(),
InputAttackDirection = AppManager.Instance.InputManager.InputAttackDirection.Serialize()
});
};
@ -139,6 +139,10 @@ namespace ZoFo.GameCore
) )
.ToPoint();
}
public void SendData()
{
networkManager.SendData();
}
internal void Draw(SpriteBatch spriteBatch)
{
for (int i = 0; i < mapObjects.Count; i++)
@ -147,7 +151,7 @@ namespace ZoFo.GameCore
}
for (int i = 0; i < stopObjects.Count; i++)
{
stopObjects[i].Draw(spriteBatch);
stopObjects[i].Draw(spriteBatch);
}
for (int i = 0; i < gameObjects.Count; i++)
{
@ -160,13 +164,21 @@ namespace ZoFo.GameCore
}
internal void UpdatesList(List<UpdateData> updates)
{
foreach (var item in updates)
{
GotData(item);
}
}
internal void GotData(UpdateData update)
{
if (update is UpdateTileCreated)
{
mapObjects.Add(
new MapObject(
(update as UpdateTileCreated).Position,
(update as UpdateTileCreated).Position.GetVector2(),
(update as UpdateTileCreated).Size.GetPoint().ToVector2(),
(update as UpdateTileCreated).sourceRectangle.GetRectangle(),
(update as UpdateTileCreated).tileSetName
@ -176,7 +188,7 @@ namespace ZoFo.GameCore
{
stopObjects.Add(
new StopObject(
(update as UpdateStopObjectCreated).Position,
(update as UpdateStopObjectCreated).Position.GetVector2(),
(update as UpdateStopObjectCreated).Size.GetPoint().ToVector2(),
(update as UpdateStopObjectCreated).sourceRectangle.GetRectangle(),
(update as UpdateStopObjectCreated).tileSetName,
@ -188,7 +200,7 @@ namespace ZoFo.GameCore
Entity created_gameObject;
if ((update as UpdateGameObjectCreated).GameObjectType == "Player")
{
created_gameObject = new Player((update as UpdateGameObjectCreated).position);
created_gameObject = new Player((update as UpdateGameObjectCreated).position.GetVector2());
players.Add(created_gameObject as Player);
myPlayer = players[0];
gameObjects.Add(created_gameObject);
@ -196,7 +208,7 @@ namespace ZoFo.GameCore
else
{
Type t = Type.GetType("ZoFo.GameCore.GameObjects." + (update as UpdateGameObjectCreated).GameObjectType);
GameObject gameObject = Activator.CreateInstance(t, (update as UpdateGameObjectCreated).position) as GameObject;
GameObject gameObject = Activator.CreateInstance(t, (update as UpdateGameObjectCreated).position.GetVector2()) as GameObject;
if (gameObject is Entity)
(gameObject as Entity).SetIdByClient((update as UpdateGameObjectCreated).IdEntity);
gameObjects.Add(gameObject);
@ -204,10 +216,10 @@ namespace ZoFo.GameCore
(gameObjects.Last() as Entity).SetIdByClient((update as UpdateGameObjectCreated).IdEntity);
}
else if (update is UpdateGameOBjectWithoutIdCreated)
else if (update is UpdateGameObjectWithoutIdCreated)
{
Type t = Type.GetType("ZoFo.GameCore.GameObjects." + (update as UpdateGameOBjectWithoutIdCreated).GameObjectClassName);
GameObject gameObject = Activator.CreateInstance(t, (update as UpdateGameOBjectWithoutIdCreated).position) as GameObject;
Type t = Type.GetType("ZoFo.GameCore.GameObjects." + (update as UpdateGameObjectWithoutIdCreated).GameObjectClassName);
GameObject gameObject = Activator.CreateInstance(t, (update as UpdateGameObjectWithoutIdCreated).position.GetVector2()) as GameObject;
if (gameObject is Particle)
particles.Add(gameObject as Particle);
}
@ -216,7 +228,7 @@ namespace ZoFo.GameCore
var ent = FindEntityById(update.IdEntity);
if (ent != null)
ent.position = (update as UpdatePosition).NewPosition;
ent.position = (update as UpdatePosition).NewPosition.GetVector2();
}
else if (update is UpdateAnimation)
{
@ -239,7 +251,10 @@ namespace ZoFo.GameCore
}
else if (update is UpdateLoot)
{
if ((update as UpdateLoot).quantity == 0)
{
return;
}
var ent = FindEntityById(update.IdEntity);
if (ent != null)
(ent as Player).lootData.AddLoot_Client((update as UpdateLoot).lootName, (update as UpdateLoot).quantity);
@ -281,8 +296,9 @@ namespace ZoFo.GameCore
if (ent != null)
{
(ent as Player).health = (update as UpdatePlayerParametrs).health;
(ent as Player).rad = (update as UpdatePlayerParametrs).radiatoin;
(ent as Player).rad = (update as UpdatePlayerParametrs).radiatoin;
}
}

View file

@ -38,7 +38,7 @@ public abstract class AbstractGUI
public virtual void LoadContent()
{
Manager.LoadContent(AppManager.Instance.Content, "Font");
Manager.LoadContent(AppManager.Instance.Content, "Fonts/Font");
mouse = AppManager.Instance.Content.Load<Texture2D>("Textures/GUI/mouse");
}

View file

@ -144,6 +144,7 @@ public class BaseGUI : AbstractGUI
ItemDisplayButtonsList.Add(temp);
temp.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Craft sound");
AppManager.Instance.playerData.CraftItem(item.Key);
AppManager.Instance.SetGUI(new BaseGUI());
};
@ -165,7 +166,9 @@ public class BaseGUI : AbstractGUI
textureName = "Textures/GUI/Button2"
};
Elements.Add(bTExit);
bTExit.LeftButtonPressed += () => { AppManager.Instance.SetGUI(new MainMenuGUI()); };
bTExit.LeftButtonPressed += () => { AppManager.Instance.SetGUI(new MainMenuGUI());
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
};
}
public override void Update(GameTime gameTime)

View file

@ -23,21 +23,23 @@ public class HUD : AbstractGUI
int width = AppManager.Instance.CurentScreenResolution.X;
int height = AppManager.Instance.CurentScreenResolution.Y;
Button pauseButton = new Button(Manager)
Button pauseButton = new Button(Manager)
{
fontName = "Fonts\\Font3", scale = 0.4f, text = "| |", fontColor = Color.Black,
mainColor = Color.Transparent, rectangle = new Rectangle(width - width / 30 - width / 40, height / 30, width / 40, width / 40),
textureName = "Textures/GUI/Button2"
};
};
Elements.Add(pauseButton);
pauseButton.LeftButtonPressed += () =>
{
{
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new PauseGUI());
//AppManager.Instance.SetGUI(new FinishingGUI());
overlayGUI = new PauseGUI();
overlayGUI.Initialize();
overlayGUI.LoadContent();
overlayGUI.LoadContent();
};
Button invButton = new Button(Manager)
Button invButton = new Button(Manager)
{
fontName = "Fonts\\Font3", scale = 0.4f, fontColor = Color.Black,
mainColor = Color.Transparent, rectangle = new Rectangle(width - width / 30 - width / 40, height / 15 + width / 40, width / 40, width / 40),

View file

@ -41,7 +41,7 @@ public class MainMenuGUI : AbstractGUI
};
playButton.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Loot");
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new SelectModeMenu());
};
Elements.Add(playButton);
@ -57,6 +57,7 @@ public class MainMenuGUI : AbstractGUI
};
baseButton.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new BaseGUI());
};
Elements.Add(baseButton);
@ -72,7 +73,7 @@ public class MainMenuGUI : AbstractGUI
};
optionButton.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Loot");
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new OptionsGUI());
};
Elements.Add(optionButton);

View file

@ -43,6 +43,7 @@ public class OptionsGUI : AbstractGUI
label_OverallVolume_Percent.text = Math.Round(slider_OverallVolume.GetSliderValue * 100) + "%";
slider_OverallVolume.SliderChanged += (newVal) =>
{
label_OverallVolume_Percent.text = Math.Round(slider_OverallVolume.GetSliderValue * 100) + "%";
AppManager.Instance.SettingsManager.SetMainVolume(newVal);
};
@ -64,6 +65,7 @@ public class OptionsGUI : AbstractGUI
label_MusicVolume_Percent.text = Math.Round(slider_MusicVolume.GetSliderValue * 100) + "%";
slider_MusicVolume.SliderChanged += (newVal) =>
{
label_MusicVolume_Percent.text = Math.Round(slider_MusicVolume.GetSliderValue * 100) + "%";
AppManager.Instance.SettingsManager.SetMusicVolume(newVal);
};
@ -85,6 +87,7 @@ public class OptionsGUI : AbstractGUI
label_EffectsVolume_Percent.text = Math.Round(slider_EffectsVolume.GetSliderValue * 100) + "%";
slider_EffectsVolume.SliderChanged += (newVal) =>
{
label_EffectsVolume_Percent.text = Math.Round(slider_EffectsVolume.GetSliderValue * 100) + "%";
AppManager.Instance.SettingsManager.SetSoundEffectsVolume(newVal);
};
@ -109,6 +112,7 @@ public class OptionsGUI : AbstractGUI
button_FullScreen.SetIsChecked(AppManager.Instance.SettingsManager.IsFullScreen);
button_FullScreen.Checked += (newCheckState) =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SettingsManager.SetIsFullScreen(newCheckState);
};
Elements.Add(button_FullScreen);
@ -124,6 +128,7 @@ public class OptionsGUI : AbstractGUI
Elements.Add(bTExit);
bTExit.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new MainMenuGUI());
};

View file

@ -32,6 +32,7 @@ public class PauseGUI : AbstractGUI
};
continueButton.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new HUD());
};
Elements.Add(continueButton);
@ -47,6 +48,9 @@ public class PauseGUI : AbstractGUI
};
exitButton.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StopAllSounds();
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SoundManager.StartAmbientSound("Background menu music");
AppManager.Instance.SetGUI(new MainMenuGUI());
};
Elements.Add(exitButton);

View file

@ -39,14 +39,17 @@ public class SelectModeMenu : AbstractGUI
};
singleButton.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StopAllSounds();
AppManager.Instance.SoundManager.StartAmbientSound("Background music");
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
// single
Server server = new Server();
Client client = new Client();
server.CreateRoom(1);
client.JoinYourself(server.MyIp.Port);
AppManager.Instance.SetServer(server);
AppManager.Instance.SetClient(client);
AppManager.Instance.ChangeState(GameState.HostPlaying);
server.CreateRoom(false);
client.JoinYourself(server.MyIp.Port);
//AppManager.Instance.ChangeState(GameState.HostPlaying);
AppManager.Instance.SetGUI(new HUD());
//server.CreateRoom(1);
@ -70,6 +73,7 @@ public class SelectModeMenu : AbstractGUI
};
optionButton.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new SelectingServerGUI());
// multi
@ -86,6 +90,9 @@ public class SelectModeMenu : AbstractGUI
Elements.Add(bTExit);
bTExit.LeftButtonPressed += () =>
{
AppManager.Instance.SoundManager.StartAmbientSound("Button click");
AppManager.Instance.SetGUI(new MainMenuGUI());
};
}

View file

@ -76,6 +76,7 @@ public class SelectingServerGUI : AbstractGUI
{
if (int.TryParse(endpoint[1], out port))
{
client.JoinRoom(endpoint[0], port);
AppManager.Instance.SetClient(client);
AppManager.Instance.SetGUI(new WaitingForPlayersGUI(false));
@ -106,10 +107,10 @@ public class SelectingServerGUI : AbstractGUI
// host
Server server = new Server(); //Server Logic MultiPlayer
Client client = new Client();
server.CreateRoom(2);
client.JoinYourself(server.MyIp.Port);
AppManager.Instance.SetServer(server);
AppManager.Instance.SetClient(client);
server.CreateRoom(true);
client.JoinYourself(server.MyIp.Port);
string key = server.MyIp.ToString();
AppManager.Instance.debugHud.Set(key, "MultiPlayer");
// ваш код здесь

View file

@ -34,8 +34,8 @@ public class WaitingForPlayersGUI : AbstractGUI
// string pcIp =
// string pcIp =
ip = new Label(Manager) { rectangle = new Rectangle(width / 2 - (int)(width / 8), height / 7, (int)(width / 4), (int)(height / 20)), text = AppManager.Instance.server.MyIp.ToString(), fontColor = Color.White, mainColor = Color.Transparent, scale = 0.9f, fontName = "Fonts/Font3" };
Elements.Add(ip);
// ip = new Label(Manager) { rectangle = new Rectangle(width / 2 - (int)(width / 8), height / 7, (int)(width / 4), (int)(height / 20)), text = AppManager.Instance.server.MyIp.ToString(), fontColor = Color.White, mainColor = Color.Transparent, scale = 0.9f, fontName = "Fonts/Font3" };
// Elements.Add(ip);
if (isHost)
{
ip = new Label(Manager) { rectangle = new Rectangle(width / 2 - (int)(width / 8), height / 7, (int)(width / 4), (int)(height / 20)), text = AppManager.Instance.server.MyIp.ToString(), fontColor = Color.White, mainColor = Color.Transparent, scale = 0.9f, fontName = "Fonts\\Font3" };
@ -53,7 +53,7 @@ public class WaitingForPlayersGUI : AbstractGUI
startButton.LeftButtonPressed += () =>
{
// start
AppManager.Instance.ChangeState(GameState.HostPlaying);
AppManager.Instance.server.StartGame();
// ваш код здесь
};
Elements.Add(startButton);
@ -74,7 +74,7 @@ public class WaitingForPlayersGUI : AbstractGUI
waitButton.LeftButtonPressed += () =>
{
// start
AppManager.Instance.ChangeState(GameState.ClientPlaying);
AppManager.Instance.SetGUI(new HUD());
// ваш код здесь
};
Elements.Add(waitButton);

View file

@ -62,12 +62,14 @@ namespace ZoFo.GameCore.GameManagers
ItemManager = new ItemManager.ItemManager();
Instance = this;
InputManager = new InputManager();
SoundManager = new SoundManager();
SoundManager.LoadSounds();
SettingsManager = new SettingsManager();
SettingsManager.LoadSettings();
SoundManager = new SoundManager();
AssetManager = new AssetManager();
SoundManager.LoadSounds();
SoundManager.StartAmbientSound("Background menu music");
currentGUI = new MainMenuGUI();
debugHud = new DebugHUD();
@ -103,8 +105,8 @@ namespace ZoFo.GameCore.GameManagers
protected override void Update(GameTime gameTime)
{
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape)) { server?.CloseConnection(); Exit(); }
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed ||
Keyboard.GetState().IsKeyDown(Keys.Escape)) { Exit(); }
// debugHud.Set("key", "value");
@ -139,6 +141,8 @@ namespace ZoFo.GameCore.GameManagers
switch (gamestate)
{
case GameState.ClientPlaying:
client.Draw(_spriteBatch);
break;
case GameState.HostPlaying:
client.Draw(_spriteBatch);
break;

View file

@ -12,7 +12,9 @@ public class AssetManager
public AssetContainer Player = new()
{
Animations = [ "player_look_down" ],
Animations = [ "player_look_down", "player_run_up", "player_run_down", "player_run_right",
"player_run_left", "player_run_right_up", "player_run_left_up", "player_run_right_down",
"player_run_left_down" ],
IdleAnimation = "player_look_down"
};
}

View file

@ -10,9 +10,11 @@ using Microsoft.Xna.Framework;
using ZoFo.GameCore.GameManagers.MapManager.MapElements;
using ZoFo.GameCore.GameObjects.Entities;
using ZoFo.GameCore.GameObjects.Entities.LivingEntities;
using ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient;
using ZoFo.GameCore.Graphics;
using ZoFo.GameCore.GameObjects.Entities.LivingEntities.Player;
using ZoFo.GameCore.Graphics;
using ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO;
using ZoFo.GameCore.GameObjects.Entities.LivingEntities.Player;
namespace ZoFo.GameCore.GameManagers.CollisionManager
{
@ -23,8 +25,27 @@ namespace ZoFo.GameCore.GameManagers.CollisionManager
public List<CollisionComponent> ObjectsWithCollisions;
public List<CollisionComponent> EntitiesWithMovements;
public List<CollisionComponent> ObjectsWithTriggers;
public List<CollisionComponent> GetEntitiesToUpdate(Player player)
{
float ViewDistance = 500;
List<CollisionComponent> EntitiesInPlayerArea = new List<CollisionComponent>();
Rectangle ViewArea = new Rectangle((int)(player.position.X), (int)(player.position.Y),
(int)(ViewDistance), (int)(ViewDistance));
for (int i = 0; i < ObjectsWithCollisions.Count; i++)
{
if (ViewArea.Contains((float)ObjectsWithCollisions[i].gameObject.position.X, (float)ObjectsWithCollisions[i].gameObject.position.Y));
{
EntitiesInPlayerArea.Add(ObjectsWithCollisions[i]);
}
}
return EntitiesInPlayerArea;
}
//чекаем коллизии в листе
/// <summary>
@ -124,7 +145,7 @@ namespace ZoFo.GameCore.GameManagers.CollisionManager
entity.graphicsComponent.ObjectDrawRectangle.X = (int)entity.position.X;
entity.graphicsComponent.ObjectDrawRectangle.Y = (int)entity.position.Y;
AppManager.Instance.server.AddData(new UpdatePosition() { NewPosition = entity.position, IdEntity = entity.Id });
AppManager.Instance.server.AddData(new UpdatePosition() { NewPosition = new SerializableVector2(entity.position), IdEntity = entity.Id });
AppManager.Instance.debugHud.Set("testPos", entity.position.ToString()); //TODO remove
}
@ -233,6 +254,7 @@ namespace ZoFo.GameCore.GameManagers.CollisionManager
rectangle.Y += (int)origin.Y;
return rectangle;
}
public static SerializableVector2 Serialize(this Vector2 vector) => new SerializableVector2(vector);
public static Vector2 RandomVector()
{
return new Vector2((float)Random.Shared.NextDouble() - 0.5f, (float)Random.Shared.NextDouble() - 0.5f);

View file

@ -5,18 +5,11 @@ using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Formats.Tar;
using System.Linq;
using System.Reflection.Metadata.Ecma335;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using ZoFo.GameCore.GUI;
namespace ZoFo.GameCore.GameManagers
{
public enum ScopeState { Idle, Left, Right, Top, Down, TopLeft, TopRight, DownLeft, DownRight }
public class InputManager
{
public event Action ShootEvent; // событие удара(когда нажат X, событие срабатывает)
@ -177,7 +170,6 @@ namespace ZoFo.GameCore.GameManagers
#region Обработка взаимодействия с collectable(например лутом). Вызывает событие OnInteract
if (keyBoardState.IsKeyDown(Keys.E) && !isInteract)
{
OnInteract?.Invoke();
Debug.WriteLine("взаимодействие с Collectable");
}
@ -204,18 +196,33 @@ namespace ZoFo.GameCore.GameManagers
DebugHUD.Instance.Set("controls", currentScopeState.ToString());
}
#region работа с ScopeState и Vector2
/// <summary>
/// возвращает число от -14 до 16, начиная с
/// </summary>
/// <param name="vector"></param>
/// <returns></returns>
public int ConvertAttackVector2ToState(Vector2 vector){
int currentSection = (int)Math.Ceiling(Math.Atan2(vector.Y,
vector.X) * (180 / Math.PI) / 360 * 32);
return currentSection;
}
public ScopeState ConvertVector2ToState(Vector2 vector)
{
//if()
int currentSection = (int)Math.Ceiling(Math.Atan2(vector.Y,
int currentSection = 0;
if(vector.X == 0f && vector.Y == 0f){
currentScopeState = ScopeState.Idle;
}
else
{
currentSection = (int)Math.Ceiling(Math.Atan2(vector.Y,
vector.X) * (180 / Math.PI) / 360 * 16);
DebugHUD.DebugSet("current section", currentSection.ToString());
//DebugHUD.DebugSet("y", InputMovementDirection.Y.ToString());
//DebugHUD.DebugSet("x", InputMovementDirection.X.ToString());
switch(currentSection)
{
case -1:
currentScopeState = ScopeState.Idle;
break;
case 0 or 1:
currentScopeState = ScopeState.Right;
break;
@ -243,8 +250,41 @@ namespace ZoFo.GameCore.GameManagers
default:
break;
}
DebugHUD.DebugSet("current section", currentSection.ToString());
DebugHUD.DebugSet("y", vector.Y.ToString());
DebugHUD.DebugSet("x", vector.X.ToString());
}
return currentScopeState;
}
}
public static Vector2 ConvertStateToVector2(ScopeState scopeState)
{
switch (scopeState)
{
case ScopeState.Idle:
return new Vector2(0, 0);
case ScopeState.Left:
return new Vector2(-1, 0);
case ScopeState.Right:
return new Vector2(1, 0);
case ScopeState.Top:
return new Vector2(0, -1);
case ScopeState.Down:
return new Vector2(0, 1);
case ScopeState.TopLeft:
return new Vector2(-1, -1);
case ScopeState.TopRight:
return new Vector2(-1, 1);
case ScopeState.DownLeft:
return new Vector2(1, -1);
case ScopeState.DownRight:
return new Vector2(1, 1);
default:
return new Vector2(0, 0);
}
}
#endregion
public bool ButtonClicked(Keys key) => keyBoardState.IsKeyUp(key) && keyBoardState.IsKeyDown(key);
}

View file

@ -1,7 +1,9 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.Json;
using System.Threading.Tasks;
namespace ZoFo.GameCore.GameManagers.ItemManager
@ -15,7 +17,7 @@ namespace ZoFo.GameCore.GameManagers.ItemManager
{
LoadPlayerData();
}
public Dictionary<string, int> items;
public Dictionary<string, int> items = new Dictionary<string, int>();
/// <summary>
/// Принимает тэг и крафтит этот объект
/// </summary>
@ -50,11 +52,44 @@ namespace ZoFo.GameCore.GameManagers.ItemManager
public void LoadPlayerData()
{
//TODO
items = new Dictionary<string, int>();
items.Add("wood", 5);
items.Add("steel", 110);
items.Add("peeble", 6);
if (File.Exists("Items.txt"))
{
string data;
using (StreamReader reader = new StreamReader("Items.txt"))
{
data = reader.ReadToEnd();
}
List<PlayerItemsData> itemsDatas = JsonSerializer.Deserialize<List<PlayerItemsData>>(data);
foreach (var item in itemsDatas)
{
items.Add(item.Name, item.Count);
}
}
}
public void SavePlayerData()
{
var options = new JsonSerializerOptions { WriteIndented = true };
List<PlayerItemsData> playerItemsDatas = new List<PlayerItemsData>();
foreach (var item in items)
{
playerItemsDatas.Add(new PlayerItemsData { Name = item.Key, Count = item.Value });
}
string data = JsonSerializer.Serialize<List<PlayerItemsData>>(playerItemsDatas);
using (StreamWriter outputFile = new StreamWriter("Items.txt", new FileStreamOptions() { Mode = FileMode.Create, Access = FileAccess.Write } ))
{
outputFile.WriteLine(data);
}
}
}
class PlayerItemsData
{
public string Name { get; set; }
public int Count { get; set; }
}
}

View file

@ -94,11 +94,12 @@ namespace ZoFo.GameCore.GameManagers.MapManager
switch (tile.Type)
{
case "Tile":
AppManager.Instance.server.RegisterGameObject(new MapObject(position,
new Vector2(tileSet.TileWidth, tileSet.TileHeight),
sourceRectangle,
"Textures/TileSetImages/" + Path.GetFileName(tileSet.Image).Replace(".png", "")));
"Content/Textures/TileSetImages/" + Path.GetFileName(tileSet.Image).Replace(".png", "")));
break;
case "StopObject":
@ -107,11 +108,11 @@ namespace ZoFo.GameCore.GameManagers.MapManager
AppManager.Instance.server.RegisterGameObject(new StopObject(position,
new Vector2(tileSet.TileWidth, tileSet.TileHeight),
sourceRectangle,
"Textures/TileSetImages/" + Path.GetFileName(tileSet.Image).Replace(".png", ""),
"Content/Textures/TileSetImages/" + Path.GetFileName(tileSet.Image).Replace(".png", ""),
collisionRectangles.ToArray()));
break;
default:
default:
break;
}
break;

View file

@ -1,3 +1,5 @@
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Data.SqlTypes;
@ -10,47 +12,52 @@ using System.Text.Json;
using System.Threading;
using System.Threading.Tasks;
using ZoFo.GameCore.GameManagers.NetworkManager.Updates;
using ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient;
using ZoFo.GameCore.GUI;
namespace ZoFo.GameCore.GameManagers.NetworkManager
{
public class ClientNetworkManager
{
private int port = 0;
private int PlayerId;
private IPEndPoint endPoint;
private IPEndPoint sendingEP;
private Socket socket;
List<UpdateData> updates = new List<UpdateData>();
private List<Datagramm> waitingDatagramm = new List<Datagramm>();
private int currentServerDatagrammId = 0;
public delegate void OnDataSent(string Data);
public event OnDataSent GetDataSent; // event
public bool IsConnected { get { return socket.Connected; } }
public IPEndPoint InfoConnect => (IPEndPoint)socket.LocalEndPoint ?? endPoint;
public ClientNetworkManager()
{
Init();
}
public bool SocketConnected()
{
return socket.Connected;
}
public void Init() //create endPoint, socket
{
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
GetDataSent += AnalyzeData;
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
endPoint = new IPEndPoint(GetIp(), 8081);
socket.Bind(endPoint);
Thread thread = new Thread(StartListening);
thread.IsBackground = true;
thread.Start();
}
public void SendData()
{
for (int i = 0; i < updates.Count; i++)
if (updates != null)
{
AppManager.Instance.server.ProcessIUpdateData(updates[i]);
Datagramm Datagramm = new Datagramm();
Datagramm.updateDatas = updates;
byte[] bytes = Encoding.UTF8.GetBytes(System.Text.Json.JsonSerializer.Serialize(Datagramm)); //нужно сериализовать
socket.SendTo(bytes, sendingEP);
updates.Clear();
}
updates.Clear();
return;// TODO remove
byte[] bytes = Encoding.UTF8.GetBytes(JsonSerializer.Serialize(updates)); //нужно сериализовать
socket.Send(bytes);
}
public void AddData(UpdateData UpdateData)
@ -58,12 +65,147 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager
updates.Add(UpdateData);
}
public void StopConnection()
{
socket.Shutdown(SocketShutdown.Both);
socket.Close();
#region Working With Data RDP
public void AnalyzeData(string data)
{
JObject jObj = JsonConvert.DeserializeObject(data) as JObject;
JToken token = JToken.FromObject(jObj);
JToken updateDatas = token["updateDatas"];
if (updateDatas.HasValues)
{
Datagramm Dgramm = new Datagramm();
Dgramm.isImportant = token["isImportant"].ToObject<bool>();
Dgramm.DatagrammId = token["DatagrammId"].ToObject<int>();
if (PlayerId == 0)
{
PlayerId = token["PlayerId"].ToObject<int>();
if (AppManager.Instance.gamestate != GameState.HostPlaying)
{
AppManager.Instance.ChangeState(GameState.ClientPlaying);
}
SendAcknowledgement(Dgramm.DatagrammId);
}
if (Dgramm.isImportant)
{
if (Dgramm.DatagrammId == currentServerDatagrammId + 1)
{
currentServerDatagrammId++;
Dgramm.updateDatas = GetSentUpdates(token["updateDatas"]);
ExecuteDatagramm(Dgramm);
CheckDatagramm();
}
else if (Dgramm.DatagrammId > currentServerDatagrammId + 1 &&
waitingDatagramm.Find(x => x.DatagrammId == Dgramm.DatagrammId) == null)
{
Dgramm.updateDatas = GetSentUpdates(token["updateDatas"]);
waitingDatagramm.Add(Dgramm);
}
SendAcknowledgement(Dgramm.DatagrammId);
}
else
{
Dgramm.updateDatas = GetSentUpdates(token["updateDatas"]);
ExecuteDatagramm(Dgramm);
}
}
}
public List<UpdateData> GetSentUpdates(JToken updatesToken)
{
List<UpdateData> data = new List<UpdateData>();
JArray updateDatas = updatesToken as JArray;
UpdateData update = new UpdateData();
foreach (JObject token in updateDatas.Children())
{
switch (token["UpdateType"].ToObject<string>())
{
case "UpdateAnimation":
update = token.ToObject<UpdateAnimation>();
data.Add(update);
break;
case "UpdateEntityHealth":
update = token.ToObject<UpdateEntityHealth>();
data.Add(update);
break;
case "UpdateGameEnded":
update = token.ToObject<UpdateGameEnded>();
data.Add(update);
break;
case "UpdateGameObjectCreated":
update = token.ToObject<UpdateGameObjectCreated>();
data.Add(update);
break;
case "UpdateGameObjectDeleted":
update = token.ToObject<UpdateGameObjectDeleted>();
data.Add(update);
break;
case "UpdateInteraction":
update = token.ToObject<UpdateInteraction>();
data.Add(update);
break;
case "UpdateStopObjectCreated":
update = token.ToObject<UpdateStopObjectCreated>();
data.Add(update);
break;
case "UpdateInteractionReady":
update = token.ToObject<UpdateInteractionReady>();
data.Add(update);
break;
case "UpdateLoot":
update = token.ToObject<UpdateLoot>();
data.Add(update);
break;
case "UpdatePlayerParametrs":
update = token.ToObject<UpdatePlayerParametrs>();
data.Add(update);
break;
case "UpdatePosition":
update = token.ToObject<UpdatePosition>();
data.Add(update);
break;
case "UpdateTileCreated":
update = token.ToObject<UpdateTileCreated>();
data.Add(update);
break;
}
}
return data;
}
public void SendAcknowledgement(int DatagrammId)
{
Datagramm Dgramm = new Datagramm() { DatagrammId = DatagrammId, PlayerId = PlayerId };
string data = System.Text.Json.JsonSerializer.Serialize(Dgramm);
byte[] buffer = Encoding.UTF8.GetBytes(data);
socket.SendTo(buffer, sendingEP);
}
void CheckDatagramm()
{
Datagramm orderedDgramm = waitingDatagramm.Find(x => x.DatagrammId == currentServerDatagrammId + 1);
while (orderedDgramm != null)
{
currentServerDatagrammId++;
ExecuteDatagramm(orderedDgramm);
waitingDatagramm.Remove(orderedDgramm);
orderedDgramm = waitingDatagramm.Find(x => x.DatagrammId == currentServerDatagrammId + 1);
}
}
void ExecuteDatagramm(Datagramm Dgramm)
{
AppManager.Instance.client.UpdatesList(Dgramm.updateDatas);
//Достаёт Update и передает в ивент
}
#endregion
#region Join
/// <summary>
/// приложение пытается подключиться к комнате
/// </summary>
@ -71,19 +213,7 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager
/// <param name="port"></param>
public void JoinRoom(string ip, int port) // multyplayer
{
endPoint = new IPEndPoint(IPAddress.Parse(ip), port);
socket.Connect(endPoint);
SendData();
Thread listen = new Thread(StartListening);
listen.IsBackground = true;
listen.Start();
}
public void JoinRoom(IPEndPoint endPoint) // multyplayer
{
this.endPoint = endPoint;
socket.Connect(endPoint);
sendingEP = new IPEndPoint(IPAddress.Parse(ip), port);
SendData();
Thread listen = new Thread(StartListening);
listen.IsBackground = true;
@ -95,38 +225,45 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager
/// </summary>
public void JoinYourself(int port) // single player
{
endPoint = new IPEndPoint(GetIp(), port);
socket.Connect(endPoint);
sendingEP = AppManager.Instance.server.MyIp;
SendData();
Thread listen = new Thread(StartListening);
listen.IsBackground = true;
listen.Start();
}
#endregion
public static IPAddress GetIp()
{
/*string hostName = Dns.GetHostName(); // Retrive the Name of HOST
var ipList = Dns.GetHostByName(hostName).AddressList;
{
string hostName = Dns.GetHostName(); // Retrive the Name of HOST
var ipList = Dns.GetHostEntry(hostName).AddressList;
var ipV4List = new List<IPAddress>();
foreach (var ip in ipList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return ip;
}
}*/
return IPAddress.Parse("127.0.0.1");
ipV4List.Add(ip);
}
}
if (ipV4List.Count>0)
{
return ipV4List[ipV4List.Count - 1];
}
return IPAddress.Loopback;
}
//поток 2
public void StartListening()
{
while(socket.Connected)
{
byte[] bytes = new byte[65535];
var countAnsw = socket.Receive(bytes); //Вылетает если кто то закрыл
string update = Encoding.UTF8.GetString(bytes, 0, countAnsw); // обновление отосланные сервером
GetDataSent(update);
byte[] buffer = new byte[65535];
string data;
while (socket != null)
{
EndPoint senderRemote = new IPEndPoint(IPAddress.Any, 0);
int size = socket.ReceiveFrom(buffer, buffer.Length, SocketFlags.None, ref senderRemote);
byte[] correctedBuffer = new byte[size];
Array.Copy(buffer, correctedBuffer, size);
data = Encoding.UTF8.GetString(correctedBuffer);
GetDataSent(data);
}
}
}

View file

@ -9,10 +9,11 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO
{
public class SerializablePoint
{
public int X;
public int Y;
public int X { get; set; }
public int Y { get; set; }
public SerializablePoint(Point point) { X = point.X; Y = point.Y;}
public SerializablePoint() { }
public Point GetPoint() { return new Point(X, Y);}
}
}

View file

@ -10,24 +10,20 @@ using ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO;
namespace ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO
{
[Serializable]
[JsonSerializable(typeof(SerializableRectangle))]
public class SerializableRectangle
{
public SerializablePoint Size { get; set; }
public SerializablePoint Location { get; set; }
public int X { get; set; }
public int Y { get; set; }
public SerializableRectangle()
{
}
public SerializableRectangle(Rectangle rectangle) { X = rectangle.X; Y = rectangle.Y;
Size = new SerializablePoint(rectangle.Size); Location = new SerializablePoint(rectangle.Location); }
public SerializableRectangle(Rectangle rectangle) { Size = new SerializablePoint(rectangle.Size); Location = new SerializablePoint(rectangle.Location); }
public Rectangle GetRectangle()
{
return new Rectangle() { X = X, Y = Y, Size = Size.GetPoint(), Location = Location.GetPoint() };
return new Rectangle(Location.GetPoint(), Size.GetPoint());
}
}
}

View file

@ -0,0 +1,28 @@
using Microsoft.Xna.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.JavaScript;
using System.Text;
using System.Threading.Tasks;
namespace ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO
{
[Serializable]
public class SerializableVector2
{
public float X { get; set; }
public float Y { get; set; }
public SerializableVector2(Vector2 vector)
{
X = vector.X;
Y = vector.Y;
}
public Vector2 GetVector2()
{
return new Vector2(X, Y);
}
}
}

View file

@ -13,23 +13,32 @@ using System.Text.Json.Serialization;
using System.Threading;
using System.Threading.Tasks;
using ZoFo.GameCore.GameManagers.NetworkManager.Updates;
using ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO;
using ZoFo.GameCore.GUI;
using Newtonsoft.Json.Linq;
using Newtonsoft.Json;
using ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient;
using ZoFo.GameCore.GameManagers.NetworkManager.Updates.ClientToServer;
namespace ZoFo.GameCore.GameManagers.NetworkManager
{
public class ServerNetworkManager
{
private IPAddress ip = IPAddress.Parse("127.0.0.1");
private const int port = 0;
private IPEndPoint endPoint;
private Socket socket;
private List<Socket> clients;
public List<UpdateData> updates;
private IPAddress ip;
private bool isMultiplayer;
//Player Id to Player endPoint
private List<IPEndPoint> clientsEP;
public IPEndPoint endPoint;
private List<UpdateData> commonUpdates;
private List<UpdateData> importantUpdates;
private List<Datagramm> sendedData;
private List<Datagramm> arrivingDataId;
private int currentDatagrammId = 0;
public delegate void OnDataSend(string data);
public event OnDataSend GetDataSend; // event
Dictionary<Socket, Thread> managerThread;
Thread serverTheread;
public IPEndPoint InfoConnect => (IPEndPoint)socket.LocalEndPoint ?? endPoint;
Thread serverThread;
int datapackSize = 150;
public ServerNetworkManager() { Init(); }
/// <summary>
@ -37,31 +46,46 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager
/// </summary>
private void Init()
{
endPoint = new IPEndPoint(GetIp(), port);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
managerThread = new Dictionary<Socket, Thread>();
clients = new List<Socket>();
updates = new List<UpdateData>();
managerThread = new Dictionary<Socket, Thread>();
endPoint = new IPEndPoint(GetIp(), 8080);
socket = new Socket(AddressFamily.InterNetwork, SocketType.Dgram, ProtocolType.Udp);
clientsEP = new List<IPEndPoint>();
commonUpdates = new List<UpdateData>();
importantUpdates = new List<UpdateData>();
sendedData = new List<Datagramm>();
arrivingDataId = new List<Datagramm>();
GetDataSend += AnalyzeData;
socket.Bind(endPoint);
}
/// <summary>
/// Получает IP устройства
/// </summary>
/// <returns></returns>
public static IPAddress GetIp()
{
/*string hostName = Dns.GetHostName(); // Retrive the Name of HOST
var ipList = Dns.GetHostByName(hostName).AddressList;
public static IPAddress GetIp()
{
string hostName = Dns.GetHostName(); // Retrive the Name of HOST
var ipList = Dns.GetHostEntry(hostName).AddressList;
var ipV4List = new List<IPAddress>();
foreach (var ip in ipList)
{
if (ip.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)
{
return ip;
}
}*/
return IPAddress.Parse("127.0.0.1");
{
ipV4List.Add(ip);
}
}
if (ipV4List.Count > 0)
{
return ipV4List[ipV4List.Count - 1];
}
return IPAddress.Loopback;
}
public void SetIsMultiplayer(bool isMultiplayer)
{
this.isMultiplayer = isMultiplayer;
}
/// <summary>
@ -69,26 +93,76 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager
/// </summary>
public void SendData()
{
for (int i = 0; i < updates.Count; i++)
{
#region Network Sending SinglePlayerFix
//for (int i = 0; i < updates.Count; i++)
//{
AppManager.Instance.client.GotData(updates[i]);
}
updates.Clear();
return; //TODO TODO REMOVE TO ADD NETWORK TODO REMOVE TO ADD NETWORK TODO REMOVE TO ADD NETWORK TODO REMOVE TO ADD NETWORK
// AppManager.Instance.client.GotData(updates[i]);
//}
//updates.Clear();
//return; //TODO TODO REMOVE TO ADD NETWORK TODO REMOVE TO ADD NETWORK TODO REMOVE TO ADD NETWORK TODO REMOVE TO ADD NETWORK
//Что это?
//по 10 паков за раз TODO FIXITFIXITFIXITFIXITFIXITFIXITFIXITFIXITFIXITFIXITFIXITFIXIT
List<UpdateData> datasToSend = new List<UpdateData>();
for (int i = 0; i < 200 && i<updates.Count; i++)
datasToSend.Add(updates[i]);
string data = JsonSerializer.Serialize(datasToSend);
var databytes = Encoding.UTF8.GetBytes(data);
foreach (Socket socket in clients)
#endregion
if (arrivingDataId.Count != 0)
{
clients[0].SendAsync(databytes);
List<Datagramm> actualArrivingId = arrivingDataId;
for (int i = 0; i < actualArrivingId.Count; i++)
{
sendedData.Remove(sendedData.Find(x => x.DatagrammId == actualArrivingId[i].DatagrammId
&& x.PlayerId == actualArrivingId[i].PlayerId));
}
arrivingDataId.Clear();
}
for (int i = 0; i < 200 && i< datasToSend.Count; i++)
updates.RemoveAt(0);
List<UpdateData> dataToSend;
if (importantUpdates.Count > 0)
{
dataToSend = new List<UpdateData>();
for (int j = 0; j < datapackSize && j < importantUpdates.Count; j++)
dataToSend.Add(importantUpdates[j]);
for (int i = 0; i < clientsEP.Count; i++)
{
Datagramm impDgramm = new Datagramm();
impDgramm.DatagrammId = currentDatagrammId;
impDgramm.updateDatas = dataToSend;
impDgramm.isImportant = true;
impDgramm.PlayerId = i + 1;
sendedData.Add(impDgramm);
}
for (int j = 0; j < datapackSize && j < dataToSend.Count; j++)
importantUpdates.RemoveAt(0);
currentDatagrammId++;
}
if (sendedData.Count != 0)
{
for (int i = 0; i < clientsEP.Count; i++)
{
foreach (Datagramm Dgramm in sendedData.Where(x => x.PlayerId == i+1))
{
string impData = System.Text.Json.JsonSerializer.Serialize(Dgramm);
byte[] impBuffer = Encoding.UTF8.GetBytes(impData);
socket.SendTo(impBuffer, clientsEP[i]);
}
}
}
Datagramm unImpDgramm = new Datagramm();
dataToSend = new List<UpdateData>();
for (int i = 0; i < 200 && i < commonUpdates.Count; i++)
dataToSend.Add(commonUpdates[i]);
unImpDgramm.updateDatas = dataToSend;
string data = System.Text.Json.JsonSerializer.Serialize(unImpDgramm);
byte[] buffer = Encoding.UTF8.GetBytes(data);
foreach (EndPoint sendingEP in clientsEP)
{
socket.SendTo(buffer, sendingEP);
}
for (int i = 0; i < 200 && i < dataToSend.Count; i++)
commonUpdates.RemoveAt(0);
}
/// <summary>
@ -97,42 +171,41 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager
/// <param name="data"></param>
public void AddData(UpdateData data)
{
updates.Add(data);
}
/// <summary>
/// По сути конец игры и отключение игроков
/// </summary>
public void CloseConnection()
{
foreach (var item in clients)
if (data.isImportant)
{
//Закрывает сокеты клиентов
item.Shutdown(SocketShutdown.Both);
item.Close();
importantUpdates.Add(data);
}
foreach (var item in managerThread)
{
foreach (var socket in clients)
{
//Закрывает потоки клиентов
managerThread[socket].Interrupt();
}
else {
commonUpdates.Add(data);
}
//очищает листы
managerThread.Clear();
clients.Clear();
}
/// <summary>
/// Начинает работу сервера (Ожидает подключений)
/// </summary>
/// <param name="players"></param>
public void Start(object players)
public void Start()
{
serverTheread = new Thread(StartWaitingForPlayers);
serverTheread.IsBackground = true;
serverTheread.Start(players);
serverThread = new Thread(StartWaitingForPlayers);
serverThread.IsBackground = true;
serverThread.Start();
}
public void StartGame()
{
for (int i = 0; i < clientsEP.Count; i++)
{
Datagramm initDgramm = new Datagramm();
initDgramm.isImportant = true;
initDgramm.DatagrammId = currentDatagrammId;
initDgramm.PlayerId = i + 1;
sendedData.Add(initDgramm);
string data = System.Text.Json.JsonSerializer.Serialize(initDgramm);
byte[] buffer = Encoding.UTF8.GetBytes(data);
socket.SendTo(buffer, clientsEP[i]);
}
currentDatagrammId++;
AppManager.Instance.ChangeState(GameState.HostPlaying);
AppManager.Instance.SetGUI(new HUD());////
}
//Потоки Клиентов
@ -140,43 +213,74 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager
/// Слушает игроков, которые хотят подключиться
/// </summary>
/// <param name="players"></param>
public void StartWaitingForPlayers(object players)
public void StartWaitingForPlayers()
{
int playNumber = (int)players;
socket.Listen(playNumber);
for (int i = 0; i < playNumber; i++)
byte[] buffer = new byte[65535];
string data;
while (socket != null)
{
Socket client = socket.Accept();
AppManager.Instance.debugHud.Log($"Connect {client.LocalEndPoint.ToString()}");
Thread thread = new Thread(StartListening);
thread.IsBackground = true;
thread.Start(client);
managerThread.Add(client, thread);
clients.Add(client);
//AppManager.Instance.ChangeState(GameState.HostPlaying);
//добавляем клиентов в лист
EndPoint senderRemote = (EndPoint)new IPEndPoint(IPAddress.Any, 0);
int size = socket.ReceiveFrom(buffer, buffer.Length, SocketFlags.None, ref senderRemote);
if (AppManager.Instance.gamestate != GameState.HostPlaying && !clientsEP.Contains(senderRemote) &&
senderRemote != new IPEndPoint(IPAddress.Any, 0))
{
clientsEP.Add((IPEndPoint)senderRemote);
AppManager.Instance.debugHud.Log($"Connect {senderRemote.ToString()}");
if (!isMultiplayer) AppManager.Instance.ChangeState(GameState.HostPlaying);
// Отправлять Init апдейт с информацией об ID игрока и ID датаграмма на сервере
//Можно добавить bool isInit для Датаграммов
}
byte[] correctedBuffer = new byte[size];
Array.Copy(buffer, correctedBuffer, size);
data = Encoding.UTF8.GetString(correctedBuffer);
GetDataSend(data);
}
AppManager.Instance.ChangeState(GameState.HostPlaying);
}
public void AnalyzeData(string data)
{
JObject jObj = JsonConvert.DeserializeObject(data) as JObject;
JToken token = JToken.FromObject(jObj);
JToken updateDatas = token["updateDatas"];
Datagramm Dgramm = new Datagramm();
Dgramm.PlayerId = token["PlayerId"].ToObject<int>();
if (!updateDatas.HasValues)
{
//Обработка acknowledgement
Dgramm.DatagrammId = token["DatagrammId"].ToObject<int>();
arrivingDataId.Add(Dgramm);
}
else
{
List<UpdateData> updates = GetSentUpdates(updateDatas);
AppManager.Instance.server.UpdatesList(updates);
}
}
public List<UpdateData> GetSentUpdates(JToken updatesToken)
{
List<UpdateData> data = new List<UpdateData>();
JArray updateDatas = updatesToken as JArray;
UpdateData update = new UpdateData();
foreach (JObject token in updateDatas.Children())
{
switch (token["UpdateType"].ToObject<string>())
{
case "UpdateInput":
update = token.ToObject<UpdateInput>();
data.Add(update);
break;
case "UpdateInputInteraction":
update = token.ToObject<UpdateInputInteraction>();
data.Add(update);
break;
case "UpdateInputShoot":
update = token.ToObject<UpdateInputShoot>();
data.Add(update);
break;
}
}
return data;
}
/// <summary>
/// начать слушать клиентов в самой игре активируют Ивент
/// </summary>
/// <param name="socket"></param>
private void StartListening(object socket)
{
// obj to Socket
Socket client = (Socket)socket;
while (client.Connected)
{
var buff = new byte[65535];
var answ = client.Receive(buff);
string response = Encoding.UTF8.GetString(buff, 0, answ);
GetDataSend(response);
}
Task.Delay(-1);
}
}
}

View file

@ -5,14 +5,15 @@ using Microsoft.Xna.Framework;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;
using ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO;
namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ClientToServer
{
public class UpdateInput :UpdateData
{
// public int IdEntity { get; set; }
public Vector2 InputMovementDirection{get;set;}
public Vector2 InputAttackDirection {get;set;}
public SerializableVector2 InputMovementDirection{get;set;}
public SerializableVector2 InputAttackDirection {get;set;}
public UpdateInput()
{
UpdateType = "UpdateInput";

View file

@ -0,0 +1,16 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates
{
public class Datagramm
{
public int DatagrammId { get; set; }
public bool isImportant { get; set; }
public List<UpdateData> updateDatas { get; set; }
public int PlayerId { get; set; }
}
}

View file

@ -7,10 +7,10 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
/// <summary>
/// Хранит новое сосотяние анимации
/// </summary>
public class UpdateGameOBjectWithoutIdCreated : UpdateData
public class UpdateGameObjectWithoutIdCreated : UpdateData
{
public UpdateGameOBjectWithoutIdCreated() { UpdateType = "UpdateGameOBjectWithoutIdCreated"; }
public UpdateGameObjectWithoutIdCreated() { UpdateType = "UpdateGameObjectWithoutIdCreated"; isImportant = true; }
public string GameObjectClassName { get; set; }
public Vector2 position { get; set; }
public SerializableVector2 position { get; set; }
}
}

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO;
namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
{
@ -12,9 +13,12 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
/// </summary>
public class UpdateGameObjectCreated : UpdateData
{
public UpdateGameObjectCreated() { UpdateType = "UpdateGameObjectCreated"; }
public string GameObjectType;
public string GameObjectId;
public Vector2 position;
public UpdateGameObjectCreated() { UpdateType = "UpdateGameObjectCreated"; isImportant = true; }
public string GameObjectType { get; set; }
public string GameObjectId { get; set; }
public SerializableVector2 position { get; set; }
}
}

View file

@ -11,7 +11,7 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
/// </summary>
public class UpdateGameObjectDeleted : UpdateData
{
public UpdateGameObjectDeleted() { UpdateType = "UpdateGameObjectDeleted"; }
public UpdateGameObjectDeleted() { UpdateType = "UpdateGameObjectDeleted"; isImportant = false; }
public string GameObjectType;
}
}

View file

@ -11,15 +11,16 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
/// </summary>
public class UpdateLoot : UpdateData
{
public string lootName;
public int quantity;
public UpdateLoot() { UpdateType = "UpdateLoot"; }
public string lootName { get; set; }
public int quantity { get; set; }
public UpdateLoot() { UpdateType = "UpdateLoot"; isImportant = true; }
public UpdateLoot(string lootName, int quantity, int id)
{
UpdateType = "UpdateLoot";
this.lootName = lootName;
this.quantity = quantity;
IdEntity = id;
isImportant = true;
}
}
}

View file

@ -11,8 +11,8 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
/// </summary>
public class UpdatePlayerParametrs : UpdateData
{
public UpdatePlayerParametrs() { UpdateType = "UpdatePlayerParametrs"; }
public float radiatoin;
public float health;
public UpdatePlayerParametrs() { UpdateType = "UpdatePlayerParametrs"; isImportant = true; }
public float radiatoin { get; set; }
public float health { get; set; }
}
}

View file

@ -4,6 +4,7 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ZoFo.GameCore.GameManagers.NetworkManager.SerializableDTO;
using ZoFo.GameCore.GameObjects.Entities.LivingEntities;
namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
@ -15,6 +16,6 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
{
public UpdatePosition() { UpdateType = "UpdatePosition"; }
public Vector2 NewPosition { get; set; }
public SerializableVector2 NewPosition { get; set; }
}
}

View file

@ -11,9 +11,9 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
{
internal class UpdateStopObjectCreated : UpdateData
{
public UpdateStopObjectCreated() { UpdateType = "UpdateStopObjectCreated"; }
public UpdateStopObjectCreated() { UpdateType = "UpdateStopObjectCreated"; isImportant = true; }
public Texture2D TextureTile { get; set; }
public Vector2 Position { get; set; }
public SerializableVector2 Position { get; set; }
public SerializablePoint Size { get; set; }
public SerializableRectangle sourceRectangle { get; set; }
public string tileSetName { get; set; }

View file

@ -17,9 +17,9 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient
/// </summary>
public class UpdateTileCreated : UpdateData
{
public UpdateTileCreated() { UpdateType = "UpdateTileCreated"; }
public Texture2D TextureTile { get; set; }
public Vector2 Position { get; set; }
public UpdateTileCreated() { UpdateType = "UpdateTileCreated"; isImportant = true; }
[JsonInclude]
public SerializableVector2 Position { get; set; }
public SerializablePoint Size { get; set; }
public SerializableRectangle sourceRectangle { get; set; }
public string tileSetName { get; set; }

View file

@ -15,19 +15,24 @@ namespace ZoFo.GameCore.GameManagers.NetworkManager.Updates
[JsonDerivedType(typeof(UpdateGameEnded))]
[JsonDerivedType(typeof(UpdateGameObjectCreated))]
[JsonDerivedType(typeof(UpdateGameObjectDeleted))]
[JsonDerivedType(typeof(UpdateInteraction))]
[JsonDerivedType(typeof(UpdateInteractionReady))]
[JsonDerivedType(typeof(UpdateLoot))]
[JsonDerivedType(typeof(UpdateGameObjectWithoutIdCreated))]
[JsonDerivedType(typeof(UpdatePlayerParametrs))]
[JsonDerivedType(typeof(UpdatePosition))]
[JsonDerivedType(typeof(UpdateStopObjectCreated))]
[JsonDerivedType(typeof(UpdateTileCreated))]
[JsonDerivedType(typeof(UpdateInput))]
[JsonDerivedType(typeof(UpdatePlayerExit))]
[JsonDerivedType(typeof(UpdateInteractionReady))]
[JsonDerivedType(typeof(UpdateInteraction))]
[JsonDerivedType(typeof(UpdateInputInteraction))]
[JsonDerivedType(typeof(UpdateInputShoot))]
public class UpdateData
{
public int IdEntity { get; set; } //Id объекта
public string UpdateType { get; protected set; } //тип обновления
public string UpdateType { get; set; } //тип обновления
public bool isImportant { get; set; }
public UpdateData()
{

View file

@ -28,18 +28,21 @@ namespace ZoFo.GameCore.GameManagers
public void SetMainVolume(float volume)
{
settingsContainer.MainVolume = volume;
//AppManager.Instance.SoundManager.Update();
// AppManager.Instance.SoundManager.Update();
SaveSettings();
}
public void SetMusicVolume(float volume)
{
settingsContainer.MusicVolume = volume;
//AppManager.Instance.SoundManager.Update();
SaveSettings();
}
public void SetSoundEffectsVolume(float volume)
{
settingsContainer.SoundEffectsVolume = volume;
// AppManager.Instance.SoundManager.Update();
SaveSettings();
}
@ -68,6 +71,7 @@ namespace ZoFo.GameCore.GameManagers
}
public void SaveSettings()
{
AppManager.Instance.SoundManager.Update();
using (StreamWriter streamWriter = new StreamWriter("GameSettings.txt"))
{
string _str = JsonConvert.SerializeObject(settingsContainer);

View file

@ -12,6 +12,7 @@ namespace ZoFo.GameCore.GameObjects
{
//public override GraphicsComponent graphicsComponent { get; } = new GraphicsComponent(new List<string> { "тут пишите название анимации" }, "сдублируйте " +
public override GraphicsComponent graphicsComponent { get; } = new AnimatedGraphicsComponent(new List<string> { "zombie_idle" }, "zombie_idle");
@ -19,6 +20,7 @@ namespace ZoFo.GameCore.GameObjects
public EntittyForAnimationTests(Vector2 position) : base(position)
{
graphicsComponent.ObjectDrawRectangle = new Rectangle(0,0,16*20, 16 * 20);
position = new Vector2(10, 10);
}

View file

@ -40,12 +40,15 @@ namespace ZoFo.GameCore.GameObjects
public void StartAnimation(string animationId)
{
(graphicsComponent as Graphics.AnimatedGraphicsComponent).StartAnimation(animationId);
AppManager.Instance.server.AddData(new GameManagers.NetworkManager.Updates.ServerToClient.UpdateAnimation()
if (AppManager.Instance.gamestate == GameState.HostPlaying)
{
animationId = animationId,
IdEntity = Id
});
(graphicsComponent as Graphics.AnimatedGraphicsComponent).StartAnimation(animationId);
AppManager.Instance.server.AddData(new GameManagers.NetworkManager.Updates.ServerToClient.UpdateAnimation()
{
animationId = animationId,
IdEntity = Id
});
}
}
public override void Draw(SpriteBatch spriteBatch)
{

View file

@ -13,10 +13,10 @@ using ZoFo.GameCore.GUI;
namespace ZoFo.GameCore.GameObjects
{
class Ammo : Collectable
{
class Ammo : Collectable
{
public override StaticGraphicsComponent graphicsComponent { get; } = new(_path + "Ammo");
public Ammo(Vector2 position) : base(position) { }
}
}

View file

@ -10,7 +10,7 @@ using ZoFo.GameCore.GUI;
namespace ZoFo.GameCore.GameObjects;
public class Collectable : Interactable
{
protected static readonly string _path = "Textures/icons/Collectables/";
protected static readonly string _path = "Content/Textures/icons/Collectables/";
public Collectable(Vector2 position) : base(position) {
graphicsComponent.ObjectDrawRectangle.Width = 20;

View file

@ -43,17 +43,38 @@ namespace ZoFo.GameCore.GameObjects
}
public override void Update()
{
if (isDying) return;
Vector2 duration = Vector2.Normalize(
AppManager.Instance.server.players[0].position - position
{
if (isDying) return;
float m = 10000000;
int j = -1;
for (int i = 0; i < AppManager.Instance.server.players.Count; i++)
{
var player = AppManager.Instance.server.players[i];
if (m > (player.position.X - position.X) * (player.position.X - position.X) + (player.position.Y - position.Y) * (player.position.Y - position.Y))
{
m = (player.position.X - position.X) * (player.position.X - position.X) + (player.position.Y - position.Y) * (player.position.Y - position.Y);
j = i;
}
}
Vector2 duration = Vector2.Zero;
if (m<= 130000)
{
duration = Vector2.Normalize(
AppManager.Instance.server.players[j].position - position
);
if (Random.Shared.NextDouble() > 0.999)
{
AppManager.Instance.SoundManager.StartSound("zombie sound", position, AppManager.Instance.server.players[0].position, pitch: new Random().Next(-1, 2) * (float)new Random().NextDouble());
}
}
if (!isAttacking) { velocity += new Vector2(duration.X * speed, duration.Y * speed); }
}
public void OnPlayerClose(GameObject sender)
{
@ -61,6 +82,8 @@ namespace ZoFo.GameCore.GameObjects
if(!isAttacking)
{
AppManager.Instance.SoundManager.StartSound("Zombi napal", position, AppManager.Instance.server.players[0].position,pitch:new Random().Next(-1,2)*(float)new Random().NextDouble());
StartAnimation("zombie_attack");
isAttacking = true;
}
@ -69,14 +92,15 @@ namespace ZoFo.GameCore.GameObjects
}
public void EndAttack(string a)
{
{
if (AppManager.Instance.server is null) return;
var damagedPlayers=AppManager.Instance.server.collisionManager.GetPlayersInZone(collisionComponent.triggerRectangle.SetOrigin(position));
//TODO ДАМАЖИТЬ ИГРОКОВ В ЗОНЕ
if (damagedPlayers.Length>0) { DebugHUD.DebugLog("End of" + a);
foreach (var item in damagedPlayers)
item.TakeDamage(5);
item.TakeDamage(1);
}
isAttacking = false;
}
public override void Die()

View file

@ -38,15 +38,15 @@ public class LivingEntity : Entity
{
base.UpdateAnimations();
}
Vector2 prevPosition_forClient;
protected Vector2 prevPosition_forClient;
public override void Draw(SpriteBatch spriteBatch)
{
if ((position - prevPosition_forClient).X < 0)
if ((positionDraw - prevPosition_forClient).X < 0)
graphicsComponent.Flip = SpriteEffects.FlipHorizontally;
else if ((position - prevPosition_forClient).X > 0)
else if ((positionDraw - prevPosition_forClient).X > 0)
graphicsComponent.Flip = SpriteEffects.None;
base.Draw(spriteBatch);
prevPosition_forClient = position;
prevPosition_forClient = positionDraw;
}
public virtual void Die()

View file

@ -8,6 +8,6 @@ namespace ZoFo.GameCore.GameObjects.Entities.LivingEntities.Player
{
internal interface IPlayerWeaponAttack
{
}
}

View file

@ -5,6 +5,7 @@ using System.Text;
using System.Threading.Tasks;
using ZoFo.GameCore.GameManagers;
using ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient;
using ZoFo.GameCore.GUI;
namespace ZoFo.GameCore.GameObjects
{
@ -14,6 +15,13 @@ namespace ZoFo.GameCore.GameObjects
public void AddLoot(string lootName, int quantity, int id)
{
if (lootName == null)
{
DebugHUD.DebugLog("PROBLEM, loot is null");
DebugHUD.DebugLog("PROBLEM, loot is null");
DebugHUD.DebugLog("PROBLEM, loot is null");
return;
}
AppManager.Instance.server.AddData(new UpdateLoot(lootName, quantity, id));
if (loots.ContainsKey(lootName))

View file

@ -11,6 +11,7 @@ using ZoFo.GameCore.GameManagers.NetworkManager.Updates.ServerToClient;
using ZoFo.GameCore.Graphics;
using System.Diagnostics;
using ZoFo.GameCore.GUI;
using System.Runtime.InteropServices;
namespace ZoFo.GameCore.GameObjects;
@ -18,18 +19,21 @@ public class Player : LivingEntity
{
public Vector2 InputWeaponRotation { get; set; }
public Vector2 InputPlayerRotation { get; set; }
private float speed;
public int reloading;
public float health= 100;
private float speed;
public int reloading;
public float health = 100;
public float MaxHealth = 100;
public override GraphicsComponent graphicsComponent { get; } = new AnimatedGraphicsComponent(AppManager.Instance.AssetManager.Player.Animations, AppManager.Instance.AssetManager.Player.IdleAnimation);
public AnimatedGraphicsComponent animatedGraphicsComponent => graphicsComponent as AnimatedGraphicsComponent;
public float rad = 0;
public float MaxRad = 100;
public LootData lootData;
public override GraphicsComponent graphicsComponent { get; } = new AnimatedGraphicsComponent(AppManager.Instance.AssetManager.Player);
Vector2 prevPosition;
public bool IsTryingToInteract { get; set; }
@ -37,66 +41,187 @@ public class Player : LivingEntity
/// Факт того, что плеер в этом апдейте пытается стрелять
/// </summary>
public bool IsTryingToShoot { get; set; }
ScopeState prevScopeState;
public Player(Vector2 position) : base(position)
{
lootData = new LootData();
lootData.loots = new Dictionary<string, int>();
graphicsComponent.ObjectDrawRectangle = new Rectangle(0, 0, 30, 30);
collisionComponent.stopRectangle = new Rectangle(0, 20, 30, 10);
speed = 5;
collisionComponent.stopRectangle = new Rectangle(10, 15, 10, 15);
speed = 5;
StartAnimation("player_look_down");
StartAnimation("player_look_down");
}
public override void Update()
public override void Update()
{
if (reloading>0)
#region название current текстуры
var idName = animatedGraphicsComponent.CurrentAnimation.Id;
#endregion
#region анимация управления подбора лута
DebugHUD.DebugSet("texture name", idName);
if (reloading > 0)
{
reloading--;
}
#region анимация управления, стрельбы
switch(AppManager.Instance.InputManager.ConvertVector2ToState(InputPlayerRotation))
switch (AppManager.Instance.InputManager.ConvertVector2ToState(InputPlayerRotation))
{
case ScopeState.Top:
if (idName != "player_run_up")
StartAnimation("player_run_up");
break;
case ScopeState.Down:
break;
if (idName != "player_run_down")
StartAnimation("player_run_down");
break;
case ScopeState.Right:
//StartAnimation("player_running_top_rotate");
break;
case ScopeState.Left:
break;
if (idName != "player_run_right")
StartAnimation("player_run_right");
break;
case ScopeState.TopRight:
break;
case ScopeState.TopLeft:
break;
if (idName != "player_run_right_up")
StartAnimation("player_run_right_up");
break;
case ScopeState.DownRight:
break;
case ScopeState.DownLeft:
break;
if (idName != "player_run_right_down")
StartAnimation("player_run_right_down");
break;
case ScopeState.Idle:
if (idName != "player_look_down")
StartAnimation("player_look_down");
break;
}
if (AppManager.Instance.InputManager.ConvertVector2ToState(InputPlayerRotation) != ScopeState.Idle)
{
prevScopeState = AppManager.Instance.InputManager.ConvertVector2ToState(InputPlayerRotation);
}
else if (AppManager.Instance.InputManager.ConvertVector2ToState(InputPlayerRotation) == ScopeState.Idle && false)
{
switch (prevScopeState)
{
case ScopeState.Top:
if (idName != "player_look_up_weapon")
StartAnimation("player_look_up_weapon");
break;
case ScopeState.Down:
if (idName != "player_look_down_weapon")
StartAnimation("player_look_down_weapon");
break;
case ScopeState.Right:
case ScopeState.Left:
if (idName != "player_look_right_down_weapon")
StartAnimation("player_look_right_down_weapon");
break;
case ScopeState.TopRight:
case ScopeState.TopLeft:
if (idName != "player_look_right_up_weapon")
StartAnimation("player_look_right_up_weapon");
break;
case ScopeState.DownRight:
case ScopeState.DownLeft:
if (idName != "player_look_right_down_weapon")
StartAnimation("player_look_right_down_weapon");
break;
case ScopeState.Idle:
if (idName != "player_look_down")
StartAnimation("player_look_down");
break;
}
}
#endregion
#region анимация поворота оружия
int currentAttackSection = AppManager.Instance.InputManager.ConvertAttackVector2ToState(InputWeaponRotation);
switch (currentAttackSection)
{
case 0 or 1:
//right
break;
case 2 or 3:
//down_right_right
break;
case 4 or 5:
//down_right
break;
case 6 or 7:
//down_right_left
break;
case 8 or 9:
//down
break;
case 10 or 11:
//down_left_right
break;
case 12 or 13:
//down_left
break;
case 14 or 15:
//down_left_left
break;
case 16 or -14:
//left
break;
case -13 or -12:
//top_left_left
break;
case -11 or -10:
//top_left
break;
case -9 or -8:
//top_left_right
break;
case -7 or -6:
//top
break;
case -5 or -4:
//top_right_left
break;
case -3 or -2:
//top_right
break;
case -1 or 0:
//top_right_right
break;
}
#endregion
MovementLogic();
}
public void MovementLogic()
public void WeaponAttack()
{
velocity += InputPlayerRotation * speed;
}
public void MovementLogic()
{
velocity += InputPlayerRotation * speed;
DebugHUD.DebugSet("player pos server", position.ToString());
}
public void HandleNewInput(UpdateInput updateInput)
{
InputPlayerRotation = updateInput.InputMovementDirection;
InputWeaponRotation = updateInput.InputAttackDirection;
InputPlayerRotation = updateInput.InputMovementDirection.GetVector2();
InputWeaponRotation = updateInput.InputAttackDirection.GetVector2();
DebugHUD.DebugSet("dir", InputWeaponRotation.ToString());
}
public void HandleInteract(UpdateInputInteraction updateInputInteraction)
{
@ -119,7 +244,7 @@ public class Player : LivingEntity
base.Die();
}
#endregion
#endregion
public void HandleShoot(UpdateInputShoot updateInputShoot)
{
if (reloading > 0)
@ -127,24 +252,42 @@ public class Player : LivingEntity
reloading = 5;
IsTryingToShoot = true;
var rect = collisionComponent.stopRectangle.SetOrigin(position);
rect.Width += 100;
rect.Height += 100;
Entity[] entities = AppManager.Instance.server.collisionManager.GetEntities(rect, this);
AppManager.Instance.server.RegisterGameObject(new Particle(rect.Location.ToVector2()));
if (entities.Length>0)
Entity[] entities = AppManager.Instance.server.collisionManager.GetEntities(GetDamageArea(InputWeaponRotation), this);
if (entities != null)
{
DebugHUD.DebugSet("ent[0]", entities[0].ToString());
if (entities != null)
foreach (Entity entity in entities)
{
foreach (Entity entity in entities)
if (entity is Enemy)
{
if (entity is Enemy)
for (int i = 0; i < 3; i++)
{
(entity as Enemy).TakeDamage(1);
Instantiate(new Particle(
(collisionComponent.stopRectangle.Location.ToVector2() * i / 3f) +
(collisionComponent.stopRectangle.Location.ToVector2() * (3 - i) / 3f)
));
}
(entity as Enemy).TakeDamage(1);
}
}
}
}
public override void Draw(SpriteBatch spriteBatch)
{
DrawDebugRectangle(spriteBatch, GetDamageArea(AppManager.Instance.InputManager.InputAttackDirection), Color.Green);
base.Draw(spriteBatch);
}
public Rectangle GetDamageArea(Vector2 direction)
{
direction.Normalize();
var rect = collisionComponent.stopRectangle.SetOrigin(position);
int size = 10;
rect.X -= size;
rect.Y -= size;
rect.Width += 2 * size;
rect.Height += 2 * size;
rect = rect.SetOrigin(direction * 40);
return rect;
}
}

View file

@ -1,13 +1,25 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading.Tasks;
using ZoFo.GameCore.GameManagers;
using ZoFo.GameCore.GameManagers.CollisionManager;
using ZoFo.GameCore.GameObjects.MapObjects.StopObjects;
namespace ZoFo.GameCore.GameObjects.Entities.LivingEntities.Player.PlayerAttacks
{
internal class SwordAttack : IPlayerWeaponAttack
{
Rectangle rectangle;
public SwordAttack(){
}
public Rectangle Attack(Vector2 position){
rectangle = new Rectangle((int)position.X, (int)position.Y, 30, 10);
return rectangle;
}
}
}

View file

@ -58,6 +58,7 @@ public abstract class GameObject
public void PlayAnimation_OnClient()
{
graphicsComponent.Update();
}
/// <summary>
@ -69,14 +70,19 @@ public abstract class GameObject
graphicsComponent.LoadContent();
}
/// <summary>
/// for smooth client draw
/// </summary>
public Vector2 positionDraw;
/// <summary>
/// Для клиента
/// Обновление, которое вызывается у клиента, для просмотра анимаций
/// </summary>
public virtual void UpdateAnimations()
{
graphicsComponent.ObjectDrawRectangle.X = (int)position.X; //Move To place where Updates Sets your position
graphicsComponent.ObjectDrawRectangle.Y = (int)position.Y;
positionDraw = (position * 0.15f + positionDraw*0.85f);
graphicsComponent.ObjectDrawRectangle.X = (int)positionDraw.X; //Move To place where Updates Sets your position
graphicsComponent.ObjectDrawRectangle.Y = (int)positionDraw.Y;
PlayAnimation_OnClient();
}

View file

@ -136,7 +136,16 @@ namespace ZoFo.GameCore.Graphics
buildSourceRectangle();
SetInterval();
}
public void StartCyclingAnimation(string startedanimationId)
{
currentFrame = 0;
currentAnimation = animations.Find(x => x.Id == startedanimationId);
currentAnimation.IsCycle = true;
buildSourceRectangle();
SetInterval();
}
public void StopAnimation()

View file

@ -1,5 +1,6 @@
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
@ -37,7 +38,7 @@ namespace ZoFo.GameCore.Graphics
return;
}
texture = AppManager.Instance.Content.Load<Texture2D>(_textureName);
texture = AppManager.Instance.Content.Load<Texture2D>(Path.Combine(AppContext.BaseDirectory, _textureName));
}
public override void Update()

View file

@ -29,14 +29,13 @@ namespace ZoFo.GameCore
public class Server
{
private ServerNetworkManager networkManager;
private int ticks = 0;
public IPEndPoint MyIp { get { return networkManager.InfoConnect; } }
private int ticks = 0;
public IPEndPoint MyIp { get { return networkManager.endPoint; } }
public Server()
{
networkManager = new ServerNetworkManager();
networkManager.GetDataSend += OnDataSend;
collisionManager = new CollisionManager();
players = new List<Player>();
}
#region server logic as App
@ -51,6 +50,13 @@ namespace ZoFo.GameCore
ProcessIUpdateData(updateDatas[i]);
}
}
internal void UpdatesList(List<UpdateData> updates)
{
foreach (var item in updates)
{
ProcessIUpdateData(item);
}
}
/// <summary>
/// Обработка апдейтсов, которые нам прислал клиент
/// </summary>
@ -61,24 +67,6 @@ namespace ZoFo.GameCore
//ТУТ Switch case будет честное слово
switch (updateData.UpdateType)
{
case "UpdateAnimation":
break;
case "UpdateEntityHealth":
break;
case "UpdateGameEnded":
break;
case "UpdateGameObjectCreated":
break;
case "UpdateGameObjectDeleted":
break;
case "UpdateInteraction":
break;
case "UpdateInteractionReady":
break;
case "UpdateLoot":
break;
case "UpdatePlayerParametrs":
break;
case "UpdateInput":
if (players.Count > 0)
players[0].HandleNewInput(updateData as UpdateInput);//TODO id instead of 0
@ -96,10 +84,6 @@ namespace ZoFo.GameCore
}
}
public void CloseConnection()
{
networkManager.CloseConnection();
}
/// <summary>
/// Для красоты) Отдел Серверов
@ -115,9 +99,10 @@ namespace ZoFo.GameCore
/// Создает комнату и запускает ожидание подключений
/// </summary>
/// <param name="players"></param>
public void CreateRoom(int players)
public void CreateRoom(bool isMultiplayer)
{
networkManager.Start(players);
networkManager.SetIsMultiplayer(isMultiplayer);
networkManager.Start();
}
#endregion
@ -135,17 +120,15 @@ namespace ZoFo.GameCore
collisionManager = new CollisionManager();
gameObjects = new List<GameObject>();
entities = new List<Entity>();
players = new List<Player>();
networkManager.StartGame();
new MapManager().LoadMap();
//AppManager.Instance.server.RegisterGameObject(new EntittyForAnimationTests(new Vector2(0, 0)));
AppManager.Instance.server.RegisterGameObject(new Player(new Vector2(740, 140)));
for (int i = 0; i < 20; i++)
for (int j = 0; j < 20; j++)
AppManager.Instance.server.RegisterGameObject(new Zombie(new Vector2(1300 + i*70, 1000+j*70)));
AppManager.Instance.server.RegisterGameObject(new Ammo(new Vector2(140, 440)));
AppManager.Instance.server.RegisterGameObject(new Ammo(new Vector2(240, 440)));
AppManager.Instance.server.RegisterGameObject(new Player(new Vector2(760, 140)));
//for (int i = 0; i < 20; i++)
// for (int j = 0; j < 20; j++)
// AppManager.Instance.server.RegisterGameObject(new Zombie(new Vector2(1300 + i*70, 1000+j*70)));
}
/// <summary>
@ -155,10 +138,9 @@ namespace ZoFo.GameCore
{
UpdateGameEnded gameEnded = new UpdateGameEnded();
networkManager.AddData(gameEnded);
networkManager.CloseConnection();
}
public List<GameObject> gameObjects;
public List<GameObject> gameObjects = new List<GameObject>();
public List<Entity> entities; //entity
public List<Player> players;
public void Update(GameTime gameTime)
@ -191,7 +173,7 @@ namespace ZoFo.GameCore
{
AddData(new UpdateStopObjectCreated()
{
Position = (gameObject as StopObject).position,
Position = (gameObject as StopObject).position.Serialize(),
sourceRectangle = new SerializableRectangle((gameObject as StopObject).sourceRectangle),
Size = new SerializablePoint((gameObject as StopObject).graphicsComponent.ObjectDrawRectangle.Size),
tileSetName = ((gameObject as StopObject).graphicsComponent as StaticGraphicsComponent)._textureName,
@ -208,7 +190,7 @@ namespace ZoFo.GameCore
{
AddData(new UpdateTileCreated()
{
Position = (gameObject as MapObject).position,
Position = new SerializableVector2((gameObject as MapObject).position),
sourceRectangle = new SerializableRectangle((gameObject as MapObject).sourceRectangle),
Size = new SerializablePoint((gameObject as MapObject).graphicsComponent.ObjectDrawRectangle.Size),
tileSetName = ((gameObject as MapObject).graphicsComponent as StaticGraphicsComponent)._textureName
@ -219,30 +201,30 @@ namespace ZoFo.GameCore
if (gameObject is Particle)
{
AddData(new UpdateGameOBjectWithoutIdCreated()
AddData(new UpdateGameObjectWithoutIdCreated()
{
GameObjectClassName = gameObject.GetType().Name,
position = gameObject.position
position = gameObject.position.Serialize()
});
return;
}
if (gameObject is Entity entity)
{
{
AddData(new UpdateGameObjectCreated()
{
GameObjectType = gameObject.GetType().Name,
IdEntity = entity.Id,
position = gameObject.position
});
position = gameObject.position.Serialize()
});
collisionManager.Register(entity.collisionComponent);
entities.Add(entity);
}
else
else
AddData(new UpdateGameObjectCreated()
{
GameObjectType = gameObject.GetType().Name,
position = gameObject.position
position = gameObject.position.Serialize()
});

View file

@ -1 +1 @@
{"IsFullScreen":false,"MainVolume":1.0,"MusicVolume":1.0,"SoundEffectsVolume":1.0,"Resolution":{"X":1440,"Y":900}}
{"IsFullScreen":false,"MainVolume":1.0,"MusicVolume":0.0,"SoundEffectsVolume":1.0,"Resolution":{"X":1440,"Y":900}}

View file

@ -35,8 +35,8 @@
<ProjectReference Include="..\MonogameLibrary\MonogameLibrary.csproj" />
</ItemGroup>
<ItemGroup>
<Folder Include="Content\sounds\Zombie\" />
<Folder Include="Content\Textures\Animations\PlayerAFK\" />
<Folder Include="Content\sounds\Zombie\" />
<Folder Include="Content\Textures\Animations\PlayerAFK\" />
<Folder Include="Content\Textures\GUI\" />
</ItemGroup>
<Target Name="RestoreDotnetTools" BeforeTargets="Restore">