[b3d]Genaues Zielen[Gelöst]

Übersicht BlitzBasic Beginners-Corner

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen

joshmami

Betreff: [b3d]Genaues Zielen[Gelöst]

BeitragSa, Mai 14, 2011 0:29
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo Community!
Es tut mir Leid, dass ich zum wiederholten Male in letzter Zeit mit einer Frage
auftauche, aber ohne Hilfe geht es eben manchmal nicht.
Ich will, dass wenn ein Schuss abgefeuert wird, automatisch das nächste Flugzeug anvisiert und getroffen wird.
Ich habe einen Pivot namens Schusszieler erstellt und damit Linepick verwendet
BlitzBasic: [AUSKLAPPEN]

PositionEntity Schusszieler,EntityX(Plane),EntityY(Plane),EntityZ(Plane);Plane ist das Flugzeug des Players
RotateEntity Schusszieler,EntityPitch(Plane),EntityYaw(Plane),0
MoveEntity Schusszieler,0,0,1000
Angepeilt = LinePick(EntityX(Plane),EntityY(Plane),EntityZ(Plane),EntityX(Schusszieler),EntityY(Schusszieler),EntityZ(Schusszieler),50)
If Angepeilt Then
PositionEntity Schusszieler,EntityX(Angepeilt),EntityY(Angepeilt),EntityRoll(Angepeilt)
RotateEntity Schusszieler,EntityPitch(Angepeilt),EntityYaw(Angepeilt),EntityRoll(Angepeilt)
MoveEntity Schusszieler,0,0,EntityDistance(Plane,Angepeilt)/120;Siehe Erklärung
EndIf
PointEntity Schuss\Ent,Schusszieler

Bei der Zeile:"MoveEntity Schusszieler,0,0,EntityDistance(Plane,Angepeilt)/120"
habe ich mir gedacht, dass das Gegnerische Flugzeug sich ja auch noch fortbewegt und wollte damit gewährleisten,dass der schuss auf jeden fall trifft.
120 ist die Geschwindigkeit, mit der sich der Schuss bewegt, und indem ich den Pivot(auf den ja gezielt wird) schon gleich im voraus verschiebe, sollte der Schuss doch eigentlich treffen, oder?
Stattdessen landet der Schuss irgendwo, noch weiter weg als wenn ich nur PointEntity verwendet hätte.Woran liegt das?
  • Zuletzt bearbeitet von joshmami am Mo, Mai 16, 2011 14:54, insgesamt 4-mal bearbeitet

Ana

BeitragSa, Mai 14, 2011 2:27
Antworten mit Zitat
Benutzer-Profile anzeigen
Mir ist nich so ganz klar wie sich dein Schuss verhalten soll, soll er in eine bestimmte Richtung geschossen werden und zum richtigen Zeitpunkt kommen, oder soll er zu einem bestimmten Zeitpunkt an die Stelle schießen, an dem dann das Flugzeug ist wenn der Schuss seine Bahn kreuzt? Letzteres ist meiner Meinung nach ziemlich schwierig, da du meines erachtens eine Differenzialgleichung bekommst, kann aber auch sein das ich mich irre Very Happy

Die Zeile :"MoveEntity Schusszieler,0,0,EntityDistance(Plane,Angepeilt)/120" glaube ich nicht das sie tut was du möchtest. Sie bewegt den Schuss jeweils um ein 120stel der Strecke, sprich er wird immer langsamer je geringer die Distanz noch ist. Du willst glaube ich aber, das der Schuss die Strecke in 120 Frames schaft, dann musst du beim Start die Distanz bestimmen und dann speichern und immer wieder diese verwenden und nicht jedesmal eine neue bestimmen. Dann kannst du den Pivot auch einfach auf die Flugzeugposition und dann um 120 * Geschwindigkeit verschieben.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragSa, Mai 14, 2011 12:06
Antworten mit Zitat
Benutzer-Profile anzeigen
Ana hat Folgendes geschrieben:
oder soll er zu einem bestimmten Zeitpunkt an die Stelle schießen, an dem dann das Flugzeug ist wenn der Schuss seine Bahn kreuzt?

