Objekt löschen wenn anderes gelöscht wurde

  • Themenstarter Themenstarter VintageSucks
  • Beginndatum Beginndatum
V

VintageSucks

Gast
Hallo, ich arbeite mit Greenfoot und habe derzeit ein Problem. In meinem Spiel gibt es ein Level, in dem sich der Spieler (Fee), ein Knopf und eine Wolke befinden. Wenn der Spieler einfach gegen die Wolke fliegt, wird der Spieler gelöscht und das Spiel setzt sich auf Game Over.

Nun das Problem. Wenn der Spieler gegen den Knopf fliegt, soll dieser gelöscht werden - aber dadurch soll auch die Wolke gelöscht werden. Aber egal was ich mache, die Wolke geht einfach nicht weg wenn der Spieler gegen den Knopf fliegt/geht. Kann man das umsetzen - und wenn ja, wie?

Teilcode des Spielers:

Java:
public void act()
    {
                Actor knopf = getOneIntersectingObject(Knopfgegenwolkelevel3.class);
                Actor boesewolke = getOneIntersectingObject(Wolkelevel3.class);
            
              // Knopf geht weg wenn die Fee gegen ihn fliegt:
                if (knopf != null) 
                    {
                        getWorld().removeObject(knopf);
                    }
  
              // Game Over wenn die Fee gegen die böse Wolke fliegt:
                if (boesewolke != null) 
                    {
                        getWorld().removeObject(this);
                        Greenfoot.delay(20);
                        Gameover();
                    }
        }
    }
 
Hallo,

  1. also zuerst mal bist du in Java nicht dafür verantwortlich, objekte zu löschen. Das übernimmt der GarbageCollector - und er entscheidet auch wann es passiert. Du kannst das Objekt auf null setzen, aber wann es aufgeräumt wird, entscheidest im Endeffekt nicht du. Du kannst jedoch den GarbageCollector aufrufen: "System.gc()"
  2. Ich nehme an deine Welt ist eine Liste? Du löschst deine Objekte wenn ich das richtig sehe nur aus der Collection, damit ist das objekt aber noch nicht entfernt. Deine Welt kennt nur die Referenz nicht mehr (das objekt ist aber weiterhin im Speicher). Um es wirklich zu löschen, solltest du es auf null setzen (damit der Garbage Collector es beim nächsten Aufruf auch aufräumt)
  3. Das große Problem nehme ich an besteht darin, dass du innerhalb eines objektes versuchst, das objekt selber zu löschen. Das wird nicht gehen, weil es ja gerade aktiv ist und deshalb noch gebraucht wird. Selbst der GC wird das objekt dann nicht aufräumen. Es sollte aber auch nicht die Aufgabe eines Spielers sein, sich selbst zu löschen. Ich würde Dir vorschlagen, die funktionalität auszilagern in einem "GameManager" bzw. in dein Weltobjekt. Der Spieler kann dann das Weltobject anweisen, dass es sterben will, wird aber nicht von sich selbst getötet. Wobei ich es etwas seltsam finde, der Spieler möchte ja nicht sterben. Vllt ist es besser, die Entscheidung von der Welt treffen zu lassen. Das macht für mich mehr Sinn...

Grüße
 
@2AndAHalfBit
da hast du jetzt aber ne Menge falsch verstanden,
es geht doch offensichtlich darum ein Objekt von der graphischen Oberfläche, aus der Spielwelt verschwinden zu lassen,
was der GC macht usw. ist dazu reichlich egal

irgendwas auf null zu setzen ist hier ein fragwürdiger Vorschlag wenn man bedenkt dass die Methode sowieso 1 ns später zu Ende ist und Variablen wie boesewolke dann viel weniger existieren als sie es mit null je könnten,

-----

@UserMitFragwürdigenTitel
kannst du Informationen beitragen?
ist die boesewolke-Variablen null oder nicht? wieso removest du this, und nicht genau boesewolke?
was ist this?
kannst du die Wolke zu beliebigen Zeitpunkten entfernen? sowas erst für sich testen, nicht kompliziert mit ifs verknüpfen
 
@SlaterB

