+ Antworten
Seite 3 von 4 ErsteErste 1 2 3 4 LetzteLetzte
Ergebnis 21 bis 30 von 31
  1. #21
    Architekt Avatar von longor1996
    Registriert seit
    27.11.2010
    Beiträge
    1.797
    Minecraft
    CTM5010
    Zitat Zitat von Gnoccy Beitrag anzeigen
    Wieso festlegen? Ich weiß doch gar nicht was ich festlegen soll.
    Oder reden wir gerade aneinander vorbei? Grundsätzlich will ich nichts anderes machen, als die oben erwähnte Zeppelin Mod: Sobald eine bestimmte Aktion ausgeführt wird bekomme ich sozusagen einen Bauplan für ein vom Spieler gestaltetes Gebilde. Dieses besteht aus einem Ursprungsblock, sowie allen angrenzenden Blöcken, den Blöcken die wiederum an diese Blöcke angrenzen, den Blöcken die an diese angrenzen und so weiter.
    Mit dem Bauplan dazu will ich das Gebilde dann an anderer Stelle rekonstruieren können.
    Jetzt verstehe ich es, glaub ich.

    Du willst einen "Filler" Algoryhtmus habe!
    Ein Algoryhtmus der einfach alle Blöcke rekursiv zu einer Liste (oder HashMap) hinzufügt.
    Das währe sowas wie: (Pseudo-Code!)
    Code:
    public ArrayList<TempBlock> doRecursiveSearch_(World world,int x,int y,int z)
    {
        ArrayList<TempBlock> list = ...;
    
        list.add(new TempBlock(world.getBlockID(x,y,z),x,y,z));
    
        doRecursiveSearch(list,world,x,y,z);
    
        return list;
    }
    
    
    public void doRecursiveSearch(ArrayList<TempBlock> list,World world,int x,int y,int z)
    {
    
        //Für jeden Block muss übrigends noch geprüft werden, ob er nicht Luft ist, und er noch nicht in der Liste steht!
        list.addIfNotExist(new TempBlock(world.getBlockID(x+1,y,z),x+1,y,z));
        list.addIfNotExist(new TempBlock(world.getBlockID(x-1,y,z),x-1,y,z));
        list.addIfNotExist(new TempBlock(world.getBlockID(x,y+1,z),x,y+1,z));
        list.addIfNotExist(new TempBlock(world.getBlockID(x,y-1,z),x,y-1,z));
        list.addIfNotExist(new TempBlock(world.getBlockID(x,y,z+1),x,y,z+1));
        list.addIfNotExist(new TempBlock(world.getBlockID(x,y,z-1),x,y,z-1));
    
        //Führe die Suche bei den hinzugefügten Blöcken fort, hier sollte noch irgendein Distanz Check hin der verhindert, 
        //das die gesamte Map Rekursiv durchsucht wird.
        doRecursiveSearch(list,world,x+1,y,z);
        doRecursiveSearch(list,world,x-1,y,z);
        doRecursiveSearch(list,world,x,y+1,z);
        doRecursiveSearch(list,world,x,y-1,z);
        doRecursiveSearch(list,world,x,y,z+1);
        doRecursiveSearch(list,world,x,y,z-1);
    }
    Das ist jetzt nur ein Pseodo-Code Algoryhtmus, bitte nicht direkt so verwenden!
    Danach müssen die Blöcke in der Liste noch irgendwie in eine Datei gespeichert werden.

    mfg Longor1996
    AdventureCraft2 Entwickler! Ich gebe gerne (Modding/Tech-)Support über PN.
    Me on Youtube

  2. Mag ich Gnoccy mag diesen Beitrag
  3. #22
    Creeper-Jäger Avatar von Gnoccy
    Registriert seit
    25.12.2010
    Beiträge
    444
    Minecraft
    Gnoccy
    @longor1996
    Danke! Das ist es, was ich gesucht habe. Das einzige was noch nicht passt ist, dass ich die Blöcke gerne relativ zum Ursprungsblock speichern würde, aber das bekomme ich auch selbst hin.

  4. #23
    Architekt Avatar von longor1996
    Registriert seit
    27.11.2010
    Beiträge
    1.797
    Minecraft
    CTM5010
    Bitte!

    Ich denke mal der Thread kann dann geschlossen werden. Oder?

    mfg Longor1996
    AdventureCraft2 Entwickler! Ich gebe gerne (Modding/Tech-)Support über PN.
    Me on Youtube

  5. #24
    Creeper-Jäger Avatar von Gnoccy
    Registriert seit
    25.12.2010
    Beiträge
    444
    Minecraft
    Gnoccy
    Moment, eine Frage hätte ich da noch.
    Und zwar muss ja bei jedem gefundenem Block nachgeschaut werden, ob er nicht schon in der Liste ist. Dafür muss die komplette Liste durchsucht werden. Meine Frage wäre nun, wie sich das auf die Performance auswirkt, wenn es dabei um ein mehrere tausend Blöcke großes Gebilde geht. Ist das auf einem normalen Rechner überhaupt noch in einer akzeptablen Zeit durchfürbar?

    Und @longor1996 noch ne Frage, der Filler Algoryhtmus von dem du gesprochen hast ist der Floodfill Algoryhtmus, oder?
    Geändert von Gnoccy (18.08.2012 um 18:47 Uhr)

  6. #25
    Architekt Avatar von longor1996
    Registriert seit
    27.11.2010
    Beiträge
    1.797
    Minecraft
    CTM5010
    Ja, das ist ein Floodfill Algoryhtmus.
    Und das mit dem durchschauen der Liste...
    keine Ahnung wie man das Lösen soll.

    Auswirken würde sich das garantiert.
    Eine Idee:
    Du kannst die Liste immer nachdem so 10 - 20 Blöcke hinzugefügt worden sind sortieren.
    Das Sortieren einfach über ein "TempBlock implements Comparable<TempBlock>",
    die darauf resultierende Methode und die "Collections.sort(list)" Funktion machen.
    In der Comparable Methode dann am besten die X,Y,Z Koodinaten die am nächsten zum Zentrum sind nach hinten in die Liste schieben.

    Andere Idee:
    Einfach die Liste rückwärts durchsuchen!
    Da die ersten Elemente am anfang stehen, stehen die die du kontrollieren willst ganz am Ende.

    Am Ende wird die Liste sowieso so sein, das die Blöcke "Spiralenförmig" um deinen Kern Block herum liegen.
    Den Algoryhtmus habe ich schonmal getestet. Das geht eigentlich recht schnell.
    Man köntne auch noch eine Liste Pro Chunk machen...
    aber das ist dann wirklich ein bisschen zu viel Aufwand für ein bisschen Performance.

    mfg Longor1996

    PS: Ich bin gerade dabei ein eigenes Zip Format ähnliches Speicherformat zu erstellen,
    folge: Ich geb mehr Konzentration fürs Programmieren her und der Text hier beinhaltet dadurch Fehler.
    AdventureCraft2 Entwickler! Ich gebe gerne (Modding/Tech-)Support über PN.
    Me on Youtube

  7. #26
    Creeper-Jäger Avatar von Gnoccy
    Registriert seit
    25.12.2010
    Beiträge
    444
    Minecraft
    Gnoccy
    Ok, hab mich mal dran gesetzt und schnell mal was zum testen hingeklatscht. So sieht das ganze bisher aus:

    Code:
    protected ArrayList flood(World pWorld, int x, int y, int z, ArrayList list){
    		if(!(pWorld.getBlockId(x, y, z) == 0) && !doesBlockAlreadyExist(list, x, y, z)){
    			list.add(new SBlock(x, y, z, pWorld.getBlockId(x, y, z)));
    			
    			System.out.println(x + y + z);
    			
    			list = appendArrayListToArrayList(list, flood(pWorld, x + 1, y, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x - 1, y, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y + 1, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y - 1, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y, z + 1, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y, z - 1, list));
    		
    		}
    		
    		
    		return list;
    	}
    Code:
    	protected boolean doesBlockAlreadyExist(ArrayList list, int x, int y, int z){
    		Object[] s = list.toArray();
    		for(int i = 0; i < s.length; i++){
    			if (((SBlock) s[i]).getX() == x && ((SBlock) s[i]).getY() == y && ((SBlock) s[i]).getZ() == z){
    				return true;
    			}
    			
    		}
    		return false;
    	}
    Wenn ich das ganze nun ausführe, verabschiedet sich Miencraft mit der Meldung, es stehe nicht genug Speicher zur Verfügung. Das passiert aber schon nach etwa 10 durchläufen. Außerdem scheinen auch Blöcke, die schon in der ArrayList sind nochmal erkannt zu werden.
    Ich vermute deshalb mal, dass der Fehler in der "doesBlockAlreadyExist" steckt, nur finde ich ihn nicht.

    Wie gesagt, das ganze ist nur mal schnell zum testen so hingeklatscht und es gibt sicher noch ein paar Ecken, an denen man Feilen könnte. Trotzdem würde ich mich freuen, wenn einfach nochmal jemand drüber schaut. Eventuell übersehe ich einfach nur eine Kleinigkeit, die anderen sofort ins Auge springt, oder ich habe mich irgendwo völlig verrannt oder sowas.
    Geändert von Gnoccy (19.08.2012 um 13:41 Uhr)

  8. #27
    Architekt Avatar von longor1996
    Registriert seit
    27.11.2010
    Beiträge
    1.797
    Minecraft
    CTM5010
    Zitat Zitat von Gnoccy Beitrag anzeigen
    Ok, hab mich mal dran gesetzt und schnell mal was zum testen hingeklatscht. So sieht das ganze bisher aus:

    Code:
    protected ArrayList flood(World pWorld, int x, int y, int z, ArrayList list){
    		if(!(pWorld.getBlockId(x, y, z) == 0) && !doesBlockAlreadyExist(list, x, y, z)){
    			list.add(new SBlock(x, y, z, pWorld.getBlockId(x, y, z)));
    			
    			System.out.println(x + y + z);
    			
    			list = appendArrayListToArrayList(list, flood(pWorld, x + 1, y, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x - 1, y, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y + 1, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y - 1, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y, z + 1, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y, z - 1, list));
    		
    		}
    		
    		
    		return list;
    	}
    Code:
    	protected boolean doesBlockAlreadyExist(ArrayList list, int x, int y, int z){
    		Object[] s = list.toArray();
    		for(int i = 0; i < s.length; i++){
    			if (((ShipBlock) s[i]).getX() == x && ((SBlock) s[i]).getY() == y && ((SBlock) s[i]).getZ() == z){
    				return true;
    			}
    			
    		}
    		return false;
    	}
    Wenn ich das ganze nun ausführe, verabschiedet sich Miencraft mit der Meldung, es stehe nicht genug Speicher zur Verfügung. Das passiert aber schon nach etwa 10 durchläufen. Außerdem scheinen auch Blöcke, die schon in der ArrayList sind nochmal erkannt zu werden.
    Ich vermute deshalb mal, dass der Fehler in der "doesBlockAlreadyExist" steckt, nur finde ich ihn nicht.

    Wie gesagt, das ganze ist nur mal schnell zum testen so hingeklatscht und es gibt sicher noch ein paar Ecken, an denen man Feilen könnte. Trotzdem würde ich mich freuen, wenn einfach nochmal jemand drüber schaut. Eventuell übersehe ich einfach nur eine Kleinigkeit, die anderen sofort ins Auge springt, oder ich habe mich irgendwo völlig verrannt oder sowas.
    Könntest du bitte den gesamten Code Posten?
    Also:
    -SBlock
    -ShipBlock
    -Und die Datei wo der Algoryhtmus ist.

    Dann kann man dir besser helfen!

    Mfg Longor1996
    AdventureCraft2 Entwickler! Ich gebe gerne (Modding/Tech-)Support über PN.
    Me on Youtube

  9. #28
    Architekt
    Registriert seit
    27.03.2012
    Beiträge
    1.000
    Zitat Zitat von Gnoccy Beitrag anzeigen
    Ok, hab mich mal dran gesetzt und schnell mal was zum testen hingeklatscht. So sieht das ganze bisher aus:

    Code:
    protected ArrayList flood(World pWorld, int x, int y, int z, ArrayList list){
    		if(pWorld.getBlockId(x, y, z) != 0 && !doesBlockAlreadyExist(list, x, y, z)){
    			list.add(new SBlock(x, y, z, pWorld.getBlockId(x, y, z)));
    			
    			System.out.println(x + y + z);
    			
    			list = appendArrayListToArrayList(list, flood(pWorld, x + 1, y, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x - 1, y, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y + 1, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y - 1, z, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y, z + 1, list));
    			list = appendArrayListToArrayList(list, flood(pWorld, x , y, z - 1, list));
    		
    		}
    		
    		
    		return list;
    	}
    Code:
    	protected boolean doesBlockAlreadyExist(ArrayList list, int x, int y, int z){
    		ShipBlock[] s = list.toArray(new ShipBlock[list.getSize()]);
    		for(int i = 0; i < s.length; i++){
    			if ((s[i]).getX() == x && (s[i]).getY() == y && (s[i]).getZ() == z){
    				return true;
    			}
    			
    		}
    		return false;
    	}
    Ich glaube, du rufst die Methode zu oft auf...also die Methode ruft sich selber auf, und irgendwann gibt es ein "StackOverflowError" (ist der, den du meinst, oder?), weil zu viele Methoden hintereinander aufgerufen wurden.
    Platziere einfach mal nur einen einzigen Block in der Luft, und teste das mit dem.

    Mit freundlichen Grüßen
    Johannes_C25

    PS: Was ich rot gemacht habe, ist jetzt nicht sooo wichtig, daran sollte es eig. nicht liegen...

  10. #29
    Creeper-Jäger Avatar von Gnoccy
    Registriert seit
    25.12.2010
    Beiträge
    444
    Minecraft
    Gnoccy
    Ich habe es jetzt mal mit einem Block versucht. Dabei crasht Minecraft zumindest nicht. An anderer Stelle lasse ich mir aber die größe der ArrayList ausgeben. Das Ergebniss ist 4608. Bei zwei Blöcken kommt 295936 raus. Deshalb vermute ich immer noch, dass es an der doesBlockAlreadyExist Methode liegt.
    Und hier nochmal der komplette Code:


    Zitat Zitat von longor1996 Beitrag anzeigen
    -Und die Datei wo der Algoryhtmus ist.
    Meinst du damit, aus welcher Datei ich den Code rauskopiert habe? Das ganze befindet sich in einem TileEntity eines Blockes.
    Geändert von Gnoccy (19.08.2012 um 14:08 Uhr)

  11. #30
    Architekt
    Registriert seit
    27.03.2012
    Beiträge
    1.000
    @Gnoccy

    Probier es mal so:
    Code:
    protected ArrayList flood(World pWorld, int x, int y, int z, ArrayList list){
    		if(pWorld.getBlockId(x, y, z) != 0 && !doesBlockAlreadyExist(list, x, y, z)){
    			list.add(new SBlock(x, y, z, pWorld.getBlockId(x, y, z)));
    			
    			System.out.println(x + y + z);
    			
    			flood(pWorld, x + 1, y, z, list);
    			flood(pWorld, x - 1, y, z, list);
    			flood(pWorld, x , y + 1, z, list);
    			flood(pWorld, x , y - 1, z, list);
    			flood(pWorld, x , y, z + 1, list);
    			flood(pWorld, x , y, z - 1, list);
    		
    		}
    		
    		
    		return list;
    	}

+ Antworten