Guten Tag,
Es geht sich um folgendes. Ich bin zurzeit dabei ein Spiel zu programmieren.
Es ist so das alle Gegner 1px bewegt werden, dannach wird eine Procedur aufgerufen die prüft, ob die Türme noch ein Ziel haben, wenn nicht wird der Gegner der in der Reichweite des Turmes liegt und am nahsten dran ist zum Ziel. Zuletzt wird ein Timer für den Turm erstellt.
Dieser prüft dann jedes mal ob das Ziel noch in Reichweite ist. Wenn ja "schießt" es auf den Gegner.
Hat der Gegner dann <=0 Lebenspunkte, wird der Timer wieder freigegeben.
Sonst soll er halt den Intervall abwarten und nochmal die Timer Procedure ausführen.
Das ganze läuft aber in der Praxis nicht wirklich flüssig ab
Es sieht so aus als würde immer nur ein timer ablaufen. Also wenn dort 10 Türme stehen, wird trotzdem nur alle 0,5 sek geschossen.
Wodran könnte es liegen? Wie kann man das ganze Optimieren?
Hier sind die Proceduren und im Anhang lad ich noch die Compilierte .exe hoch, fals man es sich genau anschauen möchte.
Delphi-Quellcode:
procedure TFormMain.moveEnemies(value: TGameStatus);
var
fieldX, fieldY: Integer;
i,k,j: Integer;
tmpField :array of TNextField;
begin
SetLength(tmpField,High(EnemyManager.enemys[Player.Level]));
for k := 0 to High(EnemyManager.enemys[Player.Level]) do
begin
fieldX := (EnemyManager.enemys[Player.Level][k].Pixels.X ) div 32;
fieldY := (EnemyManager.enemys[Player.Level][k].Pixels.Y ) div 32;
tmpField[k] := map.Playground[fieldX][fieldY].nextField;
end;
for j := 0 to 31 do
begin
for i := 0 to High(EnemyManager.enemys[Player.Level]) do
begin
if EnemyManager.enemys[Player.Level][i].isRunning then
begin
case tmpField[i] of
nfDown: EnemyManager.moveEnemy(EnemyManager.enemys[Player.Level][i],nfDown);
nfRight: EnemyManager.moveEnemy(EnemyManager.enemys[Player.Level][i],nfRight);
nfLeft: EnemyManager.moveEnemy(EnemyManager.enemys[Player.Level][i],nfLeft);
nfUp: EnemyManager.moveEnemy(EnemyManager.enemys[Player.Level][i],nfUp);
nfStay:
begin
EnemyManager.enemys[Player.Level][i].isRunning := false;
EnemyManager.enemys[Player.Level][i].HP := 0;
Player.Lives := (Player.Lives -1);
lblLives.Caption := 'Leben: ' +IntToStr(Player.Lives);
if Player.Lives = 0 then
begin
isUpgrading := False;
SetGameStatus(gsGAMEOVER);
LastFocus.fieldKind := fkUkn;
exit;
end;
end;
end;
if tmpField[i] <> nfStay then
FightManager.Fight(i);
end;
end;
Draw;
end;
end;
Delphi-Quellcode:
procedure TFightManager.Fight(indexOfEnemy: integer);
var i,k: integer;
minDistance,distance: Integer;
targetChanged: Boolean;
tw: TFightTower;
enemy: TEnemy;
begin
if (EM.enemys[FormMain.Player.Level][indexOfEnemy].isRunning ) then
begin
for I := 0 to listTower.Count -1 do
begin
tw := (TObject(listTower.Items[i]) as TFightTower );
if (tw.target = -1) then
begin
targetChanged := false;
minDistance :=tw.range div 2;
for k := 0 to High(EM.enemys[FormMain.Player.Level]) do
begin
enemy := EM.enemys[FormMain.Player.Level][k];
if enemy.isRunning then
begin
distance := getDistanceFromTowerToEnemy(tw,enemy);
if (minDistance > distance) and ( distance < tw.range div 2) then
begin
minDistance := distance;
tw.target := k;
targetChanged := true;
end
end;
end;
if targetChanged then
begin
FormMain.lblActTarget.caption := 'Ziel: ' + IntToStr((TObject(listTower.Items[i]) as TFightTower ).target);
FormMain.lblActTargetsHP.Caption := 'HP des Ziels: '+ IntToStr((TObject(EM.enemys[FormMain.Player.Level][(TObject(listTower.Items[i]) as TFightTower ).target]) as TEnemy ).HP);
createTimer(tw);
end;
end
end;
end;
end;
Delphi-Quellcode:
procedure TFightManager.CreateTimer(tower: TTower);
var timer: TTimer;
a: integer;
begin
timer := TTimer.Create(nil);
timer.Enabled := False;
timer.Interval := Round((tower as TFightTower).Speed * 1000);
timer.OnTimer := TimerProc;
timer.Enabled := true;
a := listTower.IndexOf(tower);
listTowerTimer.AddObject(IntToStr(a),timer);
end;
Delphi-Quellcode:
procedure TFightManager.TimerProc(Sender: TObject);
var a,distance,target: integer;
enemy: TEnemy;
tw: TFightTower;
b: string;
begin
a := listTowerTimer.IndexOfObject(Sender);
b := listTowerTimer.Strings[a];
tw := TObject(listTower.Items[StrToInt(b)]) as TFightTower;
target := tw.target;
if (target > -1) then
begin
enemy := EM.enemys[FormMain.Player.Level][target];
distance := getDistanceFromTowerToEnemy(tw,enemy );
if (distance < (tw.range div 2)) then
begin
ShotOnEnemy(tw.Damage,target);
FormMain.lblActTarget.caption := 'Ziel: ' + IntToStr(tw.target);
FormMain.lblActTargetsHP.Caption := 'HP des Ziels: '+ IntToStr(enemy.HP);
if enemy.HP <= 0 then
begin
tw.target := -1;
listTowerTimer.Delete(listTowerTimer.IndexOfObject(Sender));
(Sender as TTimer).Free;
end;
end
else
begin
tw.target := -1;
listTowerTimer.Delete(listTowerTimer.IndexOfObject(Sender));
(Sender as TTimer).Free;
end;
end
else
(Sender as TTimer).Free;
end;