private Dictionary <PoolBall, List <PocketTrigger> > GetConsiderBalls() { Dictionary <PoolBall, List <PocketTrigger> > considerableBalls = new Dictionary <PoolBall, List <PocketTrigger> >(); for (int i = 0; i < cMsg.ballList.Count; i++) { PoolBall ball = cMsg.ballList[i]; if (ball.BallState != PoolBall.State.IDLE) { continue; } List <PocketTrigger> triggerList = new List <PocketTrigger>(); for (int j = 0; j < Pools.PocketTriggers.Count; j++) { PocketTrigger trigger = Pools.PocketTriggers[j]; //is any obstacle between the ball and the pocket ? bool b1 = !CheckObastacleBetweenBallAndPocket(ball, trigger); if (b1) { triggerList.Add(trigger); } } if (triggerList.Count != 0) { considerableBalls.Add(ball, triggerList); } } return(considerableBalls); }
private Dictionary <PoolBall, PocketTrigger> FilterTheBestPocketForEachBall(Dictionary <PoolBall, List <PocketTrigger> > considerBalls) { Dictionary <PoolBall, PocketTrigger> optimalBalls = new Dictionary <PoolBall, PocketTrigger>(); foreach (var v in considerBalls) { PoolBall ball = v.Key; float bestDistance = float.MaxValue; PocketTrigger bestPocket = null; for (int i = 0, count = v.Value.Count; i < count; i++) { PocketTrigger pocket = v.Value[i]; if (GetPlacedSpace(ball, ball.transform.position - pocket.pointerPosition) < ball.GetRadius() * 2) { continue; } float distance = Vector3.Distance(ball.transform.position, pocket.pointerPosition); if (distance < bestDistance) { bestPocket = pocket; bestDistance = distance; } } optimalBalls.Add(ball, bestPocket); } return(optimalBalls); }
protected override void Start() { Pools.DisableStandardBalls(); List <LevelData.BallData> lp = LevelDataIndex.CurrentLevel.ballDatas; Transform ooRoot = GameObject.Find("8Ball/OtherObjects").transform; for (int i = 0, count = lp.Count; i < count; i++) { LevelData.BallData d = lp[i]; GameObject o = Resources.Load(d.Type.ToString()) as GameObject; GameObject oo = Instantiate(o) as GameObject; oo.transform.SetParent(ooRoot); d.Position.y = 0; oo.transform.position = d.Position; PoolBall pb = oo.GetComponent <PoolBall>(); pb.SetBallID(d.ID); pb.ballType = d.Type; if (pb.ballType != BallType.JIANGYOU && pb.ballType != BallType.DEMON) { m_TargetBalls.Add(d.ID); } Pools.CustomBalls.Add(pb.GetBallID(), pb); } Pools.CueBall.transform.position = LevelDataIndex.CurrentLevel.cueBallData.Position; PocketTrigger.MarkPocketType(LevelDataIndex.CurrentLevel.StartPunishmentPocket, LevelDataIndex.CurrentLevel.StartRewardPocket); PocketTrigger.Block(LevelDataIndex.CurrentLevel.BlockPockets); m_Player.ShotsRemain = LevelDataIndex.CurrentLevel.shotCount; TurnBegin(); TextDialog.Show(LevelDataIndex.CurrentLevel.DescriptionID); }
protected override void TurnBegin() { base.TurnBegin(); m_PunishmentCountThisRound = 0; m_RewardCountThisRound = 0; State = GlobalState.IDLE; if (m_Turn > 1 && LevelDataIndex.CurrentLevel.SpecificPocket) { //generate punitive pocket and reward pocket //punishment PocketIndexes punishment = PocketIndexes.None; if (Random.Range(0, 100) > ConstantData.SpecialPocketProbability) { punishment |= (PocketIndexes)(1 << Random.Range(0, 5)); if (Random.Range(0, 1) == 1) { punishment |= (PocketIndexes)(1 << Random.Range(0, 5)); } } //reward PocketIndexes reward = PocketIndexes.None; if (Random.Range(0, 100) > ConstantData.SpecialPocketProbability) { reward |= (PocketIndexes)(1 << Random.Range(0, 5)); if (Random.Range(0, 1) == 1) { reward |= (PocketIndexes)(1 << Random.Range(0, 5)); } } PocketTrigger.MarkPocketType(punishment, reward); } }
private Dictionary <PoolBall, PocketTrigger> FilterTheBestPocketForEachBallWithCueBall(Dictionary <PoolBall, List <PocketTrigger> > considerBalls, Vector3 cueBallPosition) { Dictionary <PoolBall, PocketTrigger> optimalBalls = new Dictionary <PoolBall, PocketTrigger>(); foreach (var v in considerBalls) { PoolBall ball = v.Key; float bestAngle = 70; PocketTrigger bestPocket = null; for (int i = 0, count = v.Value.Count; i < count; i++) { PocketTrigger pocket = v.Value[i]; // is any obstacle between the ball hit position and the cueball ? bool b1 = !CheckObastacleBetweenTargetPositionAndCueball(ball, ConsiderHitPoint(ball, pocket), cueBallPosition); if (b1) { float angle = MathTools.AngleBetween(ball.transform.position - cueBallPosition, pocket.pointerPosition - ball.transform.position); if (angle < bestAngle) { bestPocket = pocket; bestAngle = angle; } } } optimalBalls.Add(ball, bestPocket); } return(optimalBalls); }
public void AddCues(int cue, PocketTrigger pocket) { if (cue == 0) { return; } AddCues(cue, MathTools.World2UI(pocket.GetRealPosition())); }
private float ConsiderPowerScale(PoolBall ball, PocketTrigger trigger, Vector3 hitPoint, Vector3 cueBallPosition) { Vector3 targetBallPosition = ball.transform.position, pocketPosition = trigger.pointerPosition; //float angle = MathTools.AngleBetween(hitPoint - cueBallPosition, pocketPosition - targetBallPosition); float mag = (targetBallPosition - cueBallPosition).magnitude + (pocketPosition - targetBallPosition).magnitude; return(Mathf.Min(1, mag / Pools.GetTableSize().x)); }
public static void Block(PocketIndexes pockets) { for (int i = 0, length = Pools.PocketTriggers.Count; i < length; i++) { PocketTrigger trigger = Pools.PocketTriggers[i]; if ((trigger.PocketIndex & pockets) != 0x0) { trigger.BlockOff(); } } }
private bool CheckObastacleBetweenBallAndPocket(PoolBall originBall, PocketTrigger pocket) { Vector3 dir = pocket.pointerPosition - originBall.transform.position; RaycastHit[] hit = Physics.SphereCastAll(originBall.transform.position, originBall.GetRadius(), dir, dir.magnitude, ConstantData.OulineAndBallLayer); foreach (RaycastHit h in hit) { //Debug.Log("Obastacle between " + originBall.name + " and " + pocket.name + " : " + h.transform.name); if (h.collider.name.CompareTo(originBall.name) != 0) { return(true); } } return(false); }
private Vector3 ConsiderHitPoint(Dictionary <PoolBall, List <PocketTrigger> > considerBalls, Vector3 cueBallPosition, out PoolBall targetBall, out PocketTrigger targetTrigger) { Dictionary <PoolBall, PocketTrigger> optimalBalls = FilterTheBestPocketForEachBallWithCueBall(considerBalls, cueBallPosition); //Dictionary<PoolBall, float> ballCuebalAngles = new Dictionary<PoolBall, float>(); List <float> angles = new List <float>(); List <PoolBall> balls = new List <PoolBall>(); float totleAngle = 0; foreach (var v in optimalBalls) { PoolBall ball = v.Key; PocketTrigger trigger = v.Value; if (!trigger) { continue; } float angle = MathTools.AngleBetween(ball.transform.position - cueBallPosition, trigger.pointerPosition - ball.transform.position); //夹角越大, 旋转击打这个球的概率就越小,所以这里用90 - angle angle = 90 - angle; totleAngle += angle; balls.Add(ball); angles.Add(angle); } //随机选择一个击打球 float rand = Random.Range(0, totleAngle), threshold = 0; for (int i = 0, count = angles.Count; i < count; i++) { threshold += angles[i]; if (rand < threshold) { PoolBall k = balls[i]; targetBall = k; targetTrigger = optimalBalls[k]; return(ConsiderHitPoint(targetBall, targetTrigger)); } } targetTrigger = null; targetBall = null; return(Vector3.zero); }
public void AddScore(int score, PocketTrigger pocket) { int s = (int)(score * (m_PlayerData.Combo + 4) * .2f); Score += s; if (pocket) { string tips; if (Combo > 1) { tips = "COMBO x " + Combo + "\n+" + s; } else { tips = "+" + s; } BaseUIController.GenerateTips(tips, Color.yellow, MathTools.World2UI(pocket.GetRealPosition())); } }
public static void MarkPocketType(PocketIndexes punishmentIndex, PocketIndexes rewardIndex) { for (int i = 0, length = Pools.PocketTriggers.Count; i < length; i++) { PocketTrigger trigger = Pools.PocketTriggers[i]; if ((trigger.PocketIndex & punishmentIndex) != 0x0) { trigger.Punishment(); } else if ((trigger.PocketIndex & rewardIndex) != 0x0) { trigger.Reward(); } else { trigger.Clear(); } } PunitivePocket = punishmentIndex; RewardPocket = rewardIndex; }
public void AddScore(int score, PocketTrigger pocket) { int s = (int)(score * (m_PlayerData.Combo + 4) * .2f); Score += s; if(pocket) { string tips; if (Combo > 1) tips = "COMBO x " + Combo + "\n+" + s; else tips = "+" + s; BaseUIController.GenerateTips(tips, Color.yellow, MathTools.World2UI(pocket.GetRealPosition())); } }
public void AddCues(int cue, PocketTrigger pocket) { if (cue == 0) return; AddCues(cue, MathTools.World2UI(pocket.GetRealPosition())); }
private float ConsiderPowerScale(PoolBall ball, PocketTrigger trigger, Vector3 hitPoint, Vector3 cueBallPosition) { Vector3 targetBallPosition = ball.transform.position, pocketPosition = trigger.pointerPosition; //float angle = MathTools.AngleBetween(hitPoint - cueBallPosition, pocketPosition - targetBallPosition); float mag = (targetBallPosition - cueBallPosition).magnitude + (pocketPosition - targetBallPosition).magnitude; return Mathf.Min(1, mag / Pools.GetTableSize().x); }
private Vector3 ConsiderHitPointWithDrag(Dictionary<PoolBall, List<PocketTrigger>> considerBalls, out Vector3 cueBallPosition, out PoolBall targetBall, out PocketTrigger targetTrigger) { Dictionary<PoolBall, PocketTrigger> optimalBalls = FilterTheBestPocketForEachBall(considerBalls); cueBallPosition = Vector3.zero; targetTrigger = null; targetBall = null; if(optimalBalls.Count == 0) { return Vector3.zero; } else { foreach (KeyValuePair<PoolBall, PocketTrigger> kvp in optimalBalls) { targetBall = kvp.Key; targetTrigger = kvp.Value; if (!targetTrigger) continue; Vector3 dir = targetBall.transform.position - targetTrigger.pointerPosition; //白球摆成和目标球和袋口一条直线 cueBallPosition = targetBall.transform.position + (dir.normalized * Mathf.Min(GetPlacedSpace(targetBall, targetBall.transform.position - targetTrigger.pointerPosition), 5 * targetBall.GetRadius())); //这里随机会跳出循环,代表随机取一个球的意思, optimalBalls.count 为了使概率平均 if (Random.Range(1, optimalBalls.Count) == 1) break; } if (!targetTrigger) { return Vector3.zero; } return ConsiderHitPoint(targetBall, targetTrigger); } }
private Vector3 ConsiderHitPoint(Dictionary<PoolBall, List<PocketTrigger>> considerBalls, Vector3 cueBallPosition, out PoolBall targetBall, out PocketTrigger targetTrigger) { Dictionary<PoolBall, PocketTrigger> optimalBalls = FilterTheBestPocketForEachBallWithCueBall(considerBalls, cueBallPosition); //Dictionary<PoolBall, float> ballCuebalAngles = new Dictionary<PoolBall, float>(); List<float> angles = new List<float>(); List<PoolBall> balls = new List<PoolBall>(); float totleAngle = 0; foreach(var v in optimalBalls) { PoolBall ball = v.Key; PocketTrigger trigger = v.Value; if (!trigger) continue; float angle = MathTools.AngleBetween(ball.transform.position - cueBallPosition, trigger.pointerPosition - ball.transform.position); //夹角越大, 旋转击打这个球的概率就越小,所以这里用90 - angle angle = 90 - angle; totleAngle += angle; balls.Add(ball); angles.Add(angle); } //随机选择一个击打球 float rand = Random.Range(0, totleAngle), threshold = 0; for (int i = 0, count = angles.Count; i < count; i++) { threshold += angles[i]; if (rand < threshold) { PoolBall k = balls[i]; targetBall = k; targetTrigger = optimalBalls[k]; return ConsiderHitPoint(targetBall, targetTrigger); } } targetTrigger = null; targetBall = null; return Vector3.zero; }
private Vector3 ConsiderHitPoint(PoolBall ball, PocketTrigger trigger) { Vector3 vec = ball.transform.position - trigger.pointerPosition; return ball.transform.position + vec.normalized * ball.GetRadius() * 2; }
private bool CheckObastacleBetweenBallAndPocket(PoolBall originBall, PocketTrigger pocket) { Vector3 dir = pocket.pointerPosition - originBall.transform.position; RaycastHit[] hit = Physics.SphereCastAll(originBall.transform.position, originBall.GetRadius(), dir, dir.magnitude, ConstantData.OulineAndBallLayer); foreach (RaycastHit h in hit) { //Debug.Log("Obastacle between " + originBall.name + " and " + pocket.name + " : " + h.transform.name); if (h.collider.name.CompareTo(originBall.name) != 0) return true; } return false; }
public override void PotBall(PoolBall ball, PocketIndexes pocket) { base.PotBall(ball, pocket); if ((pocket & PocketTrigger.PunitivePocket) != 0) { //m_PunishmentCountThisRound++; m_Player.AddCues(ConstantData.PunitiveShots, PocketTrigger.GetPocketWithIndexes(pocket)); } if ((pocket & PocketTrigger.RewardPocket) != 0) { //m_RewardCountThisRound++; m_Player.AddCues(ConstantData.RewardShots, PocketTrigger.GetPocketWithIndexes(pocket)); } int score = 0; if (ball.ballType == BallType.WHITE) { m_Player.Combo = 0; m_Player.AddCues(ConstantData.MissionCueballPottedPunishment, PocketTrigger.GetPocketWithIndexes(pocket)); return; } else if (ball.ballType == BallType.BOMB) { score = ConstantData.MissionBombPottedPoint; } else if (ball.ballType == BallType.SINGULARITY) { score = ConstantData.MissionSingularityPottedPoint; } else if (ball.ballType == BallType.ABSORB) { score = ConstantData.MissionAbsorbPottedPoint; AbsorbBall b = (AbsorbBall)ball; for (int i = 0, count = b.AbsorbList.Count; i < count; i++) { PotBall(b.AbsorbList[i], pocket); Pools.StorageRack.Add(b.AbsorbList[i]); } b.AbsorbList.Clear(); } else if (ball.ballType == BallType.REDCUSTOM) { score = ConstantData.MissionRedBallPoint; } else if (ball.ballType == BallType.BLUECUSTOM) { score = ConstantData.MissionBlueBallPoint; } else if (ball.ballType == BallType.YELLOWCUSTOM) { score = ConstantData.MissionYellowBallPoint; } else if (ball.ballType == BallType.JIANGYOU) { score = ConstantData.MissionJiangYouBallPoint; } else if (ball.ballType == BallType.DEMON) { score = ConstantData.MissionDemonBallPoint; } if (score > 0) { m_Player.Combo++; m_Player.AddScore(score, PocketTrigger.GetPocketWithIndexes(pocket)); m_ScoreThisRound = score; } if (m_Player.Combo >= 5) { BaseUIController.GenerateTips("Great!"); } m_Player.Pot(); if (m_TargetBalls.Contains(ball.GetBallID())) { m_TargetBalls.Remove(ball.GetBallID()); } }
public void SetTrigger(PocketTrigger _Trigger) { m_RefTrigger = _Trigger; }
private Vector3 ConsiderHitPointWithDrag(Dictionary <PoolBall, List <PocketTrigger> > considerBalls, out Vector3 cueBallPosition, out PoolBall targetBall, out PocketTrigger targetTrigger) { Dictionary <PoolBall, PocketTrigger> optimalBalls = FilterTheBestPocketForEachBall(considerBalls); cueBallPosition = Vector3.zero; targetTrigger = null; targetBall = null; if (optimalBalls.Count == 0) { return(Vector3.zero); } else { foreach (KeyValuePair <PoolBall, PocketTrigger> kvp in optimalBalls) { targetBall = kvp.Key; targetTrigger = kvp.Value; if (!targetTrigger) { continue; } Vector3 dir = targetBall.transform.position - targetTrigger.pointerPosition; //白球摆成和目标球和袋口一条直线 cueBallPosition = targetBall.transform.position + (dir.normalized * Mathf.Min(GetPlacedSpace(targetBall, targetBall.transform.position - targetTrigger.pointerPosition), 5 * targetBall.GetRadius())); //这里随机会跳出循环,代表随机取一个球的意思, optimalBalls.count 为了使概率平均 if (Random.Range(1, optimalBalls.Count) == 1) { break; } } if (!targetTrigger) { return(Vector3.zero); } return(ConsiderHitPoint(targetBall, targetTrigger)); } }
private Vector3 ConsiderHitPoint(PoolBall ball, PocketTrigger trigger) { Vector3 vec = ball.transform.position - trigger.pointerPosition; return(ball.transform.position + vec.normalized * ball.GetRadius() * 2); }
void Awake() { m_PocketTrigger = GetComponentInParent<PocketTrigger>(); }
void Awake() { m_PocketTrigger = GetComponentInParent <PocketTrigger>(); }