Browse Source

style: 🎨 format cs code

tags/0.1.0
Timothy Liu 2 years ago
parent
commit
4b44cf151d
24 changed files with 807 additions and 744 deletions
  1. +5
    -5
      dependency/shell/format.sh
  2. +1
    -1
      installer/Installer/AssemblyInfo.cs
  3. +20
    -11
      installer/Installer/Model.cs
  4. +42
    -30
      installer/Installer/ViewModel.cs
  5. +1
    -1
      launcher/Launcher/AssemblyInfo.cs
  6. +99
    -95
      logic/GameClass/GameObj/Character/Character.BuffManager.cs
  7. +2
    -1
      logic/GameClass/GameObj/Character/Character.SkillManager.cs
  8. +29
    -17
      logic/GameClass/GameObj/Character/Character.cs
  9. +18
    -10
      logic/GameClass/GameObj/GameObj.cs
  10. +2
    -1
      logic/GameClass/GameObj/ObjOfCharacter.cs
  11. +9
    -9
      logic/GameClass/GameObj/Prop.cs
  12. +2
    -1
      logic/GameClass/GameObj/Team.cs
  13. +52
    -46
      logic/GameClass/Skill/CommonSkill.cs
  14. +63
    -63
      logic/GameClass/Skill/PassiveSkill.cs
  15. +82
    -81
      logic/GameEngine/MoveEngine.cs
  16. +107
    -105
      logic/Gaming/AttackManager.cs
  17. +159
    -158
      logic/Gaming/Game.cs
  18. +2
    -1
      logic/Gaming/MoveManager.cs
  19. +48
    -47
      logic/Gaming/PropManager.cs
  20. +6
    -6
      logic/Preparation/GameData/GameData.cs
  21. +1
    -1
      logic/Preparation/Utility/XY.cs
  22. +29
    -27
      logic/Server/Game.cs
  23. +26
    -26
      logic/Server/GameServer.cs
  24. +2
    -1
      logic/Server/Program.cs

+ 5
- 5
dependency/shell/format.sh View File

@@ -23,9 +23,9 @@ find . -iname "*.c" \
| xargs clang-format -i | xargs clang-format -i
done done


cd logic && dotnet format && cd ..
cd installer && dotnet format && cd ..
cd launcher && dotnet format && cd ..
cd playback && dotnet format && cd ..
pushd logic && dotnet format && popd
pushd installer && dotnet format && popd
pushd launcher && dotnet format && popd
pushd playback && dotnet format && popd


echo "Done!"
echo "Done!"

+ 1
- 1
installer/Installer/AssemblyInfo.cs View File

@@ -1,6 +1,6 @@
using System.Windows; using System.Windows;


[assembly:ThemeInfo(
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// or application resource dictionaries) // or application resource dictionaries)


+ 20
- 11
installer/Installer/Model.cs View File

@@ -71,23 +71,29 @@ namespace starter.viewmodel.settings
/// </summary> /// </summary>
public string Route public string Route
{ {
get {
get
{
return Downloader.Program.Data.FilePath; return Downloader.Program.Data.FilePath;
} }
set {
set
{
Downloader.Program.Data.FilePath = value; Downloader.Program.Data.FilePath = value;
} }
} }
/// <summary> /// <summary>
/// if the route was set or is under editing /// if the route was set or is under editing
/// </summary> /// </summary>
public bool EditingRoute {
get; set; }
public bool EditingRoute
{
get; set;
}
///< summary> ///< summary>
/// if already installed /// if already installed
/// </summary> /// </summary>
public bool installed {
get; set; }
public bool installed
{
get; set;
}
} }
} }
namespace Downloader namespace Downloader
@@ -224,7 +230,8 @@ namespace Downloader
GetObjectRequest request = new GetObjectRequest(bucket, key, localDir, localFileName); GetObjectRequest request = new GetObjectRequest(bucket, key, localDir, localFileName);


