Schnelles Entitypick im Radius

Übersicht BlitzBasic Blitz3D

Neue Antwort erstellen

 

BurningSoul

Betreff: Schnelles Entitypick im Radius

BeitragDo, Mai 05, 2005 19:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Hi Leute ....
ich suche ne möglichkeit, Waffen mit Splash Damage im Spiel einzubauen

hab zuerst ne Sphere erschaffen, die nen Kollisionsmodus hatte,
erscheint, dann mit allem kollidiert, schaden verursacht, und dann verschwindet ....
naja hat auch toll geklappt, nur dass diese Sphere sich sofort wegbewegt hat,
sobald ich das kollisonsdetekt eingeschaltet habe - ich hab sie einfach gescaled, und aufgrund der Kollision hat sie sich sofort so bewegt, dass sie am Rand des objektes war, dass sie beschädigen sollte -
Toll, wenn man nur wissen will,
ob ein einziges Entity im Radius ist !

Ich will aber ,dass ALLE Objekte im Explosionsradius schaden nehmen!

Ich möchte vermeiden, mit einer For-Each Schleife durch alles zu iterieren,
um dann anschliessend jeweils die Distanz zu prüfen - warum ?
Geschwindigkeitsoptimierung !
Das soll auch klappen, wenn hunderte von Objekten im Spiel sind,
und zwar nicht als Dia-Show Smile

soo , nun aber erstmal der entsprechende Code:

BlitzBasic: [AUSKLAPPEN]

Function CheckDamageSpheres ()
For sphere.DamageSphere = Each DamageSphere
sphere\lifetime = sphere\lifetime - 1

If sphere\lifetime > 0 Then ScaleEntity sphere\ent,sphere\radius / (sphere\lifetime),sphere\radius / (sphere\lifetime),sphere\radius / (sphere\lifetime)

If sphere\lifetime = 1 Then EntityType (sphere\ent,cl_CollisionSphere)

If sphere\lifetime < 1 Then ; Ab hier wird's interessant !

counter = 0 ; reset it because we could have more than one explosion the same frame

victim = EntityPick (sphere\ent,500)
If victim Then
centerprint \"treffer ... Dist:\" + EntityDistance (sphere\ent,victim)
End If

FreeEntity sphere\ent
Delete sphere
End If
Next ;sphere
End Function


Der erste Teil ist unwichtig, er sorgt nur dafür, dass sich die 20% sichtbare Sphere aufbläht, je nach explosionsradius ...

alle Entities die erstellet wurden, mit Ausnahme der DamageSphere hier
wurden so erstellt :
BlitzBasic: [AUSKLAPPEN]
EntityPickMode my\ent,1,0

pickmode ist also an! (habs schon mit Box ODER Sphere probiert)
natürlich sind auch passend grosse EntitySphere Werte und Bounding boxen gesetzt, das ist sicher, denn schüsse können die Spieler richtig treffen!

Die Idee war, den Entitypickmode jedes gefundenen objektes kurzzeitig auf Null zu setzen, sich das objekt zu merken,
und solange zu loopen, bis kein entity mehr im Radius ist -
damit habe ich eine Sammlung sämtlicher Entities im Radius -
klar, ich muß dannach noch den Pickmode wieder anmachen ...

Problem: noch nicht mal dieser EINE erste Entity wird gefunden ...
die Nachricht wird nur super selten ausgegeben ... und auch nur, wenn ich mir direkt VOR die Füße schiesse - direkt auf den Boden wo ich stehe klappt auch nicht !

Meine Idee war, das EntityPick irgendwie nicht für sowas gedacht ist,
oder aber ich noch irgendwo anders dran drehen muss,
damit es funzt!

Hat da jemand Hilfe für mich ?
Mfg,
Euer Soul =)



----------------------------------------------------------------------------------


@Admin/Webmaster: (Debug Infos)
(lösch diesen Teil nach dem Lesen wenn Du willst!)
Ich benutze Netscape 7.1 auf nem W2k System - sobald ich die Vorschau hier IM FORUM aktiviere , kommen folgende Fehlermeldungen :
(dieser Fehler trat nur dieses EINE mal auf!)

Fehler:
----------------------------------------------------------------------------------
Warning: Invalid argument supplied for foreach() in /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/geshi.php on line 1570

Warning: Invalid argument supplied for foreach() in /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/geshi.php on line 1570

