void MouseRelease(MouseButtons B) { if (!(Draw.MousePress() || FileHandler.MousePress() || Draw.SelectedFamily)) { Draw.ScreenToWorld(MousePos.X, MousePos.Y, out Vector V, out VectorI Chunk); Draw.Selected = UpdateWorld.Entities.OfType <SelectableObject>().ToList().Find( x => { Vector RelPos = UpdateWorld.GetRelativePosition(x.ChunkPos, x.Pos, Chunk, V); if (x is Tree T) { if (T.PointOnTree(RelPos)) { return(true); } } return(RelPos.MagSq() < x.Radius * x.Radius * 4); }); ManualControl = false; //Draw.Selected = Creatures.Find(x => (x.Pos - WorldPos).MagSq() < (x.Radius * x.Radius) * 4); //if (Draw.Selected == null) //Draw.Selected = Trees.Find(x => x.PointOnTree(WorldPos)); //Draw.SelectedCreature = Draw.Selected as Creature; //Draw.SelectedTree = Draw.Selected as Tree; //ManualControl = false; } }
public Leaf(Branch Parent, float Pitch, float Yaw, float Roll) { this.Parent = Parent; this.Pitch = Pitch; this.Yaw = Yaw; this.Roll = Roll; Tree = Parent.Tree; Base = Parent.Tip; RotMatrix = new Matrix3(Parent.RotMatrix); //RotMatrix = RotMatrix.RotZ(Yaw).RotX(Pitch).RotZ(Roll); RotMatrix = RotMatrix.RotZ(Yaw).RotY(Pitch).RotZ(Roll); Tip1 = RotMatrix * new Vector3(0, 1, 2); Tip2 = RotMatrix * new Vector3(0, -1, 2); Norm = Vector3.Cross(Tip1, Tip2); Norm.Norm(); Tip1 += Base; Tip2 += Base; Center = (Base + Tip1 + Tip2) / 3; if (Center.Z > Tree.TotalHeight) { Tree.TotalHeight = (float)Center.Z; } Vector Pos = new Vector((float)(Center.X) * SizeScale2d, (float)Center.Y * SizeScale2d) + Tree.Pos; VectorI ChunkPos = Tree.ChunkPos; UpdateWorld.ConstrainVectorInChunk(ref Pos, ref ChunkPos); this.Pos = Pos; this.ChunkPos = ChunkPos; Col = Tree.LeafColor; Vertecies = new Vector3[] { Base, Tip1, Tip2 }; }
public void UpdateArea() { AreaMultiplier = 1; for (int i = -1; i <= 1; i++) { for (int j = -1; j <= 1; j++) { foreach (var Entity in UpdateWorld.Chunks [(ChunkPos.X + i + UpdateWorld.ChunkAmount) % UpdateWorld.ChunkAmount] [(ChunkPos.Y + j + UpdateWorld.ChunkAmount) % UpdateWorld.ChunkAmount].Entities) { { if (Entity is Tree T && Entity != this) { float dist = UpdateWorld.GetRelativePosition(this, T).Mag(); if (dist < T.EnergyRadius + EnergyRadius && T.EnergyRadius > 0)//if their energy circles are touching { float A = GetCoveredArea(EnergyRadius, T.EnergyRadius, dist); float M1 = 1 - (A / ((float)Math.PI * (EnergyRadius * EnergyRadius))) / 2; AreaMultiplier *= M1; float M2 = 1 - (A / ((float)Math.PI * (T.EnergyRadius * T.EnergyRadius))) / 2; T.AreaMultiplier *= M2; NearbyTrees.Add(T, M1); T.NearbyTrees.Add(this, M2); } } } } } } }
void UpdateEnergy() { float PassiveDrain = 0.15f; float ActiveDrain = 0.2f; Energy -= ActiveDrain * (Math.Abs(Outputs[0]) + Math.Abs(Outputs[1])) / 2 + PassiveDrain * (1 + Age / (400 * Form1.fps)); if (EatenFood.Count > 0) { float TotalFoodEnergy = 0; for (int i = 0; i < EatenFood.Count; i++) { TotalFoodEnergy += EatenFood[i].Energy; } float FoodGain = (TotalFoodEnergy * 0.005f) + 0.1f; EatenFood[0].Energy -= FoodGain; Energy += FoodGain; if (EatenFood[0].Energy <= 0.01f) { if (EatenFood[0].Seed) { UpdateWorld.AddEntity(new Seed(EatenFood[0].Parent, Pos, ChunkPos), Pos, ChunkPos); } EatenFood.RemoveAt(0); } } if (Energy <= 0) { Kill(); } }
private void Form1_Load(object sender, EventArgs e) { MouseWheel += Form1_MouseWheel; PB = new PictureBox(); PB.Parent = this; PB.Location = new Point(0, 0); WindowState = FormWindowState.Maximized; PB.Dock = DockStyle.Fill; //BufferedGraphicsContext Context = BufferedGraphicsManager.Current; BG = BufferedGraphicsManager.Current.Allocate(PB.CreateGraphics(), PB.DisplayRectangle); Draw = new Draw(BG.Graphics, PB.Size); T.Interval = (int)(1000 / fps); T.Tick += T_Tick; KeyDown += Form1_KeyDown; KeyUp += Form1_KeyUp; T.Start(); FileHandler = new FileHandler(); SinArray = new float[SinAmount]; CosArray = new float[SinAmount]; for (int i = 0; i < SinAmount; i++) { double angle = Math.PI * 2 * i / (float)SinAmount; SinArray[i] = (float)Math.Sin(angle); CosArray[i] = (float)Math.Cos(angle); } update = new UpdateWorld(); /*for (int i = 0; i < UpdateWorld.MinTrees; i++) * { * float angle = Rand.Next(0, 360); * float Dist = Sqrt((float)Rand.NextDouble()) * (Form1.ArenaRadius - 200); * float X = Cos(angle) * Dist; * float Y = Sin(angle) * Dist; * Trees.Add(new Tree(new Vector(X, Y))); * } * for (int i = 0; i < UpdateWorld.MinCreatures; i++) * { * float angle = Rand.Next(0, 360); * float Dist = Sqrt((float)Rand.NextDouble()) * (Form1.ArenaRadius - 200); * float X = Cos(angle) * Dist; * float Y = Sin(angle) * Dist; * Creatures.Add(new Creature(new Vector(X, Y))); * }*/ update.Reset(); /*NewTree Tr = new NewTree(new Vector(0, 0)); * NewTrees.Add(Tr); * Tr.Leaves[0]=Tr.Branches[0].Leaves[0]= new NewTree.Leaf(Tr.Branches[0],90,-90,0); * Tr = new NewTree(new Vector(0, 200)); * NewTrees.Add(Tr); * Tr.Leaves[0] = Tr.Branches[0].Leaves[0] = new NewTree.Leaf(Tr.Branches[0], 90, 90, 0); * Draw.Selected = Tr;*/ }
void Hatch() { Child.IsEgg = null; Child.Brain.CopyFrom(Parents[0].Brain); int EyeMin = Parents[0].Eyes.Count; int EyeMax = EyeMin; for (int i2 = 1; i2 < Parents.Count; i2++) { int C = Parents[i2].Eyes.Count; if (C > EyeMax) { EyeMax = C; } if (C < EyeMin) { EyeMin = C; } } int EyeAmount = Form1.Rand.Next(EyeMin, EyeMax + 1); Child.Eyes = new List <Creature.Eye>(); for (int i = 0; i < EyeAmount; i++) { int Id = Form1.Rand.Next(Parents.Count); while (Parents[Id].Eyes.Count < i + 1) { Id = (Id + 1) % Parents.Count; } Child.Eyes.Add(new Creature.Eye(Child, Parents[Id].Eyes[i].Pos, Parents[Id].Eyes[i].Fov)); } int EyeId = Form1.Rand.Next(Child.Eyes.Count); double Angle = (Form1.Rand.NextDouble() * 2 - 1) * Math.PI * 0.1; float Sin = (float)Math.Sin(Angle); float Cos = (float)Math.Cos(Angle); Vector OldPos = Child.Eyes[EyeId].Pos; Child.Eyes[EyeId].Pos = new Vector(OldPos.X * Cos + OldPos.Y * Sin, OldPos.Y * Cos - OldPos.X * Sin); Child.Eyes[EyeId].Fov += (float)Form1.Rand.NextDouble() * 0.1f; Child.Eyes[EyeId].Fov = Child.Eyes[EyeId].Fov < 0 ? 0 : Child.Eyes[EyeId].Fov; Child.Eyes[EyeId].Fov = Child.Eyes[EyeId].Fov > 1 ? 1 : Child.Eyes[EyeId].Fov; //mutate Child.Name = Parents[0].Name; Child.Hue = Parents[0].Hue; Child.EggHue = Parents[0].EggHue; Child.Mutate(); UpdateWorld.AddEntity(Child, Pos, ChunkPos); UpdateWorld.RemoveEntity(this); }
public void Kill() { Dead = true; Energy = 0; foreach (var E in Eyes) { E.LookAt = null; } if (Family != null) { Family.Remove(this); } UpdateWorld.RemoveEntity(this); }
void Kill() { Dead = true; foreach (var T in NearbyTrees) { T.Key.AreaMultiplier /= T.Value; T.Key.NearbyTrees.Remove(this); } NearbyTrees.Clear(); UpdateWorld.RemoveEntity(this); for (int i = Leaves.Count - 1; i >= 0; i--) { Leaves[i].Kill(); } }
public void Kill() { Parent.Leaves.Remove(this); if (CurrentFlower != null) { UpdateWorld.RemoveEntity(CurrentFlower); } if (CurrentSeed != null) { UpdateWorld.RemoveEntity(CurrentSeed); } Tree.Leaves.Remove(this); if (Tree.Leaves.Count == 0) { Tree.Kill(); } }
public void MouseDrag(float Dx, float Dy) { if (Selected is Tree) { float mult = 0.3F; Draw3D.angle.Z -= Dx * mult; Draw3D.angle.X += Dy * mult; Draw3D.angle.X = Math.Max(Math.Min(Draw3D.angle.X, 0), -90); } else { //CameraPosition.X -= Dx / Zoom; //CameraPosition.Y -= Dy / Zoom; CameraPos2 -= new Vector(Dx, Dy) / Zoom; UpdateWorld.ConstrainVectorInChunk(ref CameraPos2, ref CameraChunk); } }
void Eat(Entity E) { bool Extend; if (!(Draw.Selected == this && Form1.ManualControl)) { Extend = UseSpike; } else { Extend = Form1.HoldKeys.Contains(System.Windows.Forms.Keys.Space); } if (E is Seed S && S.EnableCollide && !Extend) { Energy += 125; S.Dead = true; UpdateWorld.RemoveEntity(S); }
public void Fall() { EnableCollide = true; float Angle = Form1.Rand.Next(0, 360); float Rad = (float)(Math.Sqrt(Form1.Rand.NextDouble()) * Leaf.Center.Z * Tree.SizeScale2d); Vector DeltaPos = new Vector(Form1.Cos(Angle) * Rad, Form1.Sin(Angle) * Rad); //Vector DeltaPos = new Vector(UpdateWorld.ChunkSize,0); //Pos = new Vector((float)(Leaf.Center.X)*Tree.SizeScale2d, (float)Leaf.Center.Y * Tree.SizeScale2d) + DeltaPos + Leaf.Tree.Pos; //ChunkPos = Leaf.Tree.ChunkPos; Pos += DeltaPos; //Vector OldPos = Pos; //VectorI OldChunk = ChunkPos; UpdateWorld.ConstrainEntityInChunk(this); if (!UpdateWorld.Chunks[ChunkPos.X][ChunkPos.Y].Entities.Contains(this)) { throw new Exception("Entity has wrong chunk"); } }
public void Update() { if (EnableCollide) { SeedTimer += 1 / Form1.fps; if (Dead) { UpdateWorld.RemoveEntity(this); } if (SeedTimer > SeedTimerMax) { Tree Tree = new Tree(Parent, Pos, ChunkPos) { Energy = StartEnergy }; UpdateWorld.AddEntity(Tree, Pos, ChunkPos); UpdateWorld.RemoveEntity(this); } } }
public void Update() { foreach (Eye E in Eyes) { E.Update(); } updateBrain(); UseSpike = Outputs[2] > 0.5; Move(); UpdateEnergy(); if (Energy > EggEnergy + StartEnergy) { Energy -= EggEnergy * 1.25f; UpdateWorld.AddEntity(new Egg(this), Pos, ChunkPos); } Age++; if (LeafEatTimer > 0) { LeafEatTimer--; } }
public void ScreenToWorld(float x, float y, out Vector V, out VectorI C) { V = new Vector((x - Form1.PB.Width / 2) / Zoom + CameraPos2.X, (y - Form1.PB.Height / 2) / Zoom + CameraPos2.Y); C = CameraChunk; UpdateWorld.ConstrainVectorInChunk(ref V, ref C); }
public PointF WorldToScreen(VectorI Chunk, Vector Pos) { Vector V = UpdateWorld.GetRelativePosition(CameraChunk, CameraPos2, Chunk, Pos) * Zoom; return(new PointF(V.X, V.Y)); }
public void Update(NeuralNetwork Network) { Age++; if (CurrentSeed != null) { SeedTimer += Tree.MaxTimer / Form1.fps; if (SeedTimer > SeedTimerMax) { CurrentSeed.Fall(); //UpdateWorld.AddEntity(CurrentSeed, CurrentSeed.Pos, CurrentSeed.ChunkPos); CurrentSeed = null; } } float L1 = (float)Form1.Rand.NextDouble(); float L2 = (float)Form1.Rand.NextDouble(); if (L1 + L2 > 1) { L1 = 1 - L1; L2 = 1 - L2; } RayPoint = Base + (Tip1 - Base) * L1 + (Tip2 - Base) * L2; float[] Inputs = Tree.Inputs; Inputs[2] = 0; Inputs[3] = (Parent.Layer + 1) / 3f; Inputs[4] = 0; Inputs[5] = CurrentSeed == null?0:1; Inputs[6] = EnergyFlow; Inputs[7] = Age / (AgeScale * Form1.fps); Inputs[8] = CurrentFlower != null ? 1 : 0; Inputs[9] = CurrentFlower != null ? (CurrentFlower.CurrentEnergy / FruitCost): 0; Network.SetInputs(Inputs); Network.Update(); float[] Outputs = Network.GetOutputs(); if (CurrentFlower != null) { CurrentFlower.Update(Network.Clamp(Outputs[11], 0, 1)); } if (Outputs[0] < -1) { Tree.Energy += LeafCost / 2; Kill(); } else { if (Outputs[9] > 0) { if (CurrentSeed == null && CurrentFlower == null && Tree.Energy > SeedCost) { Tree.Energy -= SeedCost; CurrentSeed = new Seed(Tree, this); UpdateWorld.AddEntity(CurrentSeed, CurrentSeed.Pos, CurrentSeed.ChunkPos); } else { Tree.Energy -= SeedCost / 20; } } if (Outputs[10] > 0) { if (CurrentSeed == null && CurrentFlower == null && Tree.Energy > FlowerCost) { Tree.Energy -= FlowerCost; CurrentFlower = new Flower(this); UpdateWorld.AddEntity(CurrentFlower, Pos, ChunkPos); } else { Tree.Energy -= FlowerCost / 20; } } } }