Dictionary<string, string> test = request.GetRequestHeaders(); Dictionary<string, string> test = request.GetRequestHeaders();
request.SetCosProgressCallback(delegate(long completed, long total) {
request.SetCosProgressCallback(delegate (long completed, long total)
{
Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total)); Console.WriteLine(String.Format("progress = {0:##.##}%", completed * 100.0 / total));
}); });
// 执行请求 // 执行请求
@@ -834,7 +841,8 @@ namespace WebConnect
async public Task LoginToEEsast(HttpClient client, string useremail, string password) async public Task LoginToEEsast(HttpClient client, string useremail, string password)
{ {
string token = ""; string token = "";
using (var response = await client.PostAsync("https://api.eesast.com/users/login", JsonContent.Create(new {
using (var response = await client.PostAsync("https://api.eesast.com/users/login", JsonContent.Create(new
{
email = useremail, email = useremail,
password = password, password = password,
}))) })))
@@ -843,9 +851,10 @@ namespace WebConnect
{ {
case System.Net.HttpStatusCode.OK: case System.Net.HttpStatusCode.OK:
Console.WriteLine("Success login"); Console.WriteLine("Success login");
token = (System.Text.Json.JsonSerializer.Deserialize(await response.Content.ReadAsStreamAsync(), typeof(LoginResponse), new JsonSerializerOptions() {
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
}) as LoginResponse)
token = (System.Text.Json.JsonSerializer.Deserialize(await response.Content.ReadAsStreamAsync(), typeof(LoginResponse), new JsonSerializerOptions()
{
PropertyNamingPolicy = JsonNamingPolicy.CamelCase,
}) as LoginResponse)
?.Token ?? ?.Token ??
throw new Exception("no token!"); throw new Exception("no token!");
logintoken = token; logintoken = token;


+ 42
- 30
installer/Installer/ViewModel.cs View File

@@ -30,20 +30,24 @@ namespace starter.viewmodel.settings


public string Route public string Route
{ {
get {
get
{
return obj.Route; return obj.Route;
} }
set {
set
{
obj.Route = value; obj.Route = value;
this.RaisePropertyChanged("Route"); this.RaisePropertyChanged("Route");
} }
} }
public bool Installed public bool Installed
{ {
get {
get
{
return obj.installed; return obj.installed;
} }
set {
set
{
obj.installed = value; obj.installed = value;
this.RaisePropertyChanged("Installed"); this.RaisePropertyChanged("Installed");
this.RaisePropertyChanged("InstIntroVis"); this.RaisePropertyChanged("InstIntroVis");
@@ -53,10 +57,12 @@ namespace starter.viewmodel.settings
} }
public bool EditingRoute public bool EditingRoute
{ {
get {
get
{
return obj.EditingRoute; return obj.EditingRoute;
} }
set {
set
{
obj.EditingRoute = value; obj.EditingRoute = value;
this.RaisePropertyChanged("EditingRoute"); this.RaisePropertyChanged("EditingRoute");
this.RaisePropertyChanged("MoveIntroVis"); this.RaisePropertyChanged("MoveIntroVis");
@@ -65,7 +71,8 @@ namespace starter.viewmodel.settings
} }
public Visibility RouteBoxVis // if the route editing textbox is visible public Visibility RouteBoxVis // if the route editing textbox is visible
{ {
get {
get
{
return obj.EditingRoute ? Visibility.Visible : Visibility.Collapsed; return obj.EditingRoute ? Visibility.Visible : Visibility.Collapsed;
} }
} }
@@ -74,19 +81,22 @@ namespace starter.viewmodel.settings
/// </summary> /// </summary>
public Visibility InstIntroVis public Visibility InstIntroVis
{ {
get {
get
{
return obj.installed ? Visibility.Collapsed : Visibility.Visible; return obj.installed ? Visibility.Collapsed : Visibility.Visible;
} }
} }
public Visibility EditIntroVis public Visibility EditIntroVis
{ {
get {
get
{
return obj.installed ? Visibility.Visible : Visibility.Collapsed; return obj.installed ? Visibility.Visible : Visibility.Collapsed;
} }
} }
public Visibility MoveIntroVis public Visibility MoveIntroVis
{ {
get {
get
{
if (obj.installed == true && obj.EditingRoute == true) if (obj.installed == true && obj.EditingRoute == true)
return Visibility.Visible; return Visibility.Visible;
else else
@@ -97,7 +107,8 @@ namespace starter.viewmodel.settings
private BaseCommand clickBrowseCommand; private BaseCommand clickBrowseCommand;
public BaseCommand ClickBrowseCommand public BaseCommand ClickBrowseCommand
{ {
get {
get
{
if (clickBrowseCommand == null) if (clickBrowseCommand == null)
{ {
clickBrowseCommand = new BaseCommand(new Action<object>(o => clickBrowseCommand = new BaseCommand(new Action<object>(o =>
@@ -105,31 +116,32 @@ namespace starter.viewmodel.settings
using (FolderBrowserDialog dialog = new FolderBrowserDialog()) using (FolderBrowserDialog dialog = new FolderBrowserDialog())
{ {
_ = dialog.ShowDialog(); _ = dialog.ShowDialog();
if (dialog.SelectedPath != String.Empty)
Route = dialog.SelectedPath;
if (dialog.SelectedPath != String.Empty)
Route = dialog.SelectedPath;
}
}));
} }
}));
}
return clickBrowseCommand;
}
}
private BaseCommand clickConfirmCommand;
public BaseCommand ClickConfirmCommand
{
get {
if (clickConfirmCommand == null)
return clickBrowseCommand;
}
}
private BaseCommand clickConfirmCommand;
public BaseCommand ClickConfirmCommand
{ {
get
{
if (clickConfirmCommand == null)
{
clickConfirmCommand = new BaseCommand(new Action<object>(o => clickConfirmCommand = new BaseCommand(new Action<object>(o =>
{ {
if (obj.install()) if (obj.install())
{ {
EditingRoute = false; EditingRoute = false;
Installed = true;
}
}));
Installed = true;
}
}));
} }
return clickConfirmCommand;
}
}
}
return clickConfirmCommand;
}
}
}
} }

+ 1
- 1
launcher/Launcher/AssemblyInfo.cs View File

@@ -1,6 +1,6 @@
using System.Windows; using System.Windows;


[assembly:ThemeInfo(
[assembly: ThemeInfo(
ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located ResourceDictionaryLocation.None, // where theme specific resource dictionaries are located
//(used if a resource is not found in the page, //(used if a resource is not found in the page,
// or application resource dictionaries) // or application resource dictionaries)


+ 99
- 95
logic/GameClass/GameObj/Character/Character.BuffManager.cs View File

@@ -48,125 +48,129 @@ namespace GameClass.GameObj
() => () =>
{ {
LinkedListNode<BuffValue> buffNode; LinkedListNode<BuffValue> buffNode;
lock (buffListLock[(int)buffType])
{
buffNode = buffList[(int)buffType].AddLast(bf);
}
ReCalculateFunc();
Thread.Sleep(buffTime);
try
{
lock (buffListLock[(int)buffType])
{
buffList[(int)buffType].Remove(buffNode);
}
}
catch
{
}
ReCalculateFunc();
}
)
{ IsBackground = true }.Start();
}

private int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int minVal)
{
double times = 1.0;
lock (buffListLock[(int)buffType]) lock (buffListLock[(int)buffType])
{ {
buffNode = buffList[(int)buffType].AddLast(bf);
}
ReCalculateFunc();
Thread.Sleep(buffTime);
try
{
lock (buffListLock[(int)buffType])
foreach (var add in buffList[(int)buffType])
{ {
buffList[(int)buffType].Remove(buffNode);
times *= add.lfValue;
} }
} }
catch
{
}
ReCalculateFunc();
return Math.Max(Math.Min((int)Math.Round(orgVal * times), maxVal), minVal);
} }
)
{ IsBackground = true }.Start();
}


private int ReCalculateFloatBuff(BuffType buffType, int orgVal, int maxVal, int minVal)
{
double times = 1.0;
lock (buffListLock[(int)buffType])
{
foreach (var add in buffList[(int)buffType])
public void AddMoveSpeed(double add, int buffTime, Action<int> SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(new BuffValue(add), buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed)));
public bool HasFasterSpeed
{
get
{ {
times *= add.lfValue;
}
lock (buffListLock[(int)BuffType.AddSpeed])
{
return buffList[(int)BuffType.AddSpeed].Count != 0;
} }
return Math.Max(Math.Min((int)Math.Round(orgVal * times), maxVal), minVal);
}

public void AddMoveSpeed(double add, int buffTime, Action<int> SetNewMoveSpeed, int orgMoveSpeed) => AddBuff(new BuffValue(add), buffTime, BuffType.AddSpeed, () => SetNewMoveSpeed(ReCalculateFloatBuff(BuffType.AddSpeed, orgMoveSpeed, GameData.MaxSpeed, GameData.MinSpeed)));
public bool HasFasterSpeed
{
get {
lock (buffListLock[(int)BuffType.AddSpeed])
{
return buffList[(int)BuffType.AddSpeed].Count != 0;
} }
}
}
}


public void AddShield(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Shield, () =>
{});
public bool HasShield
{
get {
lock (buffListLock[(int)BuffType.Shield])
public void AddShield(int shieldTime) => AddBuff(new BuffValue(), shieldTime, BuffType.Shield, () =>
{ });
public bool HasShield
{
get
{ {
return buffList[(int)BuffType.Shield].Count != 0;
}
lock (buffListLock[(int)BuffType.Shield])
{
return buffList[(int)BuffType.Shield].Count != 0;
} }
}
}
}


public void AddLIFE(int totelTime) => AddBuff(new BuffValue(), totelTime, BuffType.AddLIFE, () =>
{});
public bool HasLIFE
{
get {
lock (buffListLock[(int)BuffType.AddLIFE])
public void AddLIFE(int totelTime) => AddBuff(new BuffValue(), totelTime, BuffType.AddLIFE, () =>
{ });
public bool HasLIFE
{
get
{ {
return buffList[(int)BuffType.AddLIFE].Count != 0;
}
}
}
public bool TryActivatingLIFE()
{
if (HasLIFE)
lock (buffListLock[(int)BuffType.AddLIFE])
{ {
lock (buffListLock[(int)BuffType.AddLIFE])
{
buffList[(int)BuffType.AddLIFE].Clear();
return buffList[(int)BuffType.AddLIFE].Count != 0;
}
} }
return true;
}
public bool TryActivatingLIFE()
{
if (HasLIFE)
{
lock (buffListLock[(int)BuffType.AddLIFE])
{
buffList[(int)BuffType.AddLIFE].Clear();
} }
return false;
}
return true;
}
return false;
}


public void AddSpear(int spearTime) => AddBuff(new BuffValue(), spearTime, BuffType.Spear, () =>
{});
public bool HasSpear
{
get {
lock (buffListLock[(int)BuffType.Spear])
public void AddSpear(int spearTime) => AddBuff(new BuffValue(), spearTime, BuffType.Spear, () =>
{ });
public bool HasSpear
{
get
{ {
return buffList[(int)BuffType.Spear].Count != 0;
}
}
}
/// <summary>
/// 清除所有buff
/// </summary>
public void ClearAll()
{
for (int i = 0; i < buffList.Length; ++i)
lock (buffListLock[(int)BuffType.Spear])
{ {
lock (buffListLock[i])
{
buffList[i].Clear();
}
return buffList[(int)BuffType.Spear].Count != 0;
} }
}

public BuffManeger()
{
var buffTypeArray = Enum.GetValues(typeof(BuffType));
buffList = new LinkedList<BuffValue>[buffTypeArray.Length];
buffListLock = new object[buffList.Length];
int i = 0;
foreach (BuffType type in buffTypeArray)
}
}
/// <summary>
/// 清除所有buff
/// </summary>
public void ClearAll()
{
for (int i = 0; i < buffList.Length; ++i)
{
lock (buffListLock[i])
{ {
buffList[i] = new LinkedList<BuffValue>();
buffListLock[i++] = new object();
buffList[i].Clear();
} }
}
}

public BuffManeger()
{
var buffTypeArray = Enum.GetValues(typeof(BuffType));
buffList = new LinkedList<BuffValue>[buffTypeArray.Length];
buffListLock = new object[buffList.Length];
int i = 0;
foreach (BuffType type in buffTypeArray)
{
buffList[i] = new LinkedList<BuffValue>();
buffListLock[i++] = new object();
}
}
} }
} }
} }
}

+ 2
- 1
logic/GameClass/GameObj/Character/Character.SkillManager.cs View File

@@ -23,7 +23,8 @@ namespace GameClass.GameObj
public int TimeUntilCommonSkillAvailable public int TimeUntilCommonSkillAvailable
{ {
get => timeUntilCommonSkillAvailable; get => timeUntilCommonSkillAvailable;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
timeUntilCommonSkillAvailable = value < 0 ? 0 : value; timeUntilCommonSkillAvailable = value < 0 ? 0 : value;
} }


+ 29
- 17
logic/GameClass/GameObj/Character/Character.cs View File

