Ladestatus Ressourcen betrachten

BRoll

Bekanntes Mitglied
Hi Leute, ich hab grad mal wieder eine Frage.

Also in meinem Spiel habe ich ein Frame, und viele Bilder (so ca 500+).

Java:
public static Image fighter[][] = new Image[fighteranz][30];
	public static Image faces[] = new Image[fighteranz];
	public static Image clouds[] = new Image[3];
	public static Image maps[] = new Image[12];
	public static Image aura[] = new Image[10];
	public static Image chapterimages[] = new Image[5];
	public static Image stages[] = new Image[12];
	public static Image fighterselection[] = new Image[fighteranz+2];
	public static Image effects[],explosions[],congratulations,messagepfeil,messagebox,failed,hud,leben,ki,nextrow,title,cursor,ko,menuback,mapselection,vs,versusscreen;
	public static Image blitzicon[] = new Image[2];
	public static Image fighticon[] = new Image[2];
	public static Image multisteer[] = new Image[4];
	public static Image menuicons[] = new Image[3];
	public static Image dragonballs[] = new Image[7];
	public static Image worldicons[] = new Image[3];
	public static Image maptiles[][]=new Image[2][100];
	public static Image minimap[]=new Image[2];
	public static Image mapchars[]=new Image[48];
	public static Image pod,stars,pluscharacter,subcharacter;
	private static Image icon;

Die werden alle beim starten eingelesen, und dauert auch mit den Sounds
zusammen eine gewisse Zeit.
Dafür habe ich einen Ladebalken am Start eingebaut.
Dieser füllt sich jetzt einfach automatisch ohne genau zu wissen
wie viel schon geladen wurde.
Dh. er hat immer eine konstante Zeit, was natürlich quatsch ist.

Er soll natürlich erst fertig sein, wenn alle Ressourcen (Bilder, Sounds)
eingelesen und fertig verfügbar sind.
Andernfalls kann es sein, dass das Spiel schon fertig geladen hat,
aber viele Bilder erst nach und nach angezeigt werden.

Ich weiß, dass man mit der Methode .prepareImage(image, observer) abfragen kann,
ob ein Bild fertig geladen ist.
Bloß finde ich das ein bisschen umständig und viel Aufwand jedes Bild so abzufragen...!

Also kann man nicht "einfach" irgendwie den Cache oder so auslesen,
also den Bereich wo alles eingelesen wird, und so sehen wie viel schon geladen ist?
(also sozusagen ein Gesamtlade-fortschritt für alle Ressourcen)
Damit könnte der Ladebalken nämlich schön gesteuert werden.

Oder jemand eine Idee wie man das machen kann?

mfg BRoll
 

Volvagia

Top Contributor
Du könnstes einfach einen Counter hochzählen und der Progressanzeige vom Lader ein Callback geben lassen.
Mit dem MediaTracker lässt sich der Ladezustand eines Bildes besser überprüfen. (Oder du nimmst symetrisches Laden, z. B. per ImageIO)
 

BRoll

Bekanntes Mitglied
Du könnstes einfach einen Counter hochzählen und der Progressanzeige vom Lader ein Callback geben lassen.
Mit dem MediaTracker lässt sich der Ladezustand eines Bildes besser überprüfen. (Oder du nimmst symetrisches Laden, z. B. per ImageIO)

Hmm das bringt mir nichts.
Ich will von allem das Lesen, und nicht von einem Bild nur.
Weil sonst müsste ich über 30 Abfragen machen...
Dann sieht der Code ziemlich beknackt aus xD

Das mit einem Counter hochzählen verstehe ich nicht.
:noe:
 

Volvagia

Top Contributor
Ich habe mir das etwa so vorgestellt. Kannst du sicher leicht anpassen.
Läd alle Bilder aus dem Ordner img (außer in Unterverzeichnissen).

Java:
package org.javaforum;

import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import java.io.File;
import java.util.EventListener;
import java.util.EventObject;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;

import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JProgressBar;
import javax.swing.SwingWorker;

