import javafx.ui.canvas.*; import javafx.ui.*; import java.lang.System; import javax.swing.Timer; import java.awt.event.ActionListener; import java.awt.Toolkit; import java.util.Random; import java.lang.Thread; import java.lang.Exception; var random = new Random(); var emptyBlocks:Arc* = []; var blockWidth:Integer = 50; var heightDelta:Integer = 90; var maxHeight:Integer = 560; var maxWidth:Integer = 510; var userBlock = Arc { x: 210, y: 560, width: bind blockWidth, height: 40, startAngle: 180, length: 180, closure: OPEN, fill: navy, stroke: white, strokeWidth: 1}; var bb = 0; var labelMesg = "Click mouse to start"; var hits = 0; var miss = 0; var initX = 10; var timerDelay = 400; var stoppedByProgram = false; var myTimer = new Timer(400, new ActionListener() { operation actionPerformed(event) { ((Timer)event.getSource()).setDelay(timerDelay); var i = 0; bb ++; userBlock.fill = navy; while (i < sizeof emptyBlocks) { emptyBlocks[i].y += heightDelta; if (emptyBlocks[i].y > maxHeight) { delete emptyBlocks[i]; } i ++; } if (bb%2 == 0) { var xDecider = random.nextInt((Integer)maxWidth/blockWidth); var x = initX; x += (xDecider * blockWidth); var newEmptyBlock = new Arc {x: bind x, y: 20, width: bind blockWidth, height: 40, startAngle:0, length:360, closure: OPEN, fill: black, stroke: white, strokeWidth: 3 }; insert newEmptyBlock into emptyBlocks; } if (emptyBlocks[0].x == userBlock.x and emptyBlocks[0].y == userBlock.y) { userBlock.fill = lime; emptyBlocks[0].stroke = darkgreen; emptyBlocks[0].fill = darkgreen; hits ++; } else if (emptyBlocks[0].y == userBlock.y) { emptyBlocks[0].fill = red; miss ++; } else { userBlock.fill = navy; } labelMesg = "Hits: {hits} Miss: {miss}"; if (miss > 5) { labelMesg = "Hits: {hits} Miss: {miss}: GAME OVER. Try Again!!"; ((Timer)event.getSource()).stop(); } } }); Frame { var: selfFrame width: 525 height: 680 resizable: false disposeOnClose: true title: "FX Blocks" var ctrlDlg = Dialog { var: self owner: selfFrame title: "Configure Game Parameters", width: 300, height: 150, modal: true, onClose: operation() { self.visible = false; if (stoppedByProgram) { hits = 0; miss = 0; bb = 0; emptyBlocks = []; labelMesg = "Hits: {hits} Miss: {miss}"; myTimer.start(); stoppedByProgram = false; } }, content: BorderPanel { center: GridPanel { rows: 2 columns: 2 cells: [Label { text: "Delay" }, Slider { min: 0 max: 1000 value: bind timerDelay paintTrack: true paintTicks: true majorTickSpacing: 100 minorTickSpacing: 50 }, Label { text: "Ball Width" }, Slider { min: 20 max: 200 value: bind blockWidth paintTrack: true paintTicks: true majorTickSpacing: 20 minorTickSpacing: 10 }] } bottom: FlowPanel { content: [Button { text: "OK" mnemonic: ENTER action: operation() { self.visible = false; if (stoppedByProgram) { hits = 0; miss = 0; bb = 0; emptyBlocks = []; labelMesg = "Hits: {hits} Miss: {miss}"; myTimer.start(); stoppedByProgram = false; } } }, Button { text: "Cancel" mnemonic: ESCAPE action: operation() { self.visible = false; if (stoppedByProgram) { hits = 0; miss = 0; bb = 0; emptyBlocks = []; labelMesg = "Hits: {hits} Miss: {miss}"; myTimer.start(); stoppedByProgram = false; } } }] } } } content: BorderPanel { center: Canvas { var court = Rect { x: 5 y: 5 width: 510 height: 600 fill: darkgreen stroke: white strokeWidth: 3 } background: black content: Group { content: bind [court, emptyBlocks, userBlock] } onMouseMoved: operation (e:MouseEvent) { if ((e.x + blockWidth) > maxWidth) { //Perhaps mouse is out of Canvas. Nothing can be done. // Should I stop the timer when the mouse goes out of canvas? } else if (e.x <= 0) { userBlock.x = initX; } else { var quotient:Integer = (Integer) e.x/blockWidth; userBlock.x = initX + (quotient.intValue() * blockWidth); } } keyboardAction: KeyboardAction { keyStroke: F1 enabled: true action: operation() { if (myTimer.isRunning()) { stoppedByProgram = true; myTimer.stop(); } ctrlDlg.visible = true; } } onKeyDown: operation (e:KeyEvent) { if (e.keyStroke == LEFT:KeyStroke) { if (userBlock.x >= (initX + blockWidth)) { userBlock.x -= blockWidth; } } else if (e.keyStroke == RIGHT:KeyStroke) { if (userBlock.x < (maxWidth - blockWidth)) { userBlock.x += blockWidth; } } } onMouseClicked: operation(e:MouseEvent) { if (not myTimer.isRunning()) { hits = 0; miss = 0; bb = 0; emptyBlocks = []; labelMesg = "Hits: {hits} Miss: {miss}"; myTimer.start(); } else { System.out.println("MyTimer running"); } } }, bottom: GridPanel { rows: 2 columns: 1 cells: [Label { text: bind labelMesg font: Font {face: ARIAL, style: [ITALIC, BOLD], size: 20} background: orange }, Label { text: "Press F1 to customize" font: Font {face: ARIAL, style: [ITALIC, BOLD], size: 20} background: orange }] } } visible: true }