@@ -11,7 +11,7 @@ namespace GameClass.GameObj
{ {
private readonly object beAttackedLock = new(); private readonly object beAttackedLock = new();


#region 角色的基本属性及方法,包括与道具的交互方法
#region 角色的基本属性及方法,包括与道具的交互方法


/// <summary> /// <summary>
/// 装弹冷却 /// 装弹冷却
@@ -20,8 +20,9 @@ namespace GameClass.GameObj
public int CD public int CD
{ {
get => cd; get => cd;
private
set {
private
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
cd = value; cd = value;
@@ -40,7 +41,8 @@ namespace GameClass.GameObj
public int HP public int HP
{ {
get => hp; get => hp;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
hp = value <= MaxHp ? value : MaxHp; hp = value <= MaxHp ? value : MaxHp;
} }
@@ -60,7 +62,8 @@ namespace GameClass.GameObj
public double Vampire public double Vampire
{ {
get => vampire; get => vampire;
set {
set
{
if (value > 1) if (value > 1)
lock (gameObjLock) lock (gameObjLock)
vampire = 1; vampire = 1;
@@ -76,7 +79,8 @@ namespace GameClass.GameObj
public double OriVampire public double OriVampire
{ {
get => oriVampire; get => oriVampire;
set {
set
{
if (value > 1) if (value > 1)
lock (gameObjLock) lock (gameObjLock)
vampire = 1; vampire = 1;
@@ -94,7 +98,8 @@ namespace GameClass.GameObj
public BulletType BulletOfPlayer public BulletType BulletOfPlayer
{ {
get => bulletOfPlayer; get => bulletOfPlayer;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
bulletOfPlayer = value; bulletOfPlayer = value;
} }
@@ -104,7 +109,8 @@ namespace GameClass.GameObj
public Prop? PropInventory // 持有的道具 public Prop? PropInventory // 持有的道具
{ {
get => propInventory; get => propInventory;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
propInventory = value; propInventory = value;
@@ -134,7 +140,8 @@ namespace GameClass.GameObj
public bool IsModifyingProp public bool IsModifyingProp
{ {
get => isModifyingProp; get => isModifyingProp;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
isModifyingProp = value; isModifyingProp = value;
@@ -149,7 +156,8 @@ namespace GameClass.GameObj
public bool IsInvisible public bool IsInvisible
{ {
get => isInvisible; get => isInvisible;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
isInvisible = value; isInvisible = value;
@@ -346,7 +354,8 @@ namespace GameClass.GameObj
public long TeamID public long TeamID
{ {
get => teamID; get => teamID;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
teamID = value; teamID = value;
@@ -358,7 +367,8 @@ namespace GameClass.GameObj
public long PlayerID public long PlayerID
{ {
get => playerID; get => playerID;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
playerID = value; playerID = value;
@@ -372,16 +382,17 @@ namespace GameClass.GameObj
public string Message public string Message
{ {
get => message; get => message;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
message = value; message = value;
} }
} }
} }
#endregion
#endregion


#region 角色拥有的buff相关属性、方法
#region 角色拥有的buff相关属性、方法
public void AddMoveSpeed(int buffTime, double add = 2.0) => buffManeger.AddMoveSpeed(add, buffTime, newVal => public void AddMoveSpeed(int buffTime, double add = 2.0) => buffManeger.AddMoveSpeed(add, buffTime, newVal =>
{ MoveSpeed = newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed; }, { MoveSpeed = newVal < GameData.characterMaxSpeed ? newVal : GameData.characterMaxSpeed; },
OrgMoveSpeed); OrgMoveSpeed);
@@ -399,7 +410,8 @@ namespace GameClass.GameObj
private Array buffTypeArray = Enum.GetValues(typeof(BuffType)); private Array buffTypeArray = Enum.GetValues(typeof(BuffType));
public Dictionary<BuffType, bool> Buff public Dictionary<BuffType, bool> Buff
{ {
get {
get
{
Dictionary<BuffType, bool> buff = new Dictionary<BuffType, bool>(); Dictionary<BuffType, bool> buff = new Dictionary<BuffType, bool>();
foreach (BuffType type in buffTypeArray) foreach (BuffType type in buffTypeArray)
{ {
@@ -432,7 +444,7 @@ namespace GameClass.GameObj
hp = MaxHp; hp = MaxHp;
} }
} }
#endregion
#endregion
public override void Reset() // 要加锁吗? public override void Reset() // 要加锁吗?
{ {
_ = AddDeathCount(); _ = AddDeathCount();


+ 18
- 10
logic/GameClass/GameObj/GameObj.cs View File

@@ -29,8 +29,9 @@ namespace GameClass.GameObj
public XY Position public XY Position
{ {
get => position; get => position;
protected
set {
protected
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
position = value; position = value;
@@ -43,7 +44,8 @@ namespace GameClass.GameObj
public XY FacingDirection public XY FacingDirection
{ {
get => facingDirection; get => facingDirection;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
facingDirection = value; facingDirection = value;
} }
@@ -54,7 +56,8 @@ namespace GameClass.GameObj
public bool CanMove public bool CanMove
{ {
get => canMove; get => canMove;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
canMove = value; canMove = value;
@@ -66,7 +69,8 @@ namespace GameClass.GameObj
public bool IsMoving public bool IsMoving
{ {
get => isMoving; get => isMoving;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
isMoving = value; isMoving = value;
@@ -78,7 +82,8 @@ namespace GameClass.GameObj
public bool IsResetting public bool IsResetting
{ {
get => isResetting; get => isResetting;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
isResetting = value; isResetting = value;
@@ -92,7 +97,8 @@ namespace GameClass.GameObj
public PlaceType Place public PlaceType Place
{ {
get => place; get => place;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
place = value; place = value;
@@ -106,7 +112,8 @@ namespace GameClass.GameObj
public int MoveSpeed public int MoveSpeed
{ {
get => moveSpeed; get => moveSpeed;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
moveSpeed = value; moveSpeed = value;
@@ -120,8 +127,9 @@ namespace GameClass.GameObj
public int OrgMoveSpeed public int OrgMoveSpeed
{ {
get => orgMoveSpeed; get => orgMoveSpeed;
protected
set {
protected
set
{
orgMoveSpeed = value; orgMoveSpeed = value;
} }
} }


+ 2
- 1
logic/GameClass/GameObj/ObjOfCharacter.cs View File

@@ -12,7 +12,8 @@ namespace GameClass.GameObj
public ICharacter? Parent public ICharacter? Parent
{ {
get => parent; get => parent;
set {
set
{
lock (gameObjLock) lock (gameObjLock)
{ {
parent = value; parent = value;


+ 9
- 9
logic/GameClass/GameObj/Prop.cs View File

@@ -43,14 +43,14 @@ namespace GameClass.GameObj
{ {
} }
} }
///// <summary>
///// 坑人地雷
///// </summary>
// public abstract class DebuffMine : Prop
//{
// public DebuffMine(XYPosition initPos) : base(initPos) { }
// }
#region 所有增益道具
///// <summary>
///// 坑人地雷
///// </summary>
// public abstract class DebuffMine : Prop
//{
// public DebuffMine(XYPosition initPos) : base(initPos) { }
// }
#region 所有增益道具
/// <summary> /// <summary>
/// 增加速度 /// 增加速度
/// </summary> /// </summary>
@@ -95,7 +95,7 @@ namespace GameClass.GameObj
} }
public override PropType GetPropType() => PropType.Spear; public override PropType GetPropType() => PropType.Spear;
} }
#endregion
#endregion
// #region 所有坑人地雷 // #region 所有坑人地雷
///// <summary> ///// <summary>
///// 减速 ///// 减速


+ 2
- 1
logic/GameClass/GameObj/Team.cs View File

@@ -13,7 +13,8 @@ namespace GameClass.GameObj
private readonly List<Character> playerList; private readonly List<Character> playerList;
public int Score public int Score
{ {
get {
get
{
int score = 0; int score = 0;
foreach (var player in playerList) foreach (var player in playerList)
score += player.Score; score += player.Score;


+ 52
- 46
logic/GameClass/Skill/CommonSkill.cs View File

@@ -33,8 +33,9 @@ namespace GameClass.Skill
{ {
return CommonSkillFactory.SkillEffect(this, player, () => return CommonSkillFactory.SkillEffect(this, player, () =>
{ {
player.Vampire += 0.5;
Debugger.Output(player, "becomes vampire!"); },
player.Vampire += 0.5;
Debugger.Output(player, "becomes vampire!");
},
() => () =>
{ {
double tempVam = player.Vampire - 0.5; double tempVam = player.Vampire - 0.5;
@@ -65,8 +66,9 @@ namespace GameClass.Skill
{ {
return CommonSkillFactory.SkillEffect(this, player, () => return CommonSkillFactory.SkillEffect(this, player, () =>
{ {
player.IsInvisible = true;
Debugger.Output(player, "uses atombomb!"); },
player.IsInvisible = true;
Debugger.Output(player, "uses atombomb!");
},
() => () =>
{ player.IsInvisible = false; }); { player.IsInvisible = false; });
} }
@@ -93,8 +95,9 @@ namespace GameClass.Skill
{ {
return CommonSkillFactory.SkillEffect(this, player, () => return CommonSkillFactory.SkillEffect(this, player, () =>
{ {
player.BulletOfPlayer = BulletType.AtomBomb;
Debugger.Output(player, "uses atombomb!"); },
player.BulletOfPlayer = BulletType.AtomBomb;
Debugger.Output(player, "uses atombomb!");
},
() => () =>
{ player.BulletOfPlayer = player.OriBulletOfPlayer; }); { player.BulletOfPlayer = player.OriBulletOfPlayer; });
} }
@@ -121,10 +124,11 @@ namespace GameClass.Skill
{ {
return CommonSkillFactory.SkillEffect(this, player, () => return CommonSkillFactory.SkillEffect(this, player, () =>
{ {
player.AddMoveSpeed(this.DurationTime, 3.0);
Debugger.Output(player, "moves very fast!"); },
player.AddMoveSpeed(this.DurationTime, 3.0);
Debugger.Output(player, "moves very fast!");
},
() => () =>
{});
{ });
} }
} }
public class NoCommonSkill : ICommonSkill // 这种情况不该发生,定义着以防意外 public class NoCommonSkill : ICommonSkill // 这种情况不该发生,定义着以防意外
@@ -164,53 +168,55 @@ namespace GameClass.Skill
(() => (() =>
{ {
startSkill(); startSkill();
new FrameRateTaskExecutor<int>(
() => !player.IsResetting,
() =>
new FrameRateTaskExecutor<int>(
() => !player.IsResetting,
() =>
{
player.TimeUntilCommonSkillAvailable -= (int)GameData.frameDuration;
},
timeInterval: GameData.frameDuration,
() => 0,
maxTotalDuration: (long)(commonSkill.DurationTime)
)
{ {
player.TimeUntilCommonSkillAvailable -= (int)GameData.frameDuration;
},
timeInterval: GameData.frameDuration,
() => 0,
maxTotalDuration: (long)(commonSkill.DurationTime)
) {
AllowTimeExceed = true,
MaxTolerantTimeExceedCount = ulong.MaxValue,
}
.Start();

endSkill();
Debugger.Output(player, "return to normal.");

new FrameRateTaskExecutor<int>(
() => player.TimeUntilCommonSkillAvailable > 0 && !player.IsResetting,
() =>
AllowTimeExceed = true,
MaxTolerantTimeExceedCount = ulong.MaxValue,
}
.Start();

endSkill();
Debugger.Output(player, "return to normal.");

new FrameRateTaskExecutor<int>(
() => player.TimeUntilCommonSkillAvailable > 0 && !player.IsResetting,
() =>
{
player.TimeUntilCommonSkillAvailable -= (int)GameData.frameDuration;
},
timeInterval: GameData.frameDuration,
() => 0,
maxTotalDuration: (long)(commonSkill.SkillCD - commonSkill.DurationTime)
)
{ {
player.TimeUntilCommonSkillAvailable -= (int)GameData.frameDuration;
},
timeInterval: GameData.frameDuration,
() => 0,
maxTotalDuration: (long)(commonSkill.SkillCD - commonSkill.DurationTime)
) {
AllowTimeExceed = true,
MaxTolerantTimeExceedCount = ulong.MaxValue,
}
.Start();
AllowTimeExceed = true,
MaxTolerantTimeExceedCount = ulong.MaxValue,
}
.Start();


player.TimeUntilCommonSkillAvailable = 0;
Debugger.Output(player, "CommonSkill is ready.");
}
player.TimeUntilCommonSkillAvailable = 0;
Debugger.Output(player, "CommonSkill is ready.");
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();


return true; return true;
}
else
{
}
else
{
Debugger.Output(player, "CommonSkill is cooling down!"); Debugger.Output(player, "CommonSkill is cooling down!");
return false; return false;
}
} }
} }
} }
} }
}

+ 63
- 63
logic/GameClass/Skill/PassiveSkill.cs View File

@@ -29,19 +29,19 @@ namespace GameClass.Skill // 被动技能开局时就释放,持续到游戏
() => true, () => true,
() => () =>
{ {
lastHP = nowHP; // lastHP等于上一帧的HP
nowHP = player.HP; // nowHP更新为这一帧的HP
if (lastHP > nowHP) // 这一帧扣血了
{
waitTime = 0;
}
else if (waitTime < interval)
{
waitTime += GameData.frameDuration;
}
lastHP = nowHP; // lastHP等于上一帧的HP
nowHP = player.HP; // nowHP更新为这一帧的HP
if (lastHP > nowHP) // 这一帧扣血了
{
waitTime = 0;
}
else if (waitTime < interval)
{
waitTime += GameData.frameDuration;
}


if (waitTime >= interval) // 回复时,每帧(50ms)回复5,即1s回复100。
player.TryAddHp(recoverDegree);
if (waitTime >= interval) // 回复时,每帧(50ms)回复5,即1s回复100。
player.TryAddHp(recoverDegree);
}, },
timeInterval: GameData.frameDuration, timeInterval: GameData.frameDuration,
() => 0, () => 0,
@@ -52,29 +52,29 @@ namespace GameClass.Skill // 被动技能开局时就释放,持续到游戏
MaxTolerantTimeExceedCount = ulong.MaxValue, MaxTolerantTimeExceedCount = ulong.MaxValue,
TimeExceedAction = b => TimeExceedAction = b =>
{ {
if (b)
Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!");
if (b)
Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!");


#if DEBUG #if DEBUG
else
{
Console.WriteLine("Debug info: passive skill time exceeds for once.");
}
else
{
Console.WriteLine("Debug info: passive skill time exceeds for once.");
}
#endif #endif
} }
}.Start(); }.Start();
}
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
}
} }
}
public class SpeedUpWhenLeavingGrass : IPassiveSkill // 3倍速
{
private readonly BulletType initBullet = BulletType.FastBullet;
public BulletType InitBullet => initBullet;
// 以上参数以后再改
public void SkillEffect(Character player)
public class SpeedUpWhenLeavingGrass : IPassiveSkill // 3倍速
{ {
private readonly BulletType initBullet = BulletType.FastBullet;
public BulletType InitBullet => initBullet;
// 以上参数以后再改
public void SkillEffect(Character player)
{
PlaceType nowPlace = player.Place; PlaceType nowPlace = player.Place;
PlaceType lastPlace = nowPlace; PlaceType lastPlace = nowPlace;
bool speedup = false; bool speedup = false;
@@ -88,20 +88,20 @@ public class SpeedUpWhenLeavingGrass : IPassiveSkill // 3倍速
() => true, () => true,
() => () =>
{ {
lastPlace = nowPlace;
nowPlace = player.Place;
if ((lastPlace == PlaceType.Grass1 || lastPlace == PlaceType.Grass2 || lastPlace == PlaceType.Grass3) && nowPlace == PlaceType.Land)
{
if (!speedup)
{
lastPlace = nowPlace;
nowPlace = player.Place;
if ((lastPlace == PlaceType.Grass1 || lastPlace == PlaceType.Grass2 || lastPlace == PlaceType.Grass3) && nowPlace == PlaceType.Land)
{
if (!speedup)
{
new Thread(() => new Thread(() =>
{ {
speedup = true; speedup = true;
player.AddMoveSpeed(SpeedUpTime, 3.0);
speedup = false;
})
player.AddMoveSpeed(SpeedUpTime, 3.0);
speedup = false;
})
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
}
}
} }
}, },
timeInterval: GameData.frameDuration, timeInterval: GameData.frameDuration,
@@ -113,41 +113,41 @@ public class SpeedUpWhenLeavingGrass : IPassiveSkill // 3倍速
MaxTolerantTimeExceedCount = ulong.MaxValue, MaxTolerantTimeExceedCount = ulong.MaxValue,
TimeExceedAction = b => TimeExceedAction = b =>
{ {
if (b)
Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!");
if (b)
Console.WriteLine("Fetal Error: The computer runs so slow that passive skill time exceeds!!!!!!");


#if DEBUG #if DEBUG
else
{
Console.WriteLine("Debug info: passive skill time exceeds for once.");
}
else
{
Console.WriteLine("Debug info: passive skill time exceeds for once.");
}
#endif #endif
} }
}.Start(); }.Start();
}
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
}
}
public class Vampire : IPassiveSkill // 被动就是吸血,普通子弹
{
private readonly BulletType initBullet = BulletType.LineBullet;
public BulletType InitBullet => initBullet;
// 以上参数以后再改
public void SkillEffect(Character player)
{
}
}
public class Vampire : IPassiveSkill // 被动就是吸血,普通子弹
{
private readonly BulletType initBullet = BulletType.LineBullet;
public BulletType InitBullet => initBullet;
// 以上参数以后再改
public void SkillEffect(Character player)
{
player.OriVampire = 0.5; player.OriVampire = 0.5;
player.Vampire = player.OriVampire; player.Vampire = player.OriVampire;
}
}
}
}


public class NoPassiveSkill : IPassiveSkill // 没技能,这种情况不应该发生,先定义着以防意外
{
private readonly BulletType initBullet = BulletType.OrdinaryBullet;
public BulletType InitBullet => initBullet;
// 以上参数以后再改
public void SkillEffect(Character player)
{
}
}
public class NoPassiveSkill : IPassiveSkill // 没技能,这种情况不应该发生,先定义着以防意外
{
private readonly BulletType initBullet = BulletType.OrdinaryBullet;
public BulletType InitBullet => initBullet;
// 以上参数以后再改
public void SkillEffect(Character player)
{
}
}
} }

+ 82
- 81
logic/GameEngine/MoveEngine.cs View File

@@ -66,65 +66,28 @@ namespace GameEngine
{ {
if (!obj.IsAvailable && gameTimer.IsGaming) //不能动就直接return,后面都是能动的情况 if (!obj.IsAvailable && gameTimer.IsGaming) //不能动就直接return,后面都是能动的情况
return; return;
lock (obj.MoveLock)
obj.IsMoving = true;

double moveVecLength = 0.0;
double deltaLen = moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength))); // 转向,并用deltaLen存储行走的误差
IGameObj? collisionObj = null;
bool isDestroyed = false;
new FrameRateTaskExecutor<int>(
() => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting,
() =>
{
moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond;

// 越界情况处理:如果越界,则与越界方块碰撞
bool flag; // 循环标志
do
{
flag = false;
collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength));
if (collisionObj == null)
break;
lock (obj.MoveLock)
obj.IsMoving = true;


switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
double moveVecLength = 0.0;
double deltaLen = moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength))); // 转向,并用deltaLen存储行走的误差
IGameObj? collisionObj = null;
bool isDestroyed = false;
new FrameRateTaskExecutor<int>(
() => gameTimer.IsGaming && obj.CanMove && !obj.IsResetting,
() =>
{ {
case AfterCollision.ContinueCheck:
flag = true;
break;
case AfterCollision.Destroyed:
Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
isDestroyed = true;
return false;
case AfterCollision.MoveMax:
MoveMax(obj, new XY(direction, moveVecLength));
moveVecLength = 0;
break;
}
} while (flag);
moveVecLength = obj.MoveSpeed / GameData.numOfStepPerSecond;


deltaLen += moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength)));

return true;
},
GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond,
() =>
{
int leftTime = moveTime % (GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond);
bool flag;
do
{
flag = false;
if (!isDestroyed)
{
moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell;
if ((collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength))) == null)
{
obj.Move(new XY(direction, moveVecLength));
}
else
// 越界情况处理:如果越界,则与越界方块碰撞
bool flag; // 循环标志
do
{ {
flag = false;
collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength));
if (collisionObj == null)
break;

switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength))) switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
{ {
case AfterCollision.ContinueCheck: case AfterCollision.ContinueCheck:
@@ -133,43 +96,81 @@ namespace GameEngine
case AfterCollision.Destroyed: case AfterCollision.Destroyed:
Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game."); Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
isDestroyed = true; isDestroyed = true;
break;
return false;
case AfterCollision.MoveMax: case AfterCollision.MoveMax:
MoveMax(obj, new XY(direction, moveVecLength)); MoveMax(obj, new XY(direction, moveVecLength));
moveVecLength = 0; moveVecLength = 0;
break; break;
} }
} while (flag);

deltaLen += moveVecLength - Math.Sqrt(obj.Move(new XY(direction, moveVecLength)));

return true;
},
GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond,
() =>
{
int leftTime = moveTime % (GameData.numOfPosGridPerCell / GameData.numOfStepPerSecond);
bool flag;
do
{
flag = false;
if (!isDestroyed)
{
moveVecLength = deltaLen + leftTime * obj.MoveSpeed / GameData.numOfPosGridPerCell;
if ((collisionObj = collisionChecker.CheckCollision(obj, new XY(direction, moveVecLength))) == null)
{
obj.Move(new XY(direction, moveVecLength));
}
else
{
switch (OnCollision(obj, collisionObj, new XY(direction, moveVecLength)))
{
case AfterCollision.ContinueCheck:
flag = true;
break;
case AfterCollision.Destroyed:
Debugger.Output(obj, " collide with " + collisionObj.ToString() + " and has been removed from the game.");
isDestroyed = true;
break;
case AfterCollision.MoveMax:
MoveMax(obj, new XY(direction, moveVecLength));
moveVecLength = 0;
break;
}
}
}
} while (flag);
if (leftTime > 0)
{
Thread.Sleep(leftTime); // 多移动的在这里补回来
} }
}
} while (flag);
if (leftTime > 0)
lock (obj.MoveLock)
obj.IsMoving = false; // 结束移动
EndMove(obj);
return 0;
},
maxTotalDuration: moveTime
)
{ {
Thread.Sleep(leftTime); // 多移动的在这里补回来
}
lock (obj.MoveLock)
obj.IsMoving = false; // 结束移动
EndMove(obj);
return 0;
},
maxTotalDuration: moveTime
) {
AllowTimeExceed = true,
MaxTolerantTimeExceedCount = ulong.MaxValue,
TimeExceedAction = b =>
{
if (b)
Console.WriteLine("Fatal Error: The computer runs so slow that the object cannot finish moving during this time!!!!!!");
AllowTimeExceed = true,
MaxTolerantTimeExceedCount = ulong.MaxValue,
TimeExceedAction = b =>
{
if (b)
Console.WriteLine("Fatal Error: The computer runs so slow that the object cannot finish moving during this time!!!!!!");


#if DEBUG #if DEBUG
else
{
Console.WriteLine("Debug info: Object moving time exceed for once.");
}
else
{
Console.WriteLine("Debug info: Object moving time exceed for once.");
}
#endif #endif
}
}.Start();
} }
}.Start();
}
).Start(); ).Start();
}
} }
} }
}

