Browse Source

feat: 💚 achieve functions of fixing and escaping

tags/0.1.0
shangfengh 2 years ago
parent
commit
ee57b6d6a9
25 changed files with 410 additions and 252 deletions
  1. +13
    -3
      format.sh
  2. +1
    -2
      logic/GameClass/GameObj/Bullet.cs
  3. +0
    -1
      logic/GameClass/GameObj/Character/Character.BuffManager.cs
  4. +16
    -0
      logic/GameClass/GameObj/Character/Character.SkillManager.cs
  5. +61
    -18
      logic/GameClass/GameObj/Character/Character.cs
  6. +1
    -10
      logic/GameClass/GameObj/GameObj.cs
  7. +0
    -1
      logic/GameClass/GameObj/Map/BirthPoint.cs
  8. +40
    -0
      logic/GameClass/GameObj/Map/Doorway.cs
  9. +28
    -0
      logic/GameClass/GameObj/Map/EmergencyExit.cs
  10. +24
    -1
      logic/GameClass/GameObj/Map/Generator.cs
  11. +58
    -20
      logic/GameClass/GameObj/Map/Map.cs
  12. +0
    -7
      logic/GameClass/GameObj/Map/MapInfo.cs
  13. +0
    -1
      logic/GameClass/GameObj/Map/Wall.cs
  14. +5
    -15
      logic/GameClass/GameObj/Prop.cs
  15. +0
    -1
      logic/GameClass/Skill/CommonSkill.cs
  16. +0
    -1
      logic/GameClass/Skill/PassiveSkill.cs
  17. +0
    -1
      logic/GameEngine/MoveEngine.cs
  18. +66
    -52
      logic/Gaming/ActionManager.cs
  19. +22
    -23
      logic/Gaming/AttackManager.cs
  20. +19
    -24
      logic/Gaming/Game.cs
  21. +24
    -31
      logic/Gaming/PropManager.cs
  22. +2
    -2
      logic/Preparation/Interface/IMap.cs
  23. +1
    -1
      logic/Preparation/Preparation.csproj
  24. +17
    -25
      logic/Preparation/Utility/EnumType.cs
  25. +12
    -12
      logic/Preparation/Utility/GameData.cs

+ 13
- 3
format.sh View File

@@ -1,7 +1,10 @@
for i in {1..10}
SHELL_FOLDER=$(dirname $(readlink -f "$0"))
cd $SHELL_FOLDER
cd ../..

for i in {1..3}
do
find . -iname "*.cs" \
-or -iname "*.c" \
find . -iname "*.c" \
-or -iname "*.h" \
-or -iname "*.C" \
-or -iname "*.H" \
@@ -19,3 +22,10 @@ find . -iname "*.cs" \
-or -iname "*.i++" \
| xargs clang-format -i
done

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

echo "Done!"

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

@@ -1,5 +1,4 @@
using Preparation.GameData;
using Preparation.Interface;
using Preparation.Interface;
using Preparation.Utility;
using System;



+ 0
- 1
logic/GameClass/GameObj/Character/Character.BuffManager.cs View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;
using Preparation.Utility;
using Preparation.GameData;

namespace GameClass.GameObj
{


+ 16
- 0
logic/GameClass/GameObj/Character/Character.SkillManager.cs View File

@@ -36,6 +36,22 @@ namespace GameClass.GameObj
passiveSkill(this);
return;
}

public bool IsGhost()
{
return this.characterType switch
{
CharacterType.Vampire => true,
CharacterType.Null => false,
CharacterType.RecoverAfterBattle => false,
CharacterType.SpeedUpWhenLeavingGrass => false,
CharacterType.PSkill3 => false,
CharacterType.PSkill4 => false,
CharacterType.PSkill5 => false,
_ => false,
};
}

public Character(XY initPos, int initRadius, PlaceType initPlace, CharacterType characterType, ActiveSkillType commonSkillType) :
base(initPos, initRadius, initPlace, GameObjType.Character)
{


+ 61
- 18
logic/GameClass/GameObj/Character/Character.cs View File

@@ -1,8 +1,8 @@
using Preparation.GameData;
using Preparation.Interface;
using Preparation.Interface;
using Preparation.Utility;
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using System.Threading;

namespace GameClass.GameObj
@@ -31,6 +31,27 @@ namespace GameClass.GameObj
}
}
public int OrgCD { get; protected set; }

protected int fixSpeed;
/// <summary>
/// 修理电机速度
/// </summary>
public int FixSpeed
{
get => fixSpeed;
set
{
lock (gameObjLock)
{
fixSpeed = value;
}
}
}
/// <summary>
/// 原初修理电机速度
/// </summary>
public int OrgFixSpeed { get; protected set; }

protected int maxBulletNum;
public int MaxBulletNum => maxBulletNum; // 人物最大子弹数
protected int bulletNum;
@@ -47,8 +68,21 @@ namespace GameClass.GameObj
hp = value <= MaxHp ? value : MaxHp;
}
}
private int deathCount = 0;
public int DeathCount => deathCount; // 玩家的死亡次数

private bool isEscaped=false;
public bool IsEscaped
{
get => isEscaped;
set
{
lock (gameObjLock)
if(!isEscaped&&!IsGhost())
isEscaped = value;
}
}

