Archief - Spelbord in java (swing)

Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.

GTboy

Legacy Member
Hallo iedereen :)

Ik ben voor een game een spelbord aan het maken dat random gegenereerd wordt (4 kleuren die random worden geplaatst in een 2 dim array). Nu had ik geprobeerd om mijn images van de kleuren in labels te plaatsen en deze random in een label array te steken. Tot mijn grote spijt werkt dit niet aangezien ik blijkbaar elk gemaakt component maar 1 plaatst tegelijk kan geven. Weet er iemand hoe dit op een andere manier wel werkt ?.

Alvast bedankt

Tomikaza

Legacy Member
Ik zou gewoon eerst een 2 dimensionele array genereren waar de labels een vaste positie hebben.
En daarna zou ik een method bij maken die de bestaande array gaat transformeren in een random geschudde of geshufflede array.

Lees dit maar eens even:
How to randomize a javascript array? - Stack Overflow

Hier is het wel gedaan met een één-dimensionale array, maar de redenering is vrij analoog bij een 2D-array. :)

EDIT: Let wel op dat dit in Javascript gedaan is, maar in Java is het gewoon iets andere syntax.
Hopelijk helpt dit wat.

ultddave

Legacy Member
Indien je persé met JLabels zou willen werken:

Hou een 2D array van JLabels bij, deze stellen uw spelbord visueel voor.

Code:
JLabel[][] spelbord = new JLabel[4][4];
Bijvoorbeeld voor een 4x4 spelbord.
Code:
for(int row = 0; row < 4; ++row) {
   for(int col = 0; col < 4; ++col) {
      spelbord[row][col] = new JLabel(""); // Geen tekst 
      spelbord[row][col].setLocation(row, col); // Te simplistisch en waarschijnlijk niet correct ;)
   }
}

PS: Uiteraard moet je de labels dan handmatig toevoegen aan een container component, bijvoorbeeld aan een JPanel ofzo ;).

Stel dat je dan op plaats [2,2] een rode afbeelding wilt:
Code:
URL url = new URL("C:\rood.jpg");
BufferedImage buffer = ImageIO.read(url);
spelbord[2][2].setIcon(new ImageIcon(buffer);

Afbeelding vervangen is op dezelfde manier, via de setIcon-methode.

Uiteraard kan je de BufferedImage van elke afbeelding ergens bijhouden ipv die elke keer in te laden ;).

PS: Exception-handling is weggelaten uit bovenstaande code.

nuikke

Legacy Member
Inderdaad, eerst een tweedimensionale array van labels maken met een vaste positie (positie best gegenereerd in de for-lus). In deze for-lus kan je dan ook de image van het label instellen. Genereer een getalletje van 0 tem 3 en link hiermee de kleur :)

GTboy

Legacy Member
Tomikaza zei:
Ik zou gewoon eerst een 2 dimensionele array genereren waar de labels een vaste positie hebben.

Dit is idd een goede oplossing :) , maar het probleem is dat het aantal keer een kleur voorkomt niet bekend mag zijn, dus dat bijvoorbeeld de eerste keer blauw 20 keer voorkwam en de volgende keer 10. Alles moet random zijn :(

GTboy

Legacy Member
nuikke zei:
Inderdaad, eerst een tweedimensionale array van labels maken met een vaste positie (positie best gegenereerd in de for-lus). In deze for-lus kan je dan ook de image van het label instellen. Genereer een getalletje van 0 tem 3 en link hiermee de kleur :)

idd een mogelijkheid :) maar het spelbord wordt groter en groter naarmate het level stijgt. Hoe los ik dit dan op met een array die al vast staat ?

Tomikaza

Legacy Member
Dan zou ik van te voren bepalen hoeveel kleuren blauw erin moeten komen, hoeveel kleuren rood,...
Dus ook random genereren hoeveel keer, maar zorgen dat de som van het aantal kleuren (aantal keer blauw + aantal keer rood +...) gelijk is aan de waarde van het aantal kaarten in het spelbord.

Je weet dus hoeveel kaarten er in je spelbord zitten en hoeveel kaarten je van elke kleur hebt.
Vervolgens is ze gewoon achtereenvolgens in de array plaatsen: eerst blauw bijvoorbeeld, dan rood, ...
Let hier wel bij op dat je rekening houdt met het aantal kolommen en rijen in de array zodat je nooit out of bounds gaat en op tijd naar een nieuwe rij of kolom switcht.

En op deze standaard gevulde array met de juiste hoeveelheid van elke kleur pas je dan het shuffle algoritme toe. :)

EDIT: Als je met moeilijkere levels wil werken, dan moet je per level gewoon zeggen: in level 1 wil ik bijvoorbeeld een vaste array van 4x4, in level 2 eentje van 6x6 enzovoort. Het aantal cellen is dan gewoon gelijk aan het aantal rijen maal het aantal kolommen en dit getal is dus je aantal kaarten in het spelbord waar je rekening moet mee houden in je som.

ultddave

Legacy Member
Tomikaza zei:
Ik zou gewoon eerst een 2 dimensionele array genereren waar de labels een vaste positie hebben.
En daarna zou ik een method bij maken die de bestaande array gaat transformeren in een random geschudde of geshufflede array.
Ik denk dat dit niet echt zal werken, want zoals je zegt "labels met vaste positie". Dus je gaat al die referenties gewoon op andere indices plaatsen in die array, maar de label gaan dan wel nog hun "Location" (X, Y) behouden op de GUI. Ondanks dat hij op een andere plaats in de 2D-array is gezet. Dus dan moet je die locaties gaan updaten. Wat uiteraard niet onoverkomelijk is, maar ik denk dat het een beetje omslachtig is. Ofwel heb ik het verkeerd begrepen.

