Esta e a segunda versão do quadrado na tela, agora com o efeito de manter a tecla pressionada e o movimento acontecer ! para isto acabei definindo uma classe Game que fica com loop principal e todos os Nodes da Scene atual são verificados para execução de um método update(), não sei ainda se dava para fazer com alguma estrutura do próprio JavaFx, mas assim funcionou.
Olha como ficou o movimento
esta é a classe Game, que cria um Timer que executa continuamente, e chama o método update() para todos os Nodes que sao filhos da classe Updatable, no método update() o nosso quadrado muda a sua posicao de acordo com as teclas que estão pressionadas
package javafxmeuquadradinho2;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
* @author athanazio
*/
public class Game extends Stage {
public var tick: Timeline = Timeline {
repeatCount: Timeline.INDEFINITE
keyFrames: [
KeyFrame {
time: 0.05s
action: function() {
mainLoop();
}
}]
};
// main game loop
public function mainLoop(){
for (node in scene.content) {
if( node instanceof Updatable){
(node as Updatable).update();
}
}
}
public function play(){
tick.play();
}
}
A classe KeyState é usada para manter as informações de que teclas estão pressionadas ou não, Esta solução não permite uma fácil expansão para suportar outras teclas, outra forma seria armazenar uma lista das teclas atualmente pressionadas, e possuir um método para verificar se a tecla X esta pressionada.
package javafxmeuquadradinho2;
/**
* @author athanazio
*/
public class KeyState {
public var keyUp = false;
public var keyLeft = false;
public var keyRight = false;
public var keyDown = false;
}
A classe Updatable define o metodo update() a ser executado no loop principal do jogo.
package javafxmeuquadradinho2;
/**
* @author athanazio
*/
public class Updatable{
public function update(){
}
}
A classe MovableChar cria neste exemplo um Retangulo associado com as propriedades da classe, e gera os event handlers baseados neste retangulo, melhor seria usar um ImageView para exibir uma imagem, mas isto jah é outra estória … além disto mantém controle da tecla pressionada, através de uma instância de KeyState, e quando a tecla é liberada desmarca, fazendo com q no próximo update() o movimento naquela direção não ocorra.
/*
* MovableChar.fx
*
* Created on Feb 15, 2009, 3:47:31 PM
*/
package javafxmeuquadradinho2;
import javafx.scene.CustomNode;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
import javafx.scene.Node;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
/**
* @author athanazio
*/
public class MovableChar extends CustomNode, Updatable{
public var speed = 10;
public var x = 0;
public var y = 0;
public var width = 60;
public var height = 60;
public var fill: Color;
var keyState: KeyState = KeyState{
keyUp: false;
keyLeft: false;
keyRight: false;
keyDown: false;
};
public override function create():Node {
return Rectangle {
x: bind this.x;
y: bind this.y;
width: bind this.width;
height: bind this.height;
fill: bind this.fill;
onKeyPressed: function (e: KeyEvent){
if( e.code == KeyCode.VK_LEFT ){
keyState.keyLeft = true;
}
if( e.code == KeyCode.VK_RIGHT ){
keyState.keyRight = true;
}
if( e.code == KeyCode.VK_UP ){
keyState.keyUp = true;
}
if( e.code == KeyCode.VK_DOWN ){
keyState.keyDown = true;
}
}
onKeyReleased: function(e: KeyEvent){
if( e.code == KeyCode.VK_LEFT ){
keyState.keyLeft = false;
}
if( e.code == KeyCode.VK_RIGHT ){
keyState.keyRight = false;
}
if( e.code == KeyCode.VK_UP ){
keyState.keyUp = false;
}
if( e.code == KeyCode.VK_DOWN ){
keyState.keyDown = false;
}
}
};
}
public override function update(){
if( keyState.keyLeft){
x = x - speed;
}
if( keyState.keyRight){
x = x + speed;
}
if( keyState.keyDown){
y = y + speed;
}
if( keyState.keyUp){
y = y - speed;
}
}
}
E finalmente a classe Main que instancia MovableChar e Game e chama o método start de Game.
package javafxmeuquadradinho2;
import java.lang.Object;
import javafx.scene.paint.Color;
import javafx.scene.Scene;
/**
* @author athanazio
*/
var littleBox: MovableChar = MovableChar{
x: 20,
y: 20
width: 60,
height: 60
fill: Color.RED
}
var game: Game = Game {
title: "Movendo um quadrado pela tela"
width: 640
height: 480
scene: Scene {
content: [
littleBox
]
}
}
function run(__ARGS__ : String[]) {
game.play();
}