+ 107
- 105
logic/Gaming/AttackManager.cs View File

@@ -23,14 +23,16 @@ namespace Gaming
OnCollision: (obj, collisionObj, moveVec) => OnCollision: (obj, collisionObj, moveVec) =>
{ {
//BulletBomb((Bullet)obj, (GameObj)collisionObj); //BulletBomb((Bullet)obj, (GameObj)collisionObj);
return MoveEngine.AfterCollision.Destroyed; },
return MoveEngine.AfterCollision.Destroyed;
},
EndMove: obj => EndMove: obj =>
{ {
#if DEBUG #if DEBUG
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);


#endif #endif
BulletBomb((Bullet)obj, null); }
BulletBomb((Bullet)obj, null);
}
); );
} }
private void BombOnePlayer(Bullet bullet, Character playerBeingShot) private void BombOnePlayer(Bullet bullet, Character playerBeingShot)
@@ -75,136 +77,136 @@ namespace Gaming


Thread.Sleep(GameData.reviveTime); Thread.Sleep(GameData.reviveTime);


playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾
playerBeingShot.AddShield(GameData.shieldTimeAtBirth); // 复活加个盾


// gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
// try
//{
// gameMap.GameObjDict[GameObjIdx.Player].Add(playerBeingShot);
// }
// finally { gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); }
// gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
// try
//{
// gameMap.GameObjDict[GameObjIdx.Player].Add(playerBeingShot);
// }
// finally { gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); }


