private void OnTriggerEnter(Collider other) { switch (antState) { case AntState.CollectingSugar: Sugar sugar = other.gameObject.GetComponent <Sugar>(); if (seek.target != null && sugar != null) { if (sugar.gameObject == seek.target.gameObject) { sugar.GetEaten(); SugarCollected++; if (SugarCollected == SugarToCollect) { antState = AntState.GoingToColony; seek.target = colonyTransform; } else { sugar = sugarController.GetRandomSugar(); if (sugar != null) { seek.target = sugar.transform; } else { antState = AntState.GoingToColony; seek.target = colonyTransform; } } } } break; } }
/// <summary> /// Erzeugt eine AntInfoBox-Instanz. /// </summary> /// <param name="ant">Die Ameise.</param> /// <param name="brush">Der Pinsel mit dem gezeichnet werden soll.</param> public AntInfoBox(AntState ant, int colonyId, string colonyName, string casteName, Brush brush) { // Setze Größe und Randabstand. Width = 150; Height = 73; Margin = new Padding(0); // Erzeuge die Hintergrund-Grafik und hole ihre Zeichenfläche. bitmap = new Bitmap(Width, Height); graphics = Graphics.FromImage(bitmap); this.ant = ant; this.colonyId = colonyId; this.brush = brush; name = string.Format(Resource.AntName, NameHelper.GetFemaleName(ant.Id)); if (!string.IsNullOrEmpty(casteName)) { casteColony = casteName + ", " + colonyName; } else { casteColony = colonyName; } }
IEnumerator StartMovingIntoBox() { yield return(new WaitForSeconds(0.5f)); GetComponent <NavMeshAgent>().enabled = false; transform.rotation = Quaternion.LookRotation(destination.transform.position - transform.position, Vector3.up); currentStage = AntState.MovingIntoBox; }
public List <Vector3> foodPos = new List <Vector3>(); //找到的食物位置 void Start() { pheromone = transform.GetChild(0).gameObject; net = GameObject.FindGameObjectWithTag("Net").transform; agent = GetComponent <NavMeshAgent>(); state = AntState.Explore; curPhero = 2; SetInfo(); }
private void ShooldReset() { visitedVerts.Clear(); visitedVerts.Add(_home.VertexId); State = AntState.Exploring; var nm = GetComponent <NavMeshAgent>(); nm.destination = _home.transform.position; currentIndex = 0; }
/// <summary> /// Renders an ant. /// </summary> /// <param name="colony">ID of Colony</param> /// <param name="state">State</param> /// <param name="pickray"><see cref="Pickray"/></param> /// <param name="selected">true, if ant is selected</param> /// <returns>distance from viewer to item, if <see cref="Pickray"/> hits</returns> public float RenderAnt(int colony, AntState state, Pickray pickray, bool selected) { Matrix matrix = Matrix.Identity; matrix.RotateY((float)(state.Direction * Math.PI) / 180); matrix.M41 = state.PositionX - playgroundWidth; matrix.M43 = -state.PositionY + playgroundHeight; renderDevice.Material = (selected ? selectionMaterial : antMaterial[colony]); renderDevice.Transform.World = matrix; antMesh.DrawSubset(0); // Draw sugar-block, if ant has sugar loaded if (state.LoadType == LoadType.Sugar) { matrix.M42 = 3.5f; renderDevice.Material = sugarMaterial; renderDevice.Transform.World = matrix; sugarCubeMesh.DrawSubset(0); } if (selected && state.TargetPositionX != 0) { renderDevice.Transform.World = Matrix.Identity; renderDevice.Material = sugarMaterial; CustomVertex.PositionColored[] verts = new CustomVertex.PositionColored[2]; verts[0].X = (float)state.PositionX - playgroundWidth; verts[0].Z = (float)-state.PositionY + playgroundHeight; verts[0].Y = 2; verts[1].X = (float)state.TargetPositionX - playgroundWidth; verts[1].Z = (float)-state.TargetPositionY + playgroundHeight; verts[1].Y = 2; renderDevice.VertexFormat = CustomVertex.PositionColored.Format; renderDevice.DrawUserPrimitives(PrimitiveType.LineList, 1, verts); } // Check for pickray-collision matrix.M42 = 0.0f; matrix.Invert(); pickray.Origin.TransformCoordinate(matrix); pickray.Direction.TransformNormal(matrix); if (collisionBox.Intersect(pickray.Origin, pickray.Direction)) { return (Vector3.Subtract ( pickray.Origin, new Vector3(state.PositionX - playgroundWidth, 0, -state.PositionY + playgroundHeight)).Length ()); } return(0.0f); }
// Use this for initialization void Start() { // gameData = GameObject.Find("GameData").GetComponent<GameData>(); speedUpgraded = false; dmgUpgraded = false; workUpgraded = false; liveUpgraded = false; state = AntState.waiting; if (!isQueen) { Animator[] anim = this.GetComponentsInChildren <Animator>(); antanim = anim[0]; antanimW = anim[1]; antanimD = anim[2]; antanimL = anim[3]; antanimS = anim[4]; antanimTOT = anim[5]; antanim.SetBool("Running", false); } else if (isQueen) { animQ = this.GetComponent <Animator>(); animQ.SetBool("Running", false); } // Assigning correct player id playerID = (ID > 0 ? 0 : 1); //speed = 1; //workSpeed = 1; if (!isQueen) { lives = 10; dmg = 5; workTimer = 2f; autoHitCooldown = 0; dyingTimer = 1f; position = new Position((int)transform.position.x, -(int)transform.position.y); oldPosition = new Position((int)transform.position.x, -(int)transform.position.y); } if (isQueen) { lives = 200; dmg = 3; workTimer = 2f; autoHitCooldown = 0; dyingTimer = 1f; position = new Position((int)transform.position.x, -(int)transform.position.y); oldPosition = new Position((int)transform.position.x, -(int)transform.position.y); } // DEBUGGING /*double timer = 0.3; * while (timer >= 0.0) timer -= Time.deltaTime; * print("My ID is: " + ID);*/ // DEBUGGING ENDE }
void Start() { myRigidbody = GetComponent <Rigidbody>(); carryingPosition = new Vector3(0, transform.localScale.y, 0); dropPosition = Vector3.zero; searchSeconds = Random.Range(0.0f, MAX_SEARCH_SECONDS); currentAntState = AntState.SEARCH; velocity = Vector3.zero; approaching = null; carrying = null; touchingGameObject = null; }
void SearchForFood() { speed = SEARCH_SPEED; // start following scent if there is a scent at current position ScentMap.Scent scent = scentMap.GetScentAt(transform.position); if (scent != null && !checkedPositions.Contains(scent.foodPosition)) { state = AntState.FollowTrail; targetFoodPos = scent.foodPosition; checkedPositions.Add(scent.foodPosition); } }
void build(char type, Position dest) { //antanim.SetBool("Running", true); if (ID > 0) { if (gameData.player1Stats.getCount(type) <= 2) { moveList.Dequeue(); return; } } else { if (gameData.player2Stats.getCount(type) <= 2) { moveList.Dequeue(); return; } } if (state != AntState.working) { state = AntState.working; } if (gameData.blockInfos[dest.y, dest.x].material == 'n') { workTimer -= workSpeed * Time.deltaTime; } else { state = AntState.waiting; return; } if (workTimer <= 0) { // CmdSetStats(playerID, gameData.blockInfos[dest.y, dest.x].material, -3); /*if(ID > 0) * { * // gameData.player1Stats.RpcDecStats(type, 3); * } * else * { * // gameData.player2Stats.RpcDecStats(type, 3); * }*/ gameData.spawnObject(dest.y, dest.x, type); workTimer = 2f; goingToBuild = false; moveList.Dequeue(); state = AntState.waiting; } }
void DeliverFood(bool stolen) { if (!stolen) { Destroy(carriedObject.gameObject); } carriedObject = null; state = AntState.SearchForFood; spriteRenderer.color = searchingColor; ReverseDirection(); checkedPositions = new List <Vector3>(); }
void fight(int id) { if (state != AntState.fighting) { state = AntState.fighting; } autoHitCooldown -= 1 * Time.deltaTime; if (autoHitCooldown <= 0) { CmdDecLives(id); autoHitCooldown = 2f; } }
void Update() { switch (antState) { case AntState.GoingToColony: if (Vector3.Distance(colonyTransform.position, transform.position) < inRange) { SugarCollected = 0; sugarController.ResetSugar(); antState = AntState.CollectingSugar; seek.target = sugarController.GetRandomSugar().transform; } break; } }
private void OnTriggerStay(Collider other) { if (other.gameObject.CompareTag("Pheromone")) { BoxCollider bc = other.GetComponent <BoxCollider>(); if (bc.size.z > 0.1f) { if (state != AntState.Transport) { state = AntState.Follow; } foodPos = other.GetComponent <Pheromone>().foodPos; } } }
protected override void RequestDraw() { MainState _currentState = _state; if (_currentState != null) { Index2 cells = _currentState.Map.GetCellCount(); DrawPlayground(cells, _currentState.Map.Tiles); foreach (var item in _currentState.Items) { if (item is AnthillState) { AnthillState anthillState = item as AnthillState; DrawItem(item.Id, item.Position, anthillState.Radius, null, null, Color.Brown, null, null, null, null, null, null); } if (item is AntState) { AntState antState = item as AntState; // DrawItem(item.Id, item.Position, antState.Radius, Color.Black); } if (item is SugarState) { SugarState sugarState = item as SugarState; // DrawItem(item.Id, item.Position, sugarState.Radius, Color.White); } if (item is AppleState) { AppleState appleState = item as AppleState; // DrawItem(item.Id, item.Position, 5, Color.LightGreen); } if (item is MarkerState) { MarkerState markerState = item as MarkerState; // DrawItem(item.Id, item.Position, 10, Color.Yellow); } if (item is BugState) { // DrawItem(item.Id, item.Position, 10, Color.Blue); } } } }
//跟随信息素 void FollowPheromone() { if (foodPos.Count > 0) { int j = Random.Range(0, foodPos.Count); float pj = p[j]; if (true)//p { agent.SetDestination(foodPos[j]); } } else { state = AntState.Explore; } }
private void GetThing() { Vector3 direction = (approaching.transform.position - transform.position).normalized; velocity = direction * speed; if (touchingGameObject && touchingGameObject == approaching) { carrying = approaching; carrying.GetComponent <CarriableBehavior>().beingCarriedBy = this; approaching = null; carrying.GetComponent <CarriableBehavior>().beingApproachedBy = null; carrying.transform.position = transform.position + carryingPosition; currentAntState = AntState.RETURN_TO_HILL; } }
// randomly change direction to give "wiggle" effect, move forward void Wiggle() { // check if ant has reached end of food trail if ((state == AntState.FollowTrail) && ((transform.position - targetFoodPos).sqrMagnitude < (speed * 2) * (speed * 2))) { transform.position = targetFoodPos; state = AntState.SearchForFood; } if (steps % 4 == 0) { transform.Rotate(Vector3.forward * Random.Range(-MAX_WIGGLE, MAX_WIGGLE), Space.Self); } if (!CanMove()) { ReverseDirection(); } transform.position = CalculateMove(); }
private void ReturnToHill() { Vector3 currentPosition = transform.position; Vector3 direction = (dropPosition - currentPosition).normalized; velocity = direction * speed; carrying.transform.position = currentPosition + carryingPosition; if (currentPosition.x > dropPosition.x - DROP_ZONE_RADIUS && currentPosition.x < dropPosition.x + DROP_ZONE_RADIUS && currentPosition.y > dropPosition.y - DROP_ZONE_RADIUS && currentPosition.y < dropPosition.y + DROP_ZONE_RADIUS && currentPosition.z > dropPosition.z - DROP_ZONE_RADIUS && currentPosition.z < dropPosition.z + DROP_ZONE_RADIUS) { carrying.transform.position = transform.position; CarriableBehavior carriableBehavior = carrying.GetComponent <CarriableBehavior>(); carriableBehavior.isStored = true; carriableBehavior.beingCarriedBy = null; carrying = null; currentAntState = AntState.SEARCH; } }
private void OnCollisionEnter(Collision collision) { if (collision.gameObject.CompareTag("Food")) { state = AntState.Transport; EnhancePheromone(); GameObject food = collision.gameObject; food.transform.localScale -= Vector3.one * carry; pheromone.GetComponent <Pheromone>().AddFood(food.transform.position); } if (collision.gameObject.CompareTag("Net")) { if (AntColonyManager.Instance.IsFoodEmpty()) { state = AntState.Follow; } else { state = AntState.Explore; } } }
private void OnTriggerEnter2D(Collider2D other) { if (state == AntState.ReturnToNest) { if (other.gameObject.CompareTag("Nest")) { // drop off food and start searching for food again DeliverFood(false); } } else { if (other.gameObject.CompareTag("Food")) { carriedObject = other.gameObject.GetComponent <Carriable>(); if (carriedObject == null) { throw new System.Exception("Tried to pick up food that has no Carriable script"); } if (!(!CAN_STEAL && carriedObject.isCarried) && !(CAN_STEAL && carriedObject.isCarried && !(UnityEngine.Random.value < STEAL_CHANCE))) { // pick up food and return to nest if (carriedObject.isCarried) { carriedObject.carrier.DeliverFood(true); } carriedObject.transform.parent = transform; carriedObject.transform.localPosition = jawsOffset; carriedObject.transform.rotation = transform.rotation; carriedObject.carrier = this; carriedObject.GetComponent <Carriable>().isCarried = true; state = AntState.ReturnToNest; spriteRenderer.color = returningColor; targetFoodPos = carriedObject.transform.position; } } } }
private void work(Position dest) { //antanim.SetBool("Running", true); if (this.state != AntState.working) { this.state = AntState.working; } if (gameData.blockInfos[dest.y, dest.x].material == 'e') { workTimer -= workSpeed * Time.deltaTime; } else if (gameData.blockInfos[dest.y, dest.x].material == 's') { workTimer -= workSpeed * Time.deltaTime * 0.5f; } else if (gameData.blockInfos[dest.y, dest.x].material == 'f') { workTimer -= workSpeed * Time.deltaTime * 1.5f; } if (workTimer <= 0) { //print("1.: " + playerID); CmdSetStats(playerID, gameData.blockInfos[dest.y, dest.x].material, 1); if (ID > 0) { //gameData.player1Stats.RpcIncStats(gameData.blockInfos[dest.y, dest.x].material); } else { // gameData.player2Stats.RpcIncStats(gameData.blockInfos[dest.y, dest.x].material); } gameData.spawnObject(dest.y, dest.x); workTimer = 2f; // Upgrade('s'); state = AntState.moving; } }
private void Search(List <GameObject> carriableList) { searchSeconds -= Time.deltaTime; if (searchSeconds <= 0.0f) { Vector3 direction = new Vector3(Random.Range(-1.0f, 1.0f), 0, Random.Range(-1.0f, 1.0f)).normalized; velocity = direction * speed; searchSeconds = Random.Range(0.0f, MAX_SEARCH_SECONDS); } foreach (GameObject carriable in carriableList) { CarriableBehavior carriableBehavior = carriable.GetComponent <CarriableBehavior>(); if (!carriableBehavior.beingApproachedBy && !carriableBehavior.beingCarriedBy && !carriableBehavior.isStored && carriableBehavior.InSearchArea(transform)) { approaching = carriable; carriableBehavior.beingApproachedBy = this; currentAntState = AntState.GET_THING; break; } } }
public IEnumerator die() { if (!isQueen) { state = AntState.dying; antanimW.gameObject.GetComponent <SpriteRenderer>().enabled = false; antanimS.gameObject.GetComponent <SpriteRenderer>().enabled = false; antanimD.gameObject.GetComponent <SpriteRenderer>().enabled = false; antanimL.gameObject.GetComponent <SpriteRenderer>().enabled = false; antanim.gameObject.GetComponent <SpriteRenderer>().enabled = false; antanimTOT.gameObject.GetComponent <SpriteRenderer>().enabled = true; //print("ich sterbe"); yield return(new WaitForSeconds(dyingTimer)); gameData.killAnt(ID); } else { SceneManager.LoadScene(2); } // hier animation aktivieren }
private void Update() { if (currentStage == AntState.EnteringMap) { var dist = Vector3.Distance(transform.position, destination.transform.position); if (dist < 1f) { StartCoroutine(StartMovingIntoBox()); } } else if (currentStage == AntState.MovingIntoBox) { var dist = Vector3.Distance(transform.position, destination.transform.position); if (dist < 0.1f) { currentStage = AntState.Hidden; destination.GetComponent <HidingPlace>().HideAnt(gameObject); } else { gameObject.transform.position = Vector3.MoveTowards(transform.position, destination.transform.position, 0.3f * Time.deltaTime); } } }
public void SwitchState() { timeAlive = 0; currentAntState = currentAntState == AntState.SearchingForFood ? AntState.SearchingForHive : AntState.SearchingForFood; }
void Start() { AntManager.instance.Add(1); currentAntState = AntState.SearchingForFood; }
private void render(object sender, PaintEventArgs e) { if (Visible && renderDevice != null) { if (watch.ElapsedMilliseconds > 40) { watch.Reset(); watch.Start(); Selection selectedItem = new Selection(); // Selektionsinfos zurücksetzen selectedItem.SelectionType = SelectionType.Nothing; selectedItem.Item = null; float distanceToSelectedItem = VIEWRANGE_MAX * VIEWRANGE_MAX; renderDevice.Clear(ClearFlags.Target | ClearFlags.ZBuffer, Color.FromArgb(51, 153, 255), 1.0f, 0); renderDevice.BeginScene(); //// Falls schon ein Zustand da ist kann gezeichnet werden if (simulationState != null) { SimulationState currentState = simulationState; // Update Camera camera.Update(currentState.PlaygroundWidth, currentState.PlaygroundHeight); renderDevice.Transform.View = camera.ViewMatrix; Pickray pickray = camera.Pickray; Point mousePosition = camera.MousePosition; // render Playerground modelManager.SetPlaygroundSize(currentState.PlaygroundWidth, currentState.PlaygroundHeight); modelManager.RenderPlayground(); // render these preaty little, blue items... float distance; for (int i = 0; i < currentState.BugStates.Count; i++) { if ((distance = modelManager.RenderBug(currentState.BugStates[i], pickray, false)) > 0) { // select, if pickray collides with item if (distance < distanceToSelectedItem) { distanceToSelectedItem = distance; selectedItem.Item = currentState.BugStates[i]; selectedItem.SelectionType = SelectionType.Bug; } } } // Render sugar for (int i = 0; i < currentState.SugarStates.Count; i++) { if ((distance = modelManager.RenderSugar(currentState.SugarStates[i], pickray, false)) > 0) { // select, if pickray collides with item if (distance < distanceToSelectedItem) { distanceToSelectedItem = distance; selectedItem.Item = currentState.SugarStates[i]; selectedItem.SelectionType = SelectionType.Sugar; } } } // Render Fruit for (int i = 0; i < currentState.FruitStates.Count; i++) { if ((distance = modelManager.RenderFruit(currentState.FruitStates[i], pickray, false)) > 0) { // select, if pickray collides with item if (distance < distanceToSelectedItem) { distanceToSelectedItem = distance; selectedItem.Item = currentState.FruitStates[i]; selectedItem.SelectionType = SelectionType.Fruit; } } } // Colony-specific stuff int count = 0; for (int teamIndex = 0; teamIndex < currentState.TeamStates.Count; teamIndex++) { for (int colonyIndex = 0; colonyIndex < currentState.TeamStates[teamIndex].ColonyStates.Count; colonyIndex++) { ColonyState colony = currentState.TeamStates[teamIndex].ColonyStates[colonyIndex]; // Ensure available materials for that colony modelManager.PrepareColony(count); // Render Anthills for (int anthillIndex = 0; anthillIndex < colony.AnthillStates.Count; anthillIndex++) { if ( (distance = modelManager.RenderAnthill( count, colony.AnthillStates[anthillIndex], pickray, false)) > 0) // select, if pickray collides with item { if (distance < distanceToSelectedItem) { distanceToSelectedItem = distance; selectedItem.Item = colony.AnthillStates[anthillIndex]; selectedItem.SelectionType = SelectionType.Anthill; selectedItem.AdditionalInfo = colony.ColonyName; } } } // Render Ants for (int antIndex = 0; antIndex < colony.AntStates.Count; antIndex++) { if ( (distance = modelManager.RenderAnt( count, colony.AntStates[antIndex], pickray, false)) > 0) { // select, if pickray collides with item if (distance < distanceToSelectedItem) { distanceToSelectedItem = distance; selectedItem.Item = colony.AntStates[antIndex]; selectedItem.SelectionType = SelectionType.Ant; selectedItem.AdditionalInfo = colony.ColonyName; } } } count++; } } // Render Marker // This must happen at the end, cause of alpha-tranperency count = 0; for (int teamIndex = 0; teamIndex < currentState.TeamStates.Count; teamIndex++) { TeamState team = currentState.TeamStates[teamIndex]; for (int colonyIndex = 0; colonyIndex < team.ColonyStates.Count; colonyIndex++) { ColonyState colony = team.ColonyStates[colonyIndex]; for (int markerIndex = 0; markerIndex < colony.MarkerStates.Count; markerIndex++) { MarkerState marker = colony.MarkerStates[markerIndex]; modelManager.RenderMarker(count, marker); } count++; } } // Render Statistics in the upper left corner modelManager.RenderInfobox(currentState); // Render Info-Tag at selected item if (selectedItem.SelectionType != SelectionType.Nothing) { string line1; string line2; switch (selectedItem.SelectionType) { case SelectionType.Ant: AntState ameise = (AntState)selectedItem.Item; string name; if (!antNames.ContainsKey(ameise.Id)) { name = names[random.Next(names.Length)]; antNames.Add(ameise.Id, name); } else { name = antNames[ameise.Id]; } line1 = string.Format(Resource.HovertextAntLine1, name, selectedItem.AdditionalInfo); line2 = string.Format(Resource.HovertextAntLine2, ameise.Vitality); break; case SelectionType.Anthill: line1 = Resource.HovertextAnthillLine1; line2 = string.Format(Resource.HovertextAnthillLine2, selectedItem.AdditionalInfo); break; case SelectionType.Bug: BugState bugState = (BugState)selectedItem.Item; line1 = Resource.HovertextBugLine1; line2 = string.Format(Resource.HovertextBugLine2, bugState.Vitality); break; case SelectionType.Fruit: FruitState fruitState = (FruitState)selectedItem.Item; line1 = Resource.HovertextFruitLine1; line2 = string.Format(Resource.HovertextFruitLine2, fruitState.Amount); break; case SelectionType.Sugar: SugarState sugar = (SugarState)selectedItem.Item; line1 = Resource.HovertextSugarLine1; line2 = string.Format(Resource.HovertextSugarLine2, sugar.Amount); break; default: line1 = String.Empty; line2 = String.Empty; break; } // Text an Mausposition ausgeben if (line1 != String.Empty || line2 != String.Empty) { modelManager.RenderInfoTag(mousePosition, line1, line2); } } } renderDevice.EndScene(); renderDevice.Present(); } Application.DoEvents(); Invalidate(); } }
public void AssignAntState(AntState setToState) { antState = setToState; }
private void UpdateState(AntState state) { this.state = state; FireStateChange(); }
protected virtual void CheckState() { //refresh state to take new variables state ChangeState(state); switch (state) { case AntState.lookForFood: if (food != null) { ChangeState(AntState.goToFood); } break; case AntState.goToFood: if (food.Amount == 0 && Vector2.Distance(foodPosition, Position) < ConstantsHolder.Singleton.Vision) { food = null; ChangeState(AntState.lookForFood); break; } if (Vector2.Distance(foodPosition, Position) < ConstantsHolder.Singleton.EatingRadius) { foodCarried = ConstantsHolder.Singleton.CarryMax; food.Amount -= ConstantsHolder.Singleton.CarryMax; ChangeState(AntState.bringBackFood); } break; case AntState.bringBackFood: if (Vector2.Distance(AntHill.Position, Position) < ConstantsHolder.Singleton.EatingRadius) { game.AntHill.Food += foodCarried; foodCarried = 0; ChangeState(AntState.goToFood); } break; case AntState.transportCorpse: cadaver.Position = position; //if the ant don't know a cemetery it will just put the corpse at a sanitary distance of the anthill if (cemeteryBest == null) { if (Vector2.Distance(position, antHill.Position) > ConstantsHolder.Singleton.SainityDistance) { //double tap! cadaver.Kill(); if (leftToClean > 0) { ChangeState(AntState.backToClean); } else { ChangeState(previousState); } } } else { // the ant reaches the biggest known cemetery it put the cadaver in the cemetery if (Vector2.Distance(goal, Position) < ConstantsHolder.Singleton.EatingRadius) { //if the best known have desapeared the ant just put the corpse at a sanitary distance from the anthill if (cemeteryBest.Count == 0) { cemeteryBest = null; //double tap! cadaver.Kill(); } else { cemeteryBest.Add(cadaver); } cadaver = null; //go back to clean the previous cemetery if it is not known as empty if (leftToClean > 0) { ChangeState(AntState.backToClean); } else { ChangeState(previousState); } break; } } break; case AntState.goToCorpse: if (Vector2.Distance(goal, Position) < ConstantsHolder.Singleton.EatingRadius) { //take a cadaver in a cemetery when it reach it if (cemeteryToClean.Contains(cadaver)) { cemeteryToClean.Remove(cadaver); leftToClean = cemeteryToClean.Count; //if taking the corpse clean the cemetery it will be destroyed if (cemeteryToClean.Count == 0) { game.Cemeteries.Remove(cemeteryToClean); cemeteryToClean = null; } ChangeState(AntState.transportCorpse); } //if the corpse have been taken by an other ant, it return to normal activity else { ChangeState(previousState); } } break; //go back the previous cemetery to clean it case AntState.backToClean: //if the cemetery is empty the ant remove it and go back to its activity //if it's full the ant will automatically change state to goforCorpse from the cemetery scan in the update function if (Vector2.Distance(goal, Position) < ConstantsHolder.Singleton.Vision) { if (cemeteryToClean == null || cemeteryToClean.Count == 0) { leftToClean = 0; cemeteryToClean = null; if (previousState == AntState.backToClean) { previousState = AntState.lookForFood; } ChangeState(previousState); } } break; } }
protected virtual void ChangeState(AntState newState) { state = newState; switch (newState) { case AntState.lookForFood: randomLover = ConstantsHolder.Singleton.ScoutRandom; warLover = 0.1f; goalLover = ConstantsHolder.Singleton.ScoutGoal; pheromoneLover = ConstantsHolder.Singleton.ScoutPheromones; goal = AntHill.Position; break; case AntState.bringBackFood: randomLover = ConstantsHolder.Singleton.BringFoodRandom; warLover = 0.1f; goalLover = ConstantsHolder.Singleton.BringFoodGoal; pheromoneLover = ConstantsHolder.Singleton.BringFoodPheromones; Goal = AntHill.Position; break; case AntState.goToFood: randomLover = ConstantsHolder.Singleton.GoFoodRandom; warLover = 0.1f; goalLover = ConstantsHolder.Singleton.GoFoodGoal; pheromoneLover = ConstantsHolder.Singleton.GoFoodPheromones; Goal = foodPosition; break; case AntState.goToCorpse: randomLover = ConstantsHolder.Singleton.GoFoodRandom; warLover = 0.1f; goalLover = ConstantsHolder.Singleton.GoFoodGoal; pheromoneLover = ConstantsHolder.Singleton.TransportPheromones; Goal = cadaver.Position; break; case AntState.backToClean: randomLover = ConstantsHolder.Singleton.GoFoodRandom; warLover = 0.1f; goalLover = ConstantsHolder.Singleton.GoFoodGoal; pheromoneLover = ConstantsHolder.Singleton.TransportPheromones; Goal = cemeteryToCleanPos; break; case AntState.transportCorpse: randomLover = ConstantsHolder.Singleton.TransportRandom; warLover = 0.1f; if (cemeteryBest == null) { goalLover = -ConstantsHolder.Singleton.TransportGoal; Goal = antHill.Position; } else { goalLover = ConstantsHolder.Singleton.TransportGoal; Goal = cemeteryBest.Position; } pheromoneLover = ConstantsHolder.Singleton.GoFoodPheromones; break; } }
private void Awake() { antState = AntState.IDLE; }
public override void Update(GameTime gameTime) { base.Update(gameTime); //the ant have a certain probability to die each frame double ran = game.Random.NextDouble(); if (ran < 0.5f / ConstantsHolder.Singleton.HalfLife) { Kill(); } CheckState(); if (Vector2.Distance(AntHill.Position, Position) < ConstantsHolder.Singleton.EatingRadius) { if (AntHill.Food >= 0) { AntHill.Food -= Hungry; Hungry = 0; } } if (Hungry > ConstantsHolder.Singleton.Starvation) { Kill(); } //find closest food point foreach (Food possibleFood in game.Foods) { if (Vector2.Distance(possibleFood.Position, Position) < ConstantsHolder.Singleton.Vision && (food == null || Vector2.Distance(possibleFood.Position, AntHill.Position) < Vector2.Distance(food.Position, AntHill.Position))) { food = possibleFood; foodPosition = possibleFood.Position; if (state == AntState.goToFood) { goal = food.Position; } } } //find bigest cemetery around for (int i = 0; i < game.Cemeteries.Count; i++) { Cemetery possibleCemetery = game.Cemeteries[i]; //within view range if (Vector2.Distance(possibleCemetery.Position, Position) < ConstantsHolder.Singleton.Vision && possibleCemetery.Count!=0) { //find bigest cemetery if ( Vector2.Distance(possibleCemetery.Position,antHill.Position)>=ConstantsHolder.Singleton.SainityDistance && (cemeteryBest == null || possibleCemetery.Count > cemeterySmell)) { //if the ant had a previous best cemetery, it decided to move it in the new one bool needToClean = false; if (cemeteryBest != null && cemeteryBest != possibleCemetery && state != AntState.goToCorpse && state != AntState.transportCorpse) { cemeteryToClean = cemeteryBest; cemeteryToCleanPos = cemeteryToClean.Position; previousState = state; needToClean = true; } //update the biggest known cemetery cemeteryBest = possibleCemetery; cemeterySmell = possibleCemetery.Count; if (state == AntState.transportCorpse) { goal = possibleCemetery.Position; goalLover = ConstantsHolder.Singleton.TransportGoal; } //start to clean the old cemetery if (needToClean) { ChangeState(AntState.backToClean); } } ////with a decent distance to the hill //if (Vector2.Distance(possibleCemetery.Position, antHill.Position) >= ConstantsHolder.Singleton.SainityDistance // && (cemeteryBest == null || possibleCemetery.Count > cemeterySmell)) //{ // bool needToClean = false; // if (cemeteryBest != null // && cemeteryBest != possibleCemetery // && state != AntState.goToCorpse // && state != AntState.transportCorpse) // { // cemeteryToClean = cemeteryBest; // cemeteryToCleanPos = cemeteryToClean.Position; // previousState = state; // needToClean = true; // } // cemeteryBest = possibleCemetery; // cemeterySmell = possibleCemetery.Count; // if (state == AntState.transportCorpse) // { // goal = possibleCemetery.Position; // goalLover = ConstantsHolder.Singleton.TransportGoal; // } // if (needToClean) // { // ChangeState(AntState.backToClean); // } //} //Update the size of the biggest known cemetery if (possibleCemetery == cemeteryBest) { cemeterySmell = possibleCemetery.Count; } //if the cemetery seen is not the biggest the ant start to clean it //if the ant is not already carrying a corpse a going to a corpse else if (state != AntState.goToCorpse && state != AntState.transportCorpse ) { cadaver = possibleCemetery.Last(); //handle a little bug that sometime the cemetery have one null cadaver instead of nothing //it would be maybe cleaner to prevent that if (cadaver != null) { cemeteryToClean = possibleCemetery; cemeteryToCleanPos = cemeteryToClean.Position; previousState = state; //remember the size to know if there is a need to come back to clean leftToClean = cemeteryToClean.Count; ChangeState(AntState.goToCorpse); } else { //we don't keep empty cemeteries game.Cemeteries.Remove(possibleCemetery); if (state == AntState.backToClean) { cemeteryToClean = null; ChangeState(previousState); } } } } } this.previousPosition = this.position; }