Programmieren: Explosionsradius durch Objekte beeinträchtigt?

Ireeb  05.03.2024, 14:37

Reden wir von einem 2D- oder 3D-Spiel?

ILoveCode 
Fragesteller
 05.03.2024, 14:40

2D. Würde aber das Prinzip nicht auch im 3Dimensonialen Bereich funktionieren?

1 Antwort

Vom Fragesteller als hilfreich ausgezeichnet

Generelle Logik dürfte aussehen

  1. Stelle fest was getroffen wird, im richtigen Umkreis
  2. Prüfe für jedes Objekt, ob eine Wand im Weg ist
  3. Rufe ein Event oder aktualisiere sonst irgendwie den State auf den getroffenen Objekten bei denen nichts im Weg ist.

Beachte dass du hier keine unnötigen Checks machst pro Frame und stattdessen eher zb Events nutzen solltest oder irgendwas temporäres.

Zu deiner Frage sollte eigentlich zumindest mal gehören ob es 2d/3d ist.

Meine Zeit mit Godot und Unity ist leider zu lange her dass ich das jetzt sagen kann aber in der Doku zu Kollision findest du ganz sicher eine Lösung für die einzelnen Schritte.

Alternativ könnte man auch Safe zones definieren auf der Map, wenn in dem Setting quasi die Bombe fast überall auf der Map einen Einfluss hat, aber dafür fehlen halt Infos. Wäre mein zweiter Vorschlag für eine Lösung kommt aber stark auf das Szenario an. Das eignet sich wenn es nur wenig safe zones gibt und sonst so viele Objekte dass solche line of sight checks zu performance intensiv wären.

ILoveCode 
Fragesteller
 05.03.2024, 14:41

Ich hätte eine Simple Idee. Das die Bombe unsichtbare Strahlen in jede Richtung aussendet und wenn ein Strahl ein Spieler trifft stirbt er. Würde das funktionieren?

0
BeamerBen  05.03.2024, 14:49
@ILoveCode

Klar, aber mein erster Vorschlag wäre bei wenigen Objekten definitv Performance technisch besser. Und vermutlich einfacher zu implementieren.

So ein Check wie du in beschreibst muss schon berechnet werden, ist vertretbar, aber in einem 3D Raum hättest du dann vermutlich doch so viele Checks, damit das richtig funktioniert und falls du zu wenig Checks machst hast du schwierig zu debuggende Bugs. In einem 2D Raum ist das ganze simpler, aber einen Vorteil sehe ich da trotzdem nicht wirklich, außer es geht um sehr viele Objekte. Also meistens solltest du die Anzahl solcher Checks so gering wie möglich halten.

Also da würde ich lieber einen Check pro (relevantem) Objekt machen. Da hast du einfach weniger Probleme.

0
ILoveCode 
Fragesteller
 05.03.2024, 17:56
@BeamerBen

Sehr gute Idee. Ich werde es im 2D Raum machen. Ja Performance technisch gesehen könnte es auch im 2D Bereich werden wenn es sehr sehr viele und kleine Strahlen sind. Aber so ganz verstehe ich es nicht. Wie soll den das Spie wissen das ein Spieler hinter ein Objekt in Richtung der Bombe steht, wenn ich ein Check pro relevanten Objekt mache.

0
BeamerBen  05.03.2024, 18:19
@ILoveCode

Naja du machst halt einen Ray Cast zu jedem relevanten Objekt.

Statt hunderte Raycasts in alle Richtungen machst du für jedes Objekt in der Nähe genau einen Raycast, nämlich zu dem Objekt hin. Und dann schaust du was dieser Raycast trifft, ob da eine Wand im Weg ist oder nicht.

Hier in der Godot Doku: https://docs.godotengine.org/en/stable/classes/class_physicsdirectspacestate2d.html#class-physicsdirectspacestate2d

Hier ChatGPT generierter Beispiel Code (falls das nicht geht musst du selber fixen, dient nur als Beispiel wie so etwas funktionieren könnte, ChatGPT macht auch gerne mal Fehler und denkt sich Methoden aus, habe ich jetzt nicht geprüft):

extends Node2D

var radius = 100.0
var collision_mask = 1 << 0 # Adjust based on the layers your objects are in

func _ready():
   get_objects_in_radius()

func get_objects_in_radius():
   var center_position = self.global_position
   var space_state = get_world_2d().direct_space_state
   var query_parameters = Physics2DShapeQueryParameters.new()
   var shape = CircleShape2D.new()
   shape.radius = radius
   query_parameters.set_shape(shape)
   query_parameters.transform = Transform2D(0, center_position)
   query_parameters.collision_mask = collision_mask
   var results = space_state.intersect_shape(query_parameters)

   for result in results:
       if result.collider is YourTargetType and has_line_of_sight(center_position, result.collider.global_position):
           result.collider.trigger_event() # Assuming `trigger_event` is the method you want to call

func has_line_of_sight(start_pos, end_pos):
   var space_state = get_world_2d().direct_space_state
   var result = space_state.intersect_ray(start_pos, end_pos, [], collision_mask)
   return result.empty() # Returns true if no collision was found along the ray

# YourTargetType class needs to have this method
# func trigger_event():
#   # Code to trigger the event
0
ILoveCode 
Fragesteller
 07.03.2024, 15:29
@BeamerBen

Ist das GDScript oder C#? Weil Godot hat bei GDScript ein neues Update bekommen ab Version 4.0 (Vor knapp 1 Jahr erschienen). Deshalb funktioniert der Code von ChatGPT nicht mit Godot weil ChatGPT veraltet ist.

0