Tablero Klotski continuacion...

Tu solución a como crear el tablero del juego klotski a partir de caracteres, me ha caído de lujo, funciona muy bien, pero quiero hacerlo diferente, es decir, solo quiero usar dos colores, las pieza a sacar seria rojo y las restantes serian azul, solo me refiero a las piezas movibles, los muros y espacios en blanco ya están definidos.
El problema que se me presenta es que al agregar un solo color a el resto de las piezas (a-z), no se diferencia si es un rectángulo o un cuadrado, se ve un solo color, lo que quiero es crear la separación de cada pieza y que tenga el mismo color.
1

1 respuesta

Respuesta
1
Para que solo te aparezcan dos tipos de piezas movibles simplemente tendrías que modificar tu archivo, poniendo solo esos dos caracteres. Y en el programa también tendrías que hacer lo mismo.
Ahora para lo que dices de diferenciar una pieza de otra puedes ponerle una pequeña separación entre las piezas poniéndole esto en la linea donde dibujas el rectángulo (en el método paint):
g.fillRect(posX+1,posY+1,ancho-1,alto-1);
Lo que hace es dejar un espacio entre cada cuadrado.
Gracias por responder, eso serviría pero para todas las piezas, incluyendo muros, quedo como una cuadricula, el archivo no lo debo modificar, he intentado hacerlo con muchas condiciones pero es un poco engorroso, ademas a la hora de usar el mouse sera peor, que otra solución me puedes dar.
Vi el código de gnotski de linux que usan los mismos caracteres, pero no lo entiendo, esta en c++ y usan gtk, he visto otros código pero es diferente de donde extraen las figuras, hacen como unas conversiones.
Gracias de antemano...
Bajé un ejemplo del Klotski y ya más o menos vi que es lo que quieres hacer.
Lo que puedes hacer es dejar como están los caracteres, pero tendrías que ver que cuando muevas por ejemplo el * hacia abajo se muevan todos los demás elementos de la matriz que contengan un * hacia abajo (o la dirección hacia la que lo hayas movido) Y eso mismo tendrías que hacer con todos los demás.
Esto lo puedes hacer recorriendo toda la matriz hasta encontrar caracteres iguales y también tienes que checar que todos esos caracteres queden en un espacio en blanco ( & ) o de lo contrario no puedan moverse.
Eso tal cual lo recomendaste ya lo hice, los movemientos en consola los hace perfectamente, el problema esta es hacer la parte gráficamente, si uso un color por cada pieza funciona pero se ve como un carnaval y no es la idea, lo que quiero es utilizar un único color para las letras y y otro para los ****, y que se refleje que existen cuadrados y rectángulos del mismo color pero separados, ahí es donde entra el meollo de todo, ya que el problema principal es hacer las separaciones.
Si me dices que no se puede hacer de otra forma más que con puras validaciones me tocara, gracias por responder...
Pues, lo que puedes hacer es verificar si una figura tiene otras del mismo tipo junto a ella en cada una de las posiciones (arriba, abajo, derecha e izquierda) si arriba no tiene una igual entonces aumentas la posicionY desde la que empiezas a dibujar y disminuyes la altura para que de esta forma quede un poco separado y si fuera igual no se hace nada para que queden juntos. Yo lo hice de esa forma y aquí te paso el código (Le agregue un mouseMotionListener para detectar cuando se haga un Drag):
import java.awt.*;
import java.io.*;
import java.awt.event.*;
public class tabler extends Frame implements MouseListener,MouseMotionListener{
char arreglo[][];
int lx,ly;
tabler(){
setSize(500,600);
addMouseListener(this);
addMouseMotionListener(this);
try{
BufferedReader in=new BufferedReader(new InputStreamReader(new FileInputStream("archivo.txt")));
int filas=Integer.parseInt(in.readLine());
int columnas=Integer.parseInt(in.readLine());
arreglo=new char[filas][columnas];
for(int i=0;i < filas;i++){
for(int j=0;j < columnas;j++){
arreglo[ i ][ j ]=(char)(in.read());
}
}
in.close();
}catch(Exception e){}
}
//Este metodo es el que se llama cada vez que la ventana necesite pintarse
public void paint(Graphics g){
super.paint(g);
update(g);
}
public void update(Graphics g){
Image ibuf=createImage(getWidth(),getHeight());
Graphics buf=ibuf.getGraphics();
//PosX y posY se utilizan para ir cambiando la posición en la que se pintara el rectángulo
//ancho y alto son precisamente el ancho y alto del rectangulo
int posX,posY,ancho=35,alto=35;
Color col=null;
//Recorremos los elementos del arreglo
posY=50;
for(int i=0;i < arreglo.length;i++){
posX=50;
for(int j=0;j < arreglo[ i ].length; j++){
//Escogemos el color a pintar segun el caracter (&,#,etc.)
if(arreglo[ i ][ j ]=='*')col=Color.red;
else if(arreglo[ i ][ j ]>='a'&&arreglo[j]<='y')col=Color.BLUE;//col=Color.yellow;
else if(arreglo[ i ][ j ]=='#')col=Color.gray;
else if(arreglo[ i ][ j ]=='-')col=Color.DARK_GRAY;
else if(arreglo[ i ][ j ]=='&')col=Color.white;
else if(arreglo[ i ][ j ]=='·')col=Color.red;
//Asignamos el color
buf.setColor(col);
//Dibujamos el rectangulo
pintar(i,j,posX,posY,buf);
//buf.fillRect(posX,posY,ancho,alto);
posX+=ancho;
}
posY+=alto;
}
g.drawImage(ibuf,0,0,this);
ibuf.flush();
buf.dispose();
}
public void pintar(int i,int j,int posX,int posY,Graphics g){
int ancho=35,alto=35;
//Verificamos si tiene algun caracter igual arriba
if(i-1>=0){
if(arreglo[i-1][j]!=arreglo[j]){
posY+=1;
alto-=1;
}
}
//Verificamos si tiene algun caracter igual a la izquierda
if(j-1>=0){
if(arreglo[j-1]!=arreglo[j]){
posX+=1;
ancho-=1;
}
}
//Verificamos si tiene algun caracter igual abajo
if(i+1<arreglo.length){
if(arreglo[i+1][j]!=arreglo[j])alto-=1;
}
//Verificamos si tiene algun caracter igual a la derecha
if(j+1<arreglo[0].length){
if(arreglo[j+1]!=arreglo[j])ancho-=1;
}
//Pintamos el rectangulo
g.fillRect(posX,posY,ancho,alto);
}
public void mouseExited(MouseEvent evt){
}
public void mouseEntered(MouseEvent evt){
}
public void mouseReleased(MouseEvent evt){
}
public void mover(int i,int j,int vx,int vy,char car){
//Movemos el carácter, verificando primero si hay algún carácter igual al que tratamos de mover en el camino
//Y en ese caso lo movemos antes para que no se pierda
if(arreglo[i+vy][j+vx]==car){
mover(i+vy,j+vx,vx,vy,car);
}
arreglo[i+vy][j+vx]='z';
arreglo[j]='&';
}
public void mousePressed(MouseEvent evt){
int c=(evt.getX()-50)/35;
int f=(evt.getY()-50)/35;
if(f>=arreglo.length||c>=arreglo[0].length)return;
if(arreglo[f][c]=='#'||arreglo[f][c]=='-'||arreglo[f][c]=='·'||arreglo[f][c]=='&')return;
//Guardamos la posicion en la que se hizo click
lx=c;
ly=f;
}
public void mouseDragged(MouseEvent evt){
int c,f;
c=(evt.getX()-50)/35;
f=(evt.getY()-50)/35;
if(f>=arreglo.length||c>=arreglo[0].length||f<0||c<0)return;
if(f==ly&&c==lx||arreglo[f][c]!='&'&&arreglo[f][c]!=arreglo[ly][lx]||Math.abs(lx-c)>1||Math.abs(ly-f)>1||Math.abs(lx-c)+Math.abs(ly-f)>1)return;
//Obtenemos el caracter sobre el que se hizo el click
char car=arreglo[ly][lx];
int vx,vy;
//Obtenemos la posicion hacia la que se movio
vx=c-lx;
vy=f-ly;
//Verificamos que todos los caracteres iguales a el se puedan mover, de lo contrario, salimos del metodo
for(int i=0;i<arreglo.length;i++){
for(int j=0;j<arreglo.length;j++){
if(arreglo[j]==car){
if(j+vx<0||j+vx>arreglo.length||i+vy<0||i+vy>arreglo.length)return;
if(arreglo[i+vy][j+vx]!='&'&&arreglo[i+vy][j+vx]!=car)return;
}
}
}
//Movemos las piezas y asignamos una z en la posicion donde vaya a quedar
//Esto es para no mover varias veces la misma pieza
for(int i=0;i<arreglo.length;i++){
for(int j=0;j<arreglo.length;j++){
if(arreglo[j]==car){
mover(i,j,vx,vy,car);
}
}
}
//Cambiamos las z por el caracter correcto
for(int i=0;i<arreglo.length;i++){
for(int j=0;j<arreglo.length;j++){
if(arreglo[j]=='z')arreglo[j]=car;
}
}
lx=c;
ly=f;
repaint();
}
public void mouseMoved(MouseEvent evt){}
public void mouseClicked(MouseEvent evt){
}
public static void main(String arg[]){
tabler t=new tabler();
t.show();
t.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent evt){
System.exit(0);
}
});
}
}
Perdón, algunas partes donde puse [ i ] no salieron porque si no le pongo espacios lo borra. También tienes que cambiarle el nombre del archivo de "archivo.txt" al que tu uses.
Aquí va otra vez el código:
import java.awt.*;
import java.io.*;
import java.awt.event.*;
public class tabler extends Frame implements MouseListener,MouseMotionListener{
char arreglo[][];
int lx,ly;
tabler(){
setSize(500,600);
addMouseListener(this);
addMouseMotionListener(this);
try{
BufferedReader in=new BufferedReader(new InputStreamReader(new FileInputStream("archivo.txt")));
int filas=Integer.parseInt(in.readLine());
int columnas=Integer.parseInt(in.readLine());
arreglo=new char[filas][columnas];
for(int i=0;i < filas;i++){
for(int j=0;j < columnas;j++){
arreglo[ i ][ j ]=(char)(in.read());
}
}
in.close();
}catch(Exception e){}
}
//Este metodo es el que se llama cada vez que la ventana necesite pintarse
public void paint(Graphics g){
super.paint(g);
update(g);
}
public void update(Graphics g){
//Creamos un buffer para evitar el parpadeo de la ventana
Image ibuf=createImage(getWidth(),getHeight());
Graphics buf=ibuf.getGraphics();
//PosX y posY se utilizan para ir cambiando la posición en la que se pintara el rectángulo
//ancho y alto son precisamente el ancho y alto del rectangulo
int posX,posY,ancho=35,alto=35;
Color col=null;
//Recorremos los elementos del arreglo
posY=50;
for(int i=0;i < arreglo.length;i++){
posX=50;
for(int j=0;j < arreglo[ i ].length; j++){
//Escogemos el color a pintar segun el caracter (&,#,etc.)
if(arreglo[ i ][ j ]=='*')col=Color.red;
else if(arreglo[ i ][ j ]>='a'&&arreglo[j]<='y')col=Color.BLUE;
else if(arreglo[ i ][ j ]=='#')col=Color.gray;
else if(arreglo[ i ][ j ]=='-')col=Color.DARK_GRAY;
else if(arreglo[ i ][ j ]=='&')col=Color.white;
else if(arreglo[ i ][ j ]=='·')col=Color.red;
//Asignamos el color
buf.setColor(col);
//Dibujamos el rectangulo
pintar(i,j,posX,posY,buf);
//buf.fillRect(posX,posY,ancho,alto);
posX+=ancho;
}
posY+=alto;
}
g.drawImage(ibuf,0,0,this);
ibuf.flush();
buf.dispose();
}
public void pintar(int i,int j,int posX,int posY,Graphics g){
int ancho=35,alto=35;
//Verificamos si tiene algun caracter igual arriba
if(i-1>=0){
if(arreglo[ i-1 ][ j ]!=arreglo[ i ][ j ]){
posY+=1;
alto-=1;
}
}
//Verificamos si tiene algun caracter igual a la izquierda
if(j-1>=0){
if(arreglo[ i ][ j-1 ]!=arreglo[ i ][ j ]){
posX+=1;
ancho-=1;
}
}
//Verificamos si tiene algun caracter igual abajo
if(i+1<arreglo.length){
if(arreglo[ i+1 ][ j ]!=arreglo[ i ][ j ])alto-=1;
}
//Verificamos si tiene algun caracter igual a la derecha
if(j+1<arreglo[ 0 ].length){
if(arreglo[ i ][ j+1 ]!=arreglo[ i ][ j ])ancho-=1;
}
//Pintamos el rectangulo
g.fillRect(posX,posY,ancho,alto);
}
public void mouseExited(MouseEvent evt){
}
public void mouseEntered(MouseEvent evt){
}
public void mouseReleased(MouseEvent evt){
}
public void mover(int i,int j,int vx,int vy,char car){
//Movemos el carácter, verificando primero si hay algún carácter igual al que tratamos de mover en el camino
//Y en ese caso lo movemos antes para que no se pierda
if(arreglo[ i+vy ][ j+vx ]==car){
mover(i+vy,j+vx,vx,vy,car);
}
arreglo[ i+vy ][ j+vx ]='z';
arreglo[ i ][ j ]='&';
}
public void mousePressed(MouseEvent evt){
int c=(evt.getX()-50)/35;
int f=(evt.getY()-50)/35;
if(f>=arreglo.length||c>=arreglo[ 0 ].length)return;
if(arreglo[ f ][ c ]=='#'||arreglo[ f ][ c ]=='-'||arreglo[ f ][ c ]=='·'||arreglo[ f ][ c ]=='&')return;
//Guardamos la posicion en la que se hizo click
lx=c;
ly=f;
}
public void mouseDragged(MouseEvent evt){
int c,f;
c=(evt.getX()-50)/35;
f=(evt.getY()-50)/35;
if(f>=arreglo.length||c>=arreglo[ 0 ].length||f<0||c<0)return;
if(f==ly&&c==lx||arreglo[ f ][ c ]!='&'&&arreglo[ f ][ c ]!=arreglo[ ly ][ lx ]||Math.abs(lx-c)>1||Math.abs(ly-f)>1||Math.abs(lx-c)+Math.abs(ly-f)>1)return;
//Obtenemos el caracter sobre el que se hizo el click
char car=arreglo[ly][lx];
int vx,vy;
//Obtenemos la posicion hacia la que se movio
vx=c-lx;
vy=f-ly;
//Verificamos que todos los caracteres iguales a el se puedan mover, de lo contrario, salimos del metodo
for(int i=0;i<arreglo.length;i++){
for(int j=0;j<arreglo[ i ].length;j++){
if(arreglo[ i ][ j ]==car){
if(j+vx<0||j+vx>arreglo[ i ].length||i+vy<0||i+vy>arreglo.length)return;
if(arreglo[ i+vy ][ j+vx ]!='&'&&arreglo[ i+vy ][ j+vx ]!=car)return;
}
}
}
//Movemos las piezas y asignamos una z en la posicion donde vaya a quedar
//Esto es para no mover varias veces la misma pieza
for(int i=0;i<arreglo.length;i++){
for(int j=0;j<arreglo[ i ].length;j++){
if(arreglo[ i ][ j ]==car){
mover(i,j,vx,vy,car);
}
}
}
//Cambiamos las z por el caracter correcto
for(int i=0;i<arreglo.length;i++){
for(int j=0;j<arreglo[ i ].length;j++){
if(arreglo[ i ][ j ]=='z')arreglo[ i ][ j ]=car;
}
}
lx=c;
ly=f;
repaint();
}
public void mouseMoved(MouseEvent evt){}
public void mouseClicked(MouseEvent evt){
}
public static void main(String arg[]){
tabler t=new tabler();
t.show();
t.addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent evt){
System.exit(0);
}
});
}
}
En esta linea le falto la [ i ] también
else if(arreglo[ i ][ j ]>='a'&&arreglo[ i ][ j ]<='y')col=Color.BLUE;
Te agradezco todas tus respuesta, ya te debo la mayor puntuación que puedo dar por respuesta, pero aun no termino.
Hasta ahora la mayoría de lo que me has enviado me ha servido, pero a raíz de eso ahora tengo otras inquietudes, es sobre pintar, dirás que bruto si todo esta ahí, pero no es así nada más, primera vez que programo en java y esto es super completo para aprenderlo así de rapido
En fin, lo que quiero hacer es agregar a un jpanel el tablero que se dibuja, la ventana la tengo creada en netbeans, ademas agregue un jpanel que es donde quiero mostrar mi tablero, pero es lo que no se, ya que desconozco del funcionamiento y de la implementación, se que cada objeto debe estar dentro de cada contenedor para poderse mostrar pero todo esto es un rollo.
Espero respondas proto, gracias de antemano.
Si lo que quieres es dibujar en un JPanel lo que tendrías que hacer seria hacer una subclase de JPanel en la que sobreescribas su método paint para poder dibujar sobre el.
Aquí te pongo un ejemplo sencillo de como dibujar en un JPanel creando una subclase de este, como tu ya tienes diseñada tu ventana lo único que tendrías que hacer seria agregar el panel a la ventana como lo hice en este ejemplo.
import javax.swing.*;
import java.awt.*;
public class JPinta extends JPanel{
public void paint(Graphics g){
//Establecer color
g.setColor(Color.GREEN);
//Dibujar un cuadrado
g.fillRect(20,20,40,40);
}
public static void main(String arg[]){
JFrame ventana=new JFrame();
ventana.setSize(400,400);
//Creamos nuestro panel
JPinta panel=new JPinta();
//Agregar el panel a la ventana
ventana.add(panel);
ventana.setVisible(true);
}
}
He visto muchas modificaciones del método paint, pero tengo la duda de como envío los datos que quiero que se mustren en pantalla, ya que el cnstructor solo recibe un gráfico, ejemplo: g.fillRect(posX, posY, ancho, alto); ya que losvalores cambiaran a cada momento, gracias por responder...
Puedes enviarle en el constructor la matriz del tablero y guardarla en una variable global y con esos datos ya podrías pintar el tablero en el Panel, tendrías que agregarle esto:
char arreglo[][];
public void JPinta(char matriz[][]){
   arreglo=matriz;
}

Añade tu respuesta

Haz clic para o

Más respuestas relacionadas