Verán, estava creando un juego java, en el cual un personaje (imagen) se mueve sobre un tablero creado con la clase Graphics. Hasta ahi todo bien, el problema es que gera un movimiento fluido al dejar mantenida la tecla de avanzar, y mi intencion era que avanzase un cuadradito cada vez que se pulsase el botón sin importar si se deja pulsado o no.
Despues, proximamente, tenía intencion de hacer que el personaje se moviese seleccionandolo (boolean) y mas tarde haciendeo clik derecho con el ratón para que apareciese un cuadro emergente con distintas opciones (mover, atacar, defender, etz). Les escrivo a continuacion el codigo del movimiento para que vean como lo he echo:
public void act() { super.act(); x+=vx; y+=vy; if (x < 0 ) x = 0; if (x > Stage.PLAY_WIDTH - getWidth()) x = Stage.PLAY_WIDTH - getWidth(); if (y < 0 ) y = 0; if ( y > Stage.PLAY_HEIGHT-getHeight()) y = Stage.PLAY_HEIGHT - getHeight(); } public int getVx() { return vx; } public void setVx(int i) {vx = i; } public int getVy() { return vy; } public void setVy(int i) {vy = i; } protected void updateSpeed() { vx=0;vy=0; if (down && MOV_RESTANTES>0){ vy = PLAYER_SPEED; MOV_RESTANTES--; ABAJO=true; ARRIBA=false; IZQUIERDA=false; DERECHA=false; } if (up && MOV_RESTANTES>0){ vy = -PLAYER_SPEED; MOV_RESTANTES--; ARRIBA=true; ABAJO=false; IZQUIERDA=false; DERECHA=false; } if (left && MOV_RESTANTES>0){ vx = -PLAYER_SPEED; MOV_RESTANTES--; IZQUIERDA=true; ARRIBA=false; ABAJO=false; DERECHA=false; } if (right && MOV_RESTANTES>0 ){ vx = PLAYER_SPEED; MOV_RESTANTES--; DERECHA=true; IZQUIERDA=false; ARRIBA=false; ABAJO=false; } } public void keyReleased(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_DOWN : down = false;break; case KeyEvent.VK_UP : up = false; break; case KeyEvent.VK_LEFT : left = false; break; case KeyEvent.VK_RIGHT : right = false;break; } updateSpeed(); } public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_UP : up = true; break; case KeyEvent.VK_LEFT : left = true; break; case KeyEvent.VK_RIGHT : right = true; break; case KeyEvent.VK_DOWN : down = true;break; case KeyEvent.VK_SPACE : fire(); break; } updateSpeed(); }<hr />
Editado: Movido a Tecnicas de programacion y otros lenguajes, postear en el lugar incorrecto incumple las Normas de la Comunidad, antes de volver a postear por favor revíselas.| AORV
Hola de nuevo a
Hola de nuevo a todos;
Despues de solucionar el primer problema, con el movimiento del jugador, me he topado con otro, el movimiento que deven tener los enemigos.
Veran, la clase que controla a los enemigos (Monster.java), vendría siendo exactamente igual que la clase Player.java, con la diferencia de que esta primera no contiene los KeyEvent(); .
En la clase principal del juego (Juego.java), es donde esta el codigo que controla el numero y la posicion de los personajes que se crean durante la ejecucción. He aqui ese fragmento de codigo:
Las ultimas lineas las he añadido recientemente, para intentar que los monstruos se dirigan hacia el jugador (Mas tarde ya lo condicionare más, cada cosa en su momento)
Despues, exsiste un metodo llamado "updateWorld()", en el cual, en un principio, se actualizava el movimiento del jugador, el cual ahora he dejado así:
Prove añadiendo, bajo "player.act();" "monster.act();", pero marcava un error.
Finalmente, al ejecutar el codigo con estos cambios, los monstruos, se dirigen hacia la direccion en la que estas, ya sea vertical o horizontal, pero no cambia de dirección durante la ejecucion...
No estoy muy seguro de como devo hacerlo,...
Muchas gracias a todos ! :)
Aprovechando que tengo el
Aprovechando que tengo el tema abierto, como ago para añadir una JProgressBar en el juego?
Obviamente, usar:
[...] No me ha servido de nada.
He mirado el codigo que genera NetBeans cuando añades una Barra de progreso desde la paleta y no lo he entendido.
¿Me echas una mano?
Gracias :)
No he usado nunca
No he usado nunca JProgressBar, pero supongo que con la API no tendras ningun problema.
Saludos y ya me cuentas.
Bueno, por partes: Para
Bueno, por partes:
Para evitar que el cuadradito se mueva indefinidamente yo haria lo siguiente en el metodo KeyPressed:
if(!pulsado){
---codigo correspondiente---
}
pulsado=true;
Y lo siguiente en el KeyReleased:
---codigo correspondiente---
pulsado=false;
En cuanto a hacer click secundario sobre un personaje y hacer aparecer un cuadro emergente, pues supongo que la clase Personaje debera heredar de JComponent para poder implementar escuchadores de eventos. Y dependiendo del evento, crear una ventana emergente, y seleccionar opciones y tal.
Espero que te sirva.
Un saludo.
Perdona, pero el codigo no
Perdona, pero el codigo no funciona...
Lo unico que hace añadir un if() en el metodo keypresed es que no se puedan pulsar dos teclas a la vez, pero sigue siendo un movimiento continuo.
Alguna otra idea? Muchas gracias :)
public void
¿Seguro que no funciona? Si la variable pulsado esta a true, no entrara en el if por muchos eventos de teclado que generes manteniendo pulsada una tecla. Al levantarla, le das paso a que si entre. El booleano debe ser un atributo de la clase.
Un saludo.
Perdona pero,... ¿Has
Perdona pero,... ¿Has colocado el if() en el keyRealsed ?
No devería ir en keyPresed ?
He provado el codigo que me has mandado, y poniendo el if() en keyPresed y nada, el movimiento sigue siendo continuo, no lo entiendo...
No se que mas hacer. Aunque mas tarde, cuando aga la parte de popUpMenu tendré que cambiar el codigo.
Muchas gracias por toda tu colaboracion :)
¡Cuidate!
Uff tio, perdoname es
Uff tio, perdoname es correcto lo que dices, se me ha traspapelado el keyPressed con el Released. Te pongo un ejemplo en un main, incluso con keyTyped (con keyPressed es identico):
Nada de nada... Ahora el
Nada de nada... Ahora el movimiento del personaje es algo distitno. No te permite moverte en diagonal, como lo hacia en un principio, pero sigue siendo un movimiento continuo. He provado tambien ha cambiar el Presed por Typed como añades en el ejemplo, pero nada, es más, ni se mueve.
Muchas gracias por toda tu colaboracion ! :)
Creo que se cual puede ser el problema.
La variable pulsado es innecesaria. Pulsado, equivaldría a (up || down || right || left). En tu código estás diciendo que si hay una tecla pulsada, no compruebes si hay otra, por lo que si pulsas arriba e inmediatamente después la derecha, esta última la va a obviar, moviéndose hacia arriba.
La forma más rápida de solucionarlo tal y como lo estais haciendo vosotros sería:
Aunque la forma correcta sería que los keyPressed y keyReleased no alterasen el estado del juego diréctamente, sino que solo cambiasen las variables up, left, right down y DISPARAR y el act, al principio, se llamase a update speed. De hecho, yo creo que quitando en tu código original el updateSpeed que hay en los keyPressed/relased y poniéndolo al principio de act, funcionaría perfectamente :D.
Como moraleja, siempre es bueno separar las cosas (las entradas/salidas de la modificación de las variables internas y de la representación), de forma que primero mires todas las entradas (ya sean de teclado o de ratón), después modifiques el estado interno del modelo y finalmente lo representes, siempre en ese orden.
Saludos y espero que te sirva :)
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
uu' Me ha costado bastante
uu' Me ha costado bastante entender la explicacion (Tengo poca practica en java, tengo que aclarar conceptos aun).
He provado el codigo, y ahora estamos como al principio, movimiento libre por todo el mapa :S
Me esta dando muchos dolores de cabeza este codigo...
Muchas gracias a todos, de verdad, que soys muy grandes :)
Saludos (Y)
Que raro
Estaba convencido de que ese código funcionaría. Tendría que probarlo para encontrar el error.
¿Has probado a poner el update en el método act en lugar de en la actualización de botones? Así, se actualizarían todas las variables up/down/etc todas juntas y en cada iteración actualizarías la velocidad según las teclas que estén pulsadas en ese momento, no según el número de pulsaciones. Me explico:
- Si colocas el update en keyPressed o keyReleased, llamas a la función tantas veces como pulses o levantes el botón.
- Si lo colocas en act, solo se llamará una vez, por lo que te quitarás todos los dolores de cabeza.
Prueba a ver que tal y nos cuentas
Saludos!
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Finalmente, arto de provar,
Finalmente, arto de provar, incluso lo que me dijiste, puse el siguiente codigo:
Pero no parece seguir ninguna norma al moverse, hace lo que quiere.
A veces se mueve, a veces no. Cuando disparas, puedes moverte en una direccion, pero no cambiarla.
Si no pulsas espacio para disparar, no puedes moverte.
Gracias !
Vale.
Perdón, pero es que había malentendido tu problema. He vuelto a leer lo del principio y ya se que es lo que quieres hacer. Si no he entendido mal quieres que al pulsar un botón se mueva tu jugador, pero solo cuando se pulsa el botón, si lo dejas pulsado no quieres que se mueva, no?
Si es eso, la solución es bastante simple. Simplemente haces que al terminar la función act se "levanten" las teclas haciendo que up=down=left=right=false;. Imaginemos que el usuario pulsa el botón derecho. Entonces:
- Se genera un keyPressed y right=true;
- Cuando se ejecute act, se actualizará la velocidad, y se cambiará la posición (hacia la derecha, ya que right==true).
- Al final de act, se ponen todas a false.
- La siguiente vez que se ejecute act, right==false, por lo que no se hará nada.
- Cuando se levante el botón y se vuelva a pulsar, volverá a ser true.
Un par de aclaraciones:
- El metodo keyReleased no te sirve para nada realmente.
- El updateSpeed te lo he puesto en act, porque es mejor que esté ahí, creeme.
- Los disparos no te conviene que los realices en keyPressed. Yo pondría variables como con la dirección y generaría los disparos en act.
- Te he quitado el ACTIVADO de los ifs, porque ya no hace falta.
- Si en updateSpeed, en if (up) por ejemplo pones DERECHA o IZQUIERDA=false, no podrás hacer diagonales. if(up) e if(down) solo deberían modificar ARRIBA y ABAJO, y right y left DERECHA e IZQUIERDA.
Bueno, aquí está el código:
No se si funcionará (espero que sí), pero lo que me interesa es que cojas la idea, para que si en cuentras algún fallo, lo puedas arreglar.
Saludos!
Dennis Ritchie. Padre de C y cocreador de UNIX.
R.I.P.
Buaa ! Muchas gracias, de
Buaa ! Muchas gracias, de verdad.
Al fin funciona... Lo unico que ahora siempre dispara en diagonal, no se porque, ya investigare.
Muchas gracias por tu colaboracion :)
Saludos !
Pues que raro, habra que
Pues que raro, habra que buscarse alguna otra manera de hacerlo, ahora mismo no se me ocurre nada :S
Muchas gracias, lo provare en
Muchas gracias, lo provare en cuanto pueda.