lab 1 2
diff --git a/src/sample/ArtRico.java b/src/sample/ArtRico.java
new file mode 100644
index 0000000..d7081e8
--- /dev/null
+++ b/src/sample/ArtRico.java
@@ -0,0 +1,244 @@
+package sample;
+
+import javafx.animation.AnimationTimer;
+import javafx.application.Application;
+import javafx.event.EventHandler;
+import javafx.scene.Parent;
+import javafx.scene.Scene;
+import javafx.scene.control.Button;
+import javafx.scene.control.Label;
+import javafx.scene.input.KeyEvent;
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+import javafx.stage.Stage;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+
+public class ArtRico extends Application {
+    Pane gameRoot;
+    Pane menuRoot;
+    Scene scene;
+    ArrayList<SimpleObject> bricks;              // массив кирпичей
+    Player player;                               // игрок
+    Ball ball;                                   // шар
+    SimpleObject leftWall;                       // левая стена
+    SimpleObject rightWall;                      // правая стена
+    SimpleObject top;                            // верхняя граница
+    SimpleObject bottom;                         // нижняя граница
+    static int score;                            // очки
+    Label scoreLabel;                            // лэйбл для очков
+    Bot bot;                                     // бот
+    static HashSet<String> currentlyActiveKeys;  // массив нажатых клавиш
+    static HashSet<String> lastKey;
+    boolean pause;
+    AnimationTimer timer;
+
+
+    @Override
+    public void start(Stage primaryStage) {
+        primaryStage.setTitle("ArtRik");
+        showMenu(primaryStage);
+    }
+
+    private void startGame(Stage primaryStage, int mode){
+        scene = new Scene(createContent(mode));
+        prepareActionHandlers();
+        primaryStage.setScene(scene);
+        primaryStage.show();
+        timer = new AnimationTimer() {
+            @Override
+            public void handle(long now)
+            {
+                if (ball.isGameWon()) {
+                    showMessage("You won! Your score is: ");
+                }
+                if(ball.isGameOver()) {
+                    showMessage("You lose! Your score is: ");
+                }
+                if (lastKey.contains("SPACE") ) {
+
+                    if (pause == false) {
+                        pause = true;
+                    } else {
+                        pause = false;
+                    }
+                }
+                if (lastKey.contains("ESCAPE") ) {
+                    timer.stop();
+                    showMenu(primaryStage);
+                }
+                lastKey.clear();
+                if(!pause) {
+                    update();
+                }
+
+            }
+        };
+        timer.start();
+    }
+
+    private Parent createContent(int mode) {
+        pause = true;
+        gameRoot = new Pane();
+        gameRoot.setPrefSize(1280,640);
+        Rectangle bg = new Rectangle(1280,640,Color.GREY);
+        leftWall = new SimpleObject(0,0,10,640,2,Color.ORANGE,Color.BEIGE);
+        rightWall = new SimpleObject(1270,0,10,640,2,Color.ORANGE,Color.BEIGE);
+        rightWall = new SimpleObject(1270,0,10,640,2,Color.ORANGE,Color.BEIGE);
+        bottom = new SimpleObject(0,640,1280,20,2,Color.ORANGE,Color.BEIGE);
+        top = new SimpleObject(0,0,1280,30,2,Color.ORANGE,Color.BEIGE);
+        score = 0;
+        scoreLabel = new Label("Score : " + score);
+        scoreLabel.setLayoutX(40);
+        scoreLabel.setLayoutY(0);
+        scoreLabel.setFont(javafx.scene.text.Font.font(20));
+        if(mode == 0){
+            player = new Player(500,570,280,20,2,Color.ORANGE,Color.BEIGE,10,1270,10);
+            ball = new Ball(635,550,20,20,2,Color.ORANGE,Color.BEIGE,10,1270,30,640,5,5);
+        }
+        if(mode == 1){
+            player = new Player(540,570,200,20,2,Color.ORANGE,Color.BEIGE,10,1270,10);
+            ball = new Ball(635,550,20,20,2,Color.ORANGE,Color.BEIGE,10,1270,30,640,5,5);
+        }
+        if(mode == 2){
+            player = new Player(570,570,140,20,2,Color.ORANGE,Color.BEIGE,10,1270,10);
+            ball = new Ball(635,550,20,20,2,Color.ORANGE,Color.BEIGE,10,1270,30,640,10,10);
+        }
+
+        ball.setPlayer(player);
+        ball.setFlagsInFalse();
+        bot = new Bot(player, ball);
+        gameRoot.getChildren().addAll(bg,player,ball,leftWall,rightWall,bottom,top,scoreLabel);
+        bricks = new ArrayList<>();
+        createBricks(15,8,80,40);
+        return gameRoot;
+    }
+
+    private void createBricks(int colomn, int raw, int w, int h) {
+        for(SimpleObject b : bricks) {
+            b.setVisible(false);
+        }
+        bricks.clear();
+        for (int i = 0; i < raw; i++) {
+            for(int j = 0; j < colomn; j++) {
+                SimpleObject brick = new SimpleObject(j*(w)+40,i*(h)+65,w,h,2,Color.ORANGE,Color.BEIGE);
+                bricks.add(brick);
+                gameRoot.getChildren().add(brick);
+            }
+        }
+        ball.setBricks(bricks);
+    }
+    private void restart() {
+        gameRoot.getChildren().remove(bricks);
+        createBricks(15,8,80,40);
+        score = 0;
+        player.setTranslateX(570);
+        player.setTranslateY(570);
+        ball.setTranslateX(635);
+        ball.setTranslateY(550);
+        ball.gameOver = false;
+        ball.setFlagsInFalse();
+    }
+
+    private void update() {
+        if (currentlyActiveKeys.contains("LEFT"))
+        {
+            player.moveLeft();
+        }
+        if (currentlyActiveKeys.contains("RIGHT"))
+        {
+            player.moveRight();
+        }
+        //bot.Execute();
+        ball.move();
+        scoreLabel.setText("Score : " + score);
+    }
+
+    private  void prepareActionHandlers()
+    {
+        // use a set so duplicates are not possible
+        currentlyActiveKeys = new HashSet<String>();
+        lastKey = new HashSet<String>();
+        scene.setOnKeyPressed(new EventHandler<KeyEvent>()
+        {
+            @Override
+            public void handle(KeyEvent event)
+            {
+                currentlyActiveKeys.add(event.getCode().toString());
+                lastKey.add(event.getCode().toString());
+            }
+        });
+        scene.setOnKeyReleased(new EventHandler<KeyEvent>()
+        {
+            @Override
+            public void handle(KeyEvent event)
+            {
+                currentlyActiveKeys.remove(event.getCode().toString());
+            }
+        });
+    }
+    private void showMessage (String msg) {
+        pause = true;
+        Button button = new Button(msg + score);
+        button.setLayoutX(510);
+        button.setLayoutY(240);
+        button.setPrefSize(260,80);
+        button.setOnAction(e -> {
+            pause = false;
+            button.setVisible(false);
+            gameRoot.getChildren().remove(button);
+        });
+        ball.gameWon = false;
+        ball.gameOver = false;
+        restart();
+        gameRoot.getChildren().add(button);
+    }
+    private void showMenu(Stage primaryStage){
+        menuRoot = new Pane();
+        menuRoot.setPrefSize(1280,640);
+        Rectangle bg = new Rectangle(1280,640,Color.GREY);
+        Button startButton = new Button("Start game");
+        startButton.setLayoutX(510);
+        startButton.setLayoutY(140);
+        startButton.setPrefSize(260,80);
+        startButton.setOnAction(e -> {
+            startButton.setVisible(false);
+            Button[] button = new Button[4];
+            for(int i = 0; i < 4; i++) {
+                button[i] = new Button();
+                button[i].setLayoutX(510);
+                button[i].setLayoutY(i*100+140);
+                button[i].setPrefSize(260,80);
+                menuRoot.getChildren().add(button[i]);
+            }
+            button[0].setText("Easy");
+            button[1].setText("Medium");
+            button[2].setText("Hard");
+            button[3].setText("Back");
+            button[0].setOnAction(event -> {
+                startGame(primaryStage, 0);
+            });
+            button[1].setOnAction(event -> {
+                startGame(primaryStage, 1);
+            });
+            button[2].setOnAction(event -> {
+                startGame(primaryStage, 2);
+            });
+            button[3].setOnAction(event -> {
+                for(Button b : button) {
+                    b.setVisible(false);
+                    startButton.setVisible(true);
+                }
+            });
+        });
+        menuRoot.getChildren().addAll(bg,startButton);
+        scene = new Scene(menuRoot);
+        primaryStage.setScene(scene);
+        primaryStage.show();
+    }
+    public static void main(String[] args) {
+        launch(args);
+    }
+}
diff --git a/src/sample/Ball.java b/src/sample/Ball.java
new file mode 100644
index 0000000..39117c1
--- /dev/null
+++ b/src/sample/Ball.java
@@ -0,0 +1,192 @@
+package sample;
+
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.HashSet;
+import java.util.Set;
+
+public class Ball extends SimpleObject {
+    Player player;
+    ArrayList<SimpleObject> bricks;
+    ArrayList<Integer> indexs;
+    Rectangle rect;
+    double speedX, kx;
+    double speedY, ky;          //
+    double leftBorder;          // коорд левой стены X
+    double rightBorder;         // коорд правой стены X
+    double topBorder;           // коорд. потолка Y
+    double bottomBorder;        // коорд. дна Y
+    boolean gameOver;           // флаг поражения
+    boolean gameWon;            // флаг победы
+    boolean lc, rc, tc, bc, pc; // флаги столкновений
+    public Ball(double x, double y, double w, double h, double sw, Color fillColor, Color strokeColor, double lb, double rb, double tb, double bb, double speedX, double SpeedY) {
+        super(x, y, w, h, sw, fillColor, strokeColor);
+        gameOver = false;
+        gameWon = false;
+        leftBorder = lb;
+        rightBorder = rb;
+        topBorder = tb;
+        bottomBorder = bb;
+        indexs = new ArrayList<>();
+        bricks = new ArrayList<>();
+        this.speedX = speedX;
+        this.speedY = SpeedY;
+        ky = 1;
+        kx = 0;
+    }
+    public void checkCollision(){
+        if (this.getTranslateX() + speedX*kx <= leftBorder) {
+            lc = true;
+        }
+        if (this.getTranslateX() + this.getWidth() + speedX*kx >= rightBorder) {
+            rc = true;
+        }
+        if (this.getTranslateY() + speedY*ky <= topBorder) {
+            tc = true;
+        }
+        if (this.getTranslateY() + this.getHeight() + speedY*ky >= bottomBorder) {
+
+            gameOver = true;
+        }
+        // коллизия с игроком низом
+        if(ky > 0) {
+            if (this.getTranslateX() + this.getWidth()  > player.getTranslateX() && this.getTranslateX() < player.getTranslateX() + player.getWidth()) {
+                if (this.getTranslateY() <= player.getTranslateY() && this.getTranslateY() + this.getHeight() >= player.getTranslateY()) {
+                    pc = true;
+                }
+            }
+        }
+        // коллизия с игроком правым боком
+        if(kx > 0) {
+            if (this.getTranslateY() + this.getHeight() > player.getTranslateY() && this.getTranslateY()  < player.getTranslateY() + player.getHeight()) {
+                if (this.getTranslateX()  <= player.getTranslateX() && this.getTranslateX() + this.getWidth()  >= player.getTranslateX()) {
+                    rc = true;
+                }
+            }
+        }
+        // коллизия с игроком левым боком
+        if(kx < 0) {
+            if (this.getTranslateY() + this.getHeight()  > player.getTranslateY() && this.getTranslateY()  < player.getTranslateY() + player.getHeight()) {
+                if (this.getTranslateX()  <= player.getTranslateX() + player.getWidth() && this.getTranslateX() + this.getWidth()  >= player.getTranslateX() + player.getWidth()) {
+                    lc = true;
+                }
+            }
+        }
+        // коллизия с кирпичом низом
+        if(ky > 0) {
+            for (int i = 0; i < bricks.size(); i++) {
+                SimpleObject brick = bricks.get(i);
+                if (this.getTranslateX() + this.getWidth()  > brick.getTranslateX() && this.getTranslateX()  < brick.getTranslateX() + brick.getWidth()) {
+                    if (this.getTranslateY()  <= brick.getTranslateY() && this.getTranslateY() + this.getHeight()  >= brick.getTranslateY()) {
+                        bc = true;
+                        indexs.add(i);
+                    }
+                }
+            }
+        }
+        // коллизия с кирпичом верхом
+        if(ky < 0) {
+            for (int i = 0; i < bricks.size(); i++) {
+                SimpleObject brick = bricks.get(i);
+                if (this.getTranslateX() + this.getWidth()  > brick.getTranslateX() && this.getTranslateX()  < brick.getTranslateX() + brick.getWidth()) {
+                    if (this.getTranslateY()  <= brick.getTranslateY() + brick.getHeight() && this.getTranslateY() + this.getHeight()  >= brick.getTranslateY() + brick.getHeight()) {
+                        tc = true;
+                        indexs.add(i);
+                    }
+                }
+            }
+        }
+        // коллизия с кирпичом правым боком
+        if(kx > 0) {
+            for (int i = 0; i < bricks.size(); i++) {
+                SimpleObject brick = bricks.get(i);
+                if (this.getTranslateY() + this.getHeight()  > brick.getTranslateY() && this.getTranslateY()  < brick.getTranslateY() + brick.getHeight()) {
+                    if (this.getTranslateX()  <= brick.getTranslateX() && this.getTranslateX() + this.getWidth()  >= brick.getTranslateX()) {
+                        lc = true;
+                        indexs.add(i);
+                    }
+                }
+            }
+        }
+        // коллизия с кирпичом левым боком
+        if(kx < 0) {
+            for (int i = 0; i < bricks.size(); i++) {
+                SimpleObject brick = bricks.get(i);
+                if (this.getTranslateY() + this.getHeight()  > brick.getTranslateY() && this.getTranslateY()  < brick.getTranslateY() + brick.getHeight()) {
+                    if (this.getTranslateX()  <= brick.getTranslateX() + brick.getWidth() && this.getTranslateX() + this.getWidth()  >= brick.getTranslateX() + brick.getWidth()) {
+                        lc = true;
+                        indexs.add(i);
+                    }
+                }
+            }
+        }
+    }
+    public void move() {
+        checkCollision(); // проверка коллизий, установка флагов
+        // изменение скорости в зависимости от флагов
+        if (tc ^ bc) {
+            ky = -ky;
+        }
+        else if(lc ^ rc) {
+            kx = -kx;
+        }
+        if (pc) {
+            double k;
+            k = (this.getTranslateX()+this.getWidth()/2-player.getTranslateX()-player.getWidth()/2) / (player.getWidth()/2);
+            kx = k;
+            ky = -0.8 - (1 - Math.abs(k));
+        }
+        // уничтожение кирпичей
+        Set ixs = new HashSet(indexs);
+        indexs.clear();
+        indexs.addAll(ixs);
+        indexs.sort(Comparator.naturalOrder());
+        for(int k = 0; indexs.size() > 0; k++) {
+            SimpleObject b = bricks.get(indexs.get(0) - k);
+            b.setVisible(false);
+            bricks.remove(b);
+            indexs.remove(0);
+            ArtRico.score += 1;
+        }
+        if(bricks.size() == 0) {
+            gameWon = true;
+        }
+
+        // перемещение мяча
+        setTranslateX(getTranslateX() + speedX*kx);
+        setTranslateY(getTranslateY() + speedY*ky);
+        setFlagsInFalse(); // сброс флагов
+    }
+    public void setSpeedX(double speedX) {
+        this.speedX = speedX;
+    }
+    public void setSpeedY(double speedY) {
+        this.speedY = speedY;
+    }
+    public void setBricks(ArrayList<SimpleObject> bricks) {
+        /*for(SimpleObject b : this.bricks) {
+            b.setVisible(false);
+        }*/
+        this.bricks.clear();
+        this.bricks.addAll(bricks);
+    }
+    public void setPlayer(Player player) {
+        this.player = player;
+    }
+    public boolean isGameOver() {
+        return gameOver;
+    }
+    public boolean isGameWon() {
+        return gameWon;
+    }
+    public void setFlagsInFalse() {
+        lc = false;
+        rc = false;
+        tc = false;
+        bc = false;
+        pc = false;
+    }
+}
diff --git a/src/sample/Bot.java b/src/sample/Bot.java
new file mode 100644
index 0000000..6848b1b
--- /dev/null
+++ b/src/sample/Bot.java
@@ -0,0 +1,35 @@
+package sample;
+
+public class Bot {
+    Player player;
+    Ball ball;
+    int time;
+    public Bot(Player player, Ball ball) {
+        this.player = player;
+        this.ball = ball;
+        time = 0;
+    }
+    public void Execute() {
+        if(time < 1850){
+            if (player.getTranslateX() + player.getWidth()/2 < ball.getTranslateX() + ball.getWidth()) {
+                player.moveRight();
+            }
+            else {
+                player.moveLeft();
+            }
+        }
+        if(time > 1850) {
+            if (player.getTranslateX() + player.getWidth()/2 < ball.getTranslateX()) {
+                player.moveRight();
+            }
+            else {
+                player.moveLeft();
+            }
+        }
+        if (time == 4000) {
+            time = 0;
+        }
+        time++;
+
+    }
+}
diff --git a/src/sample/Player.java b/src/sample/Player.java
new file mode 100644
index 0000000..9379382
--- /dev/null
+++ b/src/sample/Player.java
@@ -0,0 +1,29 @@
+package sample;
+
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+
+public class Player extends SimpleObject{
+    Rectangle rect;
+    double speed;
+    double leftBorder;
+    double rightBorder;
+    public Player(double x, double y, double w, double h, double sw, Color fillColor,Color strokeColor, double lb, double rb, double speed) {
+        super(x, y, w, h, sw, fillColor, strokeColor);
+        leftBorder = lb;
+        rightBorder = rb;
+        this.speed = speed;
+    }
+    public void moveLeft() {
+        if(this.getTranslateX() <= leftBorder) {
+            return;
+        }
+        setTranslateX(this.getTranslateX() - speed);
+    }
+    public void moveRight() {
+        if(this.getTranslateX() + this.getWidth() >= rightBorder) {
+            return;
+        }
+        setTranslateX(this.getTranslateX() + speed);
+    }
+}
diff --git a/src/sample/SimpleObject.java b/src/sample/SimpleObject.java
new file mode 100644
index 0000000..7c32753
--- /dev/null
+++ b/src/sample/SimpleObject.java
@@ -0,0 +1,18 @@
+package sample;
+
+import javafx.scene.layout.Pane;
+import javafx.scene.paint.Color;
+import javafx.scene.shape.Rectangle;
+
+public class SimpleObject extends Pane {
+    Rectangle rect;
+
+    public SimpleObject(double x, double y, double w, double h, double sw, Color fillColor,Color strokeColor) {
+        rect = new Rectangle(w,h,fillColor);
+        this.setTranslateX(x);
+        this.setTranslateY(y);
+        this.getChildren().add(rect);
+        rect.setStrokeWidth(sw);
+        rect.setStroke(strokeColor);
+    }
+}
\ No newline at end of file
diff --git a/src/sample/sample.fxml b/src/sample/sample.fxml
new file mode 100644
index 0000000..363237a
--- /dev/null
+++ b/src/sample/sample.fxml
@@ -0,0 +1,8 @@
+<?import javafx.geometry.Insets?>
+<?import javafx.scene.layout.GridPane?>
+
+<?import javafx.scene.control.Button?>
+<?import javafx.scene.control.Label?>
+<GridPane fx:controller="sample.Controller"
+          xmlns:fx="http://javafx.com/fxml" alignment="center" hgap="10" vgap="10">
+</GridPane>
\ No newline at end of file