Warning: Invalid argument supplied for foreach() in /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/geshi.php on line 1570

Warning: Cannot modify header information - headers already sent by (output started at /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/geshi.php:1570) in /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/page_header.php on line 476

Warning: Cannot modify header information - headers already sent by (output started at /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/geshi.php:1570) in /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/page_header.php on line 482

Warning: Cannot modify header information - headers already sent by (output started at /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/geshi.php:1570) in /is/htdocs/wp1002880_AQ97GB6MKP/www/includes/page_header.php on line 483
 

BurningSoul

Betreff: hmmm so kann das ja nix geben!

BeitragDo, Mai 05, 2005 20:55
Antworten mit Zitat
Benutzer-Profile anzeigen
ich vergass dass die Blickrichtung ja nicht verdrehbar ist ...
dachte es wäre irgendwie machbar , dass der 'Bluckstrahl' da ähnlich wie bei nem Licht auf 360° umstellbar ist ...
aber trotzdem : ich bräuchte mal was hilfe womit ich das oben geschriebene Problem lösen könnte .... schreibt mal bitte was ,
wäre Euch sehr verbunden !

Mfg Euer Soul!
 

Klaas

BeitragDo, Mai 05, 2005 22:13
Antworten mit Zitat
Benutzer-Profile anzeigen
Geh durch alle Entities durch und berechne die Distanz. Die Kollisionsberechnung die du jetzt nutzt sind langsamer als durch die Objekte zu gehen und EntityDistance zu testen.
 

BurningSoul

Betreff: ja nee , ohne durch ALLE objekte zu iterieren wenn's geht!

BeitragDo, Mai 05, 2005 22:22
Antworten mit Zitat
Benutzer-Profile anzeigen
es muß doch nen anderen weg geben ...
ich denke, wenn ich erstmal 300 entities habe,
unter anderem auch Items, Bäume etc,
wäre das viel zu langsam - dass es SO geht, ist mir auch klar,
aber ich will eben NICHT durch ALLE objekte gehen,
und dann die Distanz messen, usw ....

wie löst Ihr denn sowas in nem grösserem Game ???
 

Klaas

BeitragDo, Mai 05, 2005 22:57
Antworten mit Zitat
Benutzer-Profile anzeigen
was macht denn ein Kollisions check ?
Der geht auch durch alle Objekte durch. Dabei wird sicher noch ein Octtree benutzt zum optimieren.


Wenn es so viele Objekte sind dann teile die Welt in kleiner Bezirke ein. Teste dann nur die Objekte die in dem entsprechenden Bezirk sind.
 

BurningSoul

