Browse Source

Merge branch 'eesast:dev' into dev

tags/0.1.0
DragonAura GitHub 3 years ago
parent
commit
08e99cdfa8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 434 additions and 0 deletions
  1. +77
    -0
      logic/Preparation/GameData/GameData.cs
  2. +11
    -0
      logic/Preparation/Interface/ICharacter.cs
  3. +20
    -0
      logic/Preparation/Interface/IGameObj.cs
  4. +18
    -0
      logic/Preparation/Interface/IMap.cs
  5. +37
    -0
      logic/Preparation/Interface/IMoveable.cs
  6. +9
    -0
      logic/Preparation/Interface/IObjOfCharacter.cs
  7. +9
    -0
      logic/Preparation/Interface/ITimer.cs
  8. +14
    -0
      logic/Preparation/Utility/Debugger.cs
  9. +96
    -0
      logic/Preparation/Utility/EnumType.cs
  10. +17
    -0
      logic/Preparation/Utility/MapEncoder.cs
  11. +20
    -0
      logic/Preparation/Utility/Tools.cs
  12. +57
    -0
      logic/Preparation/Utility/Vector.cs
  13. +49
    -0
      logic/Preparation/Utility/XYPosition.cs

+ 77
- 0
logic/Preparation/GameData/GameData.cs View File

@@ -0,0 +1,77 @@
using Preparation.Utility;

namespace Preparation.GameData
{
public static class GameData
{
#region 基本常数与常方法
public const int numOfPosGridPerCell = 1000; // 每格的【坐标单位】数
public const int numOfStepPerSecond = 20; // 每秒行走的步数
public const int lengthOfMap = 50000; // 地图长度
public const int rows = 50; // 行数
public const int cols = 50; // 列数
public const long gameDuration = 600000; // 游戏时长600000ms = 10min
public const long frameDuration = 50; // 每帧时长

public const int MinSpeed = 1; // 最小速度
public const int MaxSpeed = int.MaxValue; // 最大速度

public static XYPosition GetCellCenterPos(int x, int y) // 求格子的中心坐标
{
XYPosition ret = new((x * numOfPosGridPerCell) + (numOfPosGridPerCell / 2), (y * numOfPosGridPerCell) + (numOfPosGridPerCell / 2));
return ret;
}
public static int PosGridToCellX(XYPosition pos) // 求坐标所在的格子的x坐标
{
return pos.x / numOfPosGridPerCell;
}
public static int PosGridToCellY(XYPosition pos) // 求坐标所在的格子的y坐标
{
return pos.y / numOfPosGridPerCell;
}
public static bool IsInTheSameCell(XYPosition pos1, XYPosition pos2)
{
return PosGridToCellX(pos1) == PosGridToCellX(pos2) && PosGridToCellY(pos1) == PosGridToCellY(pos2);
}
#endregion
#region 角色相关
/// <summary>
/// 玩家相关
/// </summary>
public const int characterRadius = numOfPosGridPerCell / 2; // 人物半径
public const int basicAp = 3000; // 初始攻击力
public const int basicHp = 6000; // 初始血量
public const int basicCD = 3000; // 初始子弹冷却
public const int basicBulletNum = 3; // 基本初始子弹量
public const int MinAP = 0; // 最小攻击力
public const int MaxAP = int.MaxValue; // 最大攻击力
public const double basicAttackRange = 9000; // 基本攻击范围
public const double basicBulletBombRange = 3000; // 基本子弹爆炸范围
public const int basicMoveSpeed = 3000; // 基本移动速度,单位:s-1
public const int basicBulletMoveSpeed = 3000; // 基本子弹移动速度,单位:s-1
public const int characterMaxSpeed = 12000; // 最大速度
public const int addScoreWhenKillOneLevelPlayer = 30; // 击杀一级角色获得的加分
public const int commonSkillCD = 30000; // 普通技能标准冷却时间
public const int commonSkillTime = 10000; // 普通技能标准持续时间
public const int bulletRadius = 200; // 默认子弹半径
public const int reviveTime = 30000; // 复活时间
public const int shieldTimeAtBirth = 3000; // 复活时的护盾时间
public const int gemToScore = 4; // 一个宝石的标准加分
/// <summary>
/// 道具相关
/// </summary>
public const int MinPropTypeNum = 1;
public const int MaxPropTypeNum = 10;
public const int PropRadius = numOfPosGridPerCell / 2;
public const int PropMoveSpeed = 3000;
public const int PropMaxMoveDistance = 15 * numOfPosGridPerCell;
public const int MaxGemSize = 5; // 随机生成的宝石最大size
public const long GemProduceTime = 10000;
public const long PropProduceTime = 10000;
public const int PropDuration = 10000;
#endregion
#region 游戏帧相关
public const long checkInterval = 50; // 检查位置标志、补充子弹的帧时长
#endregion
}
}

+ 11
- 0
logic/Preparation/Interface/ICharacter.cs View File

@@ -0,0 +1,11 @@
using System;
using Preparation.Utility;