// private int deathCount = 0;
// public int DeathCount => deathCount; // 玩家的死亡次数

private int score = 0;
public int Score
@@ -249,7 +283,7 @@ namespace GameClass.GameObj
}
return false;
}
/// <summary>
/* /// <summary>
/// 增加死亡次数
/// </summary>
/// <returns>当前死亡次数</returns>
@@ -260,7 +294,7 @@ namespace GameClass.GameObj
++deathCount;
return deathCount;
}
}
}*/
/// <summary>
/// 加分
/// </summary>
@@ -378,7 +412,7 @@ namespace GameClass.GameObj
/// <summary>
/// 角色携带的信息
/// </summary>
private string message = "THUAI5";
private string message = "THUAI6";
public string Message
{
get => message;
@@ -447,18 +481,27 @@ namespace GameClass.GameObj
#endregion
public override void Reset() // 要加锁吗?
{
_ = AddDeathCount();
base.Reset();
this.MoveSpeed = OrgMoveSpeed;
HP = MaxHp;
PropInventory = null;
BulletOfPlayer = OriBulletOfPlayer;
lock (gameObjLock)
bulletNum = maxBulletNum;
lock (gameObjLock)
{
// _ = AddDeathCount();
base.Reset();
this.MoveSpeed = OrgMoveSpeed;
HP = MaxHp;
PropInventory = null;
BulletOfPlayer = OriBulletOfPlayer;
lock (gameObjLock)
bulletNum = maxBulletNum;

buffManeger.ClearAll();
IsInvisible = false;
this.Vampire = this.OriVampire;
}
}

buffManeger.ClearAll();
IsInvisible = false;
this.Vampire = this.OriVampire;
public void Escape()
{
lock (gameObjLock)
IsResetting=IsEscaped=true;
}
public override bool IsRigid => true;
public override ShapeType Shape => ShapeType.Circle;


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

@@ -123,16 +123,7 @@ namespace GameClass.GameObj
/// <summary>
/// 原初移动速度
/// </summary>
private int orgMoveSpeed;
public int OrgMoveSpeed
{
get => orgMoveSpeed;
protected
set
{
orgMoveSpeed = value;
}
}
public int OrgMoveSpeed{ get; protected set; }

// 移动,改变坐标
public long Move(XY moveVec)


+ 0
- 1
logic/GameClass/GameObj/Map/BirthPoint.cs View File

@@ -1,6 +1,5 @@
using Preparation.Interface;
using Preparation.Utility;
using Preparation.GameData;

namespace GameClass.GameObj
{


+ 40
- 0
logic/GameClass/GameObj/Map/Doorway.cs View File

@@ -0,0 +1,40 @@
using Preparation.Interface;
using Preparation.Utility;

namespace GameClass.GameObj
{
/// <summary>
/// 出口
/// </summary>
public class Doorway : GameObj
{
public Doorway(XY initPos) :
base(initPos, GameData.numOfPosGridPerCell / 2, PlaceType.Land, GameObjType.Doorway)
{
this.CanMove = false;
}
public override bool IsRigid => true;
public override ShapeType Shape => ShapeType.Square;
protected override bool IgnoreCollideExecutor(IGameObj targetObj)
{
if (targetObj.Type != GameObjType.Character)
return true; // 非玩家不碰撞
else if (!((Character)targetObj).IsGhost())
return true; // 不是鬼不碰撞
return false;
}

private bool powerSupply = false;
public bool PowerSupply
{
get => powerSupply;
set
{
lock (gameObjLock)
powerSupply = value;
}
}

public bool IsOpen => powerSupply;
}
}

+ 28
- 0
logic/GameClass/GameObj/Map/EmergencyExit.cs View File

@@ -0,0 +1,28 @@
using Preparation.Interface;
using Preparation.Utility;

namespace GameClass.GameObj
{
/// <summary>
/// 紧急出口
/// </summary>
public class EmergencyExit : GameObj
{
public EmergencyExit(XY initPos) :
base(initPos, GameData.numOfPosGridPerCell / 2, PlaceType.Land, GameObjType.EmergencyExit)
{
this.CanMove = false;
}
public override bool IsRigid => true;
public override ShapeType Shape => ShapeType.Square;

protected override bool IgnoreCollideExecutor(IGameObj targetObj)
{
if (targetObj.Type != GameObjType.Character)
return true; // 非玩家不碰撞
else if (!((Character)targetObj).IsGhost())
return true; // 不是鬼不碰撞
return false;
}
}
}

+ 24
- 1
logic/GameClass/GameObj/Map/Generator.cs View File

@@ -1,5 +1,4 @@
using Preparation.Utility;
using Preparation.GameData;

namespace GameClass.GameObj
{
@@ -15,5 +14,29 @@ namespace GameClass.GameObj
}
public override bool IsRigid => true;
public override ShapeType Shape => ShapeType.Square;

private int degreeOfFRepair = 0;
public int DegreeOfFRepair
{
get => degreeOfFRepair;
set
{
lock (gameObjLock)
{
if(degreeOfFRepair<GameData.degreeOfFixedGenerator)//不允许正常破坏已经修好的发电机
if (value < 0) degreeOfFRepair = 0;
else degreeOfFRepair =value>GameData.degreeOfFixedGenerator ? GameData.degreeOfFixedGenerator : value;
}
}
}

public bool Repair(int addDegree)
{
if (DegreeOfFRepair==GameData.degreeOfFixedGenerator) return false;
DegreeOfFRepair+=addDegree;
if (DegreeOfFRepair==GameData.degreeOfFixedGenerator)
return true;
else return false;
}
}
}