public class ImgLoad {
	public static void main(String [] args) {
		final LoadProgressView view = new LoadProgressView();
		
		final ImageLoader loader = new ImageLoader();
		loader.addListener(new ImageLoaderListener() {
			public void imageLoaded(ImageLoaderEvent arg0) {
				int current = arg0.getLoadCount();
				int totalCount = arg0.getTotalImageCount();

				view.setMax(totalCount);
				view.setValue(current);
			}
		});
		
		view.show();
		
		new SwingWorker<Map<String, Image>, Void>() {
			protected Map<String, Image> doInBackground() throws Exception {
				return(loader.loadImages());
			}
			protected void done() {
				try {
					Map<String, Image> images = get();
					view.hide();
					
					new ShowImagesView(images).show();
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (ExecutionException e) {
					e.printStackTrace();
				}
			}
		}.execute();
	}
	
	private static class ShowImagesView {
		private JFrame frame;
		
		public ShowImagesView(Map<String, Image> imageMap) {
			frame = new JFrame();
			frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
			frame.getContentPane().setLayout(new FlowLayout());
			
			for(Entry<String, Image> entry:imageMap.entrySet()) {
				Image img = entry.getValue();
				if(img != null) {
					frame.add(new JLabel(new ImageIcon(img)));
				}
			}
		}

		public void show() {
			frame.pack();
			setVisible(true);
		}
		public void hide() {
			setVisible(false);
			frame.dispose();
		}
		private void setVisible(boolean b) {
			frame.setVisible(b);
		}
	}
	private static class LoadProgressView {
		private JFrame frame;
		private JProgressBar bar;
		
		public LoadProgressView() {
			frame = new JFrame();
			frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
			
			frame.add(new JLabel("Bitte warten, wärend die Bilder geladen werden..."), BorderLayout.NORTH);
			bar = new JProgressBar();
			frame.add(bar);
		}
		
		public void setValue(int min) {
			bar.setValue(min);
		}

		public void setMax(int max) {
			bar.setMaximum(max);
		}

		public void show() {
			frame.pack();
			setVisible(true);
		}
		public void hide() {
			setVisible(false);
			frame.dispose();
		}
		private void setVisible(boolean b) {
			frame.setVisible(b);
		}
	}
	private static class ImageLoader {
		private static final JComponent TRACKER_COMP = new JComponent() {};
		private static final MediaTracker tracker = new MediaTracker(TRACKER_COMP);
		
		private List<ImageLoaderListener> listeners;
		
		public ImageLoader() {
			listeners = new LinkedList<ImgLoad.ImageLoaderListener>();
		}
		public void addListener(ImageLoaderListener l) {
			listeners.add(l);
		}
		public synchronized Map<String, Image> loadImages() {
			File f = new File("img/");
			if(!f.exists()) {
				System.err.println("Ordner 'img' existiert leider nicht.");
				return(null);
			}
			
			File[] content = f.listFiles();
			int imageCount = content.length;
			int loadCounter = 0;
			
			Map<String, Image> imageMap = new HashMap<String, Image>();
			
			for(File imgFile:content) {
				Image image = Toolkit.getDefaultToolkit().getImage(imgFile.getPath());
				tracker.addImage(image, 0);
				try {
					tracker.waitForID(0);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				loadCounter++;
				
				try {
					TimeUnit.SECONDS.sleep(1L); //<- Zum Testen
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
				
				fireImageLoadEvent(image, imageCount, loadCounter);
				imageMap.put(imgFile.getName(), image);
			}
			return(imageMap);
		}
		public void fireImageLoadEvent(Image image, int imageCount, int loadCounter) {
			fireImageLoadEvent(new ImageLoaderEvent(this, image, imageCount, loadCounter));
		}
		public void fireImageLoadEvent(final ImageLoaderEvent event) {
			EventQueue.invokeLater(new Runnable() {
				public void run() {
					for(ImageLoaderListener l:listeners) {
						l.imageLoaded(event);
					}
				}
			});
		}
	}
	private static interface ImageLoaderListener extends EventListener {
		public void imageLoaded(ImageLoaderEvent arg0);
	}
	private static class ImageLoaderEvent extends EventObject {
		private Image image;
		private int totalImageCount;
		private int loadCounter;
		
		public ImageLoaderEvent(Object source, Image image, int totalImageCount, int loadCounter) {
			super(source);
			this.image = image;
			this.totalImageCount = totalImageCount;
			this.loadCounter = loadCounter;
		}
		public Image getImage() {
			return image;
		}
		public int getTotalImageCount() {
			return totalImageCount;
		}
		public int getLoadCount() {
			return loadCounter;
		}
	}
}

Da kümmert sich der Loader ums Laden, der View ums Anzeigen und die Main-Methode spielt den Controller der beides startet und vernetzt.

attachment.php

attachment.php

attachment.php

attachment.php
 

Anhänge

  • a.png
    a.png
    1,9 KB · Aufrufe: 45
  • b.png
    b.png
    1,8 KB · Aufrufe: 41
  • c.png
    c.png
    1,9 KB · Aufrufe: 44
  • d.png
    d.png
    38 KB · Aufrufe: 40
Zuletzt bearbeitet:

BRoll

Bekanntes Mitglied
Hmmm kann ich leider nicht verwenden,
da ich sonst alles umschreiben müsste.
Ich habe die Bilder ja als einzelne Variablen und Arrays,
und nicht als HashMap. Und viele zerschneide ich noch usw.

Ich glaub ich werde wohl doch jedes Bild abfragen müssen xD
 

Volvagia

Top Contributor
Macht ja nichts. Intern macht der Lader was er will.
Man kann das ja auch getrennt betrachten:

Controller ------ Lader
|
|
|
|
View

Wie bei einer Liste. Intern macht die Liste irgendwas und benutzt auch Subobjekte, was von außen keine Rolle spielt. Wichtig sind nur die Methoden (addListener und loadImages). Was dahinter passiert braucht das restliche Programm nicht zu interessieren. Der Lader kann Bilder laden, zuschneiden, umfärben oder auf dem Kopf stellen. Wichtig ist nur, dass er der "Überklasse" durch eine Benachrichtigung (in dem Fall durch einen EventListener) mitteilt, dass sich überhaupt etwas getan hat. Diese kann dann wie sie Lust hat darauf reagieren. (In dem Fall aktualisiert sie die ProgressBar)

Die Map war nur ein Beispiel. Er kann theoretisch auch die Bilder direkt in Arrays des Hauptcodes schreiben oder auch eine Kapselung für alle Arrays zurückgeben.
 

Ähnliche Java Themen

Neue Themen


Oben