Genau!
Ich dachte: Wenn ich den Pivot um die Anzahl der Frames, die der Schuss im Moment brauchen würde um die Distanz zwischen Ziel und Flugzeug zu überwinden in die Richtung, in die das Flugzeug fliegt verschiebe und, wie mir
gerade eben erst klar geworden ist, mit der Geschwindigkeit des Flugzeugs pro Frame multipliziere, müsste es doch eigentlich genau treffen.
Tut es aber nicht.Ich habe jetzt noch die Fluggeschwindigkeit hinzugefügt und der jetzige code ist:BlitzBasic: [AUSKLAPPEN]

Angepeilt = LinePick(EntityX(Plane),EntityY(Plane),EntityZ(Plane),EntityX(Schusszieler),EntityY(Schusszieler),EntityZ(Schusszieler),50)
If Angepeilt Then
For Gegner.TypeGegner = Each TypeGegner
If Gegner\Ent = Angepeilt Then
PositionEntity Schusszieler,EntityX(Angepeilt),EntityY(Angepeilt),EntityRoll(Angepeilt)
RotateEntity Schusszieler,EntityPitch(Angepeilt),EntityYaw(Angepeilt),EntityRoll(Angepeilt)
MoveEntity Schusszieler,0,0,EntityDistance(Plane,Angepeilt)/120*Gegner\Speed
EndIf
Next
EndIf
PointEntity Schuss\Ent,Schusszieler


Übrigens wollte ich noch hinzufügen, dass das ganze nur beim Abfeuern einmalig passiert, also wird nichts langsamer.

Ana

BeitragSa, Mai 14, 2011 17:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Nein tut es leider nicht, so einfach ist das nicht. Du hast hier irgendwann ein Gleichung der Art, das du sowohl Zeit, als auch Winkel benötigst, und beides nicht hast, mit nur einem Fehlenden kannst du die Gleichung lösen, mit 2en ist das schon schwieriger, aber du kannst die numerisch annähern, in dem du folgenden Algorithmus verwendest:

1. Setze Pivot eine Einheit(nicht umbedingt 1, sondern wie viel in einem Frame geschaft wird) in Flugrichtung.
2. erhöhe t um 1.
3. Überprüfe ob t * Schussgewindigkeit = Pivot/Schussstart-Distanz ist (eventuell hier eine toleranz einbauen)
Falls ja: hast du die Position gefunden die du suchst
Falls nein: springe zu 1

Die Toleranz sollte zumindest +/- Flugzeuggeschwindigkeit/2 sein.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragSa, Mai 14, 2011 19:33
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich habe das jetzt versucht so umzusetzen, allerdings komme ich da in eine Endlosschleife.BlitzBasic: [AUSKLAPPEN]
	If Angepeilt Then
For Gegner.TypeGegner = Each TypeGegner
If Gegner\Ent = Angepeilt Then
PositionEntity Schusszieler,EntityX(Angepeilt),EntityY(Angepeilt),EntityRoll(Angepeilt)
RotateEntity Schusszieler,EntityPitch(Angepeilt),EntityYaw(Angepeilt),EntityRoll(Angepeilt)
t = 0
Repeat
MoveEntity Schusszieler,0,0,Gegner\Speed
t = t + 1
Until t*120 > EntityDistance(Plane,Schusszieler) - 1 And t*120 < EntityDistance(Plane,Schusszieler) + 1
EndIf
Next
EndIf

Ana

BeitragSa, Mai 14, 2011 19:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Versuchs mal mit Gegner\Speed statt der 1 oder ist Gegner\Speed = 1?

Wenn das z.B 5 wäre würdest du vielleicht die Distanzen +3 und im nächsten Schritt -2 haben und dann ist es nie in dem einser Intervall.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragSa, Mai 14, 2011 19:43
Antworten mit Zitat
Benutzer-Profile anzeigen
Gegner\Speed ist in dem Fall 1

Ana

BeitragSa, Mai 14, 2011 22:35
Antworten mit Zitat
Benutzer-Profile anzeigen
ist schusszieler der Pivot oder der Startpunkt des Schusses?
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

biggicekey

BeitragSo, Mai 15, 2011 10:12
Antworten mit Zitat
Benutzer-Profile anzeigen
wie wäre es statt vorauszuberechnen wo hin geschossen werden muss, einfach ein Projektil zu machen welches sein Ziel verfolgt? Wesentlich einfacher, "gleicher" Effekt.
#45 www.icekeyunlimited.de www.starcrusade.de
Gewinner BCC#17 !!! mit dotkiller
Nothing more to register - you've cleaned us out![/size]