+ 58
- 20
logic/GameClass/GameObj/Map/Map.cs View File

@@ -2,7 +2,6 @@
using System.Threading;
using Preparation.Interface;
using Preparation.Utility;
using Preparation.GameData;
using System;

namespace GameClass.GameObj
@@ -13,10 +12,10 @@ namespace GameClass.GameObj
private readonly Dictionary<uint, BirthPoint> birthPointList; // 出生点列表
public Dictionary<uint, BirthPoint> BirthPointList => birthPointList;

private Dictionary<GameObjIdx, IList<IGameObj>> gameObjDict;
public Dictionary<GameObjIdx, IList<IGameObj>> GameObjDict => gameObjDict;
private Dictionary<GameObjIdx, ReaderWriterLockSlim> gameObjLockDict;
public Dictionary<GameObjIdx, ReaderWriterLockSlim> GameObjLockDict => gameObjLockDict;
private Dictionary<GameObjType, IList<IGameObj>> gameObjDict;
public Dictionary<GameObjType, IList<IGameObj>> GameObjDict => gameObjDict;
private Dictionary<GameObjType, ReaderWriterLockSlim> gameObjLockDict;
public Dictionary<GameObjType, ReaderWriterLockSlim> GameObjLockDict => gameObjLockDict;

public readonly uint[,] ProtoGameMap;
public PlaceType GetPlaceType(GameObj obj)
@@ -73,10 +72,10 @@ namespace GameClass.GameObj
public Character? FindPlayer(long playerID)
{
Character? player = null;
gameObjLockDict[GameObjIdx.Player].EnterReadLock();
gameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character person in gameObjDict[GameObjIdx.Player])
foreach (Character person in gameObjDict[GameObjType.Character])
{
if (playerID == person.ID)
{
@@ -87,17 +86,17 @@ namespace GameClass.GameObj
}
finally
{
gameObjLockDict[GameObjIdx.Player].ExitReadLock();
gameObjLockDict[GameObjType.Character].ExitReadLock();
}
return player;
}
public Map(uint[,] mapResource)
{
gameObjDict = new Dictionary<GameObjIdx, IList<IGameObj>>();
gameObjLockDict = new Dictionary<GameObjIdx, ReaderWriterLockSlim>();
foreach (GameObjIdx idx in Enum.GetValues(typeof(GameObjIdx)))
gameObjDict = new Dictionary<GameObjType, IList<IGameObj>>();
gameObjLockDict = new Dictionary<GameObjType, ReaderWriterLockSlim>();
foreach (GameObjType idx in Enum.GetValues(typeof(GameObjType)))
{
if (idx != GameObjIdx.None)
if (idx != GameObjType.Null)
{
gameObjDict.Add(idx, new List<IGameObj>());
gameObjLockDict.Add(idx, new ReaderWriterLockSlim());
@@ -109,7 +108,6 @@ namespace GameClass.GameObj

birthPointList = new Dictionary<uint, BirthPoint>(GameData.numOfBirthPoint);

// 将出生点插入
for (int i = 0; i < GameData.rows; ++i)
{
for (int j = 0; j < GameData.cols; ++j)
@@ -118,14 +116,54 @@ namespace GameClass.GameObj
{
case (uint)MapInfoObjType.Wall:
{
GameObjLockDict[GameObjIdx.Map].EnterWriteLock();
GameObjLockDict[GameObjType.Wall].EnterWriteLock();
try
{
GameObjDict[GameObjIdx.Map].Add(new Wall(GameData.GetCellCenterPos(i, j)));
GameObjDict[GameObjType.Wall].Add(new Wall(GameData.GetCellCenterPos(i, j)));
}
finally
{
GameObjLockDict[GameObjIdx.Map].ExitWriteLock();
GameObjLockDict[GameObjType.Wall].ExitWriteLock();
}
break;
}
case (uint)MapInfoObjType.Doorway:
{
GameObjLockDict[GameObjType.Doorway].EnterWriteLock();
try
{
GameObjDict[GameObjType.Doorway].Add(new Doorway(GameData.GetCellCenterPos(i, j)));
}
finally
{
GameObjLockDict[GameObjType.Doorway].ExitWriteLock();
}
break;
}

case (uint)MapInfoObjType.EmergencyExit:
{
GameObjLockDict[GameObjType.EmergencyExit].EnterWriteLock();
try
{
GameObjDict[GameObjType.EmergencyExit].Add(new EmergencyExit(GameData.GetCellCenterPos(i, j)));
}
finally
{
GameObjLockDict[GameObjType.EmergencyExit].ExitWriteLock();
}
break;
}
case (uint)MapInfoObjType.Generator:
{
GameObjLockDict[GameObjType.Generator].EnterWriteLock();
try
{
GameObjDict[GameObjType.Generator].Add(new Generator(GameData.GetCellCenterPos(i, j)));
}
finally
{
GameObjLockDict[GameObjType.Generator].ExitWriteLock();
}
break;
}
@@ -136,15 +174,15 @@ namespace GameClass.GameObj
case (uint)MapInfoObjType.BirthPoint5:
{
BirthPoint newBirthPoint = new BirthPoint(GameData.GetCellCenterPos(i, j));
birthPointList.Add(MapInfo.BirthPointEnumToIdx((MapInfoObjType)mapResource[i, j]), newBirthPoint);
GameObjLockDict[GameObjIdx.Map].EnterWriteLock();
birthPointList.Add(mapResource[i, j], newBirthPoint);
GameObjLockDict[GameObjType.BirthPoint].EnterWriteLock();
try
{
GameObjDict[GameObjIdx.Map].Add(newBirthPoint);
GameObjDict[GameObjType.BirthPoint].Add(newBirthPoint);
}
finally
{
GameObjLockDict[GameObjIdx.Map].ExitWriteLock();
GameObjLockDict[GameObjType.BirthPoint].ExitWriteLock();
}
break;
}


+ 0
- 7
logic/GameClass/GameObj/Map/MapInfo.cs View File

@@ -11,15 +11,8 @@ namespace GameClass.GameObj
/// <param name="obj"></param>
/// <returns></returns>

public static uint BirthPointEnumToIdx(MapInfoObjType birthPointEnum)
{
uint tmp = (uint)birthPointEnum;
// if (tmp < 5 || tmp > 12) throw new Exception("The parameter of BirthPointEnumToIdx is not a valid birth point enumeration value!");
return tmp - 5;
}
/// <summary>
/// 50*50
/// 1:Wall; 2:Grass1; 3:Grass2 ; 4:Grass3 ; 5~12:BirthPoint ; 13:GemWell
/// </summary>
public static uint[,] defaultMap = new uint[,] {
{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },


+ 0
- 1
logic/GameClass/GameObj/Map/Wall.cs View File

@@ -1,5 +1,4 @@
using Preparation.Utility;
using Preparation.GameData;

namespace GameClass.GameObj
{


+ 5
- 15
logic/GameClass/GameObj/Prop.cs View File

@@ -1,6 +1,5 @@
using Preparation.Interface;
using Preparation.Utility;
using Preparation.GameData;

namespace GameClass.GameObj
{
@@ -33,16 +32,7 @@ namespace GameClass.GameObj
this.Position = pos;
}
}
/// <summary>
/// 增益道具
/// </summary>
public abstract class BuffProp : Prop
{
public BuffProp(XY initPos) :
base(initPos)
{
}
}

///// <summary>
///// 坑人地雷
///// </summary>
@@ -54,7 +44,7 @@ namespace GameClass.GameObj
/// <summary>
/// 增加速度
/// </summary>
public sealed class AddSpeed : BuffProp
public sealed class AddSpeed : Prop
{
public AddSpeed(XY initPos) :
base(initPos)
@@ -65,7 +55,7 @@ namespace GameClass.GameObj
/// <summary>
/// 复活甲
/// </summary>
public sealed class AddLIFE : BuffProp
public sealed class AddLIFE : Prop
{
public AddLIFE(XY initPos) :
base(initPos)
@@ -76,7 +66,7 @@ namespace GameClass.GameObj
/// <summary>
/// 护盾
/// </summary>
public sealed class Shield : BuffProp
public sealed class Shield : Prop
{
public Shield(XY initPos) :
base(initPos)
@@ -87,7 +77,7 @@ namespace GameClass.GameObj
/// <summary>
/// 矛
/// </summary>
public sealed class Spear : BuffProp
public sealed class Spear : Prop
{
public Spear(XY initPos) :
base(initPos)


+ 0
- 1
logic/GameClass/Skill/CommonSkill.cs View File

@@ -2,7 +2,6 @@
using System.Threading;
using Preparation.Interface;
using Preparation.Utility;
using Preparation.GameData;
using System;
using Timothy.FrameRateTask;



+ 0
- 1
logic/GameClass/Skill/PassiveSkill.cs View File

@@ -1,7 +1,6 @@
using System;
using System.Threading;
using GameClass.GameObj;
using Preparation.GameData;
using Preparation.Interface;
using Preparation.Utility;
using Timothy.FrameRateTask;


+ 0
- 1
logic/GameEngine/MoveEngine.cs View File

@@ -3,7 +3,6 @@ using System.Threading;
using Preparation.Interface;
using Preparation.Utility;
using Timothy.FrameRateTask;
using Preparation.GameData;

namespace GameEngine
{


+ 66
- 52
logic/Gaming/ActionManager.cs View File

@@ -1,7 +1,7 @@
using System;
using System.Runtime.InteropServices;
using GameClass.GameObj;
using GameEngine;
using Preparation.GameData;
using Preparation.Utility;

namespace Gaming
@@ -18,90 +18,104 @@ namespace Gaming
moveEngine.MoveObj(playerToMove, moveTimeInMilliseconds, moveDirection);
}

public bool Fix(Character player, Generator? generator = null)
public bool TryToFix(Character player)// 自动检查有无发电机可修
{
if (player.IsResetting)
if (player.IsResetting||player.IsGhost())
return false;
Generator? generatorForFix = null;


Prop? pickProp = null;
if (propType == PropType.Null) // 自动检查有无道具可捡
{
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock();
gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock();
try
{
foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop])
foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator])
{
if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false)
if (GameData.IsInTheSameCell(generator.Position, player.Position))
{
pickProp = prop;
generatorForFix = generator;
break;
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock();
gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock();
}
}
else

if (generatorForFix != null)
{
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock();
gameMap.GameObjLockDict[GameObjType.Generator].EnterReadLock();
try
{
foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop])
{
if (prop.GetPropType() == propType)
if (generatorForFix.Repair(player.FixSpeed))
{
Doorway exit = (Doorway)gameMap.GameObjDict[GameObjType.Doorway][1];
if (!exit.PowerSupply)
{
if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false)
int numOfFixedGenerator = 0;
foreach (Generator generator in gameMap.GameObjDict[GameObjType.Generator])
if (generator.DegreeOfFRepair==GameData.degreeOfFixedGenerator)
++numOfFixedGenerator;
if(numOfFixedGenerator>=GameData.numOfGeneratorRequiredForRepair)
{
pickProp = prop;
gameMap.GameObjLockDict[GameObjType.Doorway].EnterWriteLock();
try
{
foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway])
doorway.PowerSupply=true;
}
finally
{
gameMap.GameObjLockDict[GameObjType.Doorway].ExitWriteLock();
}
}
}
}
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock();
gameMap.GameObjLockDict[GameObjType.Generator].ExitReadLock();
}
return true;
}
else
return false;
}

public bool TryToEscape(Character player)
{
if (player.IsResetting||player.IsGhost())
return false;
Doorway? doorwayForEscape = null;

if (pickProp != null)

gameMap.GameObjLockDict[GameObjType.Doorway].EnterReadLock();
try
{
// pickProp.CanMove = false;
Prop? dropProp = null;
if (player.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地
{
dropProp = player.PropInventory;
dropProp.SetNewPos(GameData.GetCellCenterPos(player.Position.x / GameData.numOfPosGridPerCell, player.Position.y / GameData.numOfPosGridPerCell));
}
player.PropInventory = pickProp;
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
try
foreach (Doorway doorway in gameMap.GameObjDict[GameObjType.Doorway])
{
gameMap.GameObjDict[GameObjIdx.Prop].Remove(pickProp);
if (dropProp != null)
gameMap.GameObjDict[GameObjIdx.Prop].Add(dropProp);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
}
gameMap.GameObjLockDict[GameObjIdx.PickedProp].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.PickedProp].Add(new PickedProp(pickProp));
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.PickedProp].ExitWriteLock();
if (GameData.IsInTheSameCell(doorway.Position, player.Position))
{
doorwayForEscape = doorway;
break;
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjType.Doorway].ExitReadLock();
}


if (doorwayForEscape != null&& doorwayForEscape.IsOpen)
{
player.Escape();
return true;
}
else
return false;
}

/*
private void ActivateMine(Character player, Mine mine)
{
@@ -125,11 +139,11 @@ namespace Gaming
}
*/

// private readonly Map gameMap;
private readonly Map gameMap;
private readonly MoveEngine moveEngine;
public ActionManager(Map gameMap)
{
// this.gameMap = gameMap;
this.gameMap = gameMap;
this.moveEngine = new MoveEngine(
gameMap: gameMap,
OnCollision: (obj, collisionObj, moveVec) =>


+ 22
- 23
logic/Gaming/AttackManager.cs View File

@@ -2,7 +2,6 @@
using System.Threading;
using System.Collections.Generic;
using GameClass.GameObj;
using Preparation.GameData;
using Preparation.Utility;
using GameEngine;

@@ -41,14 +40,14 @@ namespace Gaming
{
playerBeingShot.CanMove = false;
playerBeingShot.IsResetting = true;
// gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
// gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
// try
//{
// gameMap.GameObjDict[GameObjIdx.Player].Remove(playerBeingShot);
// gameMap.GameObjDict[GameObjType.Character].Remove(playerBeingShot);
// }
// finally
//{
// gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
// gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
// }

Prop? dropProp = null;
@@ -57,15 +56,15 @@ namespace Gaming
dropProp = playerBeingShot.PropInventory;
dropProp.SetNewPos(GameData.GetCellCenterPos(playerBeingShot.Position.x / GameData.numOfPosGridPerCell, playerBeingShot.Position.y / GameData.numOfPosGridPerCell));
}
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock();
try
{
if (dropProp != null)
gameMap.GameObjDict[GameObjIdx.Prop].Add(dropProp);
gameMap.GameObjDict[GameObjType.Prop].Add(dropProp);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock();
}

playerBeingShot.Reset();
@@ -79,12 +78,12 @@ namespace Gaming

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

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

if (gameMap.Timer.IsGaming)
{
@@ -102,30 +101,30 @@ namespace Gaming
Debugger.Output(bullet, "bombed!");
#endif
bullet.CanMove = false;
gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Bullet].EnterWriteLock();
try
{
foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjIdx.Bullet])
foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjType.Bullet])
{
if (_bullet.ID == bullet.ID)
{
gameMap.GameObjLockDict[GameObjIdx.BombedBullet].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.BombedBullet].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.BombedBullet].Add(new BombedBullet(bullet));
gameMap.GameObjDict[GameObjType.BombedBullet].Add(new BombedBullet(bullet));
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.BombedBullet].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.BombedBullet].ExitWriteLock();
}
gameMap.GameObjDict[GameObjIdx.Bullet].Remove(_bullet);
gameMap.GameObjDict[GameObjType.Bullet].Remove(_bullet);
break;
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock();
}

