Du verwendest einen veralteten Browser. Es ist möglich, dass diese oder andere Websites nicht korrekt angezeigt werden. Du solltest ein Upgrade durchführen oder ein alternativer Browser verwenden.
Hi,
ich muss für die Schule ein Verschiebepuzzle programmieren, das ist so, ein Bild wird geladen und das wird dann in 5*5 Teile geteilt, ein Teil wird weggelassen und ist leer und diese Zeile werden dann zufälig angeordnet, so das man das Orgianl wieder zusammenbasteln muss.
Ich habe aber keine Ahnung wie ich das machen soll. ;(
Ich weiß wie man ein Bild anzeigt usw.
Aber wie man das jetzt Splittet ist mir völlig fremd, kann mir einer von euch vielleicht helfen?
Zum Splitten:
Mach dir 5*5 BufferedImages (new BufferedImage(..., TYPE_INT_RGB)), generiere für jedes dieser Images ein Graphics-Object (image.getGraphics), und zeichne ein Stücklein deines grossen Bildes mit Hilfe eines solchen Graphics-Object.
Also etwa so:
Code:
Image[][] images = new Image[5][5];
for( int i = 0; i < 5; i++ ){
for( int j = 0; j < 5; j++ ){
BufferedImage image = new BufferedImage( ... );
Graphics g = image.getGraphics();
g.drawImage( grossesImage, i*..., j*..., ... );
image[i][j] = image;
}
}
Erst mal schon vielen lieben Dank, ich bin gerade dabei den Code einzubasteln, noch eine frage, wüsstest du vielleicht noch wie ich den Zufall simulieren könnte?
Die Bilder müssen bei einem neuen Spiel ja durcheinander angezeigt werden und bei jedem Spiel zufällig angeordnet.
mit Math.random() bekommst du eine zufällige zahl zwischen 0 und 1. das rechnest du * 25, --> 25 Möglichkeiten
dann setzt du die Bilder so an zufällige Orte, musst allerdings beachten, dass nicht 2 am selben ort sein dürfen.
Würde die Zahlen die schon vorkamen in einem Array speichern und dann immer kontrollieren ob der Ort schon besetzt ist...
Oder (wie dotlens geschrieben hat mit Math.random()):
http://java.sun.com/j2se/1.5.0/docs/api/java/lang/Math.html#random()
Vielleicht könntest du dir ja auch ein boolean Array anfertigen, wobei du die Elemente auf true setzt wenn das Bild schon da ist, dann musst du nur noch auf den Wert im Array kontrollieren.
WOW, also nochmal VIELEN Dank für eure reichen Antworten!
Aber, ich muss euch gestehen, ich habe erst heute RICHTIG mit Java begonnen und so ist noch lang nicht alles Gold was glenzt! ;(
Ich komme so von VB(.Net), Delphi usw., deshlab ist Java momentan irgendwie noch so...weit weg, wir sind noch nicht beste Freunde
Dehalb, poste ich jetzt mal hier meine Klasse, die ich gebastelt habe und es wäre klasse, wenn ihr die Bugs ausmerzt, was dazu sagt und meine Kommentarfragen, ergenzt.
Wäre euch superdankbar, ich denke dann bin ich wieder was näher an Java gekommen.
Code:
package puzzlemaster;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.math.*;
/**
*
Title: ImageSplitter</p>
*
*
Description: Diese Klasse dient zum anzeigen eines Bildes und dann wird es geteilt</p>
*
*
Copyright: Christian N. (c) 2005</p>
*
*
Company: WebTec GbR</p>
*
* @author Christian N.
* @version 1.0
*/
public class ImageSplitter extends JPanel
{
private Image pic;
private Image[][] Bilder;
private Toolkit toolkit;
private MediaTracker tracker;
private int Hor_Teile = 0;
private int Ver_Teile = 0;
private int Teil_Breit = 0;
private int Teil_Hoch = 0;
private boolean[] HatteIchSchon;
private double ZufallsZahl;
public ImageSplitter(int Horizontal, int Vertikal)
{
Hor_Teile = Horizontal;
Ver_Teile = Vertikal;
Bilder = new Image[Hor_Teile][Ver_Teile];
}
public void BildSplitten(String Bild)
{
toolkit = Toolkit.getDefaultToolkit();
tracker = new MediaTracker(this);
pic = toolkit.getImage( Bild );
tracker.addImage(pic , 0);
Teil_Breit = pic.getWidth(this) / Hor_Teile;
Teil_Breit = pic.getHeight(this) / Ver_Teile;
// Die einzelnden Teile werden in ein BilderArray gespeichert
for( int i = 0; i < Ver_Teile; i++ )
{
for( int j = 0; j < Hor_Teile; j++ )
{
BufferedImage image = new BufferedImage(Teil_Breit, Teil_Hoch, TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.drawImage(pic, i * Teil_Breit, j * Teil_Hoch, Teil_Breit, Teil_Hoch, this);
Bilder[i][j] = image;
}
}
// Die einzelden Teile werden nun gezeichnet
for( int i = 0; i < Ver_Teile; i++ )
{
for( int j = 0; j < Hor_Teile; j++ )
{
ZufallsZahl = Math.random()*25;
// Bis ich ein noch nicht angezeigtes Bild gefunden habe
while(HatteIchSchon[(int)ZufallsZahl] == true)
{
ZufallsZahl = Math.random()*25;
}
// Hier jetzt irgendwie an Position i*Teil_Breit, j*Teil_Hoch
// Bilder[(int)ZufallsZahl/Ver_Teile][(int)ZufallsZahl%Hor_Teile] auf mein Panel zeichen
HatteIchSchon[(int)ZufallsZahl] = true;
}
}
try
{
tracker.waitForAll();
}
catch(InterruptedException e)
{
}
}
public void paintComponent( Graphics g )
{
// Bruache ich das noch?
//super.paintComponent( g );
//g.drawImage( pic, 0, 0, this );
}
}
### Known Bugs ###
1. TYPE_INT_RGB kennt er nicht.
Ich hoffe jemand tut mir diesen wahrlich großen Gefallen.
Dann reissen wir diesen Code mal auseinander :-D :wink:
Code:
public class ImageSplitter extends JPanel
{
private Image pic;
private Image[][] Bilder;
private Toolkit toolkit;
private MediaTracker tracker;
private int Hor_Teile = 0;
private int Ver_Teile = 0;
private int Teil_Breit = 0;
private int Teil_Hoch = 0;
private boolean[] HatteIchSchon;
private double ZufallsZahl;
public ImageSplitter(int Horizontal, int Vertikal)
{
Hor_Teile = Horizontal;
Ver_Teile = Vertikal;
Bilder = new Image[Hor_Teile][Ver_Teile];
}
public void BildSplitten(String Bild)
{
Für Java gibt es strenge Codeconventions. Die werden von praktisch allen Programmieren (Ausnahme: Professoren + Lehrer) eingehalten. Daher kann jeder Java-Programmierer relativ leicht den Code eines anderen lesen.
Für nicht konstante Variablen gilt: Name beginnt mit Kleinbuchstaben, und wird mit CamelCase geschrieben (keine "_", sondern Grossbuchstaben im Namen).
Dasselbe gilt für Methoden.
Code:
toolkit = Toolkit.getDefaultToolkit();
Benötigst du das Toolkit (oder auch zufallsZahl) noch an einem anderen Ort? Sieht nicht so aus, darum sollte "toolkit" keine Instanzvariable, sondern eine Methodenvariable sein. D.h. du kannst Zeile 27 löschen, und hier direkt "Toolkit toolkit = Toolkit.getDefaultToolkit();" hinschreiben.
Die Klasse ImageIO und die Methode ImageIO.read könnten interessant für dich sein. Dann kannst du den MediaTracker weglassen.
Code:
Teil_Breit = pic.getWidth(this) / Hor_Teile;
Teil_Breit = pic.getHeight(this) / Ver_Teile;
// Die einzelnden Teile werden in ein BilderArray gespeichert
for( int i = 0; i < Ver_Teile; i++ )
{
for( int j = 0; j < Hor_Teile; j++ )
{
BufferedImage image = new BufferedImage(Teil_Breit, Teil_Hoch, TYPE_INT_RGB);
In Java gibt es keine globalen Variablen (bzw. Konstanten), deshalb ist TYPE_INT_RGB hier unbekannt.
Als "Ersatz" gibt es sog. statische Variablen (und Konstanten), man spricht diese Werte über die Klasse an, in der sie definiert sind: "new BufferedImage( teilBreit, teilHoch, BufferedImage.TYPE_INT_RGB );"
Code:
Graphics g = image.getGraphics();
g.drawImage(pic, i * Teil_Breit, j * Teil_Hoch, Teil_Breit, Teil_Hoch, this);
Bilder[i][j] = image;
}
}
Code:
// Die einzelden Teile werden nun gezeichnet
for( int i = 0; i < Ver_Teile; i++ )
{
for( int j = 0; j < Hor_Teile; j++ )
{
ZufallsZahl = Math.random()*25;
// Bis ich ein noch nicht angezeigtes Bild gefunden habe
while(HatteIchSchon[(int)ZufallsZahl] == true)
{
ZufallsZahl = Math.random()*25;
}
// Hier jetzt irgendwie an Position i*Teil_Breit, j*Teil_Hoch
// Bilder[(int)ZufallsZahl/Ver_Teile][(int)ZufallsZahl%Hor_Teile] auf mein Panel zeichen
HatteIchSchon[(int)ZufallsZahl] = true;
}
}
Das wird schon funktionieren (hoff ich mal, habs nicht ausprobiert), aber rein theoretisch könnte es passieren, dass bei unglücklichen Zufallszahlen hier ziemlich lange herumgewürfelt wird.
Ein alternativer Algorithmus: Ein Array mit den Zahlen 1 - 25. Nun wird ein Index zufällig erzeugt. Die Zahl an dieser Stelle wird mit der Zahl die an der letzten gültigen Position des Arrays steht vertauscht, und die Anzahl gülter Positionen um 1 verringert. Nun wird der nächste Index gezogen... (nun nicht mehr "Math.random()*25" sondern "Math.random()*(25-1)")
Code:
try
{
tracker.waitForAll();
}
catch(InterruptedException e)
{
}
}
public void paintComponent( Graphics g )
{
// Bruache ich das noch?
//super.paintComponent( g );
//g.drawImage( pic, 0, 0, this );
}
}
Hm, du willst ja die einzelnen Bilder im bilderArray zeichen. Die Methode "paintComponent" brauchst du also schon noch, nur der Inhalt sieht anders aus.