if (gameMap.Timer.IsGaming)
{
playerBeingShot.CanMove = true;
}
playerBeingShot.IsResetting = false;
}
if (gameMap.Timer.IsGaming)
{
playerBeingShot.CanMove = true;
}
playerBeingShot.IsResetting = false;
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
}
} }
}
private void BulletBomb(Bullet bullet, GameObj? objBeingShot)
{
private void BulletBomb(Bullet bullet, GameObj? objBeingShot)
{
#if DEBUG #if DEBUG
Debugger.Output(bullet, "bombed!");
Debugger.Output(bullet, "bombed!");
#endif #endif
bullet.CanMove = false;
gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock();
try
{
foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjIdx.Bullet])
{
if (_bullet.ID == bullet.ID)
bullet.CanMove = false;
gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock();
try
{
foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjIdx.Bullet])
{ {
gameMap.GameObjLockDict[GameObjIdx.BombedBullet].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.BombedBullet].Add(new BombedBullet(bullet));
}
finally
if (_bullet.ID == bullet.ID)
{ {
gameMap.GameObjLockDict[GameObjIdx.BombedBullet].ExitWriteLock();
gameMap.GameObjLockDict[GameObjIdx.BombedBullet].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.BombedBullet].Add(new BombedBullet(bullet));
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.BombedBullet].ExitWriteLock();
}
gameMap.GameObjDict[GameObjIdx.Bullet].Remove(_bullet);
break;
} }
gameMap.GameObjDict[GameObjIdx.Bullet].Remove(_bullet);
break;
} }
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock();
}