/*if (objBeingShot != null)
@@ -138,10 +137,10 @@ namespace Gaming

// 子弹爆炸会发生的事↓↓↓
var beAttackedList = new List<Character>();
gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock();
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
{
if (bullet.CanAttack(player))
{
@@ -153,7 +152,7 @@ namespace Gaming
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock();
gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
}

foreach (Character beAttackedPlayer in beAttackedList)
@@ -184,14 +183,14 @@ namespace Gaming
if (bullet != null)
{
bullet.CanMove = true;
gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Bullet].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.Bullet].Add(bullet);
gameMap.GameObjDict[GameObjType.Bullet].Add(bullet);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Bullet].ExitWriteLock();
}
moveEngine.MoveObj(bullet, (int)((player.AttackRange - player.Radius - BulletFactory.BulletRadius(player.BulletOfPlayer)) * 1000 / bullet.MoveSpeed), angle); // 这里时间参数除出来的单位要是ms
#if DEBUG


+ 19
- 24
logic/Gaming/Game.cs View File

@@ -3,7 +3,6 @@ using System.Threading;
using System.Collections.Generic;
using GameClass.GameObj;
using Preparation.Utility;
using Preparation.GameData;
using Timothy.FrameRateTask;
using Preparation.Interface;

@@ -44,16 +43,16 @@ namespace Gaming
// Console.WriteLine($"x,y: {pos.x},{pos.y}");
Character newPlayer = new(pos, GameData.characterRadius, gameMap.GetPlaceType(pos), playerInitInfo.characterType, playerInitInfo.commonSkill);
gameMap.BirthPointList[playerInitInfo.birthPointIndex].Parent = newPlayer;
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.Player].Add(newPlayer);
gameMap.GameObjDict[GameObjType.Character].Add(newPlayer);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
}
// Console.WriteLine($"GameObjDict[GameObjIdx.Player] length:{gameMap.GameObjDict[GameObjIdx.Player].Count}");
// Console.WriteLine($"GameObjDict[GameObjType.Character] length:{gameMap.GameObjDict[GameObjType.Character].Count}");
teamList[(int)playerInitInfo.teamID].AddPlayer(newPlayer);
newPlayer.TeamID = playerInitInfo.teamID;
newPlayer.PlayerID = playerInitInfo.playerID;
@@ -103,10 +102,10 @@ namespace Gaming
{
if (gameMap.Timer.IsGaming)
return false;
gameMap.GameObjLockDict[GameObjIdx.Player].EnterReadLock();
gameMap.GameObjLockDict[GameObjType.Character].EnterReadLock();
try
{
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
{
player.CanMove = true;

@@ -115,7 +114,7 @@ namespace Gaming
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Player].ExitReadLock();
gameMap.GameObjLockDict[GameObjType.Character].ExitReadLock();
}

propManager.StartProducing();
@@ -130,7 +129,7 @@ namespace Gaming
{
foreach (var kvp in gameMap.GameObjDict) // 检查物体位置
{
if (kvp.Key == GameObjIdx.Bullet || kvp.Key == GameObjIdx.Player || kvp.Key == GameObjIdx.Prop)
if (kvp.Key == GameObjType.Bullet || kvp.Key == GameObjType.Character || kvp.Key == GameObjType.Prop)
{
gameMap.GameObjLockDict[kvp.Key].EnterWriteLock();
try
@@ -167,14 +166,14 @@ namespace Gaming

public void EndGame()
{
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
/*try
{
}
finally
{
}*/
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
}
public void MovePlayer(long playerID, int moveTimeInMilliseconds, double angle)
{
@@ -183,11 +182,7 @@ namespace Gaming
Character? player = gameMap.FindPlayer(playerID);
if (player != null)
{
<<<<<<< HEAD
actionManager.MovePlayer(player, moveTimeInMilliseconds, angle);
=======
moveManager.MovePlayer(player, moveTimeInMilliseconds, angle);
>>>>>>> bad3c7b1c2a9453f59ea260079904624c3df6fb1
#if DEBUG
Console.WriteLine($"PlayerID:{playerID} move to ({player.Position.x},{player.Position.y})!");
#endif
@@ -258,25 +253,25 @@ namespace Gaming
{
if (!gameMap.Timer.IsGaming)
return;
gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Character].EnterWriteLock();
try
{
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
{
skillManager.UsePassiveSkill(player);
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Character].ExitWriteLock();
}
}

public void ClearLists(GameObjIdx[] objIdxes)
public void ClearLists(GameObjType[] objIdxes)
{
foreach (var idx in objIdxes)
{
if (idx != GameObjIdx.None)
if (idx != GameObjType.Null)
{
gameMap.GameObjLockDict[idx].EnterWriteLock();
try
@@ -294,14 +289,14 @@ namespace Gaming
{
foreach (var keyValuePair in gameMap.GameObjDict)
{
if (keyValuePair.Key != GameObjIdx.Map)
if (((uint)keyValuePair.Key) <= GameData.numOfObjNotMap)
{
gameMap.GameObjLockDict[keyValuePair.Key].EnterWriteLock();
try
{
if (keyValuePair.Key == GameObjIdx.Player)
if (keyValuePair.Key == GameObjType.Character)
{
foreach (Character player in gameMap.GameObjDict[GameObjIdx.Player])
foreach (Character player in gameMap.GameObjDict[GameObjType.Character])
{
player.CanMove = false;
}
@@ -325,7 +320,7 @@ namespace Gaming
var gameObjList = new List<IGameObj>();
foreach (var keyValuePair in gameMap.GameObjDict)
{
if (keyValuePair.Key != GameObjIdx.Map)
if (((uint)keyValuePair.Key) <= GameData.numOfObjNotMap)
{
gameMap.GameObjLockDict[keyValuePair.Key].EnterReadLock();
try


+ 24
- 31
logic/Gaming/PropManager.cs View File

@@ -1,7 +1,6 @@
using System.Collections.Generic;
using GameClass.GameObj;
using System.Threading;
using Preparation.GameData;
using Preparation.Utility;
using System;
using Timothy.FrameRateTask;
@@ -66,10 +65,10 @@ namespace Gaming
Prop? pickProp = null;
if (propType == PropType.Null) // 自动检查有无道具可捡
{
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock();
gameMap.GameObjLockDict[GameObjType.Prop].EnterReadLock();
try
{
foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop])
foreach (Prop prop in gameMap.GameObjDict[GameObjType.Prop])
{
if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false)
{
@@ -79,15 +78,15 @@ namespace Gaming
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock();
gameMap.GameObjLockDict[GameObjType.Prop].ExitReadLock();
}
}
else
{
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock();
gameMap.GameObjLockDict[GameObjType.Prop].EnterReadLock();
try
{
foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop])
foreach (Prop prop in gameMap.GameObjDict[GameObjType.Prop])
{
if (prop.GetPropType() == propType)
{
@@ -100,7 +99,7 @@ namespace Gaming
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock();
gameMap.GameObjLockDict[GameObjType.Prop].ExitReadLock();
}
}

@@ -114,25 +113,25 @@ namespace Gaming
dropProp.SetNewPos(GameData.GetCellCenterPos(player.Position.x / GameData.numOfPosGridPerCell, player.Position.y / GameData.numOfPosGridPerCell));
}
player.PropInventory = pickProp;
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.Prop].Remove(pickProp);
gameMap.GameObjDict[GameObjType.Prop].Remove((Preparation.Interface.IGameObj)pickProp);
if (dropProp != null)
gameMap.GameObjDict[GameObjIdx.Prop].Add(dropProp);
gameMap.GameObjDict[GameObjType.Prop].Add((Preparation.Interface.IGameObj)dropProp);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock();
}
gameMap.GameObjLockDict[GameObjIdx.PickedProp].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.PickedProp].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.PickedProp].Add(new PickedProp(pickProp));
gameMap.GameObjDict[GameObjType.PickedProp].Add(new PickedProp(pickProp));
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.PickedProp].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.PickedProp].ExitWriteLock();
}

return true;
@@ -153,14 +152,14 @@ namespace Gaming

prop.CanMove = true;
prop.SetNewPos(player.Position);
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.Prop].Add(prop);
gameMap.GameObjDict[GameObjType.Prop].Add((Preparation.Interface.IGameObj)prop);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock();
}
timeInMilliseconds = timeInMilliseconds < GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000 ? timeInMilliseconds : GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000;
moveEngine.MoveObj(prop, timeInMilliseconds, angle);
@@ -182,22 +181,22 @@ namespace Gaming
int rand = r.Next(0, len);
XY randPos = availableCellForGenerateProp[rand];

gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].EnterWriteLock();
try
{
switch (r.Next(0, 4))
{
case 0:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddLIFE(randPos));
gameMap.GameObjDict[GameObjType.Prop].Add((Preparation.Interface.IGameObj)new AddLIFE(randPos));
break;
case 1:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new AddSpeed(randPos));
gameMap.GameObjDict[GameObjType.Prop].Add((Preparation.Interface.IGameObj)new AddSpeed(randPos));
break;
case 2:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new Shield(randPos));
gameMap.GameObjDict[GameObjType.Prop].Add((Preparation.Interface.IGameObj)new Shield(randPos));
break;
case 3:
gameMap.GameObjDict[GameObjIdx.Prop].Add(new Spear(randPos));
gameMap.GameObjDict[GameObjType.Prop].Add((Preparation.Interface.IGameObj)new Spear(randPos));
break;
default:
break;
@@ -205,7 +204,7 @@ namespace Gaming
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
gameMap.GameObjLockDict[GameObjType.Prop].ExitWriteLock();
}
},
GameData.PropProduceTime,
@@ -233,21 +232,15 @@ namespace Gaming
availableCellForGenerateProp = new List<XY>();
for (int i = 0; i < gameMap.ProtoGameMap.GetLength(0); i++)
{
<<<<<<< HEAD
for (int j = 0; j < gameMap.ProtoGameMap.GetLength(1); j++)
{
if (gameMap.ProtoGameMap[i, j] == (int)MapInfoObjType.Null)
=======
for (int j = 0; j < gameMap.ProtoGameMap.GetLength(1); j++)
>>>>>>> bad3c7b1c2a9453f59ea260079904624c3df6fb1
{
if (gameMap.ProtoGameMap[i, j] == (int)MapInfo.MapInfoObjType.Null)
{
availableCellForGenerateProp.Add(GameData.GetCellCenterPos(i, j));
}
availableCellForGenerateProp.Add(GameData.GetCellCenterPos(i, j));
}
}
}
}
}
}
}