namespace Preparation.Interface
{
public interface ICharacter : IGameObj
{
public long TeamID { get; }
public int HP { get; set; }
}
}

+ 20
- 0
logic/Preparation/Interface/IGameObj.cs View File

@@ -0,0 +1,20 @@
using Preparation.Utility;

namespace Preparation.Interface
{
public interface IGameObj
{
public GameObjType Type { get; set; }
public long ID { get; }
public XYPosition Position { get; } // if Square, Pos equals the center
public double FacingDirection { get; }
public bool IsRigid { get; }
public ShapeType Shape { get; }
public bool CanMove { get; set; }
public bool IsMoving { get; set; }
public bool IsResetting { get; set; } // reviving
public bool IsAvailable { get; }
public int Radius { get; } // if Square, Radius equals half length of one side
public PlaceType Place { get; set; }
}
}

+ 18
- 0
logic/Preparation/Interface/IMap.cs View File

@@ -0,0 +1,18 @@
using System.Collections.Generic;
using System.Threading;
using Preparation.Utility;

namespace Preparation.Interface
{
public interface IMap
{
ITimer Timer { get; }

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

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

+ 37
- 0
logic/Preparation/Interface/IMoveable.cs View File

@@ -0,0 +1,37 @@
using System;
using Preparation.Utility;

namespace Preparation.Interface
{
public interface IMoveable : IGameObj
{
object MoveLock { get; }
public int MoveSpeed { get; }
public long Move(Vector moveVec);
protected bool IgnoreCollide(IGameObj targetObj); // 忽略碰撞,在具体类中实现
public bool WillCollideWith(IGameObj? targetObj, XYPosition nextPos) // 检查下一位置是否会和目标物碰撞
{
if (targetObj == null)
return false;
// 会移动的只有子弹和人物,都是Circle
if (!targetObj.IsRigid || targetObj.ID == ID)
return false;
if (IgnoreCollide(targetObj))
return false;
if (targetObj.Shape == ShapeType.Circle)
{
return XYPosition.Distance(nextPos, targetObj.Position) < targetObj.Radius + Radius;
}
else // Square
{
long deltaX = Math.Abs(nextPos.x - targetObj.Position.x), deltaY = Math.Abs(nextPos.y - targetObj.Position.y);
if (deltaX >= targetObj.Radius + Radius || deltaY >= targetObj.Radius + Radius)
return false;
if (deltaX < targetObj.Radius || deltaY < targetObj.Radius)
return true;
else
return ((long)(deltaX - targetObj.Radius) * (deltaX - targetObj.Radius)) + ((long)(deltaY - targetObj.Radius) * (deltaY - targetObj.Radius)) <= (long)Radius * (long)Radius;
}
}
}
}

+ 9
- 0
logic/Preparation/Interface/IObjOfCharacter.cs View File

@@ -0,0 +1,9 @@
using System;

namespace Preparation.Interface
{
public interface IObjOfCharacter : IGameObj
{
ICharacter? Parent { get; set; }
}
}

+ 9
- 0
logic/Preparation/Interface/ITimer.cs View File

@@ -0,0 +1,9 @@

namespace Preparation.Interface
{
public interface ITimer
{
bool IsGaming { get; }
public bool StartGame(int timeInMilliseconds);
}
}

+ 14
- 0
logic/Preparation/Utility/Debugger.cs View File

@@ -0,0 +1,14 @@
using System;

namespace Preparation.Utility
{
public class Debugger
{
static public void Output(object current, string str)
{
#if DEBUG
Console.WriteLine(current.GetType() + " " + current.ToString() + " " + str);
#endif
}
}
}

+ 96
- 0
logic/Preparation/Utility/EnumType.cs View File

@@ -0,0 +1,96 @@

namespace Preparation.Utility
{
/// <summary>
/// 存放所有用到的枚举类型
/// </summary>
public enum GameObjType
{
Null = 0,
Character = 1,
Prop = 2,
PickedProp = 3,
Bullet = 4,
BombedBullet = 5,

Wall = 6,
Grass = 7,
Generator = 8, // 发电机
BirthPoint = 9,
Exit = 10,
EmergencyExit = 11,
OutOfBoundBlock = 12, // 范围外
}
public enum ShapeType
{
Null = 0,
Circle = 1, // 子弹和人物为圆形,格子为方形
Square = 2
}
public enum PlaceType // 位置标志,包括陆地(一般默认为陆地,如墙体等),草丛。游戏中每一帧都要刷新各个物体的该属性
{
Null = 0,
Land = 1,
Grass1 = 2,
Grass2 = 3,
Grass3 = 4,
Grass4 = 5,
Grass5 = 6,
}
public enum BulletType // 子弹类型
{
Null = 0,
OrdinaryBullet = 1, // 普通子弹
AtomBomb = 2, // 原子弹
FastBullet = 3, // 快速子弹
LineBullet = 4 // 直线子弹
}
public enum PropType // 道具类型
{
Null = 0,
addSpeed = 1,
addLIFE = 2,
Shield = 3,
Spear = 4,
Gem = 5, // 新增:宝石
}
public enum PassiveSkillType // 被动技能
{
Null = 0,
RecoverAfterBattle = 1,
SpeedUpWhenLeavingGrass = 2,
Vampire = 3,
PSkill3 = 4,
PSkill4 = 5,
PSkill5 = 6
}
public enum ActiveSkillType // 主动技能
{
Null = 0,
BecomeVampire = 1,
BecomeAssassin = 2,
NuclearWeapon = 3,
SuperFast = 4,
ASkill4 = 5,
ASkill5 = 6
}
public enum BuffType // buff
{
Null = 0,
AddSpeed = 1,
AddLIFE = 2,
Shield = 3,
Spear = 4
}
public enum GameObjIdx
{
None = 0,
Player = 1,
Bullet = 2,
Prop = 3,
Gem = 4,
Map = 5,
BombedBullet = 6,
PickedProp = 7
}
}

+ 17
- 0
logic/Preparation/Utility/MapEncoder.cs View File

@@ -0,0 +1,17 @@
using System;

namespace Preparation.Utility
{
public class MapEncoder
{
static public char Dec2Hex(int d)
{
return char.Parse(d.ToString("X"));
}
static public int Hex2Dec(char h)
{
string hexabet = "0123456789ABCDEF";
return hexabet.IndexOf(h);
}
}
}

+ 20
- 0
logic/Preparation/Utility/Tools.cs View File

@@ -0,0 +1,20 @@
using System;

namespace Preparation.Utility
{
public static class Tools
{
public static double CorrectAngle(double angle) // 将幅角转化为主值0~2pi
{
if (double.IsNaN(angle) || double.IsInfinity(angle))
{
return 0.0;
}
while (angle < 0)
angle += 2 * Math.PI;
while (angle >= 2 * Math.PI)
angle -= 2 * Math.PI;
return angle;
}
}
}

+ 57
- 0
logic/Preparation/Utility/Vector.cs View File

@@ -0,0 +1,57 @@
using System;

namespace Preparation.Utility
{
public struct Vector
{
public double angle;
public double length;

public static XYPosition VectorToXY(Vector v)
{
return new XYPosition((int)(v.length * Math.Cos(v.angle)), (int)(v.length * Math.Sin(v.angle)));
}
public Vector2 ToVector2()
{
return new Vector2((int)(this.length * Math.Cos(this.angle)), (int)(this.length * Math.Sin(this.angle)));
}
public static Vector XYToVector(double x, double y)
{
return new Vector(Math.Atan2(y, x), Math.Sqrt((x * x) + (y * y)));
}
public Vector(double angle, double length)
{
if (length < 0)
{
angle += Math.PI;
length = -length;
}
this.angle = Tools.CorrectAngle(angle);
this.length = length;
}
}

public struct Vector2
{
public double x;
public double y;
public Vector2(double x, double y)
{
this.x = x;
this.y = y;
}

public static double operator*(Vector2 v1, Vector2 v2)
{
return (v1.x * v2.x) + (v1.y * v2.y);
}
public static Vector2 operator +(Vector2 v1, Vector2 v2)
{
return new Vector2(v1.x + v2.x, v1.y + v2.y);
}
public static Vector2 operator -(Vector2 v1, Vector2 v2)
{
return new Vector2(v1.x - v2.x, v1.y - v2.y);
}
}
}

+ 49
- 0
logic/Preparation/Utility/XYPosition.cs View File

@@ -0,0 +1,49 @@
using System;

namespace Preparation.Utility
{
public struct XYPosition
{
public int x;
public int y;
public XYPosition(int x, int y)
{
this.x = x;
this.y = y;
}
public override string ToString()
{
return "(" + x.ToString() + "," + y.ToString() + ")";
}
public static XYPosition operator +(XYPosition p1, XYPosition p2)
{
return new XYPosition(p1.x + p2.x, p1.y + p2.y);
}
public static XYPosition operator -(XYPosition p1, XYPosition p2)
{
return new XYPosition(p1.x - p2.x, p1.y - p2.y);
}
public static double Distance(XYPosition p1, XYPosition p2)
{
return Math.Sqrt(((long)(p1.x - p2.x) * (p1.x - p2.x)) + ((long)(p1.y - p2.y) * (p1.y - p2.y)));
}
/*public static XYPosition[] GetSquareRange(uint edgeLen) // 从THUAI4的BULLET.CS移植而来,不知还有用否
{
XYPosition[] range = new XYPosition[edgeLen * edgeLen];
int offset = (int)(edgeLen >> 1);
for (int i = 0; i < (int)edgeLen; ++i)
{
for (int j = 0; j < (int)edgeLen; ++j)
{
range[i * edgeLen + j].x = i - offset;
range[i * edgeLen + j].y = j - offset;
}
}
return range;
}*/
public Vector2 ToVector2()
{
return new Vector2(this.x, this.y);
}
}
}

Loading…
Cancel
Save