Browse Source

to solve conflict

tags/0.1.0
shangfengh 2 years ago
parent
commit
0029d4b9bb
2 changed files with 456 additions and 0 deletions
  1. +210
    -0
      logic/Gaming/AttackManager.cs
  2. +246
    -0
      logic/Gaming/PropManager.cs

+ 210
- 0
logic/Gaming/AttackManager.cs View File

@@ -0,0 +1,210 @@
using System;
using System.Threading;
using System.Collections.Generic;
using GameClass.GameObj;
using Preparation.GameData;
using Preparation.Utility;
using GameEngine;

namespace Gaming
{
public partial class Game
{
private readonly AttackManager attackManager;
private class AttackManager
{
readonly Map gameMap;
readonly MoveEngine moveEngine;
public AttackManager(Map gameMap)
{
this.gameMap = gameMap;
this.moveEngine = new MoveEngine(
gameMap: gameMap,
OnCollision: (obj, collisionObj, moveVec) =>
{
//BulletBomb((Bullet)obj, (GameObj)collisionObj);
return MoveEngine.AfterCollision.Destroyed; },
EndMove: obj =>
{
#if DEBUG
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64);

#endif
BulletBomb((Bullet)obj, null); }
);
}
private void BombOnePlayer(Bullet bullet, Character playerBeingShot)
{
if (playerBeingShot.BeAttack(bullet))
{
playerBeingShot.CanMove = false;
playerBeingShot.IsResetting = true;
// gameMap.GameObjLockDict[GameObjIdx.Player].EnterWriteLock();
// try
//{
// gameMap.GameObjDict[GameObjIdx.Player].Remove(playerBeingShot);
// }
// finally
//{
// gameMap.GameObjLockDict[GameObjIdx.Player].ExitWriteLock();
// }

Prop? dropProp = null;
if (playerBeingShot.PropInventory != null) // 若角色原来有道具,则原始道具掉落在原地
{
dropProp = playerBeingShot.PropInventory;
dropProp.SetNewPos(GameData.GetCellCenterPos(playerBeingShot.Position.x / GameData.numOfPosGridPerCell, playerBeingShot.Position.y / GameData.numOfPosGridPerCell));
}
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
try
{
if (dropProp != null)
gameMap.GameObjDict[GameObjIdx.Prop].Add(dropProp);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
}

playerBeingShot.Reset();
((Character?)bullet.Parent)?.AddScore(GameData.addScoreWhenKillOneLevelPlayer); // 给击杀者加分

new Thread
(() =>
{

Thread.Sleep(GameData.reviveTime);

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

// 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;
}
)
{ IsBackground = true }.Start();
}
}
private void BulletBomb(Bullet bullet, GameObj? objBeingShot)
{
#if DEBUG
Debugger.Output(bullet, "bombed!");
#endif
bullet.CanMove = false;
gameMap.GameObjLockDict[GameObjIdx.Bullet].EnterWriteLock();
try
{
foreach (ObjOfCharacter _bullet in gameMap.GameObjDict[GameObjIdx.Bullet])
{
if (_bullet.ID == bullet.ID)
{
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;
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Bullet].ExitWriteLock();
}

/*if (objBeingShot != null)
{
else if (objBeingShot is Bullet) //子弹不能相互引爆,若要更改这一设定,取消注释即可。
{
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();
}

foreach (Character beAttackedPlayer in beAttackedList)
{
BombOnePlayer(bullet, beAttackedPlayer);
}
beAttackedList.Clear();
}
public bool Attack(Character? player, double angle) // 射出去的子弹泼出去的水(狗头)
{ // 子弹如果没有和其他物体碰撞,将会一直向前直到超出人物的attackRange
if (player == null)
{
#if DEBUG
Console.WriteLine("the player who will attack is NULL!");
#endif
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 DEBUG
Console.WriteLine($"playerID:{player.ID} successfully attacked!");
#endif
return true;
}
else
{
#if DEBUG
Console.WriteLine($"playerID:{player.ID} has no bullets so that he can't attack!");
#endif
return false;
}
}
}
}
}

+ 246
- 0
logic/Gaming/PropManager.cs View File

@@ -0,0 +1,246 @@
using System.Collections.Generic;
using GameClass.GameObj;
using System.Threading;
using Preparation.GameData;
using Preparation.Utility;
using System;
using Timothy.FrameRateTask;
using GameEngine;

namespace Gaming
{
public partial class Game
{
private readonly PropManager propManager;
private class PropManager
{
private readonly Map gameMap;

private MoveEngine moveEngine;

private bool isProducingProp = false;

private readonly List<XY> availableCellForGenerateProp;
public void StartProducing()
{
if (isProducingProp)
return;
isProducingProp = true;
ProduceProp();
}

public void UseProp(Character player)
{
if (player.IsResetting)
return;
Prop? prop = player.UseProp();
switch (prop?.GetPropType())
{
case PropType.Spear:
player.AddSpear(GameData.PropDuration);
break;
case PropType.Shield:
player.AddShield(GameData.PropDuration);
break;
case PropType.addLIFE:
player.AddLIFE(GameData.PropDuration);
break;
case PropType.addSpeed:
player.AddMoveSpeed(GameData.PropDuration);
break;
default:
break;
}
}

/// <summary>
///
/// </summary>
/// <param name="player"></param>
/// <param name="propType">若不指定,则自动判断可捡起什么道具</param>
/// <returns></returns>
public bool PickProp(Character player, PropType propType = PropType.Null)
{
if (player.IsResetting)
return false;
Prop? pickProp = null;
if (propType == PropType.Null) // 自动检查有无道具可捡
{
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock();
try
{
foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop])
{
if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false)
{
pickProp = prop;
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock();
}
}
else
{
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterReadLock();
try
{
foreach (Prop prop in gameMap.GameObjDict[GameObjIdx.Prop])
{
if (prop.GetPropType() == propType)
{
if (GameData.IsInTheSameCell(prop.Position, player.Position) && prop.CanMove == false)
{
pickProp = prop;
}
}
}
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitReadLock();
}
}

if (pickProp != null)
{
// 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
{
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();
}

return true;
}
else
return false;
}

public void ThrowProp(Character player, int timeInMilliseconds, double angle)
{
if (!gameMap.Timer.IsGaming)
return;
if (player.IsResetting) // 移动中也能扔,但由于“惯性”,可能初始位置会有点变化
return;
Prop? prop = player.UseProp();
if (prop == null)
return;

prop.CanMove = true;
prop.SetNewPos(player.Position);
gameMap.GameObjLockDict[GameObjIdx.Prop].EnterWriteLock();
try
{
gameMap.GameObjDict[GameObjIdx.Prop].Add(prop);
}
finally
{
gameMap.GameObjLockDict[GameObjIdx.Prop].ExitWriteLock();
}
timeInMilliseconds = timeInMilliseconds < GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000 ? timeInMilliseconds : GameData.PropMaxMoveDistance / prop.MoveSpeed * 1000;
moveEngine.MoveObj(prop, timeInMilliseconds, angle);
}
private void ProduceProp()
{
int len = availableCellForGenerateProp.Count;
Random r = new Random(Environment.TickCount);
new Thread
(
() =>
{
while (!gameMap.Timer.IsGaming)
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))
{
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();
}
public PropManager(Map gameMap) // 道具不能扔过墙
{
this.gameMap = gameMap;
this.moveEngine = new MoveEngine(
gameMap: gameMap,
OnCollision: (obj, collision, moveVec) =>
{ return MoveEngine.AfterCollision.MoveMax; },
EndMove: obj =>
{
// obj.Place = gameMap.GetPlaceType((GameObj)obj);
obj.CanMove = false;
Debugger.Output(obj, " end move at " + obj.Position.ToString() + " At time: " + Environment.TickCount64); }
);
availableCellForGenerateProp = new List<XY>();
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)
{
availableCellForGenerateProp.Add(GameData.GetCellCenterPos(i, j));
}
}
}
}
}
}
}

Loading…
Cancel
Save