+ 2
- 2
logic/Preparation/Interface/IMap.cs View File

@@ -9,8 +9,8 @@ namespace Preparation.Interface
ITimer Timer { get; }

// the two dicts must have same keys
Dictionary<GameObjIdx, IList<IGameObj>> GameObjDict { get; }
Dictionary<GameObjIdx, ReaderWriterLockSlim> GameObjLockDict { get; }
Dictionary<GameObjType, IList<IGameObj>> GameObjDict { get; }
Dictionary<GameObjType, ReaderWriterLockSlim> GameObjLockDict { get; }

public bool IsOutOfBound(IGameObj obj);
public IOutOfBound GetOutOfBound(XY pos); // 返回新建的一个OutOfBound对象


+ 1
- 1
logic/Preparation/Preparation.csproj View File

@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.NET.Sdk">
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<OutputType>Library</OutputType>


+ 17
- 25
logic/Preparation/Utility/EnumType.cs View File

@@ -4,6 +4,7 @@ namespace Preparation.Utility
/// <summary>
/// 存放所有用到的枚举类型
/// </summary>
// public const int numOfObjNotMap = 5;在GameData中
public enum GameObjType
{
Null = 0,
@@ -17,7 +18,7 @@ namespace Preparation.Utility
Grass = 7,
Generator = 8, // 发电机
BirthPoint = 9,
Exit = 10,
Doorway = 10,
EmergencyExit = 11,
OutOfBoundBlock = 12, // 范围外
}
@@ -80,30 +81,21 @@ namespace Preparation.Utility
Shield = 3,
Spear = 4
}
public enum GameObjIdx