joshmami

BeitragSo, Mai 15, 2011 11:51
Antworten mit Zitat
Benutzer-Profile anzeigen
@Ana: Schusszieler ist der Pivot
@biggicekey: Aber dann würde man doch sehen, dass sich die Laufbahn des Schusses krümmt

Ana

BeitragSo, Mai 15, 2011 12:15
Antworten mit Zitat
Benutzer-Profile anzeigen
Du musst aber Distanz vom Startpunkt des Schusses zum Zielpunkt des Schusses nehmen,Plane sollte da nicht drin sein, dann solltes es auch klappen, die Distanz von Plane und Schusszieler sollte ja immer fleißig wachsen.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragSo, Mai 15, 2011 12:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Ja,Plane ist ja der Startpunkt des Schusses, ich habe Plane das Flugzeug des Players genannt

Ana

BeitragSo, Mai 15, 2011 14:19
Antworten mit Zitat
Benutzer-Profile anzeigen
Dann würde ich als nächstes mal
BlitzBasic: [AUSKLAPPEN]
Until t*120 > EntityDistance(Plane,Schusszieler) - 1 And t*120 < EntityDistance(Plane,Schusszieler) + 1


in
BlitzBasic: [AUSKLAPPEN]
Until t*120 > EntityDistance(Plane,Schusszieler) - 120 And t*120 < EntityDistance(Plane,Schusszieler) + 120


ändern und wenn es dann geht mit 60 was auch noch passen müsste, am besten schaust dir mal die Wert entwicklung im debuger an.
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragSo, Mai 15, 2011 15:18
Antworten mit Zitat
Benutzer-Profile anzeigen
Jetzt hänge ich zwar in keiner endlosschleife mehr, aber die Schüsse treffen auch nicht.Der DebugLog sagt mir nichts, ich habe mal t, t*120 und die Distanz ausgben lassen.Sieht dann meistens so aus:
Code: [AUSKLAPPEN]
t: 1
Distanz: 482.96
t*120: 60
t: 2
Distanz: 482.05
t*120: 120
t: 3
Distanz: 481.141
t*120: 180
t: 4
Distanz: 480.232
t*120: 240
t: 5
Distanz: 479.323
t*120: 300
t: 6
Distanz: 478.415
t*120: 360
t: 7
Distanz: 477.507
t*120: 420
t: 8
Distanz: 476.599
t*120: 480

Ana

BeitragSo, Mai 15, 2011 17:07
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich hab mal den Algorithmus aufgeschrieben wie ich ihn machen würde, allerdings in 2d und Bmax (Hab kein B3d auf dem Rechner), aber den Transfer solltest du denke ich gut hinbekommen

BlitzMax: [AUSKLAPPEN]
SuperStrict 
Graphics 1024,800

Global TSpeed:Float = 1,BSpeed:Float = 2 'T = Target, B = Bullet
Global AimX:Float,AimY:Float
Global StartX:Float,StartY:Float
Global TargetX:Float,TargetY:Float,VectorX:Float,VectorY:Float

Function Distance:Float(x1:Float,y1:Float,x2:Float,y2:Float)
Local x:Float = (x1 - x2)
Local y:Float = (y1 - y2)
Return Sqr(x*x+y*y)
End Function

Function GetShootingPosition(Tx:Float,Ty:Float,Vx:Float,Vy:Float,Sx:Float,Sy:Float) 'T = Target, V = Vector, S = Start
Local x:Float = Tx
Local y:Float = ty
Local t:Int = 0
While( Abs(Distance(x,y,sx,sy) - t * Bspeed) > Max(Tspeed,BSpeed))
x = x + Vx
y = y + Vy
t = t + 1
Wend
AimX = x
AimY = Y
End Function


StartX = 400
StartY =500
TargetX = 0
TargetY = 100
VectorX = 1
VectorY = 2
GetShootingPosition(TargetX,TargetY,VectorX,VectorY,StartX,StartY)

Local vx:Float,vy:Float,dis:Float
Repeat

