JavaFX Bubble Breaker
Originally posted by me on ericonjavafx.com
package bubblebreaker; import javafx.stage.Stage; import javafx.scene.text.Text; import javafx.scene.text.Font; import java.util.Random; import javafx.animation.KeyFrame; import javafx.animation.Timeline; import javafx.scene.CustomNode; import javafx.scene.effect.Glow; import javafx.scene.Group; import javafx.scene.paint.Color; import javafx.scene.paint.RadialGradient; import javafx.scene.paint.Stop; import javafx.scene.Scene; import javafx.scene.shape.Circle; import javafx.scene.text.TextAlignment; import javafx.scene.effect.InnerShadow; import javafx.scene.effect.DropShadow; import javafx.ext.swing.SwingButton; var shift = 10; // from from scene.x and scene.y var score_count: Number = 0; var group: Group = new Group; var slots = []; var checkedGroup = Group { }; var totalScore = 0; function initGroup() { group = new Group; slots = []; totalScore = 0; for (i in [1..10]) { for (j in [1..10]) { insert "true" into slots; insert Ball2 { radius: 25; vx: i * 50 + shift; vy: j * 50 + (shift * 5); slot: sizeof slots; id: "{sizeof slots}"; } into group.content; } } insert "true" into slots;//this is required for the 100 slot } initGroup(); function fallStep() { var aball ; //1. iterate through the entire set of balls for (node in group.content) { aball = (node as Ball2); //2. if a ball is marked for deletion then remove from the group and mark the slot as empty(false) if (aball.flaggedfordeletion) { slots[aball.slot] = "false"; totalScore = totalScore + Integer.parseInt(aball.score); delete aball from group.content; } //3. if the slot below a ball is empty and not ending with a 1 if (slots[aball.slot + 1] == "false") { var aa = aball.slot + 1; if (aa == 11 or aa == 21 or aa == 31 or aa == 41 or aa == 51 or aa == 61 or aa == 71 or aa == 81 or aa == 91) { //do nothing } else { //4. mark the slot at taken(true) and move the ball into it....also mark the previous slot as empty(false); slots[aball.slot + 1] = "true"; slots[aball.slot] = "false"; aball.slot = aball.slot + 1; aball.vy = aball.vy + 50; aball.id = "{aball.slot}"; } } } } function shiftRightStep() { for (i in [100..20 step -10]) { if (slots[i] == "false") { for (j in [(i - 10)..1 step -1]) { var aa = group.lookup("{j}") as Ball2; if (aa != null) { slots[j + 10] = "true"; aa.slot = aa.slot + 10; aa.vx = aa.vx + 50; aa.id = "{aa.slot}"; slots[j] = "false"; } } } } } function findNeighbors(aball: Ball2): Void { var val ; //1.calculate all neighbors var r_nball = group.lookup("{aball.slot + 10}") as Ball2; var d_nball = group.lookup("{aball.slot + 1}") as Ball2; var l_nball = group.lookup("{aball.slot - 10}") as Ball2; var u_nball = group.lookup("{aball.slot - 1}") as Ball2; //2. make a recursive call to check left,right,up and down if (aball.slot <= 90 and not r_nball.checked) { r_nball.checked = true; val = check(aball, r_nball); if (val) { aball.checked = true; findNeighbors(r_nball); } } if (aball.slot mod 10 != 0 and not d_nball.checked) { d_nball.checked = true; val = check(aball, d_nball); if (val) { findNeighbors(d_nball); } } if (aball.slot > 10 and not l_nball.checked) { l_nball.checked = true; val = check(aball, l_nball); if (val) { findNeighbors(l_nball); } } if (aball.slot mod 10 != 1 and not u_nball.checked) { u_nball.checked = true; val = check(aball, u_nball); if (val) { findNeighbors(u_nball); } } } function check(aball: Ball2, u_nball: Ball2): Boolean { var return_value: Boolean = false; if (checkColor(aball, u_nball)) { aball.effect = Glow { level: .4 input: InnerShadow { choke: 0.05 radius: 25 color: Color.BLACK } } u_nball.effect = Glow { level: .4 input: InnerShadow { choke: 0.05 radius: 25 color: Color.BLACK } } u_nball.initialSelect = true; return_value = true; } return return_value; } function checkColor(aball: Ball2, nball: Ball2): Boolean { var returnvalue: Boolean = false; if (aball.colorval == nball.colorval) { returnvalue = true; } return returnvalue; } function displayScore() { for (node in group.content) { var tball = (node as Ball2); if (tball.effect != null) { tball.score = "{score_count.intValue()}"; } } } Timeline { repeatCount: Timeline.INDEFINITE keyFrames: KeyFrame { time: 30ms action: function () { var aball ; for (node in group.content) { aball = (node as Ball2); if (aball.flaggedfordeletion == true) { for (i in [0..9]) { fallStep(); } for (i in [0..9]) { shiftRightStep(); } } } } } }.play(); class Ball2 extends CustomNode { var radius: Number; var vx: Number; var vy: Number; var slot: Integer; var initialSelect: Boolean; var flaggedfordeletion: Boolean; var checked: Boolean; var colorval ; var score: String; def acolor = [Color.ORANGE, Color.BLACK, Color.DODGERBLUE, Color.PURPLE]; var random: Random = Random { }; override function create() { colorval = random.nextInt(4); Group {content: [ Circle { translateX: bind vx translateY: bind vy radius: radius - 1 effect: DropShadow { offsetX: 10 offsetY: 10 color: Color.BLACK radius: 24 } fill: RadialGradient { radius: radius * .9; focusX: radius * 0.2 focusY: radius * -8 proportional: false stops: [ Stop { offset: 0 color: Color.WHITE } Stop { offset: 1 color: acolor[colorval]; } ] } onMousePressed: function (event) { score_count = 0; //1. for every event check to see if the a group has already been identified and this is the second click to initiate deletion if (initialSelect) { var flagged = [];//this is to check to see if only one ball is select FIX ME for (node in group.content) { var aball = (node as Ball2); if (aball.initialSelect == true) { insert aball into flagged; } } if (sizeof flagged > 1) {//this is to check to see if only one ball is select FIX ME for (flag in flagged) { var f = (flag as Ball2); f.flaggedfordeletion = true; } } } else { //2. if we have a group identified but the user doesn't want to delete that group ( by selecting another groups ball) then // remove the intialSelects and effects from the first group for (node in group.content) { var aball = (node as Ball2); if (aball.initialSelect == true) { aball.initialSelect = false; aball.effect = null; aball.score = ""; } } } if (initialSelect == false) { initialSelect = true; findNeighbors(this); for (node in group.content) { var tball = (node as Ball2); if (tball.effect != null) { score_count = score_count + 1; } if (tball.checked == true) { tball.checked = false; } } if (score_count > 9) { score_count = score_count * 9 } if (score_count == 8) { score_count = score_count * 7 } if (score_count == 7) { score_count = score_count * 6 } if (score_count == 6) { score_count = score_count * 5 } if (score_count == 5) { score_count = score_count * 5 } if (score_count == 4) { score_count = score_count * 3 } if (score_count == 3) { score_count = score_count * 2 } displayScore(); } } } Text { font: Font {size: 12 } x: bind vx - 5, y: bind vy textAlignment: TextAlignment.LEFT content: bind "{score}"; } ] } } } var button = Group { translateY: 610 translateX: 245 content: [ SwingButton { text: "New Game" action: function () { initGroup() } } ] } var x = Stage { title: "Bubble Breaker" width: 600 height: 700 scene: Scene { fill: Color.GREY; content: bind [ button, Text { x: 220 y: 50 fill: Color.ORANGE effect: Glow { level: .8 input: InnerShadow { choke: 0.05 radius: 2 color: Color.BLACK } } font: Font {size: 30 } content: "Score {totalScore}" } group ] } }
No comments yet.
Comments are closed.