Betreff: Das muß doch zu schaffen sein =(

BeitragDo, Mai 05, 2005 23:05
Antworten mit Zitat
Benutzer-Profile anzeigen
ein Kollisionscheck testet, ob er mit etwas kollidiert - ZUSÄTZLICH bewegt er aber auch noch das zu prüfende objekt -

wenn ich jetzt meine kollisionssphere mit einer grösser versehe,
dann 'schiebt' das erste mit ihr kollisierende objekt sie weg,
und es wird folglich auch nur ein einziges objekt erfasst !

SO geht es , wie ich schon schrieb also nicht!

Ausserdem kann man
weder mit dem Befehl Collisions(parameter),
noch mit einer For - Each - Schleife erreichen,
dass nur ein TEIL abgecheckt wird Sad

hab ich beides schon getest !

....

Das muß doch zu schaffen sein *grummel =(
 

Michi

BeitragDo, Mai 05, 2005 23:06
Antworten mit Zitat
Benutzer-Profile anzeigen
eben mit Entitydistance.
schau mal, entitydistance, das ist irgendwie 4 mal Phytagoras-berechnung. Darüber lacht sich der Pc doch kaputt!
Wenn du möchtest, kannst du es ja mal messen:
BlitzBasic: [AUSKLAPPEN]

Graphics3D 800, 600, 16, 1
SetBuffer BackBuffer()

Global c=CreateCamera()

Dim entities (299)

For i=0 To 299
entities(i)=CreateCube()
Next

Global pivot=CreatePivot()
MoveEntity pivot, 0, 0, 5

Global time1=MilliSecs()
For i=0 To 299
blub=EntityDistance(pivot, entities(i))
Next
Global time2=MilliSecs()

RenderWorld
UpdateWorld

Text 10, 10, time2-time1
Flip
WaitKey()
End


Bei mir hatte er maximal 3 Millisekunden !
Aber..Wozu soll er gut sein???
IBM-Ingeneur über die Idee des Mikroprozessors, 1968
Code: [AUSKLAPPEN]

   __
<_/__\_> <--- die Wayne-Zeichnung
 

Klaas

BeitragDo, Mai 05, 2005 23:26
Antworten mit Zitat
Benutzer-Profile anzeigen
Zitat:
wenn ich jetzt meine kollisionssphere mit einer grösser versehe,
dann 'schiebt' das erste mit ihr kollisierende objekt sie weg,
und es wird folglich auch nur ein einziges objekt erfasst !


der Rechner muß trotzdem für alle potentiel in reichweite befindlichen Objekte ie Kollisionsberechnung machen. Jeh nach dem in welchen ColliModus das Objekt ist sind die berechnungen dafür 100'te male ausfwändiger als ein simpler Pythagoras.

Aber wenn dus nicht glauben magst dann kann ich dir auch nicht helfen

stfighter01

BeitragFr, Mai 06, 2005 0:37
Antworten mit Zitat
Benutzer-Profile anzeigen
ausserdem überleg noch was anderes.

wieviele explosionen o.ä. mit splash damage können pro durchlauf entstehen?
2 explosionen/frame gleichzeit ist schon sehr viel

damit hast du maximal 2 explosionen die mit allen objekte auf kollision geprüft werden müssen (1000 objekte-> 2000 überprüfungen/frame) u. das ist für den pc noch ein klacks.

anders verhält es sich wenn die explosionen sich langsam ausdehen sollen, dann werdens halt etwas mehr, aber wenns geht würde ich eine kontrolle der im radius befindlichen objekte nur beim einschlag überprüfen.


mfg stfighter
Denken hilft!
 

BurningSoul

BeitragFr, Mai 06, 2005 12:46
Antworten mit Zitat
Benutzer-Profile anzeigen
Also für die Explosionen geb ich Dir recht - hab mir grad mal nen kleines , süßes Testprogramm dafür geschrieben,
und bei 20.000 objekten dauerte dass grad mal 25-50 Millisekunden ....
ist also unproblematisch ... Problematisch ist allerdings folgendes:

Wenn ich ein Spiel habe - z.b ein echtzeit-strategiespiel,
dann muss ja jedes Fahrzeug - (oder in einem ego-shooter jedes Monster)
des öfteren mal checken, ob ein Feind in Sichtweite ist ....

und DA wäre es dann wirklich praktisch, wenn man eine Funktion
hätte , die nur in einem bestimmten RADIUS nach Objekten sucht,
damit man diese dann checken kann, und nicht ALLES auf der Welt überprüfen muss - okay, hierbei könnte man dann sagen ok,
checken wir nur alle 0.5 Sekunden, das tuts auch noch ...

aber ich bin dabei Hartnäckig ... ich wüssste da zu gern einfach ne Allgemeingültige Lösung für ,
da mir Performance doch recht wichtig ist!

Mfg, Euer Soul =)
 

Klaas

BeitragFr, Mai 06, 2005 13:38
Antworten mit Zitat
Benutzer-Profile anzeigen
Die Lösung heißt: BSP-Tree

Das sind sogenannte Binärbäume welche die Welt in kleinere "Happen" unterteilt und diese geordnet ablegt.

Aber diese Technik auf frei bewegte Objekte anzuwenden könnte langsamer werden als alles zu testen.

Ich würde einen Mittelweg gehen. Unterteile die Welt in kleinere Sektoren. Immer wenn ein Objekt in einen anderen Sektor geht sortiert es sich in die Liste aller Objekte in diesem Sektor ein. wenn nun eine Explosion passiert wird nur die Liste der Objekte getestet die sich im selben Sektor befindet.
Die Sektoren sollten sich überschneiden um den Betrag den die Größte Explosion als Radius hat, um am Rand keine unsichtbare Mauer zu haben.
D.h. in einigen Fällen sind Objekte dann in 2 Sektoren gleichzeitig.

Die größe der Sektoren kommt stark auf dein Spiel an bzw. wieviel wriklich los ist.

Das ganze würde ich dann mit Types umsetzen die nach sektoren sortiert sind.

Neue Antwort erstellen


Übersicht BlitzBasic Blitz3D

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group