/*if (objBeingShot != null)
{
else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。
}
finally
{ {
new Thread(() => { BulletBomb((Bullet)objBeingShot, null); }) { IsBackground = true }.Start();
gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock();
} }
}*/


// 子弹爆炸会发生的事↓↓↓
var beAttackedList = new List<Character>();
gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock();
try
{
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
{
if (bullet.CanAttack(player))
/*if (objBeingShot != null)
{
else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。
{ {
beAttackedList.Add(player);
if (player.ID != bullet.Parent.ID)
bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * bullet.AP));
new Thread(() => { BulletBomb((Bullet)objBeingShot, null); }) { IsBackground = true }.Start();
} }
}*/

// 子弹爆炸会发生的事↓↓↓
var beAttackedList = new List<Character>();
gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock();
try
{
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
{
if (bullet.CanAttack(player))
{
beAttackedList.Add(player);
if (player.ID != bullet.Parent.ID)
bullet.Parent.HP = (int)(bullet.Parent.HP + (bullet.Parent.Vampire * bullet.AP));
} }
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock();
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock();
}


foreach (Character beAttackedPlayer in beAttackedList)
{
BombOnePlayer(bullet, beAttackedPlayer);
foreach (Character beAttackedPlayer in beAttackedList)
{
BombOnePlayer(bullet, beAttackedPlayer);
}
beAttackedList.Clear();
} }
beAttackedList.Clear();
}
public bool Attack(Character? player, double angle) // 射出去的子弹泼出去的水(狗头)
{ // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange
if (player == null)
{
public bool Attack(Character? player, double angle) // 射出去的子弹泼出去的水(狗头)
{ // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange
if (player == null)
{
#if DEBUG #if DEBUG
Console.WriteLine("the player who will attack is NULL!");
Console.WriteLine("the player who will attack is NULL!");
#endif #endif
return false;
}
return false;
}


if (player.IsResetting)
return false;
Bullet? bullet = player.RemoteAttack(
new XY // 子弹紧贴人物生成。
(
(int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Cos(angle)),
(int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Sin(angle))
)
);
if (bullet != null)
{
bullet.CanMove = true;
gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.Bullet].Add(bullet);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock();
}
moveEngine.MoveObj(bullet, (int)((player.AttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms
if (player.IsResetting)
return false;
Bullet? bullet = player.RemoteAttack(
new XY // 子弹紧贴人物生成。
(
(int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Cos(angle)),
(int)((player.Radius + BulletFactory.BulletRadius(player.BulletOfPlayer)) * Math.Sin(angle))
)
);
if (bullet != null)
{
bullet.CanMove = true;
gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.Bullet].Add(bullet);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock();
}
moveEngine.MoveObj(bullet, (int)((player.AttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms
#if DEBUG #if DEBUG
Console.WriteLine($"playerID:{player.ID} successfully attacked!");
Console.WriteLine($"playerID:{player.ID} successfully attacked!");
#endif #endif
return true;
}
else
{
return true;
}
else
{
#if DEBUG #if DEBUG
Console.WriteLine($"playerID:{player.ID} has no bullets so that he can't attack!");
Console.WriteLine($"playerID:{player.ID} has no bullets so that he can't attack!");
#endif #endif
return false;
return false;
}
} }
} }
} }
} }
}

+ 159
- 158
logic/Gaming/Game.cs View File

@@ -64,57 +64,58 @@ namespace Gaming
{ {
while (!gameMap.Timer.IsGaming) while (!gameMap.Timer.IsGaming)
Thread.Sleep(newPlayer.CD); Thread.Sleep(newPlayer.CD);
long lastTime = Environment.TickCount64;
new FrameRateTaskExecutor<int>(
loopCondition: () => gameMap.Timer.IsGaming,
loopToDo: () =>
{
if (!newPlayer.IsResetting)
long lastTime = Environment.TickCount64;
new FrameRateTaskExecutor<int>(
loopCondition: () => gameMap.Timer.IsGaming,
loopToDo: () =>
{
if (!newPlayer.IsResetting)
{
long nowTime = Environment.TickCount64;
if (newPlayer.BulletNum == newPlayer.MaxBulletNum)
lastTime = nowTime;
if (nowTime - lastTime >= newPlayer.CD)
{
_ = newPlayer.TryAddBulletNum();
lastTime = nowTime;
}
}
},
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
)
{ {
long nowTime = Environment.TickCount64;
if (newPlayer.BulletNum == newPlayer.MaxBulletNum)
lastTime = nowTime;
if (nowTime - lastTime >= newPlayer.CD)
AllowTimeExceed = true
/*MaxTolerantTimeExceedCount = 5,
TimeExceedAction = exceedTooMuch =>
{ {
_ = newPlayer.TryAddBulletNum();
lastTime = nowTime;
}
if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!");
}*/
} }
},
timeInterval: GameData.checkInterval,
finallyReturn: () => 0
) {
AllowTimeExceed = true
/*MaxTolerantTimeExceedCount = 5,
TimeExceedAction = exceedTooMuch =>
{
if (exceedTooMuch) Console.WriteLine("The computer runs too slow that it cannot check the color below the player in time!");
}*/
}
.Start();
}
.Start();
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();


return newPlayer.ID; return newPlayer.ID;
}
public bool StartGame(int milliSeconds)
{
}
public bool StartGame(int milliSeconds)
{
if (gameMap.Timer.IsGaming) if (gameMap.Timer.IsGaming)
return false;
return false;
gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock(); gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock();
try try
{ {
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
{
player.CanMove = true;
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
{
player.CanMove = true;


player.AddShield(GameData.shieldTimeAtBirth);
}
player.AddShield(GameData.shieldTimeAtBirth);
}
} }
finally finally
{ {
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock();
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock();
} }


propManager.StartProducing(); propManager.StartProducing();
@@ -127,24 +128,24 @@ namespace Gaming
loopCondition: () => gameMap.Timer.IsGaming, loopCondition: () => gameMap.Timer.IsGaming,
loopToDo: () => loopToDo: () =>
{ {
foreach (var kvp in gameMap.GameObjDict) // 检查物体位置
{
if (kvp.Key == GameObjIdx.Bullet || kvp.Key == GameObjIdx.Player || kvp.Key == GameObjIdx.Prop)
{
gameMap.GameObjLockDict[kvp.Key].EnterWriteLock();
try
{
foreach (var item in gameMap.GameObjDict[kvp.Key])
{
item.Place = gameMap.GetPlaceType(item.Position);
}
}
finally
{
gameMap.GameObjLockDict[kvp.Key].ExitWriteLock();
}
}
}
foreach (var kvp in gameMap.GameObjDict) // 检查物体位置
{
if (kvp.Key == GameObjIdx.Bullet || kvp.Key == GameObjIdx.Player || kvp.Key == GameObjIdx.Prop)
{
gameMap.GameObjLockDict[kvp.Key].EnterWriteLock();
try
{
foreach (var item in gameMap.GameObjDict[kvp.Key])
{
item.Place = gameMap.GetPlaceType(item.Position);
}
}
finally
{
gameMap.GameObjLockDict[kvp.Key].ExitWriteLock();
}
}
}
}, },
timeInterval: GameData.checkInterval, timeInterval: GameData.checkInterval,
finallyReturn: () => 0 finallyReturn: () => 0
@@ -152,20 +153,20 @@ namespace Gaming
{ {
AllowTimeExceed = true AllowTimeExceed = true
}.Start(); }.Start();
}
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
// 开始游戏 // 开始游戏
if (!gameMap.Timer.StartGame(milliSeconds)) if (!gameMap.Timer.StartGame(milliSeconds))
return false;
return false;


EndGame(); // 游戏结束时要做的事 EndGame(); // 游戏结束时要做的事


return true; return true;
}
}