Cls
SetColor 255,0,0
DrawRect (TargetX - 25,TargetY - 25,50,50)
SetColor 0,255,0
DrawRect (StartX- 25,StartY- 25,50,50)
SetColor 0,0,255
DrawRect (AimX - 25,AimY - 25,50,50)
Delay 10
TargetX = TargetX + VectorX
TargetY = TargetY + VectorY
'Uninteressanter Vektorteil bewegt Start auf Aim
vx = (Startx - AimX)
vy = (Starty - Aimy)
dis = Distance(Startx,Starty,AimX,Aimy)
vx = vx /dis
vy = vy /dis
Startx = StartX - vx * BSpeed
Starty = Starty - vy * BSpeed

Flip
Until AppTerminate()


Wirklich interessant sollte für dich nur die GetShootingPosition sein
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragSo, Mai 15, 2011 17:47
Antworten mit Zitat
Benutzer-Profile anzeigen
Das mit den Vektoren verstehe ich leider nicht, aber ich habe jetzt mal versucht
die Funktion GetShootingPosition zu "übersetzen"
BlitzBasic: [AUSKLAPPEN]

Global ZielX#
Global ZielY#
Global ZielZ#
Function GetShootingPosition(Tx#,Ty#,Tz#,Vx#,Vy#,Vz#,Sx#,Sy#,Sz#,Gs#)
x# = Tx
y# = Ty
z# = Tz
t = 0
While Abs(Distance(x,y,Sx,Sy)-t*PlaneSpeed) >(Gs,PlaneSpeed)
x = x + Vx
y = y + Vy
z = z + Vz
t = t + 1
Wend
ZielX = x
ZielY = y
ZielZ = z
End Function

Wobei ich den Speed des gegnerischen Flugzeugs auch noch übergeben habe lassen.
Vielen Dank das du dir die Zeit genommen hast, das zusammenzubasteln.

Ana

BeitragSo, Mai 15, 2011 20:51
Antworten mit Zitat
Benutzer-Profile anzeigen
Das geht noch um einiges hübscher

BlitzBasic: [AUSKLAPPEN]

Function GetShootingPosition(TargetEntity,StartEntity)
PivotEntity = CreatePivot(Targetentity)
t = 0
While Abs(EntityDistance(PivotEntity,StartEntity)-t*PlaneSpeed) > max(Gs,PlaneSpeed))
Move(PivotEntity,0,0,PlaneSpeed)
t = t + 1
Wend
Return PivotEntity
End Function


Dann erstellt dir deine Funktion einen Pivot an der richtigen Stelle und liefert dir seine Identität zurück. Dran denken, der muss wieder gelöscht werden, wenn dein Schuss angekommen ist. Von daher eventuell gleich in einer Funktion mit löschen und dem Schuss eine Flugzeit/Lebensdauer geben, damit er nachdem er fertig ist, gelöscht wird.

Ich tu mal so als hätten wir einen Type Schuss der ein Feld Entity hat und ein Feld Lebenszeit vom typ int.
BlitzBasic: [AUSKLAPPEN]

Function GetShootingPosition(TargetEntity,StartEntity.Schuss)
PivotEntity = CreatePivot(Targetentity)
t = 0
While (EntityDistance(PivotEntity,StartEntity\Entity -t*PlaneSpeed) > max(Gs,PlaneSpeed))
Move(PivotEntity,0,0,PlaneSpeed)
t = t + 1
Wend
PointEntity(StartEntity\Entity,PivotEntity)
StartEntity\Lebenszeit = t
FreeEntity Pivotentity
End Function


und bitte und gern geschehen
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragMo, Mai 16, 2011 14:31
Antworten mit Zitat
Benutzer-Profile anzeigen
Leider kenne ich mich mit Bmax überhaupt nicht aus Embarassed und kann deswegen
die Funktion Max() nicht ersetzten, deswegen funktioniert es noch nicht.

Ana

BeitragMo, Mai 16, 2011 14:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Oh die Funktion Max liefert den größeren der beiden Werte, wahrscheinlich kannst du auch einfach durch die Projektilgeschwindigkeit ersetzen, weil es eh schneller ist als das Flugzeug
Don't only practice your art,
but force your way into its secrets,
for it and knowledge
can raise human to divine

joshmami

BeitragMo, Mai 16, 2011 14:52
Antworten mit Zitat
Benutzer-Profile anzeigen
Genial!!
Jetzt trifft jeder einzelne Schuss!Vielen Dank! Very Happy Very Happy Very Happy Very Happy Very Happy Cool

Gehe zu Seite 1, 2  Weiter

Neue Antwort erstellen


Übersicht BlitzBasic Beginners-Corner

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group