public Environment(String name, short foodValue, short energyValue, short size, short xPos, short yPos, int type, int randSeed, Crop theCrop) { this.name = name; this.foodValue = foodValue; this.size = size; this.energyValue = energyValue; this.position = new Vector2((float)xPos, (float)yPos); this.type = type; this.frame = 0; random = new Random(randSeed); this.theCrop = theCrop; switch (type) { case 0: spriteRectangle = Sprites.flower; break; case 1: spriteRectangle = Sprites.flower; break; default: spriteRectangle = Sprites.flower; break; } float w = size * 0.1f * spriteRectangle.Width; float h = size * 0.1f * spriteRectangle.Height; orientation = random.Next(62) * 0.1f; origin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2); body = new CircleOfLife.RotatedRectangle(new Rectangle(xPos, yPos, (int)w, (int)h), orientation); color = Color.Green; }
//constructor public Creature(int xPos, int yPos, Ecosystem.speciesStats stats, Random seed, Species parent) { this.parent = parent; diet = stats.diet; switch (diet) { case 0: spriteRectangle = Sprites.herbivore; break; case 1: spriteRectangle = Sprites.carnivore; break; default: spriteRectangle = Sprites.mormo; break; } size = stats.size; detection = stats.detection; speed = stats.speed; energyCap = stats.energyCap; foodCap = stats.foodCap; waterCap = stats.waterCap; energyValue = stats.energyValue; agility = stats.agility; color = stats.color; random = seed; position = new Vector2(xPos, yPos); orientation = new float(); origin = new Vector2(spriteRectangle.Width / 2, spriteRectangle.Height / 2); body = new RotatedRectangle(new Rectangle(xPos - size / 2, yPos - size / 2, size, size), orientation); state = 0; //wander food = 0; water = waterCap; energy = energyCap; currSpeed = 1f; deathtimer = new TimeSpan(0, 0, 0); feedTimer = new TimeSpan(0, 0, 0); sprintTime = new TimeSpan(0, 0, 0); restTime = new TimeSpan(0, 0, 0); //Death corpseTimer = new TimeSpan(0, 0, 0); rotTime = 15; rotStage = 0; this.stamina = 6; this.mapWidth = 1920; //hmm this.mapHeight = 1920; foodValue = 30;//Should be tweeked(size) randomGoal(mapWidth, mapHeight); //animation offset frameOffset = random.Next(4); //REMOVE THIS!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! if(diet == 1) this.energyCap *= 5; }
public void update(GameTime gameTime) { if (state == 4) { corpseTimer += gameTime.ElapsedGameTime; if (corpseTimer > TimeSpan.FromSeconds(rotTime) || foodValue < 1) state = 6; else if (corpseTimer > TimeSpan.FromSeconds(rotTime*2/3) || foodValue < 10) rotStage = 2; else if (corpseTimer > TimeSpan.FromSeconds(rotTime * 1 / 3) || foodValue < 20) rotStage = 1; } else if (state == 1) // chase { this.sprintTime += gameTime.ElapsedGameTime; Chase(position, ref prey, ref orientation, agility); Vector2 heading = new Vector2((float)Math.Cos(orientation), (float)Math.Sin(orientation)); if (currSpeed < speed) { currSpeed += 0.03f * currSpeed; } position += heading * currSpeed; } else if (state == 0) // wander { this.restTime += gameTime.ElapsedGameTime; if (flora != null && this.diet == 0) { goalPosition = flora.position; } else if (prey != null && this.diet == 1) { goalPosition = prey.position; } Wander(position, ref goalPosition, ref orientation, agility); Vector2 heading = new Vector2( (float)Math.Cos(orientation), (float)Math.Sin(orientation)); if (currSpeed > 0.25f * speed) { currSpeed -= 0.05f * currSpeed; } position += heading * currSpeed; } else if (state == 2) // evade { this.sprintTime += gameTime.ElapsedGameTime; Evade(position, ref predator, ref orientation, agility); Vector2 heading = new Vector2( (float)Math.Cos(orientation), (float)Math.Sin(orientation)); if (currSpeed < speed) { currSpeed += 0.07f * currSpeed; } position += heading * currSpeed; } else if (state == 3) // feed { this.currSpeed = 0.25f * speed; } deathtimer += gameTime.ElapsedGameTime; // remove energy if (deathtimer > TimeSpan.FromSeconds(1)) { this.energy -= 2; if (energy < 0) { // kill the creature this.state = 4; } deathtimer = TimeSpan.Zero; } float w = this.size * 0.01f * spriteRectangle.Width; float h = this.size * 0.01f * spriteRectangle.Height; body = new RotatedRectangle(new Rectangle((int)position.X, (int)position.Y, (int)w, (int)h), orientation); this.width = w; this.height = h; }
/// <summary> /// Check to see if two Rotated Rectangls have collided /// </summary> /// <param name="theRectangle"></param> /// <returns></returns> public bool Intersects(RotatedRectangle theRectangle) { //Calculate the Axis we will use to determine if a collision has occurred //Since the objects are rectangles, we only have to generate 4 Axis (2 for //each rectangle) since we know the other 2 on a rectangle are parallel. List<Vector2> aRectangleAxis = new List<Vector2>(); aRectangleAxis.Add(UpperRightCorner() - UpperLeftCorner()); aRectangleAxis.Add(UpperRightCorner() - LowerRightCorner()); aRectangleAxis.Add(theRectangle.UpperLeftCorner() - theRectangle.LowerLeftCorner()); aRectangleAxis.Add(theRectangle.UpperLeftCorner() - theRectangle.UpperRightCorner()); //Cycle through all of the Axis we need to check. If a collision does not occur //on ALL of the Axis, then a collision is NOT occurring. We can then exit out //immediately and notify the calling function that no collision was detected. If //a collision DOES occur on ALL of the Axis, then there is a collision occurring //between the rotated rectangles. We know this to be true by the Seperating Axis Theorem foreach (Vector2 aAxis in aRectangleAxis) { if (!IsAxisCollision(theRectangle, aAxis)) { return false; } } return true; }
/// <summary> /// Determines if a collision has occurred on an Axis of one of the /// planes parallel to the Rectangle /// </summary> /// <param name="theRectangle"></param> /// <param name="aAxis"></param> /// <returns></returns> private bool IsAxisCollision(RotatedRectangle theRectangle, Vector2 aAxis) { //Project the corners of the Rectangle we are checking on to the Axis and //get a scalar value of that project we can then use for comparison List<int> aRectangleAScalars = new List<int>(); aRectangleAScalars.Add(GenerateScalar(theRectangle.UpperLeftCorner(), aAxis)); aRectangleAScalars.Add(GenerateScalar(theRectangle.UpperRightCorner(), aAxis)); aRectangleAScalars.Add(GenerateScalar(theRectangle.LowerLeftCorner(), aAxis)); aRectangleAScalars.Add(GenerateScalar(theRectangle.LowerRightCorner(), aAxis)); //Project the corners of the current Rectangle on to the Axis and //get a scalar value of that project we can then use for comparison List<int> aRectangleBScalars = new List<int>(); aRectangleBScalars.Add(GenerateScalar(UpperLeftCorner(), aAxis)); aRectangleBScalars.Add(GenerateScalar(UpperRightCorner(), aAxis)); aRectangleBScalars.Add(GenerateScalar(LowerLeftCorner(), aAxis)); aRectangleBScalars.Add(GenerateScalar(LowerRightCorner(), aAxis)); //Get the Maximum and Minium Scalar values for each of the Rectangles int aRectangleAMinimum = aRectangleAScalars.Min(); int aRectangleAMaximum = aRectangleAScalars.Max(); int aRectangleBMinimum = aRectangleBScalars.Min(); int aRectangleBMaximum = aRectangleBScalars.Max(); //If we have overlaps between the Rectangles (i.e. Min of B is less than Max of A) //then we are detecting a collision between the rectangles on this Axis if (aRectangleBMinimum <= aRectangleAMaximum && aRectangleBMaximum >= aRectangleAMaximum) { return true; } else if (aRectangleAMinimum <= aRectangleBMaximum && aRectangleAMaximum >= aRectangleBMaximum) { return true; } return false; }