public void EndGame()
{
public void EndGame()
{
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
/*try /*try
{ {
@@ -174,169 +175,169 @@ public void EndGame()
{ {
}*/ }*/
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock(); gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
}
public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle)
{
}
public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle)
{
if (!gameMap.Timer.IsGaming) if (!gameMap.Timer.IsGaming)
return;
return;
Character? player = gameMap.FindPlayer(playerID); Character? player = gameMap.FindPlayer(playerID);
if (player != null) if (player != null)
{ {
moveManager.MovePlayer(player, moveTimeInMilliseconds, angle);
moveManager.MovePlayer(player, moveTimeInMilliseconds, angle);
#if DEBUG #if DEBUG
Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!");
Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!");
#endif #endif
} }
else else
{ {
#if DEBUG #if DEBUG
Console.WriteLine($"PlayerID:{playerID} player does not exists!");
Console.WriteLine($"PlayerID:{playerID} player does not exists!");
#endif #endif
} }
}
public void Attack(long playerID, double angle)
{
}
public void Attack(long playerID, double angle)
{
if (!gameMap.Timer.IsGaming) if (!gameMap.Timer.IsGaming)
return;
return;
Character? player = gameMap.FindPlayer(playerID); Character? player = gameMap.FindPlayer(playerID);
if (player != null) if (player != null)
{ {
_ = attackManager.Attack(player, angle);
_ = attackManager.Attack(player, angle);
} }
}
public void UseProp(long playerID)
{
}
public void UseProp(long playerID)
{
if (!gameMap.Timer.IsGaming) if (!gameMap.Timer.IsGaming)
return;
return;
Character? player = gameMap.FindPlayer(playerID); Character? player = gameMap.FindPlayer(playerID);
if (player != null) if (player != null)
{ {
propManager.UseProp(player);
propManager.UseProp(player);
} }
}
public void ThrowProp(long playerID, int timeInmillionSeconds, double angle)
{
}
public void ThrowProp(long playerID, int timeInmillionSeconds, double angle)
{
if (!gameMap.Timer.IsGaming) if (!gameMap.Timer.IsGaming)
return;
return;
Character? player = gameMap.FindPlayer(playerID); Character? player = gameMap.FindPlayer(playerID);
if (player != null) if (player != null)
{ {
propManager.ThrowProp(player, timeInmillionSeconds, angle);
propManager.ThrowProp(player, timeInmillionSeconds, angle);
} }
}
public bool PickProp(long playerID, PropType propType = PropType.Null)
{
}
public bool PickProp(long playerID, PropType propType = PropType.Null)
{
if (!gameMap.Timer.IsGaming) if (!gameMap.Timer.IsGaming)
return false;
return false;
Character? player = gameMap.FindPlayer(playerID); Character? player = gameMap.FindPlayer(playerID);
if (player != null) if (player != null)
{ {
return propManager.PickProp(player, propType);
return propManager.PickProp(player, propType);
} }
return false; return false;
}
}


public bool UseCommonSkill(long playerID)
{
public bool UseCommonSkill(long playerID)
{
if (!gameMap.Timer.IsGaming) if (!gameMap.Timer.IsGaming)
return false;
return false;
Character? player = gameMap.FindPlayer(playerID); Character? player = gameMap.FindPlayer(playerID);
if (player != null) if (player != null)
{ {
return skillManager.UseCommonSkill(player);
return skillManager.UseCommonSkill(player);
} }
else else
return false;
}
return false;
}


public void AllPlayerUsePassiveSkill()
{
public void AllPlayerUsePassiveSkill()
{
if (!gameMap.Timer.IsGaming) if (!gameMap.Timer.IsGaming)
return;
return;
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock(); gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
try try
{ {
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
{
skillManager.UsePassiveSkill(player);
}
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
{
skillManager.UsePassiveSkill(player);
}
} }
finally finally
{ {
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
} }
}
}


public void ClearLists(GameObjIdx[] objIdxes)
{
public void ClearLists(GameObjIdx[] objIdxes)
{
foreach (var idx in objIdxes) foreach (var idx in objIdxes)
{ {
if (idx != GameObjIdx.None)
{
gameMap.GameObjLockDict[idx].EnterWriteLock();
try
{
gameMap.GameObjDict[idx].Clear();
}
finally
{
gameMap.GameObjLockDict[idx].ExitWriteLock();
}
}
if (idx != GameObjIdx.None)
{
gameMap.GameObjLockDict[idx].EnterWriteLock();
try
{
gameMap.GameObjDict[idx].Clear();
}
finally
{
gameMap.GameObjLockDict[idx].ExitWriteLock();
}
}
} }
}
public void ClearAllLists()
{
}
public void ClearAllLists()
{
foreach (var keyValuePair in gameMap.GameObjDict) foreach (var keyValuePair in gameMap.GameObjDict)
{ {
if (keyValuePair.Key != GameObjIdx.Map)
{
gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock();
try
{
if (keyValuePair.Key == GameObjIdx.Player)
if (keyValuePair.Key != GameObjIdx.Map)
{ {
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock();
try
{
if (keyValuePair.Key == GameObjIdx.Player)
{
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
{
player.CanMove = false;
}
}
gameMap.GameObjDict[keyValuePair.Key].Clear();
}
finally
{ {
player.CanMove = false;
gameMap.GameObjLockDict[keyValuePair.Key].ExitWriteLock();
} }
} }
gameMap.GameObjDict[keyValuePair.Key].Clear();
} }
finally
{
gameMap.GameObjLockDict[keyValuePair.Key].ExitWriteLock();
}
}
}
}
}


public int GetTeamScore(long teamID)
{
public int GetTeamScore(long teamID)
{
return teamList[(int)teamID].Score; return teamList[(int)teamID].Score;
}
public List<IGameObj> GetGameObj()
{
}
public List<IGameObj> GetGameObj()
{
var gameObjList = new List<IGameObj>(); var gameObjList = new List<IGameObj>();
foreach (var keyValuePair in gameMap.GameObjDict) foreach (var keyValuePair in gameMap.GameObjDict)
{ {
if (keyValuePair.Key != GameObjIdx.Map)
{
gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock();
try
{
gameObjList.AddRange(gameMap.GameObjDict[keyValuePair.Key]);
}
finally
{
gameMap.GameObjLockDict[keyValuePair.Key].ExitReadLock();
}
}
if (keyValuePair.Key != GameObjIdx.Map)
{
gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock();
try
{
gameObjList.AddRange(gameMap.GameObjDict[keyValuePair.Key]);
}
finally
{
gameMap.GameObjLockDict[keyValuePair.Key].ExitReadLock();
}
}
} }
return gameObjList; return gameObjList;
}
public Game(uint[,] mapResource, int numOfTeam)
{
}
public Game(uint[,] mapResource, int numOfTeam)
{
// if (numOfTeam > maxTeamNum) throw new TeamNumOverFlowException(); // if (numOfTeam > maxTeamNum) throw new TeamNumOverFlowException();


gameMap = new Map(mapResource); gameMap = new Map(mapResource);
@@ -346,13 +347,13 @@ public Game(uint[,] mapResource, int numOfTeam)
teamList = new List<Team>(); teamList = new List<Team>();
for (int i = 0; i < numOfTeam; ++i) for (int i = 0; i < numOfTeam; ++i)
{ {
teamList.Add(new Team());
teamList.Add(new Team());
} }


skillManager = new SkillManager(); skillManager = new SkillManager();
attackManager = new AttackManager(gameMap); attackManager = new AttackManager(gameMap);
moveManager = new MoveManager(gameMap); moveManager = new MoveManager(gameMap);
propManager = new PropManager(gameMap); propManager = new PropManager(gameMap);
}
}
}
}
} }

+ 2
- 1
logic/Gaming/MoveManager.cs View File