this ist hier der spieler, den man bewegen kann.
Code:
public void act()
wird übrigens von greenfoot ununterbrochen ausgeführt, solange das spiel läuft.

ob boesewolke null ist oder nicht, weiß ich gar nicht.

kann man nicht während der knopf weg geht, in der world class (level 3) einen
Code:
boolean
wolke
oder so auf true setzen, und in der actor class (Wolkelevel3)

Java:
if(((Level3) getWorld()).Wolke)
    {
       getWorld().removeObject(this);
    }

erstellen, damit die wolke entfernt wird, wenn wolke auf true ist? dafür müsste ich aber wissen, wie (ob) man den boolean wolke in Level3.class (World) aus der Fee.class (Actor) auf true setzt.

was ich auch nicht verstehe ist, wenn ich
Code:
getWorld().removeObject(knopf);
durch
Code:
getWorld().removeObject(boesewolke);
ersetze, verschwindet die wolke auch nicht. was mache ich falsch?
 
was ich auch nicht verstehe ist, wenn ich getWorld().removeObject(knopf); durch getWorld().removeObject(boesewolke); ersetze, verschwindet die wolke auch nicht. was mache ich falsch?
Ich glaube in die Richtung zielte SlaterB's Frage ab, ob boesewolke evtl. null sein könnte und, ob Du die Wolke überhaupt irgendwie/irgendwo/irgendwann removen kannst. Du initialisierst die Variable ja mit:
Java:
Actor boesewolke = getOneIntersectingObject(Wolkelevel3.class);
Wenn nun dieser Aufruf vielleicht garnicht die zu löschende Wolke zurück liefert, sondern etwas anderes z.B. null, dann ist klar, warum die Wolke auch nach einem Remove nicht verschwindet. Mach also nach dem Initialisieren mal:
Java:
System.out.println(boesewolke);
Oder mach ein log-Statement oder sonst eine Ausgabe in Greenfoot.
 
> verschwindet die wolke auch nicht. was mache ich falsch?
vielleicht ist boesewolke null? wie gesagt solltest du klären was da in deiner Methode passiert,
der denkbar einfachste Befehl System.out.println() bietet sich an, ansonsten kommt die Grundregel zum Tragen,
dass jedes Programm erstmal irgendeine sinnvolle Art von Log braucht, ohne sowas ist es schwer Erkenntnisse zu gewinnen,
Debugger gibts noch

warum fragst du boesewolke überhaupt so kompliziert mit intersect an, was immer das in der unbekannten Greenfoot bedeuten mag?,
wenn die Wolke eines von wenigen festen bekannten Objekten ist, lohnt sich dafür doch eine normale Variable irgendwo,
notfalls als Anfänger auch statisch, dann überall bekannt

eine boolean-Variable kann man deklarieren und dann Werte wie true oder false zuweisen oder den Wert abfragen,
was kann man dazu sagen?
höchstens noch bemeckern, dass das was für einfache Anfängerprogramme, nicht für komplizierte graphische Oberflächen ist,
ohne Java-Kenntnisse nur mit paar Befehlen einer API wie Greenfoot arbeiten, das funktioniert kaum
 
auf jeden Fall wird sie dort nicht initialisiert, sondern doch wohl gesucht/ abgefragt?

mein Posting von 14:34 könnte übersehen worden sein,
ich bin noch für eine allgemeine Variable/ Attribut für die wolke
 
Indem du die besagte Wolke Initialisierst. 😀
tu ich das nicht, indem ich sie in die welt (Level3) einsetze? (
Code:
addObject ( new Wolkelevel3(), 555, 312 );
)

Wie schaut denn die Methode getOneIntersectingObject(Wolkelevel3.class); aus?

getOneIntersectingObject

ich bin noch für eine allgemeine Variable/ Attribut für die wolke

wie müsste das dann aussehen?
 
> Wolke w = die Wolke;
also quasi das was du sowieso schon irgendwo stehen hast, nur nicht als lokale Variable die verschwindet und später mühsam in der Welt gesucht werden muss, sondern als Instanzattribut, evtl. statisches Klassenattribut,
was das ist musst du schon wissen oder nachschlagen
 

Zurück
Oben