public enum MapInfoObjType
{
None = 0,
Player = 1,
Bullet = 2,
Prop = 3,
Map = 4,
BombedBullet = 5,
PickedProp = 6
Null = 0,
BirthPoint1 = 1,//必须从1开始
BirthPoint2 = 2,
BirthPoint3 = 3,
BirthPoint4 = 4,
BirthPoint5 = 5,
Wall = 6,
Grass1 = 7,
Grass2 = 8,
Grass3 = 9,
Generator = 10, // 发电机
Doorway = 11,
EmergencyExit = 12
}
}
public enum MapInfoObjType
{
Null = 0,
Wall = 1,
Grass1 = 2,
Grass2 = 3,
Grass3 = 4,
Generator = 5, // 发电机
Exit = 6,
EmergencyExit = 7,
BirthPoint1 = 8,
BirthPoint2 = 9,
BirthPoint3 = 10,
BirthPoint4 = 11,
BirthPoint5 = 12,
}

logic/Preparation/GameData/GameData.cs → logic/Preparation/Utility/GameData.cs View File

@@ -1,6 +1,4 @@
using Preparation.Utility;

namespace Preparation.GameData
namespace Preparation.Utility
{
public static class GameData
{
@@ -16,9 +14,15 @@ namespace Preparation.GameData
public const int MinSpeed = 1; // 最小速度
public const int MaxSpeed = int.MaxValue; // 最大速度

public const int numOfBirthPoint = 5;
// public const int numOfGenerator = 7;
public const int numOfGeneratorRequiredForRepair = 5;

public const int numOfObjNotMap = 5;

public static XY GetCellCenterPos(int x, int y) // 求格子的中心坐标
{
XY ret = new((x * numOfPosGridPerCell) + (numOfPosGridPerCell / 2), (y * numOfPosGridPerCell) + (numOfPosGridPerCell / 2));
XY ret = new(x * numOfPosGridPerCell + numOfPosGridPerCell / 2, y * numOfPosGridPerCell + numOfPosGridPerCell / 2);
return ret;
}
public static int PosGridToCellX(XY pos) // 求坐标所在的格子的x坐标
@@ -33,13 +37,8 @@ namespace Preparation.GameData
{
return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2);
}

public static int numOfBirthPoint = 5;
#endregion
#region 角色相关
/// <summary>
/// 玩家相关
/// </summary>
public const int characterRadius = numOfPosGridPerCell / 2; // 人物半径
public const int basicAp = 3000; // 初始攻击力
public const int basicHp = 6000; // 初始血量
@@ -59,9 +58,8 @@ namespace Preparation.GameData
public const int reviveTime = 30000; // 复活时间
public const int shieldTimeAtBirth = 3000; // 复活时的护盾时间
public const int gemToScore = 4; // 一个宝石的标准加分
/// <summary>
/// 道具相关
/// </summary>
#endregion
#region 道具相关
public const int MinPropTypeNum = 1;
public const int MaxPropTypeNum = 10;
public const int PropRadius = numOfPosGridPerCell / 2;
@@ -71,6 +69,8 @@ namespace Preparation.GameData
public const long GemProduceTime = 10000;
public const long PropProduceTime = 10000;
public const int PropDuration = 10000;

public const int degreeOfFixedGenerator = 100;
#endregion
#region 游戏帧相关
public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长

Loading…
Cancel
Save