@@ -54,7 +54,8 @@ namespace Gaming
// ActivateMine((Character)obj, (Mine)collisionObj); // ActivateMine((Character)obj, (Mine)collisionObj);
// return MoveEngine.AfterCollision.ContinueCheck; // return MoveEngine.AfterCollision.ContinueCheck;
//} //}
return MoveEngine.AfterCollision.MoveMax; },
return MoveEngine.AfterCollision.MoveMax;
},
EndMove: obj => EndMove: obj =>
{ {
// Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); // Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);


+ 48
- 47
logic/Gaming/PropManager.cs View File

@@ -175,49 +175,49 @@ namespace Gaming
{ {
while (!gameMap.Timer.IsGaming) while (!gameMap.Timer.IsGaming)
Thread.Sleep(1000); Thread.Sleep(1000);
new FrameRateTaskExecutor<int>(
() => gameMap.Timer.IsGaming,
() =>
{
int rand = r.Next(0, len);
XY randPos = availableCellForGenerateProp[rand];

gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
try
{
switch (r.Next(0, 4))
new FrameRateTaskExecutor<int>(
() => gameMap.Timer.IsGaming,
() =>
{ {
case 0:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddLIFE(randPos));
break;
case 1:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddSpeed(randPos));
break;
case 2:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new Shield(randPos));
break;
case 3:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new Spear(randPos));
break;
default:
break;
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
}
},
GameData.PropProduceTime,
() => 0
)
.Start();
}
int rand = r.Next(0, len);
XY randPos = availableCellForGenerateProp[rand];

gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
try
{
switch (r.Next(0, 4))
{
case 0:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddLIFE(randPos));
break;
case 1:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddSpeed(randPos));
break;
case 2:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new Shield(randPos));
break;
case 3:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new Spear(randPos));
break;
default:
break;
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
}
},
GameData.PropProduceTime,
() => 0
)
.Start();
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
}
public PropManager(Map gameMap) // 道具不能扔过墙
{
}
public PropManager(Map gameMap) // 道具不能扔过墙
{
this.gameMap = gameMap; this.gameMap = gameMap;
this.moveEngine = new MoveEngine( this.moveEngine = new MoveEngine(
gameMap: gameMap, gameMap: gameMap,
@@ -227,20 +227,21 @@ namespace Gaming
{ {
// obj.Place = gameMap.GetPlaceType((GameObj)obj); // obj.Place = gameMap.GetPlaceType((GameObj)obj);
obj.CanMove = false; obj.CanMove = false;
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); }
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);
}
); );
availableCellForGenerateProp = new List<XY>(); availableCellForGenerateProp = new List<XY>();
for (int i = 0; i < gameMap.ProtoGameMap.GetLength(0); i++) for (int i = 0; i < gameMap.ProtoGameMap.GetLength(0); i++)
{ {
for (int j = 0; j < gameMap.ProtoGameMap.GetLength(1); j++)
{
if (gameMap.ProtoGameMap[i, j] == (int)MapInfo.MapInfoObjType.Null)
for (int j = 0; j < gameMap.ProtoGameMap.GetLength(1); j++)
{ {
availableCellForGenerateProp.Add(GameData.GetCellCenterPos(i, j));
if (gameMap.ProtoGameMap[i, j] == (int)MapInfo.MapInfoObjType.Null)
{
availableCellForGenerateProp.Add(GameData.GetCellCenterPos(i, j));
}
} }
} }
}
}
} }
} }
} }
}

+ 6
- 6
logic/Preparation/GameData/GameData.cs View File

@@ -4,7 +4,7 @@ namespace Preparation.GameData
{ {
public static class GameData public static class GameData
{ {
#region 基本常数与常方法
#region 基本常数与常方法
public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数 public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数
public const int numOfStepPerSecond = 20; // 每秒行走的步数 public const int numOfStepPerSecond = 20; // 每秒行走的步数
public const int lengthOfMap = 50000; // 地图长度 public const int lengthOfMap = 50000; // 地图长度
@@ -35,8 +35,8 @@ namespace Preparation.GameData
} }


public static int numOfBirthPoint = 5; public static int numOfBirthPoint = 5;
#endregion
#region 角色相关
#endregion
#region 角色相关
/// <summary> /// <summary>
/// 玩家相关 /// 玩家相关
/// </summary> /// </summary>
@@ -71,9 +71,9 @@ namespace Preparation.GameData
public const long GemProduceTime = 10000; public const long GemProduceTime = 10000;
public const long PropProduceTime = 10000; public const long PropProduceTime = 10000;
public const int PropDuration = 10000; public const int PropDuration = 10000;
#endregion
#region 游戏帧相关
#endregion
#region 游戏帧相关
public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长 public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长
#endregion
#endregion
} }
} }

+ 1
- 1
logic/Preparation/Utility/XY.cs View File

@@ -21,7 +21,7 @@ namespace Preparation.Utility
{ {
return "(" + x.ToString() + "," + y.ToString() + ")"; return "(" + x.ToString() + "," + y.ToString() + ")";
} }
public static int operator*(XY v1, XY v2)
public static int operator *(XY v1, XY v2)
{ {
return (v1.x * v2.x) + (v1.y * v2.y); return (v1.x * v2.x) + (v1.y * v2.y);
} }


+ 29
- 27
logic/Server/Game.cs View File

@@ -18,7 +18,7 @@ namespace Server
public bool IsGaming public bool IsGaming
{ {
get => Interlocked.CompareExchange(ref isGaming, 0, 0) != 0; get => Interlocked.CompareExchange(ref isGaming, 0, 0) != 0;
set => Interlocked.Exchange(ref isGaming, value? 1: 0);
set => Interlocked.Exchange(ref isGaming, value ? 1 : 0);
} }


public MessageToClient GetCopiedGameInfo() public MessageToClient GetCopiedGameInfo()
@@ -36,14 +36,16 @@ namespace Server
return; return;
if (player.PlayerType == PlayerType.HumanPlayer) if (player.PlayerType == PlayerType.HumanPlayer)
{ {
gameInfo.HumanMessage.Add(new MessageOfHuman() {
gameInfo.HumanMessage.Add(new MessageOfHuman()
{
PlayerId = player.PlayerId PlayerId = player.PlayerId
}); });
return; return;
} }
if (player.PlayerType == PlayerType.ButcherPlayer) if (player.PlayerType == PlayerType.ButcherPlayer)
{ {
gameInfo.ButcherMessage.Add(new MessageOfButcher() {
gameInfo.ButcherMessage.Add(new MessageOfButcher()
{
PlayerId = player.PlayerId PlayerId = player.PlayerId
}); });
return; return;
@@ -69,39 +71,39 @@ namespace Server
() => IsGaming, () => IsGaming,
() => () =>
{ {
lock (gameInfo)
{
for (int i = 0; i < gameInfo.HumanMessage.Count; i++)
{
if (gameInfo.HumanMessage[i] != null)
{
gameInfo.HumanMessage[i].X++;
gameInfo.HumanMessage[i].Y--;
}
}
for (int i = 0; i < gameInfo.ButcherMessage.Count; i++)
{
if (gameInfo.ButcherMessage[i] != null)
{
gameInfo.ButcherMessage[i].X--;
gameInfo.ButcherMessage[i].Y++;
}
}
}
lock (gameInfo)
{
for (int i = 0; i < gameInfo.HumanMessage.Count; i++)
{
if (gameInfo.HumanMessage[i] != null)
{
gameInfo.HumanMessage[i].X++;
gameInfo.HumanMessage[i].Y--;
}
}
for (int i = 0; i < gameInfo.ButcherMessage.Count; i++)
{
if (gameInfo.ButcherMessage[i] != null)
{
gameInfo.ButcherMessage[i].X--;
gameInfo.ButcherMessage[i].Y++;
}
}
}
}, },
100, 100,
() => () =>
{ {
IsGaming = false;
waitHandle.Release();
return 0;
IsGaming = false;
waitHandle.Release();
return 0;
}, },
gameTime gameTime
).Start(); ).Start();
}
}
) )
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
return waitHandle; return waitHandle;
}
} }
} }
}

+ 26
- 26
logic/Server/GameServer.cs View File

@@ -80,42 +80,42 @@ namespace Server
1000, 1000,
() => () =>
{ {
ReportGame(); // 最后发一次消息,唤醒发消息的线程,防止发消息的线程由于有概率处在 Wait 状态而卡住
return 0;
ReportGame(); // 最后发一次消息,唤醒发消息的线程,防止发消息的线程由于有概率处在 Wait 状态而卡住
return 0;
} }
).Start(); ).Start();
})
})
{ IsBackground = true }.Start(); { IsBackground = true }.Start();
new Thread(() => new Thread(() =>
{ {
waitHandle.Wait(); waitHandle.Wait();
this.endGameSem.Release();
})
this.endGameSem.Release();
})
{ IsBackground = true }.Start(); { IsBackground = true }.Start();


}
public void WaitForEnd()
{
this.endGameSem.Wait();
}
}
public void WaitForEnd()
{
this.endGameSem.Wait();
}


public void ReportGame()
{
currentGameInfo = game.GetCopiedGameInfo();
public void ReportGame()
{
currentGameInfo = game.GetCopiedGameInfo();


foreach (var kvp in semaDict)
{
kvp.Value.Item1.Release();
}
foreach (var kvp in semaDict)
{
kvp.Value.Item1.Release();
}


foreach (var kvp in semaDict)
{
kvp.Value.Item2.Wait();
}
}
foreach (var kvp in semaDict)
{
kvp.Value.Item2.Wait();
}
}


public GameServer()
{
}
}
public GameServer()
{
}
}
} }

+ 2
- 1
logic/Server/Program.cs View File

@@ -14,7 +14,8 @@ namespace Server
try try
{ {
GameServer gameServer = new(); GameServer gameServer = new();
Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) }) {
Grpc.Core.Server server = new Grpc.Core.Server(new[] { new ChannelOption(ChannelOptions.SoReuseport, 0) })
{
Services = { AvailableService.BindService(gameServer) }, Services = { AvailableService.BindService(gameServer) },
Ports = { new ServerPort("127.0.0.1", 8888, ServerCredentials.Insecure) } Ports = { new ServerPort("127.0.0.1", 8888, ServerCredentials.Insecure) }
}; };


Loading…
Cancel
Save