├── .gitignore ├── bin └── TetrisJFX.jar ├── src ├── main │ ├── resources │ │ ├── digital.ttf │ │ ├── background_image.png │ │ ├── window_style.css │ │ └── gameLayout.fxml │ └── java │ │ └── com │ │ └── quirko │ │ ├── logic │ │ ├── events │ │ │ ├── EventSource.java │ │ │ ├── EventType.java │ │ │ ├── InputEventListener.java │ │ │ └── MoveEvent.java │ │ ├── bricks │ │ │ ├── Brick.java │ │ │ ├── BrickGenerator.java │ │ │ ├── OBrick.java │ │ │ ├── SBrick.java │ │ │ ├── ZBrick.java │ │ │ ├── IBrick.java │ │ │ ├── JBrick.java │ │ │ ├── LBrick.java │ │ │ ├── TBrick.java │ │ │ └── RandomBrickGenerator.java │ │ ├── DownData.java │ │ ├── Board.java │ │ ├── Score.java │ │ ├── rotator │ │ │ ├── NextShapeInfo.java │ │ │ └── BrickRotator.java │ │ ├── ClearRow.java │ │ ├── ViewData.java │ │ ├── MatrixOperations.java │ │ └── SimpleBoard.java │ │ ├── gui │ │ ├── GameOverPanel.java │ │ ├── Main.java │ │ ├── NotificationPanel.java │ │ └── GuiController.java │ │ └── app │ │ └── GameController.java └── test │ └── java │ └── com │ └── quirko │ └── logic │ ├── rotator │ └── NextShapeInfoTest.java │ ├── bricks │ └── IBrickTest.java │ └── MatrixOperationsTest.java ├── sonar-project.properties ├── README.md └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | .idea 2 | .sonar 3 | target 4 | jar_builder.bat -------------------------------------------------------------------------------- /bin/TetrisJFX.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javafx-dev/JavaFX-Tetris-Clone/HEAD/bin/TetrisJFX.jar -------------------------------------------------------------------------------- /src/main/resources/digital.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javafx-dev/JavaFX-Tetris-Clone/HEAD/src/main/resources/digital.ttf -------------------------------------------------------------------------------- /src/main/resources/background_image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/javafx-dev/JavaFX-Tetris-Clone/HEAD/src/main/resources/background_image.png -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/events/EventSource.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.events; 2 | 3 | public enum EventSource { 4 | USER, THREAD 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/events/EventType.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.events; 2 | 3 | public enum EventType { 4 | DOWN, LEFT, RIGHT, ROTATE 5 | } 6 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/Brick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import java.util.List; 4 | 5 | public interface Brick { 6 | 7 | List getShapeMatrix(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/BrickGenerator.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | public interface BrickGenerator { 4 | 5 | Brick getBrick(); 6 | 7 | Brick getNextBrick(); 8 | } 9 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/gui/GameOverPanel.java: -------------------------------------------------------------------------------- 1 | package com.quirko.gui; 2 | 3 | import javafx.scene.control.Label; 4 | import javafx.scene.layout.BorderPane; 5 | 6 | 7 | public class GameOverPanel extends BorderPane { 8 | 9 | public GameOverPanel() { 10 | final Label gameOverLabel = new Label("GAME OVER"); 11 | gameOverLabel.getStyleClass().add("gameOverStyle"); 12 | setCenter(gameOverLabel); 13 | } 14 | 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/events/InputEventListener.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.events; 2 | 3 | import com.quirko.logic.ViewData; 4 | import com.quirko.logic.DownData; 5 | 6 | public interface InputEventListener { 7 | 8 | DownData onDownEvent(MoveEvent event); 9 | 10 | ViewData onLeftEvent(MoveEvent event); 11 | 12 | ViewData onRightEvent(MoveEvent event); 13 | 14 | ViewData onRotateEvent(MoveEvent event); 15 | 16 | void createNewGame(); 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/DownData.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic; 2 | 3 | public final class DownData { 4 | private final ClearRow clearRow; 5 | private final ViewData viewData; 6 | 7 | public DownData(ClearRow clearRow, ViewData viewData) { 8 | this.clearRow = clearRow; 9 | this.viewData = viewData; 10 | } 11 | 12 | public ClearRow getClearRow() { 13 | return clearRow; 14 | } 15 | 16 | public ViewData getViewData() { 17 | return viewData; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/Board.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic; 2 | 3 | public interface Board { 4 | 5 | boolean moveBrickDown(); 6 | 7 | boolean moveBrickLeft(); 8 | 9 | boolean moveBrickRight(); 10 | 11 | boolean rotateLeftBrick(); 12 | 13 | boolean createNewBrick(); 14 | 15 | int[][] getBoardMatrix(); 16 | 17 | ViewData getViewData(); 18 | 19 | void mergeBrickToBackground(); 20 | 21 | ClearRow clearRows(); 22 | 23 | Score getScore(); 24 | 25 | void newGame(); 26 | } 27 | -------------------------------------------------------------------------------- /sonar-project.properties: -------------------------------------------------------------------------------- 1 | # Required metadata 2 | sonar.projectKey=tetris 3 | sonar.projectName=Tetris FX 4 | sonar.projectVersion=1.0 5 | 6 | # Comma-separated paths to directories with sources (required) 7 | sonar.sources=src/main/java 8 | 9 | #sonar.binaries=target\classes 10 | 11 | # Language 12 | sonar.language=java 13 | 14 | # Encoding of the source files 15 | sonar.sourceEncoding=UTF-8 16 | 17 | sonar.junit.reportsPath=target/surefire-reports 18 | sonar.jacoco.reportPath=target/jacoco.exec 19 | sonar.dynamicAnalysis=reuseReports 20 | sonar.java.coveragePlugin=jacoco -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | JavaFX Tetris Clone Game 2 | ============= 3 | 4 | JavaFX Tetris Clone Game 5 | 6 | ## Screenshots 7 |

8 | TetrisJFX Screen Shoot 9 | TetrisJFX Screen Shoot 1 10 |

11 | 12 | ## Gameplay 13 | See Youtube: https://www.youtube.com/watch?v=uzyOOlCvQN0 14 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/Score.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic; 2 | 3 | import javafx.beans.property.IntegerProperty; 4 | import javafx.beans.property.SimpleIntegerProperty; 5 | 6 | public final class Score { 7 | 8 | private final IntegerProperty score = new SimpleIntegerProperty(0); 9 | 10 | public IntegerProperty scoreProperty() { 11 | return score; 12 | } 13 | 14 | public void add(int i){ 15 | score.setValue(score.getValue() + i); 16 | } 17 | 18 | public void reset() { 19 | score.setValue(0); 20 | } 21 | } 22 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/events/MoveEvent.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.events; 2 | 3 | public final class MoveEvent { 4 | private final EventType eventType; 5 | private final EventSource eventSource; 6 | 7 | public MoveEvent(EventType eventType, EventSource eventSource) { 8 | this.eventType = eventType; 9 | this.eventSource = eventSource; 10 | } 11 | 12 | public EventType getEventType() { 13 | return eventType; 14 | } 15 | 16 | public EventSource getEventSource() { 17 | return eventSource; 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/rotator/NextShapeInfo.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.rotator; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | public final class NextShapeInfo { 6 | 7 | private final int[][] shape; 8 | private final int position; 9 | 10 | public NextShapeInfo(final int[][] shape, final int position) { 11 | this.shape = shape; 12 | this.position = position; 13 | } 14 | 15 | public int[][] getShape() { 16 | return MatrixOperations.copy(shape); 17 | } 18 | 19 | public int getPosition() { 20 | return position; 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /src/test/java/com/quirko/logic/rotator/NextShapeInfoTest.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.rotator; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class NextShapeInfoTest { 7 | 8 | @Test 9 | public void testGetShape() throws Exception { 10 | int[][] shape = new int[][]{{1, 2, 3}, {1, 2, 3}}; 11 | int position = 3; 12 | NextShapeInfo nextShapeInfo = new NextShapeInfo(shape, position); 13 | nextShapeInfo.getShape()[0][0] = 23; 14 | Assert.assertEquals(1, nextShapeInfo.getShape()[0][0]); 15 | } 16 | 17 | @Test 18 | public void testGetPosition() throws Exception { 19 | 20 | } 21 | } -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/OBrick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | final class OBrick implements Brick { 9 | 10 | private final List brickMatrix = new ArrayList<>(); 11 | 12 | public OBrick() { 13 | brickMatrix.add(new int[][]{ 14 | {0, 0, 0, 0}, 15 | {0, 4, 4, 0}, 16 | {0, 4, 4, 0}, 17 | {0, 0, 0, 0} 18 | }); 19 | } 20 | 21 | @Override 22 | public List getShapeMatrix() { 23 | return MatrixOperations.deepCopyList(brickMatrix); 24 | } 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/ClearRow.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic; 2 | 3 | public final class ClearRow { 4 | 5 | private final int linesRemoved; 6 | private final int[][] newMatrix; 7 | private final int scoreBonus; 8 | 9 | public ClearRow(int linesRemoved, int[][] newMatrix, int scoreBonus) { 10 | this.linesRemoved = linesRemoved; 11 | this.newMatrix = newMatrix; 12 | this.scoreBonus = scoreBonus; 13 | } 14 | 15 | public int getLinesRemoved() { 16 | return linesRemoved; 17 | } 18 | 19 | public int[][] getNewMatrix() { 20 | return MatrixOperations.copy(newMatrix); 21 | } 22 | 23 | public int getScoreBonus() { 24 | return scoreBonus; 25 | } 26 | } 27 | -------------------------------------------------------------------------------- /src/test/java/com/quirko/logic/bricks/IBrickTest.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import org.junit.Assert; 4 | import org.junit.Test; 5 | 6 | public class IBrickTest { 7 | 8 | @Test 9 | public void testGetShapeMatrix() throws Exception { 10 | Brick brick = new IBrick(); 11 | brick.getShapeMatrix().get(0)[0][0] = 2; 12 | brick.getShapeMatrix().get(0)[1][0] = 3; 13 | Assert.assertEquals(0, brick.getShapeMatrix().get(0)[0][0]); 14 | Assert.assertEquals(1, brick.getShapeMatrix().get(0)[1][0]); 15 | } 16 | 17 | @Test 18 | public void testGetShapeMatrixList() throws Exception { 19 | Brick brick = new IBrick(); 20 | brick.getShapeMatrix().remove(0); 21 | Assert.assertEquals(2, brick.getShapeMatrix().size()); 22 | } 23 | } -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/rotator/BrickRotator.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.rotator; 2 | 3 | import com.quirko.logic.bricks.Brick; 4 | 5 | public class BrickRotator { 6 | 7 | private Brick brick; 8 | private int currentShape = 0; 9 | 10 | public NextShapeInfo getNextShape() { 11 | int nextShape = currentShape; 12 | nextShape = (++nextShape) % brick.getShapeMatrix().size(); 13 | return new NextShapeInfo(brick.getShapeMatrix().get(nextShape), nextShape); 14 | } 15 | 16 | public int[][] getCurrentShape() { 17 | return brick.getShapeMatrix().get(currentShape); 18 | } 19 | 20 | public void setCurrentShape(int currentShape) { 21 | this.currentShape = currentShape; 22 | } 23 | 24 | public void setBrick(Brick brick) { 25 | this.brick = brick; 26 | currentShape = 0; 27 | } 28 | 29 | 30 | } 31 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/SBrick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | final class SBrick implements Brick { 9 | 10 | private final List brickMatrix = new ArrayList<>(); 11 | 12 | public SBrick() { 13 | brickMatrix.add(new int[][]{ 14 | {0, 0, 0, 0}, 15 | {0, 5, 5, 0}, 16 | {5, 5, 0, 0}, 17 | {0, 0, 0, 0} 18 | }); 19 | brickMatrix.add(new int[][]{ 20 | {5, 0, 0, 0}, 21 | {5, 5, 0, 0}, 22 | {0, 5, 0, 0}, 23 | {0, 0, 0, 0} 24 | }); 25 | } 26 | 27 | @Override 28 | public List getShapeMatrix() { 29 | return MatrixOperations.deepCopyList(brickMatrix); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/ZBrick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | final class ZBrick implements Brick { 9 | 10 | private final List brickMatrix = new ArrayList<>(); 11 | 12 | public ZBrick() { 13 | brickMatrix.add(new int[][]{ 14 | {0, 0, 0, 0}, 15 | {7, 7, 0, 0}, 16 | {0, 7, 7, 0}, 17 | {0, 0, 0, 0} 18 | }); 19 | brickMatrix.add(new int[][]{ 20 | {0, 7, 0, 0}, 21 | {7, 7, 0, 0}, 22 | {7, 0, 0, 0}, 23 | {0, 0, 0, 0} 24 | }); 25 | } 26 | 27 | @Override 28 | public List getShapeMatrix() { 29 | return MatrixOperations.deepCopyList(brickMatrix); 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/IBrick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | final class IBrick implements Brick { 9 | 10 | private final List brickMatrix = new ArrayList<>(); 11 | 12 | public IBrick() { 13 | brickMatrix.add(new int[][]{ 14 | {0, 0, 0, 0}, 15 | {1, 1, 1, 1}, 16 | {0, 0, 0, 0}, 17 | {0, 0, 0, 0} 18 | }); 19 | brickMatrix.add(new int[][]{ 20 | {0, 1, 0, 0}, 21 | {0, 1, 0, 0}, 22 | {0, 1, 0, 0}, 23 | {0, 1, 0, 0} 24 | }); 25 | } 26 | 27 | @Override 28 | public List getShapeMatrix() { 29 | return MatrixOperations.deepCopyList(brickMatrix); 30 | } 31 | 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/ViewData.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic; 2 | 3 | public final class ViewData { 4 | 5 | private final int[][] brickData; 6 | private final int xPosition; 7 | private final int yPosition; 8 | private final int[][] nextBrickData; 9 | 10 | public ViewData(int[][] brickData, int xPosition, int yPosition, int[][] nextBrickData) { 11 | this.brickData = brickData; 12 | this.xPosition = xPosition; 13 | this.yPosition = yPosition; 14 | this.nextBrickData = nextBrickData; 15 | } 16 | 17 | public int[][] getBrickData() { 18 | return MatrixOperations.copy(brickData); 19 | } 20 | 21 | public int getxPosition() { 22 | return xPosition; 23 | } 24 | 25 | public int getyPosition() { 26 | return yPosition; 27 | } 28 | 29 | public int[][] getNextBrickData() { 30 | return MatrixOperations.copy(nextBrickData); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/gui/Main.java: -------------------------------------------------------------------------------- 1 | package com.quirko.gui; 2 | 3 | import com.quirko.app.GameController; 4 | import javafx.application.Application; 5 | import javafx.fxml.FXMLLoader; 6 | import javafx.scene.Parent; 7 | import javafx.scene.Scene; 8 | import javafx.stage.Stage; 9 | 10 | import java.net.URL; 11 | import java.util.ResourceBundle; 12 | 13 | public class Main extends Application { 14 | 15 | @Override 16 | public void start(Stage primaryStage) throws Exception { 17 | 18 | URL location = getClass().getClassLoader().getResource("gameLayout.fxml"); 19 | ResourceBundle resources = null; 20 | FXMLLoader fxmlLoader = new FXMLLoader(location, resources); 21 | Parent root = fxmlLoader.load(); 22 | GuiController c = fxmlLoader.getController(); 23 | 24 | primaryStage.setTitle("TetrisJFX"); 25 | Scene scene = new Scene(root, 400, 510); 26 | primaryStage.setScene(scene); 27 | primaryStage.show(); 28 | new GameController(c); 29 | } 30 | 31 | 32 | public static void main(String[] args) { 33 | launch(args); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/JBrick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | final class JBrick implements Brick { 9 | 10 | private final List brickMatrix = new ArrayList<>(); 11 | 12 | public JBrick() { 13 | brickMatrix.add(new int[][]{ 14 | {0, 0, 0, 0}, 15 | {2, 2, 2, 0}, 16 | {0, 0, 2, 0}, 17 | {0, 0, 0, 0} 18 | }); 19 | brickMatrix.add(new int[][]{ 20 | {0, 0, 0, 0}, 21 | {0, 2, 2, 0}, 22 | {0, 2, 0, 0}, 23 | {0, 2, 0, 0} 24 | }); 25 | brickMatrix.add(new int[][]{ 26 | {0, 0, 0, 0}, 27 | {0, 2, 0, 0}, 28 | {0, 2, 2, 2}, 29 | {0, 0, 0, 0} 30 | }); 31 | brickMatrix.add(new int[][]{ 32 | {0, 0, 2, 0}, 33 | {0, 0, 2, 0}, 34 | {0, 2, 2, 0}, 35 | {0, 0, 0, 0} 36 | }); 37 | } 38 | 39 | @Override 40 | public List getShapeMatrix() { 41 | return MatrixOperations.deepCopyList(brickMatrix); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/LBrick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | final class LBrick implements Brick { 9 | 10 | private final List brickMatrix = new ArrayList<>(); 11 | 12 | public LBrick() { 13 | brickMatrix.add(new int[][]{ 14 | {0, 0, 0, 0}, 15 | {0, 3, 3, 3}, 16 | {0, 3, 0, 0}, 17 | {0, 0, 0, 0} 18 | }); 19 | brickMatrix.add(new int[][]{ 20 | {0, 0, 0, 0}, 21 | {0, 3, 3, 0}, 22 | {0, 0, 3, 0}, 23 | {0, 0, 3, 0} 24 | }); 25 | brickMatrix.add(new int[][]{ 26 | {0, 0, 0, 0}, 27 | {0, 0, 3, 0}, 28 | {3, 3, 3, 0}, 29 | {0, 0, 0, 0} 30 | }); 31 | brickMatrix.add(new int[][]{ 32 | {0, 3, 0, 0}, 33 | {0, 3, 0, 0}, 34 | {0, 3, 3, 0}, 35 | {0, 0, 0, 0} 36 | }); 37 | } 38 | 39 | @Override 40 | public List getShapeMatrix() { 41 | return MatrixOperations.deepCopyList(brickMatrix); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/TBrick.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import com.quirko.logic.MatrixOperations; 4 | 5 | import java.util.ArrayList; 6 | import java.util.List; 7 | 8 | final class TBrick implements Brick { 9 | 10 | private final List brickMatrix = new ArrayList<>(); 11 | 12 | public TBrick() { 13 | brickMatrix.add(new int[][]{ 14 | {0, 0, 0, 0}, 15 | {6, 6, 6, 0}, 16 | {0, 6, 0, 0}, 17 | {0, 0, 0, 0} 18 | }); 19 | brickMatrix.add(new int[][]{ 20 | {0, 6, 0, 0}, 21 | {0, 6, 6, 0}, 22 | {0, 6, 0, 0}, 23 | {0, 0, 0, 0} 24 | }); 25 | brickMatrix.add(new int[][]{ 26 | {0, 6, 0, 0}, 27 | {6, 6, 6, 0}, 28 | {0, 0, 0, 0}, 29 | {0, 0, 0, 0} 30 | }); 31 | brickMatrix.add(new int[][]{ 32 | {0, 6, 0, 0}, 33 | {6, 6, 0, 0}, 34 | {0, 6, 0, 0}, 35 | {0, 0, 0, 0} 36 | }); 37 | } 38 | 39 | @Override 40 | public List getShapeMatrix() { 41 | return MatrixOperations.deepCopyList(brickMatrix); 42 | } 43 | } 44 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.quirko 8 | tetris 9 | 1.0-SNAPSHOT 10 | 11 | UTF-8 12 | 1.8 13 | 1.8 14 | 15 | 16 | 17 | 18 | com.zenjava 19 | javafx-maven-plugin 20 | 2.0 21 | 22 | com.quirko.gui.Main 23 | 24 | 25 | 26 | 27 | 28 | 29 | junit 30 | junit 31 | 4.11 32 | 33 | 34 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/logic/bricks/RandomBrickGenerator.java: -------------------------------------------------------------------------------- 1 | package com.quirko.logic.bricks; 2 | 3 | import java.util.ArrayDeque; 4 | import java.util.ArrayList; 5 | import java.util.Deque; 6 | import java.util.List; 7 | import java.util.concurrent.ThreadLocalRandom; 8 | 9 | public class RandomBrickGenerator implements BrickGenerator { 10 | 11 | private final List brickList; 12 | 13 | private final Deque nextBricks = new ArrayDeque<>(); 14 | 15 | public RandomBrickGenerator() { 16 | brickList = new ArrayList<>(); 17 | brickList.add(new IBrick()); 18 | brickList.add(new JBrick()); 19 | brickList.add(new LBrick()); 20 | brickList.add(new OBrick()); 21 | brickList.add(new SBrick()); 22 | brickList.add(new TBrick()); 23 | brickList.add(new ZBrick()); 24 | nextBricks.add(brickList.get(ThreadLocalRandom.current().nextInt(brickList.size()))); 25 | nextBricks.add(brickList.get(ThreadLocalRandom.current().nextInt(brickList.size()))); 26 | } 27 | 28 | @Override 29 | public Brick getBrick() { 30 | if (nextBricks.size() <= 1) { 31 | nextBricks.add(brickList.get(ThreadLocalRandom.current().nextInt(brickList.size()))); 32 | } 33 | return nextBricks.poll(); 34 | } 35 | 36 | @Override 37 | public Brick getNextBrick() { 38 | return nextBricks.peek(); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/com/quirko/gui/NotificationPanel.java: -------------------------------------------------------------------------------- 1 | package com.quirko.gui; 2 | 3 | import javafx.animation.FadeTransition; 4 | import javafx.animation.ParallelTransition; 5 | import javafx.animation.TranslateTransition; 6 | import javafx.collections.ObservableList; 7 | import javafx.event.ActionEvent; 8 | import javafx.event.EventHandler; 9 | import javafx.scene.Node; 10 | import javafx.scene.control.Label; 11 | import javafx.scene.effect.Effect; 12 | import javafx.scene.effect.Glow; 13 | import javafx.scene.layout.BorderPane; 14 | import javafx.scene.paint.Color; 15 | import javafx.util.Duration; 16 | 17 | public class NotificationPanel extends BorderPane { 18 | 19 | public NotificationPanel(String text) { 20 | setMinHeight(200); 21 | setMinWidth(220); 22 | final Label score = new Label(text); 23 | score.getStyleClass().add("bonusStyle"); 24 | final Effect glow = new Glow(0.6); 25 | score.setEffect(glow); 26 | score.setTextFill(Color.WHITE); 27 | setCenter(score); 28 | 29 | } 30 | 31 | public void showScore(ObservableList list) { 32 | FadeTransition ft = new FadeTransition(Duration.millis(2000), this); 33 | TranslateTransition tt = new TranslateTransition(Duration.millis(2500), this); 34 | tt.setToY(this.getLayoutY() - 40); 35 | ft.setFromValue(1); 36 | ft.setToValue(0); 37 | ParallelTransition transition = new ParallelTransition(tt, ft); 38 | transition.setOnFinished(new EventHandler() { 39 | @Override 40 | public void handle(ActionEvent event) { 41 | list.remove(NotificationPanel.this); 42 | } 43 | }); 44 | transition.play(); 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/main/resources/window_style.css: -------------------------------------------------------------------------------- 1 | .root { 2 | -fx-background-image: url("background_image.png"); 3 | } 4 | 5 | .nextBrick { 6 | -fx-border-width: 2px; 7 | -fx-border-color: whitesmoke; 8 | -fx-border-radius: 17px; 9 | } 10 | 11 | .gameBoard { 12 | -fx-border-color: linear-gradient(#2A5058, #61a2b1); 13 | -fx-border-width: 12px; 14 | -fx-border-radius: 12px; 15 | } 16 | 17 | .nextBrickLabel { 18 | -fx-font-family: "Let's go Digital"; 19 | -fx-padding: 20px 0 0 0; 20 | -fx-font-size: 16px; 21 | -fx-text-fill: yellow; 22 | } 23 | 24 | .ipad-dark-grey { 25 | -fx-background-color: linear-gradient(#686868 0%, #232723 25%, #373837 75%, #757575 100%), 26 | linear-gradient(#020b02, #3a3a3a), 27 | linear-gradient(#9d9e9d 0%, #6b6a6b 20%, #343534 80%, #242424 100%), 28 | linear-gradient(#8a8a8a 0%, #6b6a6b 20%, #343534 80%, #262626 100%), 29 | linear-gradient(#777777 0%, #606060 50%, #505250 51%, #2a2b2a 100%); 30 | -fx-background-insets: 0, 1, 4, 5, 6; 31 | -fx-background-radius: 9, 8, 5, 4, 3; 32 | -fx-padding: 8; 33 | /*-fx-font-family: "Helvetica";*/ 34 | -fx-font-family: "Let's go Digital"; 35 | -fx-font-size: 22px; 36 | -fx-font-weight: bold; 37 | -fx-text-fill: white; 38 | -fx-effect: dropshadow(three-pass-box, rgba(255, 255, 255, 0.2), 1, 0.0, 0, 1); 39 | } 40 | 41 | .rectangleStyle { 42 | -fx-fill: linear-gradient(from 41px 34px to 50px 50px, reflect, #ff7f50 30%, #faebd7 47%); 43 | } 44 | 45 | .vbox { 46 | -fx-spacing: 12; 47 | } 48 | 49 | .helpInfo { 50 | -fx-fill: white; 51 | -fx-alignment: center-left; 52 | -fx-text-alignment: left; 53 | -fx-font-size: 10px; 54 | } 55 | 56 | .bonusStyle { 57 | -fx-font-size: 40px; 58 | -fx-font-weight: bold; 59 | } 60 | 61 | .gameOverStyle { 62 | -fx-font-family: "Let's go Digital"; 63 | -fx-font-size: 48; 64 | -fx-background-color: red; 65 | } 66 | 67 | .scoreClass{ 68 | -fx-font-family: "Let's go Digital"; 69 | -fx-font-size: 38; 70 | -fx-fill: yellow; 71 | -fx-text-fill: yellow; 72 | } -------------------------------------------------------------------------------- /src/main/java/com/quirko/app/GameController.java: -------------------------------------------------------------------------------- 1 | package com.quirko.app; 2 | 3 | import com.quirko.gui.GuiController; 4 | import com.quirko.logic.*; 5 | import com.quirko.logic.events.EventSource; 6 | import com.quirko.logic.events.InputEventListener; 7 | import com.quirko.logic.events.MoveEvent; 8 | 9 | public class GameController implements InputEventListener { 10 | 11 | private Board board = new SimpleBoard(25, 10); 12 | 13 | private final GuiController viewGuiController; 14 | 15 | public GameController(GuiController c) { 16 | viewGuiController = c; 17 | board.createNewBrick(); 18 | viewGuiController.setEventListener(this); 19 | viewGuiController.initGameView(board.getBoardMatrix(), board.getViewData()); 20 | viewGuiController.bindScore(board.getScore().scoreProperty()); 21 | } 22 | 23 | @Override 24 | public DownData onDownEvent(MoveEvent event) { 25 | boolean canMove = board.moveBrickDown(); 26 | ClearRow clearRow = null; 27 | if (!canMove) { 28 | board.mergeBrickToBackground(); 29 | clearRow = board.clearRows(); 30 | if (clearRow.getLinesRemoved() > 0) { 31 | board.getScore().add(clearRow.getScoreBonus()); 32 | } 33 | if (board.createNewBrick()) { 34 | viewGuiController.gameOver(); 35 | } 36 | 37 | viewGuiController.refreshGameBackground(board.getBoardMatrix()); 38 | 39 | } else { 40 | if (event.getEventSource() == EventSource.USER) { 41 | board.getScore().add(1); 42 | } 43 | } 44 | return new DownData(clearRow, board.getViewData()); 45 | } 46 | 47 | @Override 48 | public ViewData onLeftEvent(MoveEvent event) { 49 | board.moveBrickLeft(); 50 | return board.getViewData(); 51 | } 52 | 53 | @Override 54 | public ViewData onRightEvent(MoveEvent event) { 55 | board.moveBrickRight(); 56 | return board.getViewData(); 57 | } 58 | 59 | @Override 60 | public ViewData onRotateEvent(MoveEvent event) { 61 | board.rotateLeftBrick(); 62 | return board.getViewData(); 63 | } 64 | 65 | 66 | @Override 67 | public void createNewGame() { 68 | board.newGame(); 69 | viewGuiController.refreshGameBackground(board.getBoardMatrix()); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /src/main/resources/gameLayout.fxml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 11 | 12 | 13 |
14 | 15 |
16 |
17 | 18 | 19 | 20 | 23 | 24 | 31 |