version: 4.4.3
i am making a game where plants grow and multiply. first i did this with objects but now i am using the _draw function to draw them line by line. but i amr unning into a problem where the lines after the first two stages of growth are drawn instantly to there end point instead of growing gradually how can i fix this?
heres my code:
use [new Vector3(100, (float)PPTypes.Branch, 30), new Vector3(100, (float)PPTypes.Leaf, 0), new Vector3(100, (float)PPTypes.Leaf, 90), new Vector3(100, (float)PPTypes.Leaf, 270),new Vector3(100, (float)PPTypes.Branch, 30),new Vector3(100, (float)PPTypes.Branch, 330),new Vector3(100, (float)PPTypes.Branch, 300),new Vector3(100, (float)PPTypes.Branch, 30), new Vector3(100, 1, 90), new Vector3(100, 1, 270), new Vector3(100, (float)PPTypes.Leaf, 90), new Vector3(100, (float)PPTypes.Leaf, 270),new Vector3(100, (float)PPTypes.Leaf, 90), new Vector3(100, (float)PPTypes.Branch, 30), new Vector3(100, (float)PPTypes.SeedGrowingOrgan, 100)] in GeneticCode and [1,0,5,4,2,5,2,6,3,7,1,13,1] in ReplicationSteps
using Godot;
using System;
using System.Collections.Generic;
public partial class LineDrawnPlantGrowing : Node2D
{
enum PPTypes
{
Branch,Leaf,Flower,SeedGrowingOrgan,Root,Energycollector,
all = 255
}
//LinePart Stuff
List LinePartEndAddres = [];
List LenghtsToGrowTo = [];
List ScalesGrown = [];
int PartsFullyGrown;
float GrowthSpeed = 5;
short FullyGrown;
List LinePartsEnds = [];
List LinePartsStarts = [];
List StoreGrowingLinePartsEnds = [];
List LinePartWidths = [];
Vector3[] GeneticCode = [];
int[] ReplicationSteps = [];
byte[] FruitsAndFlowersGenes = [0,1];
Color BaseColor;
bool HasBeenMined = false;
byte MoveRepSteps;
int StepsAmount;
int stepsToTake;
int StepsStart;
int originalSteps;
byte procreationallowed;
int Energy;
bool rotatetoleft;
float rotationSpeed = 0.1f;
bool AllowedToGrow;
bool Dying = false;
public async override void _Ready()
{//add checking for if other plants are too close
//cannot rotate
if(GD.RandRange(0, 1) == 0)
{
BaseColor = Color.Color8(139, (byte)GD.RandRange(210, 255), 0);//original plant if you want to go back to that rgb(139,255,0,255)
}
else
{
BaseColor = Color.Color8((byte)GD.RandRange(20, 255),0,(byte)GD.RandRange(20, 255));
}
if(GD.RandRange(0,1) == 0)
{
rotatetoleft = true;
}
await ToSignal(GetTree().CreateTimer(GD.RandRange(20,60)), SceneTreeTimer.SignalName.Timeout);//temp(lie)
Dying = true;
DeathAnimation();
}
private void GetSpecies(Vector3[] PreGeneticCode,int[] PreReplicationSteps)
{
GeneticCode = PreGeneticCode;
ReplicationSteps = PreReplicationSteps;
stepsToTake = PreReplicationSteps[0];
if(GeneticCode != Array.Empty() && ReplicationSteps != Array.Empty())
{
InitialPlantPartLines();
AllowedToGrow = true;
}
}
public override void _PhysicsProcess(double delta)
{
if(Dying)
{
DeathAnimation();
return;
}
if (StepsAmount < GeneticCode.Length && AllowedToGrow)
{
MainLoop();
}
else
{
if(procreationallowed < 2 && GetParent().GetChildCount() < 1000)//add this behaviour to the seeds so the script plantparts and to fullygrown seeds
{//can grow 500 plants at a time at 30 to 50 fps and 1000 at 8 to 20 fps and rested at 40 to 60 fps with 3000 non active plants// it does slighty better than this now but slighty worse resting
var preNewPlant = GD.Load(“res://PlantGrower/tscn/line_drawn_plant.tscn”);//add to seed
var NewPlant = preNewPlant.Instantiate();
AddChild(NewPlant);
NewPlant.Set(Node2D.PropertyName.Position, new Vector2(Mathf.Snapped(GD.RandRange(-150,150),60),Mathf.Snapped(GD.RandRange(-150,150),60)));
NewPlant.Call(“GetSpecies”,GeneticCode,ReplicationSteps);
NewPlant.Reparent(GetParent());
procreationallowed++;
return;
}
}
}
private void MainLoop()
{
if(LinePartEndAddres.Count == 0)
{
//ScalesGrown = [];
if (stepsToTake > 0)
{
CreateNewLineSegments();
}
else
{
if(MoveRepSteps < ReplicationSteps.Length - 2)
{
MoveRepSteps += 2;
stepsToTake = ReplicationSteps[MoveRepSteps];
originalSteps = ReplicationSteps[MoveRepSteps - 1];
}
}
}
else
{
GrowLineEnds();
}
}
private void CreateNewLineSegments()
{
for(int i = 0; i < stepsToTake;)
{
Vector3 LinePartGene = GeneticCode[StepsAmount];
PlantPartTypes((PPTypes)LinePartGene[1]);
LinePartsStarts.Add(LinePartsEnds[originalSteps]);
LinePartsEnds.Add(LinePartsEnds[originalSteps]);
StoreGrowingLinePartsEnds.Add(LinePartsEnds[originalSteps] + new Vector2(0,-LenghtsToGrowTo[StepsAmount]).Rotated(Mathf.DegToRad(LinePartGene[2])));
LinePartEndAddres.Add(StepsAmount);
ScalesGrown.Add(0);
StepsAmount++;
i++;
}
stepsToTake = 0;
QueueRedraw();
}
public override void _Draw()
{
for(int i = 0; i < StepsAmount;)
{
DrawLine(LinePartsStarts[i],LinePartsEnds[i],BaseColor,LinePartWidths[i]);
i++;
}
}
private async void DeathAnimation()
{
if(HasBeenMined)
{
Dying = false;
return;
}
if(RotationDegrees < 90)
{
RotationDegrees += (float)GetProcessDeltaTime() * 60;
}
else
{
RotationDegrees = 91;
Dying = false;
await ToSignal(GetTree().CreateTimer(0.5f), SceneTreeTimer.SignalName.Timeout);
QueueFree();
}
}
private int ChangeEnergy(ref int PreEnergy)
{
Energy += PreEnergy;
return 0;
}
private int ChangeResources(ref int PreResource)
{
//Resource += PreResource;
return 0;
}
private void MinePlant()//needs to be changed
{
GD.Print(“*Mined”);
if(HasBeenMined == true)
{
return;
}
for(int i = -1; i < GetChildCount(); i++)
{
if(GetChild(i).HasMethod(“BecomeItem”))
{
GetChild(i).CallDeferred(“BecomeItem”);
}
}
HasBeenMined = true;
}
private void PlantPartTypes(PPTypes IntNameCode)
{//add mutation and thus evolution
switch (IntNameCode)
{
case PPTypes.Branch:
LenghtsToGrowTo.Add(30);
LinePartWidths.Add(6);
break;
case PPTypes.Leaf:
LenghtsToGrowTo.Add(15);
LinePartWidths.Add(5);
break;
case PPTypes.Flower:
LenghtsToGrowTo.Add(3);
LinePartWidths.Add(3);
//SelfModulate = Color.Color8(150,0,0);
break;
case PPTypes.SeedGrowingOrgan:
LenghtsToGrowTo.Add(8);
LinePartWidths.Add(5);
//SelfModulate = Color.Color8(60,200,0);
break;
default:
LenghtsToGrowTo.Add(1);
LinePartWidths.Add(1);
break;
}
}
private void InitialPlantPartLines()
{
for(int i = 0; i < stepsToTake;)
{
Vector3 LinePartGene = GeneticCode[StepsAmount];
PlantPartTypes((PPTypes)LinePartGene[1]);
LinePartsStarts.Add(new Vector2(0,0));
LinePartsEnds.Add(new Vector2(0,0));
StoreGrowingLinePartsEnds.Add(new Vector2(0,-LenghtsToGrowTo[StepsAmount]).Rotated(Mathf.DegToRad(LinePartGene[2])));
LinePartEndAddres.Add(StepsAmount);
ScalesGrown.Add(0);
StepsAmount++;
i++;
GD.Print(stepsToTake,“&”);
}
stepsToTake = 0;
QueueRedraw();
}
private void GrowLineEnds()//should remove ScalesGrown after growth is done
{
for(int i = 0; i < StoreGrowingLinePartsEnds.Count;)
{
if(ScalesGrown[i] >= 1)
{
LinePartsEnds[LinePartEndAddres[i]] = StoreGrowingLinePartsEnds[i];
StoreGrowingLinePartsEnds.RemoveAt(i);
LinePartEndAddres.RemoveAt(i);
PartsFullyGrown++;
return;
}
LinePartsEnds[LinePartEndAddres[i]] = new Vector2(Mathf.Lerp(LinePartsStarts[LinePartEndAddres[i]].X,StoreGrowingLinePartsEnds[LinePartEndAddres[i]].X,ScalesGrown[LinePartEndAddres[i]]),Mathf.Lerp(LinePartsStarts[LinePartEndAddres[i]].Y,StoreGrowingLinePartsEnds[LinePartEndAddres[i]].Y,ScalesGrown[LinePartEndAddres[i]]));
ScalesGrown[LinePartEndAddres[i]] += GrowthSpeed * 0.01f;
i++;
}
QueueRedraw();
}
}