Ik zou zoals nuikke zegt, gewoon de kleuren in de for-lussen genereren;

Code:
BufferedImage[] kleuren = new BufferedImage[4];
kleuren[0] = ImageIO.read(new URL("C:\rood.jpg"));
kleuren[1] = ImageIO.read(new URL("C:\geel.jpg"));
kleuren[2] = ImageIO.read(new URL("C:\groen.jpg"));
kleuren[3] = ImageIO.read(new URL("C:\blauw.jpg"));

for(int row = 0; row < 4; ++row) {
   for(int col = 0; col < 4; ++col) {
      spelbord[row][col] = new JLabel(""); // Geen tekst 
      spelbord[row][col].setLocation(row, col);
      int kleur = (int) (Math.random() * 4.0)
      spelbord[row][col].setIcon(new ImageIcon(kleuren[kleur]));
   }
}

Hoe los ik dit dan op met een array die al vast staat ?
Gewoon een ArrayList gebruiken.

Code:
ArrayList<ArrayList<JLabel>> spelbord = new ArrayList<>();

Code wordt dan:
Code:
for(int row = 0; row < AANTAL_RIJEN; ++row) 
{      
   ArrayList<JLabel> column = new ArrayList<>();
   for(int col = 0; col < AANTAL_KOLOMMEN; ++col) {

      column.add(new JLabel("")); // Geen tekst 
      column.get(col).setLocation(row, col);
      int kleur = (int) (Math.random() * 4.0)
      column.get(col).setIcon(new ImageIcon(kleuren[kleur]));
   }
   spelbord.add(column);
}

(Mijn excuses voor syntax fouten, heb het gewoon getypt op 9lives ipv een editor).

GTboy

Legacy Member
Bedankt allemaal voor de tips :) kzal ze is in de praktijk gaan testen :)

Tomikaza

Legacy Member
Denk ook wel dat het idee van ultddave beter is.
Ik heb trouwens nog geen ArrayLists gezien. :p

GTboy

Legacy Member
ultddave zei:
Code:
BufferedImage[] kleuren = new BufferedImage[4];
kleuren[0] = ImageIO.read(new URL("C:\rood.jpg"));
kleuren[1] = ImageIO.read(new URL("C:\geel.jpg"));
kleuren[2] = ImageIO.read(new URL("C:\groen.jpg"));
kleuren[3] = ImageIO.read(new URL("C:\blauw.jpg"));

for(int row = 0; row < 4; ++row) {
   for(int col = 0; col < 4; ++col) {
      spelbord[row][col] = new JLabel(""); // Geen tekst 
      spelbord[row][col].setLocation(row, col);
      int kleur = (int) (Math.random() * 4.0)
      spelbord[row][col].setIcon(new ImageIcon(kleuren[kleur]));
   }
}

Oke ik ben nog redelijk nieuw in java :) en ik weet niet hoe het komt maar ik kan blijkbaar de read method van ImageIO niet implementeren :( "cannot resolve symbol read" terwijl ik wel de nodige zaken heb geimporteerd ;(

ultddave

Legacy Member
Dat is vreemd: Je hebt de volgende imports nodig voor de images:

import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

Hou er rekening mee dat "read" een statische functie is van de ImageIO klasse. Gewoon:
ImageIO.read(<parameters>); is voldoende voor te gebruiken ;).

Welke IDE gebruik je?

GTboy

Legacy Member
ultddave zei:
Dat is vreemd: Je hebt de volgende imports nodig voor de images:

import java.awt.image.BufferedImage;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;

Hou er rekening mee dat "read" een statische functie is van de ImageIO klasse. Gewoon:
ImageIO.read(<parameters>); is voldoende voor te gebruiken ;).

Welke IDE gebruik je?

Allemaal geimporteerd :)
en ik gebruik IntelliJ.

ultddave

Legacy Member
Ah ok, het feit dat hij die kan importeren lijkt me dan toch te bevestigen dat hij die kan vinden.

"cannot resolve symbol read" => Heb je toevallig een variabele gebruikt die "read" heet op die regel?

GTboy

Legacy Member
ultddave zei:
Ah ok, het feit dat hij die kan importeren lijkt me dan toch te bevestigen dat hij die kan vinden.

"cannot resolve symbol read" => Heb je toevallig een variabele gebruikt die "read" heet op die regel?

nope, dat is de enige read in men code :(

cptKangaroo

Legacy Member
Als ik ultddave's post zie, kan je misschien

import javax.ImageIO
in plaats van
import javax.imageio.ImageIO

geschreven hebben?

ultddave

Legacy Member
Probleem is gevonden, hij had:
"<var> = new ImageIO.read(...)" staan ipv:
"<var> = ImageIO.read(...)"

Had hem gevraagd via PM om de code even door te sturen ;). Probleem is dus opgelost, wilde het hier even melden.
Het archief is een bevroren moment uit een vorige versie van dit forum, met andere regels en andere bazen. Deze posts weerspiegelen op geen enkele manier onze huidige ideeën, waarden of wereldbeelden en zijn op sommige plaatsen gecensureerd wegens ontoelaatbaar. Veel zijn in een andere tijdsgeest gemaakt, al dan niet ironisch - zoals in het ironische subforum Off-Topic - en zouden op dit moment niet meer gepost (mogen) worden. Toch bieden we dit archief nog graag aan als informatiedatabank en naslagwerk. Lees er hier meer over of start een gesprek met anderen.
Terug
Bovenaan