├── Chrome-Dino-Game-AI ├── ChromeDino.rar ├── README.md ├── chromedino │ ├── ChromeDino.java │ ├── constants │ │ └── Constants.java │ ├── display │ │ ├── GameScreen.java │ │ ├── metrics │ │ │ ├── DataMetrics.java │ │ │ └── GraphicData.java │ │ └── objects │ │ │ ├── AirPlane.java │ │ │ ├── Dinosaur.java │ │ │ ├── enemies │ │ │ ├── EnemiesManager.java │ │ │ ├── entities │ │ │ │ ├── Bird.java │ │ │ │ ├── Cactus.java │ │ │ │ └── Spike.java │ │ │ └── model │ │ │ │ └── Enemy.java │ │ │ └── scenario │ │ │ ├── Clouds.java │ │ │ ├── Land.java │ │ │ └── Montain.java │ ├── image_tools │ │ └── ImageTool.java │ ├── neuralnetwork │ │ ├── LiveView.java │ │ ├── NeuralNetwork.java │ │ └── SaveLoad.java │ └── utils │ │ ├── Animation.java │ │ └── Utils.java ├── data │ ├── airplane │ │ ├── airplane0.bmp │ │ └── airplane1.bmp │ ├── bird │ │ ├── bird1.png │ │ └── bird2.png │ ├── dinosaur │ │ ├── dino0.bmp │ │ ├── dino1.bmp │ │ ├── dino2.bmp │ │ ├── dino3.bmp │ │ ├── dino4.bmp │ │ ├── dino5.bmp │ │ ├── dino6.bmp │ │ ├── dino7.bmp │ │ ├── dino8.bmp │ │ └── dino9.bmp │ ├── enemies │ │ ├── cactus │ │ │ ├── cactus0.bmp │ │ │ ├── cactus1.bmp │ │ │ ├── cactus2.bmp │ │ │ ├── cactus3.bmp │ │ │ └── cactus4.bmp │ │ └── spike │ │ │ └── spike.png │ ├── scenario │ │ ├── cloud │ │ │ └── cloud.png │ │ ├── land │ │ │ ├── land0.bmp │ │ │ ├── land1.bmp │ │ │ ├── land2.bmp │ │ │ ├── land3.bmp │ │ │ ├── land4.bmp │ │ │ └── land5.bmp │ │ └── montain │ │ │ ├── montain0.bmp │ │ │ ├── montain1.bmp │ │ │ ├── montain2.bmp │ │ │ ├── montain3.bmp │ │ │ ├── montain4.bmp │ │ │ └── montain5.bmp │ ├── several │ │ ├── gameover_text.png │ │ └── replay_button.png │ └── synapses │ │ └── 3530_synapses.txt └── trained.gif ├── FlappyBirdAI ├── FlappyBird.jar ├── README.md ├── constants │ └── Constants.java ├── data │ ├── FlappyBird-demo.gif │ ├── sprites │ │ ├── flappy_bird.png │ │ ├── game_over.png │ │ ├── get_ready.png │ │ ├── gold.png │ │ ├── menu.png │ │ ├── new.png │ │ ├── numbers.png │ │ ├── play.png │ │ ├── player │ │ │ ├── bird1.bmp │ │ │ ├── bird2.bmp │ │ │ └── bird3.bmp │ │ ├── scenario │ │ │ ├── enemies │ │ │ │ ├── pipe1.png │ │ │ │ └── pipe2.png │ │ │ ├── ground.png │ │ │ └── landscape.png │ │ ├── score.png │ │ └── silver.png │ └── synapses │ │ └── 3420_synapses.txt ├── game │ ├── Game.java │ ├── GameScreen.java │ ├── controller │ │ └── GameController.java │ └── display │ │ ├── Player.java │ │ ├── enemies │ │ ├── EnemiesManager.java │ │ ├── entities │ │ │ └── Pipe.java │ │ └── model │ │ │ └── Enemy.java │ │ └── scenario │ │ ├── Ground.java │ │ └── Landscape.java ├── maxtercreations │ └── FlappyBird.java ├── neuralnetwork │ ├── NeuralNetwork.java │ └── NeuronRetrieve.java └── utils │ ├── Animation.java │ ├── ImageTool.java │ └── Utils.java ├── README.md └── ResponsiveSwingMaterialDesign ├── README.md ├── ResponsiveSwingMaterialDesign.java ├── animation ├── AnimateComponent.java └── Animation.java ├── callback ├── Callback.java └── CallbackT.java ├── components ├── buttons │ ├── MaterialButton.java │ ├── RoundedButton.java │ └── RoundedFillButton.java ├── check │ └── CheckCircle.java ├── combobox │ ├── AutoCompletion.java │ ├── ComboBox.java │ └── render │ │ ├── MaterialComboBoxEditor.java │ │ ├── MaterialComboBoxRenderer.java │ │ ├── MaterialComboBoxUI.java │ │ └── MaterialDrawingUtils.java ├── date │ ├── DatePicker.java │ ├── fields │ │ ├── DateField.java │ │ └── DateTimeField.java │ └── picker │ │ ├── DarkDatePicker.java │ │ └── LightDatePicker.java ├── image │ └── ImageLabel.java ├── input │ ├── InputField.java │ ├── PasswordField.java │ └── TextArea.java └── utils │ ├── ImageRoundedBorder.java │ ├── RoundedBorder.java │ ├── RoundedPane.java │ └── filters │ ├── BlackFilter.java │ └── GaussianBlur.java ├── constants └── Constants.java ├── demo ├── Demo1_RegisterForm.java └── Demo2_General_Components.java ├── display └── FrameUtility.java ├── images ├── Darkmode.png ├── DatePicker DarkMode.png ├── Form.png ├── Screenshot_1.png ├── Screenshot_10.png ├── Screenshot_11.png ├── Screenshot_2.png ├── Screenshot_3.png ├── Screenshot_4.png ├── Screenshot_5.png ├── Screenshot_6.png ├── Screenshot_7.png ├── Screenshot_8.png └── Screenshot_9.png ├── layouts ├── LayoutInfo.java └── ResponsiveLayout.java ├── resources ├── GOTHIC.TTF ├── GOTHICB.TTF ├── GOTHICBI.TTF ├── GOTHICI.TTF └── components │ └── icons │ ├── calendar-icon.png │ ├── check-icon.png │ └── eye-icon.png ├── theme ├── ThemeModel.java └── ThemesManager.java └── utils └── Utils.java /Chrome-Dino-Game-AI/ChromeDino.rar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/ChromeDino.rar -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/README.md: -------------------------------------------------------------------------------- 1 | ## Google Dinosaur Game - Artificial Intelligence 2 | 3 | Google Dinosaur Auto-learning using Neural Networks 4 | 5 | [![Dinosaur](https://github.com/GustavoRolimSantos/Java/blob/master/Chrome-Dino-Game-AI/trained.gif)](https://www.youtube.com/watch?v=szKEPME56y8&feature=youtu.be) 6 | 7 | ### About the project 8 | The idea is to use Neural Networks to find the best Dinosaur by using Natural Selection (Random Mutations). 9 | The game was recreated from scratch (without engines) using Java. 10 | 11 | The Neural Network was created with 3 layers and Sigmoid as the activation function: 12 | - Input Layer with 6 sensors 13 | - Hidden layer with 6 neurons + 1 bias 14 | - Output layer with 3 neurons (Jump, Down, Airplane) 15 | 16 | The population size used to train was between 1000-2000 dinosaurs. 17 | 18 | The learning time was between 30 and 60 minutes. 19 | 20 | ### Fight the AI 21 | **ChromeDino.rar**: Contains 2 jars (Normal game mode and 1x1 mode) 22 | 23 | Keyboard Commands: 24 | - Jump (ARROW UP) 25 | - Down (ARROW DOWN) 26 | - Airplane (A) 27 | - Reset Game (ENTER) 28 | 29 | **For more information watch the [demonstration video](https://www.youtube.com/watch?v=szKEPME56y8&feature=youtu.be).** 30 | 31 | ### Code 32 | Inside the "data" folder there is another folder called "synapses", the file inside this folder is the training. 33 | Delete this file if you want to train the Neural Network again. 34 | 35 | This project was inspired in Universo Programado (https://github.com/JVictorDias/Dinossauro-Google) 36 | 37 | > COPYRIGHT BY GUSTAVO ROLIM DOS SANTOS 2020. -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/ChromeDino.java: -------------------------------------------------------------------------------- 1 | package chromedino; 2 | 3 | import javax.swing.JFrame; 4 | 5 | import chromedino.constants.Constants; 6 | import chromedino.display.GameScreen; 7 | 8 | @SuppressWarnings("serial") 9 | public class ChromeDino extends JFrame { 10 | 11 | private static GameScreen gameScreen; 12 | 13 | public ChromeDino() { 14 | super("ChromeDino"); 15 | setSize(Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT); 16 | setLocationRelativeTo(null); 17 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 18 | setResizable(false); 19 | 20 | gameScreen = new GameScreen(); 21 | 22 | addKeyListener(gameScreen); 23 | add(gameScreen); 24 | } 25 | 26 | public void startGame() { 27 | setVisible(true); 28 | gameScreen.startGame(); 29 | } 30 | 31 | public static GameScreen getGameScreen() { 32 | return gameScreen; 33 | } 34 | 35 | public static void main(String args[]) { 36 | new ChromeDino().startGame(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/constants/Constants.java: -------------------------------------------------------------------------------- 1 | package chromedino.constants; 2 | 3 | public class Constants { 4 | 5 | public static final boolean BATTLE_MODE = false; 6 | 7 | public static int START_POPULATION = 2000; 8 | 9 | public static final int START_GAME_STATE = 0; 10 | public static final int GAME_PLAYING_STATE = 1; 11 | public static final int GAME_OVER_STATE = 2; 12 | 13 | public static final int SCREEN_WIDTH = 1280; 14 | public static final int SCREEN_HEIGHT = 720; 15 | 16 | public static final double START_SPEED = 4; 17 | 18 | public static double SPEED = START_SPEED; 19 | 20 | } 21 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/metrics/DataMetrics.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.metrics; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Graphics; 6 | import java.awt.Graphics2D; 7 | import java.awt.RenderingHints; 8 | import java.awt.font.FontRenderContext; 9 | import java.awt.font.LineMetrics; 10 | import java.awt.geom.Ellipse2D; 11 | import java.awt.geom.Line2D; 12 | import java.util.ArrayList; 13 | 14 | public class DataMetrics { 15 | 16 | public ArrayList bestOfGeneration = new ArrayList<>(), average = new ArrayList<>(), learningCurve = new ArrayList<>(); 17 | 18 | private final int PAD = 20; 19 | 20 | public DataMetrics() { 21 | bestOfGeneration.add(0); 22 | average.add(0); 23 | learningCurve.add(0); 24 | } 25 | 26 | public Graphics2D getGraphics(Graphics g, int w, int h) { 27 | 28 | if (bestOfGeneration.size() > 50 || average.size() > 50 || learningCurve.size() > 50) { 29 | bestOfGeneration.clear(); 30 | average.clear(); 31 | learningCurve.clear(); 32 | 33 | bestOfGeneration.add(0); 34 | average.add(0); 35 | learningCurve.add(0); 36 | } 37 | 38 | Graphics2D g2 = (Graphics2D) g; 39 | 40 | g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 41 | 42 | g2.fillRect(0, 0, w, h); 43 | 44 | g2.setColor(Color.decode("#D6D6D6")); 45 | 46 | int y_1 = 0, x_1 = 0; 47 | 48 | for (int x = 0; x < (h / PAD) - 1; x++) { 49 | y_1 += PAD; 50 | g2.draw(new Line2D.Double(PAD, y_1, w - PAD, y_1)); 51 | } 52 | 53 | for (int x = 0; x < (w / PAD) - 1; x++) { 54 | x_1 += PAD; 55 | g2.draw(new Line2D.Double(x_1, PAD, x_1, h - PAD)); 56 | } 57 | 58 | // Draw ordinate. 59 | g2.draw(new Line2D.Double(PAD, PAD, PAD, h - PAD)); 60 | // Draw abcissa. 61 | g2.draw(new Line2D.Double(PAD, h - PAD, w - PAD, h - PAD)); 62 | // Draw labels. 63 | Font font = g2.getFont(); 64 | FontRenderContext frc = g2.getFontRenderContext(); 65 | LineMetrics lm = font.getLineMetrics("0", frc); 66 | float sh = lm.getAscent() + lm.getDescent(); 67 | // Ordinate label. 68 | String s = "Score"; 69 | float sy = PAD + ((h - 2 * PAD) - s.length() * sh) / 2 + lm.getAscent(); 70 | g2.setColor(Color.BLACK); 71 | for (int i = 0; i < s.length(); i++) { 72 | String letter = String.valueOf(s.charAt(i)); 73 | float sw = (float) font.getStringBounds(letter, frc).getWidth(); 74 | float sx = (PAD - sw) / 2; 75 | g2.drawString(letter, sx, sy); 76 | sy += sh; 77 | } 78 | 79 | drawSubtitle(g2, lm, sh, font, h, w, PAD * 2, Color.BLUE, "Generation's Best"); 80 | drawSubtitle(g2, lm, sh, font, h, w, 220, Color.ORANGE, "Average"); 81 | drawSubtitle(g2, lm, sh, font, h, w, 340, Color.MAGENTA, "Learning Curve"); 82 | // Draw lines. 83 | 84 | g2.setColor(Color.decode("#D6D6D6")); 85 | 86 | drawData(bestOfGeneration, g2, w, h, Color.BLUE, Color.BLUE.darker()); 87 | drawData(average, g2, w, h, Color.ORANGE, Color.ORANGE.darker()); 88 | drawData(learningCurve, g2, w, h, Color.MAGENTA, Color.MAGENTA.darker()); 89 | 90 | return g2; 91 | } 92 | 93 | private void drawSubtitle(Graphics2D g2, LineMetrics lm, float sh, Font font, int h, int w, int addX, Color color, String text) { 94 | g2.setColor(Color.BLACK); 95 | float sy = h - PAD + (PAD - sh) / 2 + lm.getAscent(); 96 | float sx = PAD + addX; 97 | g2.drawString(text, sx, sy); 98 | 99 | g2.setColor(color); 100 | g2.fill(new Ellipse2D.Double(sx - 20, sy - 8, 10, 10)); 101 | } 102 | 103 | private void drawData(ArrayList dataList, Graphics2D g2, int w, int h, Color lineColor, Color pointColor) { 104 | double xInc = (double) (w - 2 * PAD) / (dataList.size() - 1); 105 | double scale = (double) (h - 2 * PAD) / getMax(dataList); 106 | g2.setPaint(lineColor); 107 | for (int i = 0; i < dataList.size() - 1; i++) { 108 | double x1 = PAD + i * xInc; 109 | double y1 = h - PAD - scale * dataList.get(i); 110 | double x2 = PAD + (i + 1) * xInc; 111 | double y2 = h - PAD - scale * dataList.get(i + 1); 112 | g2.draw(new Line2D.Double(x1, y1, x2, y2)); 113 | } 114 | // Mark data points. 115 | g2.setPaint(pointColor); 116 | for (int i = 0; i < dataList.size(); i++) { 117 | double x = PAD + i * xInc; 118 | double y = h - PAD - scale * dataList.get(i); 119 | g2.fill(new Ellipse2D.Double(x - 2, y - 2, 4, 4)); 120 | } 121 | } 122 | 123 | private int getMax(ArrayList dataList) { 124 | int max = -Integer.MAX_VALUE; 125 | for (int i = 0; i < dataList.size(); i++) { 126 | if (dataList.get(i) > max) 127 | max = dataList.get(i); 128 | } 129 | return max; 130 | } 131 | 132 | } -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/metrics/GraphicData.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.metrics; 2 | 3 | import chromedino.display.GameScreen; 4 | 5 | public class GraphicData { 6 | 7 | private GameScreen gameScreen; 8 | 9 | public GraphicData(GameScreen gameScreen) { 10 | this.gameScreen = gameScreen; 11 | } 12 | 13 | public void updateLearningCurve() { 14 | if (gameScreen.getBestDinosaur() != null) { 15 | 16 | gameScreen.getDied().get(gameScreen.getDied().size() - 1).getNeuralNetwork().getSaveLoad().saveToFile(gameScreen.getBestDinosaur().score); 17 | 18 | if (gameScreen.getDataMetrics().learningCurve.isEmpty() || (gameScreen.bestScore > gameScreen.getDataMetrics().learningCurve.get(gameScreen.getDataMetrics().learningCurve.size() - 1))) { 19 | gameScreen.getDataMetrics().learningCurve.add(gameScreen.bestScore); 20 | } 21 | } 22 | } 23 | 24 | public void updateAverage() { 25 | gameScreen.getDataMetrics().bestOfGeneration.add(gameScreen.getDied().get(gameScreen.getDied().size() - 1).score); 26 | 27 | int average = 0; 28 | 29 | if (gameScreen.getDied().size() > 10) { 30 | for (int i = 11; i > 1; i--) { 31 | average += gameScreen.getDied().get(gameScreen.getDied().size() - i).getScore(); 32 | } 33 | 34 | average /= 10; 35 | } else { 36 | for (int i = 0; i < gameScreen.getDied().size(); i++) { 37 | average += gameScreen.getDied().get(i).getScore(); 38 | } 39 | 40 | average /= gameScreen.getDied().size(); 41 | } 42 | 43 | gameScreen.getDataMetrics().average.add(average); 44 | } 45 | 46 | } 47 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/AirPlane.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.image.BufferedImage; 5 | import java.util.Random; 6 | 7 | import chromedino.ChromeDino; 8 | import chromedino.utils.Utils; 9 | 10 | public class AirPlane { 11 | 12 | private boolean isUsing; 13 | 14 | private BufferedImage airplane1, airplane2; 15 | 16 | private Dinosaur dinosaur; 17 | 18 | private float posX; 19 | private int posY; 20 | 21 | private int TRIGGER_PIXELS, START_PIXEL; 22 | 23 | public static int PIXELS_RATE = 4029; 24 | 25 | public static int CHARGING_RATE = 6000; 26 | 27 | private final int OBSTACLE_WIDTH = 970; 28 | 29 | private Random random = new Random(); 30 | 31 | public AirPlane(int width, Dinosaur dinosaur) { 32 | this.dinosaur = dinosaur; 33 | airplane1 = Utils.getResouceImage("data/airplane/airplane0.bmp"); 34 | airplane2 = Utils.getResouceImage("data/airplane/airplane1.bmp"); 35 | 36 | posX = dinosaur.getPosX() - 15; 37 | posY = 517; 38 | } 39 | 40 | public void use() { 41 | if (!isUsing) { 42 | int width = ChromeDino.getGameScreen().getLand().getScreenWidth(); 43 | 44 | if (width != 0 && (TRIGGER_PIXELS == 0 || width > TRIGGER_PIXELS)) { 45 | isUsing = true; 46 | dinosaur.setPosY(posY - 15); 47 | 48 | TRIGGER_PIXELS = width + PIXELS_RATE; 49 | START_PIXEL = width; 50 | } 51 | } 52 | } 53 | 54 | public void reset() { 55 | isUsing = false; 56 | TRIGGER_PIXELS = 0; 57 | START_PIXEL = 0; 58 | } 59 | 60 | public void stopUsing() { 61 | isUsing = false; 62 | TRIGGER_PIXELS = ChromeDino.getGameScreen().getLand().getScreenWidth() + PIXELS_RATE; 63 | START_PIXEL = 0; 64 | } 65 | 66 | public void draw(Graphics g) { 67 | if (!dinosaur.isAlive() || TRIGGER_PIXELS == 0 || START_PIXEL == 0) 68 | return; 69 | 70 | int width = ChromeDino.getGameScreen().getLand().getScreenWidth(); 71 | 72 | if (width > START_PIXEL + OBSTACLE_WIDTH) 73 | stopUsing(); 74 | 75 | if (isUsing) { 76 | g.drawImage(random.nextBoolean() ? airplane1 : airplane2, (int) posX, posY, null); 77 | } 78 | 79 | } 80 | 81 | public boolean isUsing() { 82 | return isUsing; 83 | } 84 | 85 | } 86 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/Dinosaur.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects; 2 | 3 | import java.awt.Color; 4 | import java.awt.Graphics; 5 | import java.awt.Point; 6 | import java.awt.Rectangle; 7 | import java.awt.image.BufferedImage; 8 | import java.io.File; 9 | import java.util.Random; 10 | 11 | import chromedino.ChromeDino; 12 | import chromedino.constants.Constants; 13 | import chromedino.display.GameScreen; 14 | import chromedino.display.objects.enemies.model.Enemy; 15 | import chromedino.neuralnetwork.NeuralNetwork; 16 | import chromedino.utils.Animation; 17 | import chromedino.utils.Utils; 18 | 19 | public class Dinosaur { 20 | 21 | /* Dinosaur constants */ 22 | 23 | public static final int LAND_POSY = 627; 24 | public static float GRAVITY = 0.35f; 25 | 26 | private static final int NORMAL_RUN = 0; 27 | private static final int JUMPING = 1; 28 | private static final int DOWN_RUN = 2; 29 | private static final int DEATH = 3; 30 | private static final int AIRPLANE = 4; 31 | 32 | /* Neural Network Config */ 33 | 34 | private final int MIN_WEIGHT = -1; 35 | private final int MAX_WEIGHT = 1; 36 | 37 | private final int GENOMES_PER_GENERATION = 3; 38 | private final int[] NEURONS_AMOUNT = { 6, 6, 3 }; 39 | 40 | private final double MUTATION_PROBABILITY = 0.7; 41 | 42 | /* Variables */ 43 | 44 | private float posY; 45 | private float posX; 46 | 47 | private float speedY; 48 | private Rectangle rectBound; 49 | 50 | public int id, score = 0; 51 | 52 | private int state = NORMAL_RUN; 53 | 54 | private Animation normalRunAnim; 55 | private BufferedImage jumping; 56 | private Animation downRunAnim; 57 | private BufferedImage deathImage; 58 | 59 | private AirPlane airPlane; 60 | 61 | private Color randomColor; 62 | private boolean alive = true; 63 | 64 | private NeuralNetwork neuralNetwork; 65 | 66 | private boolean playAsHuman = false; 67 | 68 | public int getScore() { 69 | return score; 70 | } 71 | 72 | public Dinosaur(GameScreen gameScreen, boolean playAsHuman) { 73 | id = gameScreen.getDinosaurs().size(); 74 | 75 | this.neuralNetwork = new NeuralNetwork(id, NEURONS_AMOUNT, GENOMES_PER_GENERATION, MUTATION_PROBABILITY, MIN_WEIGHT, MAX_WEIGHT); 76 | 77 | this.playAsHuman = playAsHuman; 78 | 79 | if (Constants.BATTLE_MODE) { 80 | if (playAsHuman) { 81 | randomColor = new Color(255, 57, 57); 82 | posX = (int) (50 + id * 0.087); 83 | } else { 84 | randomColor = new Color(239, 239, 239); 85 | posX = (int) (200 + id * 0.087); 86 | } 87 | } else { 88 | posX = (int) (13 + id * 0.087); 89 | 90 | Random rand = new Random(); 91 | float red = rand.nextFloat(), green = rand.nextFloat(), blue = rand.nextFloat(); 92 | 93 | randomColor = new Color(red, green, blue); 94 | } 95 | 96 | 97 | posY = LAND_POSY; 98 | rectBound = new Rectangle(); 99 | normalRunAnim = new Animation(90); 100 | normalRunAnim.addFrame(Utils.changeColor(new File("data/dinosaur/dino0.bmp"), randomColor)); 101 | normalRunAnim.addFrame(Utils.changeColor(new File("data/dinosaur/dino1.bmp"), randomColor)); 102 | jumping = Utils.changeColor(new File("data/dinosaur/dino4.bmp"), randomColor); 103 | downRunAnim = new Animation(90); 104 | downRunAnim.addFrame(Utils.changeColor(new File("data/dinosaur/dino2.bmp"), randomColor)); 105 | downRunAnim.addFrame(Utils.changeColor(new File("data/dinosaur/dino3.bmp"), randomColor)); 106 | deathImage = Utils.changeColor(new File("data/dinosaur/dino7.bmp"), randomColor); 107 | 108 | airPlane = new AirPlane(Constants.SCREEN_WIDTH, this); 109 | } 110 | 111 | public void setAlive(boolean alive) { 112 | this.state = alive ? NORMAL_RUN : DEATH; 113 | this.alive = alive; 114 | } 115 | 116 | public boolean isAlive() { 117 | return alive; 118 | } 119 | 120 | public int getId() { 121 | return id; 122 | } 123 | 124 | public AirPlane getAirPlane() { 125 | return airPlane; 126 | } 127 | 128 | public NeuralNetwork getNeuralNetwork() { 129 | return neuralNetwork; 130 | } 131 | 132 | public float getPosX() { 133 | return posX; 134 | } 135 | 136 | public void setPosY(int posY) { 137 | this.posY = posY; 138 | } 139 | 140 | public void setPosX(float f) { 141 | this.posX = f; 142 | } 143 | 144 | public void draw(Graphics g) { 145 | if (!alive) 146 | return; 147 | 148 | switch (state) { 149 | case NORMAL_RUN: 150 | g.drawImage(normalRunAnim.getFrame(), (int) posX, (int) posY, null); 151 | break; 152 | case AIRPLANE: 153 | g.drawImage(normalRunAnim.getFrame(), (int) posX, (int) posY, null); 154 | break; 155 | case JUMPING: 156 | g.drawImage(jumping, (int) posX, (int) posY, null); 157 | break; 158 | case DOWN_RUN: 159 | g.drawImage(downRunAnim.getFrame(), (int) posX, (int) (posY + 20), null); 160 | break; 161 | case DEATH: 162 | g.drawImage(deathImage, (int) posX, (int) posY, null); 163 | break; 164 | } 165 | 166 | airPlane.draw(g); 167 | } 168 | 169 | public Object[] getNextEnemy() { 170 | double smallerDistance = 9999; 171 | 172 | if (ChromeDino.getGameScreen().getEnimiesManager().getEnemies().isEmpty()) { 173 | return new Object[] { null, smallerDistance }; 174 | } 175 | 176 | Enemy enemy = ChromeDino.getGameScreen().getEnimiesManager().getEnemies().get(0); 177 | 178 | for (Enemy e : ChromeDino.getGameScreen().getEnimiesManager().getEnemies()) { 179 | double currentDistance = new Point((int) posX, (int) posY).distance(new Point((int) e.getBound().getX(), (int) e.getBound().getY())); 180 | 181 | if (currentDistance <= smallerDistance) { 182 | smallerDistance = currentDistance; 183 | enemy = e; 184 | } 185 | } 186 | return new Object[] { enemy, smallerDistance }; 187 | } 188 | 189 | public void update() { 190 | 191 | if (!playAsHuman) { 192 | 193 | 194 | Object[] nextEnemy = getNextEnemy(); 195 | 196 | double distance = (double) nextEnemy[1]; 197 | 198 | Enemy enemy = (Enemy) nextEnemy[0]; 199 | 200 | if (distance == 9999) 201 | return; 202 | 203 | neuralNetwork.getOutputs(new double[] { distance, enemy.getBound().getWidth(), enemy.getBound().getHeight(), enemy.getBound().getY(), Constants.SPEED, posY }); 204 | 205 | boolean jump = neuralNetwork.neurons[2][0] > 0.5; 206 | boolean squat = neuralNetwork.neurons[2][1] > 0.5; 207 | boolean useAirplane = neuralNetwork.neurons[2][2] > 0.5; 208 | 209 | if (useAirplane) { 210 | down(false); 211 | airPlane.use(); 212 | } 213 | 214 | if (!airPlane.isUsing()) { 215 | if (jump) 216 | jump(); 217 | 218 | if (squat) 219 | down(true); 220 | } else { 221 | //if (squat) { 222 | //airPlane.stopUsing(); 223 | //} 224 | } 225 | 226 | 227 | } 228 | 229 | normalRunAnim.updateFrame(); 230 | downRunAnim.updateFrame(); 231 | 232 | if (posY >= LAND_POSY) { 233 | posY = LAND_POSY; 234 | if (!airPlane.isUsing()) { 235 | if (state != DOWN_RUN) { 236 | state = NORMAL_RUN; 237 | } 238 | } else { 239 | state = AIRPLANE; 240 | } 241 | } else { 242 | if (!airPlane.isUsing()) { 243 | speedY += GRAVITY; 244 | posY += speedY; 245 | } 246 | } 247 | } 248 | 249 | public Dinosaur playAsHuman() { 250 | playAsHuman = !playAsHuman; 251 | return this; 252 | } 253 | 254 | public boolean isPlayingAsHuman() { 255 | return playAsHuman; 256 | } 257 | 258 | public void jump() { 259 | if (posY >= LAND_POSY) { 260 | speedY = -8f; 261 | posY += speedY; 262 | state = JUMPING; 263 | } 264 | } 265 | 266 | public void down(boolean isDown) { 267 | if (airPlane.isUsing()) 268 | return; 269 | 270 | speedY = 4f; 271 | posY += speedY; 272 | state = isDown ? DOWN_RUN : NORMAL_RUN; 273 | } 274 | 275 | public Rectangle getBound() { 276 | rectBound = new Rectangle(); 277 | if (state == DOWN_RUN) { 278 | rectBound.x = (int) posX + 5; 279 | rectBound.y = (int) posY + 20; 280 | rectBound.width = downRunAnim.getFrame().getWidth() - 10; 281 | rectBound.height = downRunAnim.getFrame().getHeight(); 282 | } else { 283 | rectBound.x = (int) posX + 5; 284 | rectBound.y = (int) posY; 285 | rectBound.width = normalRunAnim.getFrame().getWidth() - 10; 286 | rectBound.height = normalRunAnim.getFrame().getHeight(); 287 | } 288 | return rectBound; 289 | } 290 | 291 | public void reset() { 292 | posY = LAND_POSY; 293 | score = 0; 294 | airPlane.reset(); 295 | alive = true; 296 | } 297 | 298 | public void upScore(int up) { 299 | if (isAlive()) { 300 | score += up; 301 | 302 | if (score > ChromeDino.getGameScreen().getBestScore()) { 303 | ChromeDino.getGameScreen().bestScore = score; 304 | ChromeDino.getGameScreen().bestDistance = ChromeDino.getGameScreen().getLand().getScreenWidth(); 305 | ChromeDino.getGameScreen().bestDinosaur = this; 306 | } 307 | } 308 | } 309 | 310 | } 311 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/enemies/EnemiesManager.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.enemies; 2 | 3 | import java.awt.Graphics; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | import java.util.Random; 7 | 8 | import chromedino.ChromeDino; 9 | import chromedino.display.objects.Dinosaur; 10 | import chromedino.display.objects.enemies.entities.Bird; 11 | import chromedino.display.objects.enemies.entities.Cactus; 12 | import chromedino.display.objects.enemies.entities.Spike; 13 | import chromedino.display.objects.enemies.model.Enemy; 14 | 15 | public class EnemiesManager { 16 | 17 | private List enemies = new ArrayList(); 18 | 19 | private Enemy nextEnemy = null; 20 | private Enemy bird, cactus, /*cactus2, cactus3,*/ spike; 21 | 22 | private Random random = new Random(); 23 | 24 | public EnemiesManager() { 25 | reset(); 26 | } 27 | 28 | public void update() { 29 | bird.update(); 30 | cactus.update(); 31 | //cactus2.update(); 32 | //cactus3.update(); 33 | spike.update(); 34 | 35 | Enemy enemy = enemies.get(0); 36 | 37 | if (nextEnemy == null) { 38 | nextEnemy = createEnemy(enemy); 39 | 40 | if (nextEnemy instanceof Spike) { 41 | //Enemy lastEnemy = enemies.set(1, nextEnemy); 42 | enemies.add(nextEnemy); 43 | nextEnemy = null; 44 | } 45 | } 46 | 47 | if (enemy.isOutOfScreen()) { 48 | for (Dinosaur dinosaur : ChromeDino.getGameScreen().getDinosaurs()) { 49 | dinosaur.upScore(enemy.score()); 50 | } 51 | 52 | enemy.reset(); 53 | enemies.remove(enemy); 54 | 55 | if (nextEnemy != null) { 56 | enemies.add(nextEnemy); 57 | //enemies.add(cactus2); 58 | //enemies.add(cactus3); 59 | } 60 | nextEnemy = null; 61 | } 62 | } 63 | 64 | public void draw(Graphics g) { 65 | bird.draw(g); 66 | cactus.draw(g); 67 | //cactus2.draw(g); 68 | //cactus3.draw(g); 69 | spike.draw(g); 70 | } 71 | 72 | private Enemy createEnemy(Enemy enemy) { 73 | if (spike.appearRule()) 74 | return spike; 75 | 76 | if (enemy == null || enemy.isOutOfScreen()) { 77 | 78 | if (bird.appearRule()) 79 | return bird; 80 | 81 | if (cactus.appearRule()) 82 | return cactus; 83 | 84 | } 85 | 86 | return cactus; 87 | } 88 | 89 | public boolean isCollision(Dinosaur dinosaur) { 90 | for (Enemy e : enemies) { 91 | if (dinosaur.getBound().intersects(e.getBound())) { 92 | return true; 93 | } 94 | } 95 | return false; 96 | } 97 | 98 | public void reset() { 99 | nextEnemy = null; 100 | 101 | enemies.clear(); 102 | 103 | if (spike != null) { 104 | spike.reset(); 105 | } 106 | 107 | bird = new Bird(1280); 108 | cactus = new Cactus(1280 + random.nextInt(270)); 109 | //cactus2 = new Cactus(1707 + random.nextInt(270)); 110 | //cactus3 = new Cactus(1977 + random.nextInt(200)); 111 | spike = new Spike(1380); 112 | 113 | enemies = new ArrayList(); 114 | 115 | nextEnemy = createEnemy(null); 116 | 117 | enemies.add(nextEnemy); 118 | //enemies.add(cactus2); 119 | //enemies.add(cactus3); 120 | } 121 | 122 | public List getEnemies() { 123 | return enemies; 124 | } 125 | 126 | } 127 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/enemies/entities/Bird.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.enemies.entities; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Rectangle; 5 | import java.awt.image.BufferedImage; 6 | import java.util.Random; 7 | 8 | import chromedino.ChromeDino; 9 | import chromedino.constants.Constants; 10 | import chromedino.display.objects.enemies.model.Enemy; 11 | import chromedino.utils.Utils; 12 | 13 | public class Bird extends Enemy { 14 | 15 | public static int Y_LAND = 545; 16 | 17 | private int startX, posX, width, height; 18 | 19 | private BufferedImage image1, image2; 20 | 21 | private Rectangle rectBound; 22 | 23 | private Random random = new Random(); 24 | 25 | private boolean reseting = true; 26 | 27 | private boolean option1; 28 | 29 | public Bird(int posX) { 30 | this.startX = posX; 31 | this.posX = posX; 32 | 33 | image1 = Utils.getResouceImage("data/bird/bird1.png"); 34 | image2 = Utils.getResouceImage("data/bird/bird2.png"); 35 | 36 | this.width = image1.getWidth() - 10; 37 | this.height = image1.getHeight() - 10; 38 | 39 | rectBound = new Rectangle(); 40 | 41 | randomize(); 42 | } 43 | 44 | @Override 45 | public void update() { 46 | if (rectBound.getX() == 0 && reseting) 47 | return; 48 | 49 | double speed = Constants.SPEED * 1.6; 50 | 51 | posX -= speed; 52 | } 53 | 54 | @Override 55 | public void draw(Graphics g) { 56 | if (rectBound.getX() == 0 && reseting) 57 | return; 58 | 59 | g.drawImage(posX % 7 == 0 ? image2 : image1, posX, Y_LAND - image1.getHeight(), null); 60 | } 61 | 62 | @Override 63 | public Rectangle getBound() { 64 | rectBound = new Rectangle(); 65 | rectBound.x = posX + (image1.getWidth() - width) / 2; 66 | rectBound.y = Y_LAND - image1.getHeight() + (image1.getHeight() - height) / 2; 67 | rectBound.width = width; 68 | rectBound.height = height; 69 | reseting = false; 70 | return rectBound; 71 | } 72 | 73 | @Override 74 | public boolean isOutOfScreen() { 75 | if (posX < -image1.getWidth()) { 76 | return true; 77 | } 78 | return false; 79 | } 80 | 81 | @Override 82 | public int score() { 83 | return option1 ? 80 : 40; 84 | } 85 | 86 | @Override 87 | public boolean appearRule() { 88 | if (ChromeDino.getGameScreen() == null) 89 | return false; 90 | 91 | int width = ChromeDino.getGameScreen().getLand().getScreenWidth(); 92 | 93 | return width > 3000 && random.nextInt(100) <= 70; 94 | } 95 | 96 | @Override 97 | public void reset() { 98 | posX = startX; 99 | rectBound = new Rectangle(); 100 | randomize(); 101 | reseting = true; 102 | } 103 | 104 | private void randomize() { 105 | if (random.nextInt(100) <= 70) 106 | Y_LAND = 635; 107 | } 108 | 109 | } 110 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/enemies/entities/Cactus.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.enemies.entities; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Rectangle; 5 | import java.awt.image.BufferedImage; 6 | import java.util.ArrayList; 7 | import java.util.Random; 8 | 9 | import chromedino.ChromeDino; 10 | import chromedino.constants.Constants; 11 | import chromedino.display.objects.enemies.model.Enemy; 12 | import chromedino.utils.Utils; 13 | 14 | public class Cactus extends Enemy { 15 | 16 | public static final int Y_LAND = 660; 17 | 18 | private int startX, backupX, posX, width, height; 19 | 20 | private ArrayList images = new ArrayList<>(); 21 | 22 | private BufferedImage currentImage; 23 | 24 | private Rectangle rectBound; 25 | 26 | private Random random = new Random(); 27 | 28 | private boolean reseting = true; 29 | 30 | private boolean showing = true; 31 | 32 | public Cactus(int posX) { 33 | this.startX = posX; 34 | this.posX = posX; 35 | this.backupX = posX; 36 | 37 | for (int i = 0; i < 5; i++) { 38 | images.add(Utils.getResouceImage("data/enemies/cactus/cactus" + i + ".bmp")); 39 | } 40 | 41 | rectBound = new Rectangle(); 42 | 43 | randomize(); 44 | } 45 | 46 | @Override 47 | public void update() { 48 | if (!showing && ChromeDino.getGameScreen().getEnimiesManager().getEnemies().get(0) instanceof Cactus) { 49 | showing = true; 50 | } 51 | 52 | if ((rectBound.getX() == 0 && reseting) || (!showing)) 53 | return; 54 | 55 | posX -= Constants.SPEED; 56 | } 57 | 58 | @Override 59 | public void draw(Graphics g) { 60 | if ((rectBound.getX() == 0 && reseting) || (!showing)) 61 | return; 62 | 63 | g.drawImage(currentImage, posX, Y_LAND - currentImage.getHeight(), null); 64 | } 65 | 66 | @Override 67 | public Rectangle getBound() { 68 | rectBound = new Rectangle(); 69 | rectBound.x = posX + currentImage.getWidth(); 70 | rectBound.y = Y_LAND - currentImage.getHeight(); 71 | rectBound.width = width; 72 | rectBound.height = height; 73 | reseting = false; 74 | return rectBound; 75 | } 76 | 77 | @Override 78 | public boolean isOutOfScreen() { 79 | if (posX < -currentImage.getWidth()) { 80 | return true; 81 | } 82 | return false; 83 | } 84 | 85 | @Override 86 | public int score() { 87 | return 10; 88 | } 89 | 90 | @Override 91 | public boolean appearRule() { 92 | return true; 93 | } 94 | 95 | @Override 96 | public void reset() { 97 | posX = startX; 98 | rectBound = new Rectangle(); 99 | randomize(); 100 | reseting = true; 101 | showing = true; 102 | } 103 | 104 | private void randomize() { 105 | currentImage = images.get(random.nextInt(images.size() - 1)); 106 | 107 | startX = (int) (backupX + random.nextInt(270)); 108 | 109 | this.width = currentImage.getWidth() - 10; 110 | this.height = currentImage.getHeight() - 10; 111 | } 112 | 113 | public void setStartX(int startX) { 114 | this.startX = startX; 115 | } 116 | 117 | public void setShowing(boolean showing) { 118 | this.showing = showing; 119 | } 120 | 121 | public boolean isShowing() { 122 | return showing; 123 | } 124 | 125 | } 126 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/enemies/entities/Spike.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.enemies.entities; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Rectangle; 5 | import java.awt.image.BufferedImage; 6 | import java.util.ArrayList; 7 | 8 | import chromedino.ChromeDino; 9 | import chromedino.constants.Constants; 10 | import chromedino.display.objects.AirPlane; 11 | import chromedino.display.objects.enemies.model.Enemy; 12 | import chromedino.utils.Utils; 13 | 14 | public class Spike extends Enemy { 15 | 16 | public static final int Y_LAND = 672; 17 | 18 | private int startX, posX, width, height; 19 | 20 | private BufferedImage image; 21 | 22 | private Rectangle rectBound; 23 | 24 | private int appers = 0; 25 | 26 | private boolean reseting = true; 27 | 28 | public Spike(int posX) { 29 | this.startX = posX; 30 | this.posX = posX; 31 | this.image = Utils.getResouceImage("data/enemies/spike/spike.png"); 32 | 33 | this.width = image.getWidth() - 10; 34 | this.height = image.getHeight() - 10; 35 | 36 | rectBound = new Rectangle(); 37 | } 38 | 39 | @Override 40 | public void update() { 41 | if (rectBound.getX() == 0 && reseting) 42 | return; 43 | 44 | posX -= Constants.SPEED; 45 | 46 | removeNearObjects(); 47 | } 48 | 49 | @Override 50 | public void draw(Graphics g) { 51 | if (rectBound.getX() == 0 && reseting) 52 | return; 53 | 54 | g.drawImage(image, posX, Y_LAND - image.getHeight(), null); 55 | } 56 | 57 | @Override 58 | public Rectangle getBound() { 59 | rectBound = new Rectangle(); 60 | rectBound.x = posX + (image.getWidth() - width) / 2; 61 | rectBound.y = Y_LAND - image.getHeight() + (image.getHeight() - height) / 2; 62 | rectBound.width = width; 63 | rectBound.height = height; 64 | reseting = false; 65 | return rectBound; 66 | } 67 | 68 | @Override 69 | public boolean isOutOfScreen() { 70 | if (posX < -image.getWidth()) { 71 | return true; 72 | } 73 | return false; 74 | } 75 | 76 | @Override 77 | public int score() { 78 | return 20; 79 | } 80 | 81 | @Override 82 | public boolean appearRule() { 83 | if (ChromeDino.getGameScreen() == null) 84 | return false; 85 | 86 | int width = ChromeDino.getGameScreen().getLand().getScreenWidth(); 87 | 88 | int dif = width / AirPlane.CHARGING_RATE; 89 | 90 | if (width > 3000 && dif > appers) { 91 | appers = dif; 92 | return true; 93 | } 94 | 95 | return false; 96 | } 97 | 98 | @Override 99 | public void reset() { 100 | posX = startX; 101 | rectBound = new Rectangle(); 102 | reseting = true; 103 | } 104 | 105 | private void removeNearObjects() { 106 | boolean hasSpike = false, outOfScreen = isOutOfScreen(); 107 | 108 | for (Enemy e : ChromeDino.getGameScreen().getEnimiesManager().getEnemies()) { 109 | if (e instanceof Spike) { 110 | hasSpike = true; 111 | } 112 | 113 | if (outOfScreen && e instanceof Cactus && !((Cactus)e).isShowing()) { 114 | ((Cactus)e).setShowing(true); 115 | } 116 | } 117 | 118 | if (outOfScreen) 119 | return; 120 | 121 | if (hasSpike) { 122 | ArrayList remove = new ArrayList<>(); 123 | ChromeDino.getGameScreen().getEnimiesManager().getEnemies().forEach(e -> { 124 | if (e instanceof Cactus) { 125 | double x = getBound().getX() - 50; 126 | 127 | if (e.getBound().getX() + e.getBound().getWidth() >= x && e.getBound().getX() <= x + getBound().getWidth() + 100) { 128 | e.reset(); 129 | ((Cactus) e).setShowing(false); 130 | remove.add(e); 131 | } 132 | } else if (e instanceof Bird) { 133 | double x = getBound().getX() - 50; 134 | 135 | if (e.getBound().getX() + e.getBound().getWidth() >= x && e.getBound().getX() <= x + getBound().getWidth() + 100) { 136 | e.reset(); 137 | remove.add(e); 138 | } 139 | } 140 | }); 141 | 142 | ChromeDino.getGameScreen().getEnimiesManager().getEnemies().removeAll(remove); 143 | } 144 | } 145 | } 146 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/enemies/model/Enemy.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.enemies.model; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Rectangle; 5 | 6 | public abstract class Enemy { 7 | 8 | public abstract void update(); 9 | 10 | public abstract void draw(Graphics g); 11 | 12 | public abstract Rectangle getBound(); 13 | 14 | public abstract boolean isOutOfScreen(); 15 | 16 | public abstract int score(); 17 | 18 | public abstract boolean appearRule(); 19 | 20 | public abstract void reset(); 21 | 22 | } 23 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/scenario/Clouds.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.scenario; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.image.BufferedImage; 5 | import java.util.ArrayList; 6 | import java.util.Random; 7 | 8 | import chromedino.constants.Constants; 9 | import chromedino.utils.Utils; 10 | 11 | public class Clouds { 12 | 13 | private static final int LAND_POSY = 300; 14 | private static final int CLOUDS_QUANTITY = 8; 15 | 16 | private BufferedImage image; 17 | private ArrayList listClouds = new ArrayList<>(); 18 | 19 | private int width; 20 | 21 | private Random random; 22 | 23 | public Clouds(int width) { 24 | this.width = width; 25 | 26 | random = new Random(); 27 | 28 | image = Utils.getResouceImage("data/scenario/cloud/cloud.png"); 29 | 30 | int currentWidth = 0; 31 | 32 | int currency = width / CLOUDS_QUANTITY; 33 | 34 | for (int i = 0; i < CLOUDS_QUANTITY; i++) { 35 | ImageCoud imageLand = new ImageCoud(); 36 | imageLand.image = image; 37 | imageLand.posX = currentWidth; 38 | imageLand.posY = LAND_POSY + random.nextInt(300); 39 | 40 | listClouds.add(imageLand); 41 | 42 | currentWidth += currency; 43 | } 44 | 45 | } 46 | 47 | public void update() { 48 | listClouds.forEach(imageCloud -> { 49 | 50 | imageCloud.posX -= (Constants.SPEED / 20); 51 | 52 | if (imageCloud.posX <= 0) { 53 | imageCloud.posX = width; 54 | } 55 | }); 56 | } 57 | 58 | public void draw(Graphics g) { 59 | try { 60 | for (ImageCoud imgCloud : listClouds) { 61 | g.drawImage(imgCloud.image, (int) imgCloud.posX, imgCloud.posY, null); 62 | } 63 | } catch (Exception e) { 64 | 65 | } 66 | } 67 | 68 | private class ImageCoud { 69 | float posX; 70 | int posY; 71 | BufferedImage image; 72 | } 73 | 74 | } 75 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/scenario/Land.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.scenario; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.image.BufferedImage; 5 | import java.util.ArrayList; 6 | 7 | import chromedino.constants.Constants; 8 | import chromedino.utils.Utils; 9 | 10 | public class Land { 11 | 12 | public static final int LAND_POSY = 650; 13 | 14 | private ArrayList images = new ArrayList<>(); 15 | private ArrayList listLand = new ArrayList<>(); 16 | 17 | private int screenWidth; 18 | 19 | private int width; 20 | 21 | public Land(int width) { 22 | this.width = width; 23 | 24 | for (int i = 0; i < 6; i++) { 25 | images.add(Utils.getResouceImage("data/scenario/land/land" + i + ".bmp")); 26 | } 27 | 28 | int currentWidth = 0, counter = 0; 29 | 30 | while (currentWidth < width) { 31 | ImageLand imageLand = new ImageLand(); 32 | imageLand.image = images.get(counter); 33 | imageLand.posX = currentWidth; 34 | 35 | listLand.add(imageLand); 36 | 37 | counter++; 38 | currentWidth += imageLand.image.getWidth(); 39 | 40 | if (counter == images.size()) 41 | counter = 0; 42 | } 43 | 44 | } 45 | 46 | public void update() { 47 | 48 | for (int i = 0; i < Constants.SPEED; i++) { 49 | listLand.forEach(imageLand -> { 50 | if (imageLand.posX - 1 <= 0) { 51 | imageLand.posX = width; 52 | } else { 53 | imageLand.posX -= 1; 54 | } 55 | }); 56 | } 57 | 58 | screenWidth += Constants.SPEED; 59 | } 60 | 61 | public int getScreenWidth() { 62 | return screenWidth; 63 | } 64 | 65 | public void reset() { 66 | screenWidth = 0; 67 | } 68 | 69 | public void draw(Graphics g) { 70 | try { 71 | for (ImageLand imgLand : listLand) { 72 | g.drawImage(imgLand.image, (int) imgLand.posX, LAND_POSY, null); 73 | } 74 | } catch (Exception e) { 75 | 76 | } 77 | } 78 | 79 | private class ImageLand { 80 | float posX; 81 | BufferedImage image; 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/display/objects/scenario/Montain.java: -------------------------------------------------------------------------------- 1 | package chromedino.display.objects.scenario; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.image.BufferedImage; 5 | import java.util.ArrayList; 6 | 7 | import chromedino.constants.Constants; 8 | import chromedino.utils.Utils; 9 | 10 | public class Montain { 11 | 12 | public static final int LAND_POSY = 475; 13 | 14 | private ArrayList images = new ArrayList<>(); 15 | private ArrayList listMontain = new ArrayList<>(); 16 | 17 | private int width; 18 | 19 | public Montain(int width) { 20 | this.width = width; 21 | 22 | for (int i = 0; i < 6; i++) { 23 | images.add(Utils.getResouceImage("data/scenario/montain/montain" + i + ".bmp")); 24 | } 25 | 26 | build(0); 27 | build(2); 28 | build(4); 29 | } 30 | 31 | private void build(int montainId) { 32 | int currentWidth = 0, counter = 0; 33 | 34 | while (currentWidth < width) { 35 | ImageMontain imageMontain = new ImageMontain(); 36 | imageMontain.image = images.get(montainId + counter); 37 | 38 | imageMontain.posX = currentWidth; 39 | imageMontain.type = montainId; 40 | 41 | listMontain.add(imageMontain); 42 | 43 | counter++; 44 | currentWidth += imageMontain.image.getWidth(); 45 | 46 | if (counter == 2) 47 | counter = 0; 48 | } 49 | } 50 | 51 | public void update() { 52 | listMontain.forEach(imageMontain -> { 53 | 54 | if (imageMontain.posX <= -imageMontain.image.getWidth()) { 55 | imageMontain.posX = imageMontain.image.getWidth(); 56 | } 57 | 58 | for (int i = 0; i < Constants.SPEED / 100; i++) { 59 | if (imageMontain.type == 0) 60 | imageMontain.posX -= 0.5; 61 | 62 | if (imageMontain.type == 2) 63 | imageMontain.posX -= 1; 64 | 65 | if (imageMontain.type == 4) 66 | imageMontain.posX -= 1.5; 67 | } 68 | 69 | }); 70 | } 71 | 72 | public void draw(Graphics g) { 73 | try { 74 | for (ImageMontain imageMontain : listMontain) { 75 | g.drawImage(imageMontain.image, (int) imageMontain.posX, LAND_POSY, null); 76 | } 77 | } catch (Exception e) { 78 | 79 | } 80 | } 81 | 82 | private class ImageMontain { 83 | int type; 84 | float posX; 85 | BufferedImage image; 86 | } 87 | 88 | } 89 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/image_tools/ImageTool.java: -------------------------------------------------------------------------------- 1 | package chromedino.image_tools; 2 | 3 | import java.awt.Color; 4 | import java.awt.Graphics; 5 | import java.awt.image.BufferedImage; 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import javax.imageio.ImageIO; 10 | 11 | public class ImageTool { 12 | 13 | private static final int THRESHOLD = 35, TRANSPARENT = 0; // 0x00000000; 14 | 15 | private File inputFile, outputFile; 16 | 17 | private BufferedImage outputImage; 18 | 19 | public ImageTool(File inputFile) { 20 | this.inputFile = inputFile; 21 | } 22 | 23 | public void setOutputFile(File outputFile) { 24 | this.outputFile = outputFile; 25 | } 26 | 27 | public void removeColor(Color replaceColor) { 28 | try { 29 | 30 | if (outputImage == null) 31 | outputImage = ImageIO.read(inputFile); 32 | 33 | int width = outputImage.getWidth(null), height = outputImage.getHeight(null); 34 | 35 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 36 | 37 | Graphics g = image.getGraphics(); 38 | 39 | g.drawImage(outputImage, 0, 0, null); 40 | 41 | for (int y = 0; y < height; y++) { 42 | for (int x = 0; x < width; x++) { 43 | int pixel = image.getRGB(x, y); 44 | Color color = new Color(pixel); 45 | 46 | int dr = Math.abs(color.getRed() - replaceColor.getRed()), dg = Math.abs(color.getGreen() - replaceColor.getGreen()), db = Math.abs(color.getBlue() - replaceColor.getBlue()); 47 | 48 | if (dr < THRESHOLD && dg < THRESHOLD && db < THRESHOLD) { 49 | image.setRGB(x, y, TRANSPARENT); 50 | } 51 | } 52 | } 53 | 54 | outputImage = image; 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | public void changeColor(Color oldColor, Color newColor) { 61 | try { 62 | if (outputImage == null) 63 | outputImage = ImageIO.read(inputFile); 64 | 65 | int RGB_MASK = 0x00ffffff; 66 | 67 | int oldRGB = oldColor.getRed() << 16 | oldColor.getGreen() << 8 | oldColor.getBlue(); 68 | int toggleRGB = oldRGB ^ (newColor.getRed() << 16 | newColor.getGreen() << 8 | newColor.getBlue()); 69 | 70 | int w = outputImage.getWidth(); 71 | int h = outputImage.getHeight(); 72 | 73 | int[] rgb = outputImage.getRGB(0, 0, w, h, null, 0, w); 74 | for (int i = 0; i < rgb.length; i++) { 75 | if ((rgb[i] & RGB_MASK) == oldRGB) { 76 | rgb[i] ^= toggleRGB; 77 | } 78 | } 79 | outputImage.setRGB(0, 0, w, h, rgb, 0, w); 80 | 81 | } catch (Exception e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | 86 | public BufferedImage getImage() { 87 | return outputImage; 88 | } 89 | 90 | public void save(String fileType) throws Exception { 91 | if (outputFile == null) 92 | throw new Exception("The output file is null."); 93 | 94 | try { 95 | ImageIO.write(outputImage, fileType, outputFile); 96 | } catch (IOException e) { 97 | e.printStackTrace(); 98 | } 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/neuralnetwork/LiveView.java: -------------------------------------------------------------------------------- 1 | package chromedino.neuralnetwork; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Graphics2D; 6 | import java.awt.RenderingHints; 7 | import java.text.DecimalFormat; 8 | 9 | public class LiveView { 10 | 11 | public static void paintNeuralNetwork(Graphics2D g, NeuralNetwork neuralNetwork) { 12 | nn = neuralNetwork; 13 | 14 | boolean jump = nn.neurons[2][0] > 0.5; 15 | boolean squat = nn.neurons[2][1] > 0.5; 16 | boolean useAirplane = nn.neurons[2][2] > 0.5; 17 | 18 | g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 19 | 20 | for (int i = 0; i < nn.layers_amount; i++) { 21 | int currentNeuronHeight = (nn.neurons_amount[i] - 1) * VERTICAL_SPACE_BETWEEN_NEURONS + nn.neurons_amount[i] * NEURONS_DIAMETER + PANEL_PADDING * 2; 22 | int topMargin = (height - currentNeuronHeight) / 2; 23 | 24 | // Draw neurons[i] 25 | for (int l = 0; l < nn.neurons_amount[i]; l++) { 26 | // Draw synapses[current_genome][i][l] 27 | g.setColor(Color.LIGHT_GRAY); 28 | 29 | if (i > 0) { 30 | if (l + 1 < nn.neurons_amount[i] && nn.neurons[i][l] > 0.5 && nn.neurons[i][l + 1] > 0.5) { 31 | g.setColor(Color.decode("#FFC3C3")); 32 | } 33 | } else { 34 | if (i + 1 < nn.layers_amount && nn.neurons[i + 1][l] > 0.5) { 35 | g.setColor(Color.decode("#FFC3C3")); 36 | } 37 | } 38 | 39 | g.setFont(new Font("Arial", Font.PLAIN, 12)); 40 | 41 | if (i != nn.layers_amount - 1) { 42 | int nextNeuronHeight = (nn.neurons_amount[i + 1] - 1) * VERTICAL_SPACE_BETWEEN_NEURONS + nn.neurons_amount[i + 1] * NEURONS_DIAMETER + PANEL_PADDING * 2; // Height of the next neurons (including paddings) 43 | int nextTopMargin = (height - nextNeuronHeight) / 2, m; 44 | 45 | if (i + 1 != nn.layers_amount - 1) { 46 | m = nn.neurons_amount[i + 1] - 1; 47 | } else { 48 | m = nn.neurons_amount[i + 1]; 49 | } 50 | 51 | for (int n = 0; n < m; n++) { 52 | g.drawLine(baseX + NEURONS_DIAMETER / 2 + PANEL_PADDING + NEURONS_DIAMETER * i + HORIZONTAL_SPACE_BETWEEN_NEURONS * i, baseY + NEURONS_DIAMETER / 2 + PANEL_PADDING + topMargin + NEURONS_DIAMETER * l + VERTICAL_SPACE_BETWEEN_NEURONS * l, baseX + NEURONS_DIAMETER / 2 + PANEL_PADDING + NEURONS_DIAMETER * (i + 1) + HORIZONTAL_SPACE_BETWEEN_NEURONS * (i + 1), baseY + nextTopMargin - topMargin + NEURONS_DIAMETER / 2 + PANEL_PADDING + topMargin + NEURONS_DIAMETER * n + VERTICAL_SPACE_BETWEEN_NEURONS * n); 53 | } 54 | } 55 | 56 | g.setColor(Color.LIGHT_GRAY); 57 | 58 | if (i > 0) { 59 | if (nn.neurons[i][l] > 0.5) 60 | g.setColor(activeColor); 61 | } else { 62 | 63 | if (nn.neurons[i + 1][l] > 0.5) 64 | g.setColor(activeColor); 65 | 66 | String value = getTitle(l); 67 | 68 | g.setColor(Color.BLACK); 69 | g.setFont(new Font("Arial", Font.PLAIN, 12)); 70 | 71 | value += df.format(nn.neurons[i][l]); 72 | 73 | g.drawString(value, baseX - 200, baseY + NEURONS_DIAMETER / 2 + 7 + PANEL_PADDING + topMargin + NEURONS_DIAMETER * l + VERTICAL_SPACE_BETWEEN_NEURONS * l); 74 | 75 | g.setColor(Color.LIGHT_GRAY); 76 | } 77 | 78 | if (i == nn.layers_amount - 1) { 79 | 80 | if (l == 0 && jump) { 81 | g.setColor(activeColor); 82 | } else if (l == 1 && squat) { 83 | g.setColor(activeColor); 84 | } else if (l == 2 && useAirplane) { 85 | g.setColor(activeColor); 86 | } 87 | 88 | } 89 | 90 | g.fillOval(baseX + PANEL_PADDING + NEURONS_DIAMETER * i + HORIZONTAL_SPACE_BETWEEN_NEURONS * i, baseY + PANEL_PADDING + topMargin + NEURONS_DIAMETER * l + VERTICAL_SPACE_BETWEEN_NEURONS * l, NEURONS_DIAMETER, NEURONS_DIAMETER); 91 | } 92 | } 93 | 94 | g.setColor(Color.LIGHT_GRAY); 95 | 96 | g.setFont(new Font("Arial", Font.PLAIN, 15)); 97 | if (jump) 98 | g.setColor(activeColor); 99 | g.drawString("Jump", baseX + width + PANEL_PADDING + 100, baseY - 20); 100 | 101 | g.setColor(Color.LIGHT_GRAY); 102 | 103 | if (squat) 104 | g.setColor(activeColor); 105 | g.drawString("Down", baseX + width + PANEL_PADDING + 100, baseY + (height / 2) + 5); 106 | 107 | g.setColor(Color.LIGHT_GRAY); 108 | 109 | if (useAirplane) 110 | g.setColor(activeColor); 111 | 112 | g.drawString("Airplane", baseX + width + PANEL_PADDING + 100, baseY + (height / 2) + 30); 113 | 114 | g.setColor(Color.LIGHT_GRAY); 115 | } 116 | 117 | private static String getTitle(int l) { 118 | String value = ""; 119 | 120 | if (l == 0) 121 | value = "Distance: "; 122 | if (l == 1) 123 | value = "Width [Obst]: "; 124 | if (l == 2) 125 | value = "Height [Obst]: "; 126 | if (l == 3) 127 | value = "Vertical Position [Obst]: "; 128 | if (l == 4) 129 | value = "Speed: "; 130 | if (l == 5) 131 | value = "Vertical Position: "; 132 | 133 | return value; 134 | } 135 | 136 | private static NeuralNetwork nn; 137 | 138 | private static DecimalFormat df = new DecimalFormat("#0.00"); 139 | private static Color activeColor = Color.decode("#FF6C6C"); 140 | 141 | private static final int NEURONS_DIAMETER = 15, HORIZONTAL_SPACE_BETWEEN_NEURONS = 15, VERTICAL_SPACE_BETWEEN_NEURONS = 10, PANEL_PADDING = 5; 142 | private static int width, height, baseX = 800, baseY = 130; 143 | 144 | 145 | } -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/neuralnetwork/NeuralNetwork.java: -------------------------------------------------------------------------------- 1 | package chromedino.neuralnetwork; 2 | 3 | import static java.lang.Math.exp; 4 | 5 | import java.io.IOException; 6 | import java.util.Random; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | import chromedino.constants.Constants; 11 | 12 | public class NeuralNetwork { 13 | 14 | protected int layers_amount; 15 | private double fits[]; // [genome_index] 16 | protected int neurons_amount[]; // [layer_index]. Must be >= 2 (inputs and outputs). This is also used to 17 | // calculate the synapses amount 18 | private double inputs[]; 19 | public double neurons[][]; // [layer_index][neuron_index] 20 | protected double synapses[][][][]; // [genome_index][layer_index][neuron_index][synapses_index] 21 | public int genomes_per_generation; 22 | public int current_genome = 0; 23 | public int current_generation = 0; 24 | private double random_mutation_probability; 25 | private double min_weight, max_weight; 26 | 27 | private SaveLoad save_load; 28 | 29 | public NeuralNetwork(int dinosaurId, int neurons_amount[], int genomes_per_generation, double random_mutation_probability, double min_weight, double max_weight) { 30 | // Copy costructor parameters 31 | 32 | this.neurons_amount = neurons_amount; 33 | this.genomes_per_generation = genomes_per_generation; 34 | this.random_mutation_probability = random_mutation_probability; 35 | this.min_weight = min_weight; 36 | this.max_weight = max_weight; 37 | 38 | layers_amount = neurons_amount.length; 39 | 40 | // Create fits array 41 | fits = new double[genomes_per_generation]; 42 | 43 | // Generate neurons 44 | neurons = new double[layers_amount][]; 45 | for (int i = 0; i < layers_amount; i++) { 46 | if (i != layers_amount - 1) { 47 | neurons_amount[i]++; // The last neuron is the bias. 48 | } 49 | neurons[i] = new double[neurons_amount[i]]; 50 | } 51 | 52 | // Set biases to 1 53 | for (int i = 0; i < layers_amount - 1; i++) { 54 | neurons[i][neurons_amount[i] - 1] = 1; 55 | } 56 | 57 | // Generate synapses 58 | synapses = new double[genomes_per_generation][][][]; 59 | for (int k = 0; k < genomes_per_generation; k++) { 60 | synapses[k] = new double[layers_amount - 1][][]; 61 | for (int i = 0; i < layers_amount - 1; i++) { 62 | synapses[k][i] = new double[neurons_amount[i]][]; 63 | for (int j = 0; j < neurons_amount[i]; j++) { 64 | if (i + 1 != layers_amount - 1) { 65 | synapses[k][i][j] = new double[neurons_amount[i + 1] - 1]; 66 | } else { 67 | synapses[k][i][j] = new double[neurons_amount[i + 1]]; 68 | } 69 | } 70 | } 71 | } 72 | 73 | save_load = new SaveLoad(this); 74 | 75 | // If the file exists, load it. Else, init randomly 76 | if (save_load.fileExists()) { 77 | try { 78 | save_load.loadFromFile(); 79 | 80 | if (!Constants.BATTLE_MODE) { 81 | crossover(); 82 | } 83 | } catch (IOException ex) { 84 | Logger.getLogger(NeuralNetwork.class.getName()).log(Level.SEVERE, null, ex); 85 | } 86 | } else { 87 | initSynapsesRandomly(); 88 | } 89 | } 90 | 91 | private void initSynapsesRandomly() { 92 | for (int l = 0; l < genomes_per_generation; l++) { 93 | for (int i = 0; i < layers_amount - 1; i++) { 94 | for (int j = 0; j < neurons_amount[i]; j++) { 95 | int m; 96 | if (i + 1 != layers_amount - 1) { 97 | m = neurons_amount[i + 1] - 1; 98 | } else { 99 | m = neurons_amount[i + 1]; 100 | } 101 | for (int k = 0; k < m; k++) { 102 | synapses[l][i][j][k] = randDouble(min_weight, max_weight); 103 | } 104 | } 105 | } 106 | } 107 | } 108 | 109 | public SaveLoad getSaveLoad() { 110 | return save_load; 111 | } 112 | 113 | public double[] getOutputs(double inputs[]) { 114 | // Copy function parameters 115 | this.inputs = inputs; 116 | 117 | setNeuronsValues(); 118 | 119 | // Return outputs 120 | return neurons[layers_amount - 1]; 121 | } 122 | 123 | public void newGenome(double current_genome_fit) { 124 | // Set current genome fit 125 | fits[current_genome] = current_genome_fit; 126 | 127 | // If all genomes have been executed, create a new generation 128 | if (current_genome + 1 == genomes_per_generation) { 129 | current_genome = 0; 130 | newGeneration(); 131 | } else { 132 | current_genome++; 133 | } 134 | } 135 | 136 | private void newGeneration() { 137 | boolean no_progress = true; 138 | 139 | // Check if the NN made any progress 140 | for (int i = 0; i < genomes_per_generation; i++) { 141 | if (fits[i] != 0) { 142 | no_progress = false; 143 | break; 144 | } 145 | } 146 | 147 | if (no_progress) { 148 | initSynapsesRandomly(); 149 | } else { 150 | crossover(); 151 | } 152 | 153 | current_generation++; 154 | } 155 | 156 | private void crossover() { 157 | // Sort 158 | int j_max; 159 | double fit_temp, synapses_temp[][][]; 160 | for (int i = 0; i < genomes_per_generation - 1; i++) { 161 | j_max = i; 162 | for (int j = i + 1; j < genomes_per_generation; j++) { 163 | if (fits[j] > fits[j_max]) { 164 | j_max = j; 165 | } 166 | } 167 | if (j_max != i) { 168 | fit_temp = fits[i]; 169 | synapses_temp = synapses[i]; 170 | fits[i] = fits[j_max]; 171 | synapses[i] = synapses[j_max]; 172 | fits[j_max] = fit_temp; 173 | synapses[j_max] = synapses_temp; 174 | } 175 | } 176 | 177 | // The best genome is now the first. We mix it with all the other genomes 178 | double prob_rand; 179 | for (int l = 1; l < genomes_per_generation; l++) { 180 | for (int i = 0; i < layers_amount - 1; i++) { 181 | for (int j = 0; j < neurons_amount[i]; j++) { 182 | int m; 183 | if (i + 1 != layers_amount - 1) { 184 | m = neurons_amount[i + 1] - 1; 185 | } else { 186 | m = neurons_amount[i + 1]; 187 | } 188 | for (int k = 0; k < m; k++) { 189 | // If this genome made any progress, mix it with the first genome or generate a 190 | // new number randomly or keep the current value 191 | if (fits[l] != 0) { 192 | prob_rand = randDouble(0, 1); 193 | if (prob_rand < random_mutation_probability) { 194 | synapses[l][i][j][k] = randDouble(min_weight, max_weight); 195 | } else { 196 | prob_rand = randDouble(0, 1); 197 | if (prob_rand < 0.5) { 198 | synapses[l][i][j][k] = synapses[0][i][j][k]; 199 | } 200 | // Else keep the current value (implicit) 201 | } 202 | } 203 | // Else mix it with the first genome or generate a new number randomly 204 | else { 205 | prob_rand = randDouble(0, 1); 206 | if (prob_rand < random_mutation_probability) { 207 | synapses[l][i][j][k] = randDouble(min_weight, max_weight); 208 | } else { 209 | synapses[l][i][j][k] = synapses[0][i][j][k]; 210 | } 211 | } 212 | } 213 | } 214 | } 215 | } 216 | } 217 | 218 | private void setNeuronsValues() { 219 | // Copy inputs 220 | for (int i = 0; i < neurons_amount[0] - 1; i++) { 221 | neurons[0][i] = inputs[i]; 222 | } 223 | 224 | // Init the other neurons to 0 225 | for (int i = 1; i < layers_amount; i++) { 226 | int m; 227 | if (i + 1 != layers_amount) { 228 | m = neurons_amount[i] - 1; 229 | } else { 230 | m = neurons_amount[i]; 231 | } 232 | for (int j = 0; j < m; j++) { 233 | neurons[i][j] = 0; 234 | } 235 | } 236 | 237 | // Multiply neurons and synapses and sum the results (calculate the next neurons 238 | // values) 239 | for (int i = 1; i < layers_amount; i++) { 240 | int m; 241 | if (i != layers_amount - 1) { 242 | m = neurons_amount[i] - 1; 243 | } else { 244 | m = neurons_amount[i]; 245 | } 246 | for (int j = 0; j < m; j++) { 247 | for (int k = 0; k < neurons_amount[i - 1]; k++) { 248 | neurons[i][j] += neurons[i - 1][k] * synapses[current_genome][i - 1][k][j]; 249 | } 250 | 251 | // Activation function 252 | neurons[i][j] = sigmoid(neurons[i][j]); 253 | } 254 | } 255 | } 256 | 257 | private double sigmoid(double x) { 258 | return 1 / (1 + exp(-x)); 259 | } 260 | 261 | private double randDouble(double min, double max) { 262 | Random r = new Random(); 263 | return min + (max - min) * r.nextDouble(); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/neuralnetwork/SaveLoad.java: -------------------------------------------------------------------------------- 1 | package chromedino.neuralnetwork; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileOutputStream; 7 | import java.io.FileReader; 8 | import java.io.IOException; 9 | import java.io.PrintWriter; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | import chromedino.constants.Constants; 14 | 15 | public class SaveLoad { 16 | 17 | private final NeuralNetwork neuralNetwork; 18 | 19 | private String file_name = "data/synapses/"; 20 | private File file = new File(file_name); 21 | 22 | private boolean first_line = true; 23 | 24 | public SaveLoad(NeuralNetwork nn) { 25 | 26 | this.neuralNetwork = nn; 27 | } 28 | 29 | protected boolean fileExists() { 30 | updateFile(); 31 | 32 | return file.exists() && !file.isDirectory(); 33 | } 34 | 35 | public void saveToFile(int score) { 36 | if (Constants.BATTLE_MODE) 37 | return; 38 | 39 | int biggerScore = updateFile(); 40 | 41 | if (file != null && score >= biggerScore) { 42 | save(score, file); 43 | } 44 | } 45 | 46 | private int updateFile() { 47 | int bigger = 0; 48 | File current = null; 49 | for (File file : new File(file_name).listFiles()) { 50 | try { 51 | Integer lastScore = Integer.valueOf(file.getName().split("_")[0]); 52 | 53 | if (lastScore >= bigger) { 54 | current = file; 55 | bigger = lastScore; 56 | } 57 | } catch (Exception e) { 58 | e.printStackTrace(); 59 | } 60 | } 61 | 62 | if (current != null) 63 | file = current; 64 | 65 | return bigger; 66 | } 67 | 68 | private void save(int score, File lastFile) { 69 | this.file = new File(file_name + score + "_synapses.txt"); 70 | try { 71 | try (PrintWriter writer = new PrintWriter(new FileOutputStream(file, true))) { 72 | if (!first_line) { 73 | writer.print("\n"); 74 | } else { 75 | first_line = false; 76 | } 77 | 78 | // Append the current generation at the end of the file 79 | for (int l = 0; l < neuralNetwork.genomes_per_generation; l++) { 80 | for (int i = 0; i < neuralNetwork.layers_amount - 1; i++) { 81 | for (int j = 0; j < neuralNetwork.neurons_amount[i]; j++) { 82 | int m; 83 | if (i + 1 != neuralNetwork.layers_amount - 1) { 84 | m = neuralNetwork.neurons_amount[i + 1] - 1; 85 | } else { 86 | m = neuralNetwork.neurons_amount[i + 1]; 87 | } 88 | for (int k = 0; k < m; k++) { 89 | writer.print(neuralNetwork.synapses[l][i][j][k] + " "); 90 | } 91 | } 92 | } 93 | } 94 | } 95 | lastFile.delete(); 96 | } catch (Exception e) { 97 | e.printStackTrace(); 98 | } 99 | } 100 | 101 | protected void loadFromFile() throws FileNotFoundException, IOException { 102 | String current_line, last_generation = null; 103 | 104 | @SuppressWarnings("resource") 105 | BufferedReader reader = new BufferedReader(new FileReader(file)); 106 | 107 | // Get the last line and store it into last_generation 108 | while ((current_line = reader.readLine()) != null) { 109 | last_generation = current_line; 110 | } 111 | 112 | // Split the string and store the numbers (as text) 113 | List values = Arrays.asList(last_generation.trim().split(" ")); 114 | 115 | // Init the synapsis 116 | int n = 0; 117 | for (int l = 0; l < neuralNetwork.genomes_per_generation; l++) { 118 | for (int i = 0; i < neuralNetwork.layers_amount - 1; i++) { 119 | for (int j = 0; j < neuralNetwork.neurons_amount[i]; j++) { 120 | int m; 121 | if (i + 1 != neuralNetwork.layers_amount - 1) { 122 | m = neuralNetwork.neurons_amount[i + 1] - 1; 123 | } else { 124 | m = neuralNetwork.neurons_amount[i + 1]; 125 | } 126 | for (int k = 0; k < m; k++) { 127 | neuralNetwork.synapses[l][i][j][k] = Double.parseDouble(values.get(n)); 128 | n++; 129 | } 130 | } 131 | } 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/utils/Animation.java: -------------------------------------------------------------------------------- 1 | package chromedino.utils; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class Animation { 8 | 9 | private List list; 10 | private long deltaTime, previousTime; 11 | private int currentFrame = 0; 12 | 13 | public Animation(int deltaTime) { 14 | this.deltaTime = deltaTime; 15 | this.list = new ArrayList(); 16 | this.previousTime = 0; 17 | } 18 | 19 | public void updateFrame() { 20 | if (System.currentTimeMillis() - previousTime >= deltaTime) { 21 | currentFrame++; 22 | 23 | if (currentFrame >= list.size()) 24 | currentFrame = 0; 25 | 26 | previousTime = System.currentTimeMillis(); 27 | } 28 | } 29 | 30 | public void addFrame(BufferedImage image) { 31 | list.add(image); 32 | } 33 | 34 | public BufferedImage getFrame() { 35 | if (currentFrame == list.size()) 36 | return list.get(0); 37 | 38 | return list.get(currentFrame); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/chromedino/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package chromedino.utils; 2 | 3 | import java.awt.Color; 4 | import java.awt.image.BufferedImage; 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | import javax.imageio.ImageIO; 9 | 10 | import chromedino.image_tools.ImageTool; 11 | 12 | public class Utils { 13 | 14 | public static BufferedImage changeColor(File file, Color color) { 15 | ImageTool imageTool = new ImageTool(file); 16 | 17 | imageTool.changeColor(Color.WHITE, color); 18 | 19 | return imageTool.getImage(); 20 | } 21 | 22 | public static String compareTime(long current, long end) { 23 | long different = end - current; 24 | 25 | long secondsInMilli = 1000; 26 | long minutesInMilli = secondsInMilli * 60; 27 | long hoursInMilli = minutesInMilli * 60; 28 | long daysInMilli = hoursInMilli * 24; 29 | long mounthsInMilli = daysInMilli * 30; 30 | 31 | //long mounths = different / mounthsInMilli; 32 | different = different % mounthsInMilli; 33 | 34 | long days = different / daysInMilli; 35 | different = different % daysInMilli; 36 | 37 | long hours = different / hoursInMilli; 38 | different = different % hoursInMilli; 39 | 40 | long minutes = different / minutesInMilli; 41 | different = different % minutesInMilli; 42 | 43 | long seconds = different / secondsInMilli; 44 | 45 | return days + "d " + hours + "h " + minutes + "min " + seconds + " sec"; 46 | } 47 | 48 | public static BufferedImage getResouceImage(String path) { 49 | BufferedImage img = null; 50 | try { 51 | img = ImageIO.read(new File(path)); 52 | } catch (IOException e) { 53 | e.printStackTrace(); 54 | } 55 | return img; 56 | } 57 | 58 | } 59 | -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/airplane/airplane0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/airplane/airplane0.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/airplane/airplane1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/airplane/airplane1.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/bird/bird1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/bird/bird1.png -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/bird/bird2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/bird/bird2.png -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino0.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino1.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino2.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino3.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino4.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino5.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino6.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino6.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino7.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino7.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino8.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino8.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/dinosaur/dino9.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/dinosaur/dino9.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/enemies/cactus/cactus0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/enemies/cactus/cactus0.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/enemies/cactus/cactus1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/enemies/cactus/cactus1.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/enemies/cactus/cactus2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/enemies/cactus/cactus2.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/enemies/cactus/cactus3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/enemies/cactus/cactus3.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/enemies/cactus/cactus4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/enemies/cactus/cactus4.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/enemies/spike/spike.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/enemies/spike/spike.png -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/cloud/cloud.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/cloud/cloud.png -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/land/land0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/land/land0.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/land/land1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/land/land1.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/land/land2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/land/land2.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/land/land3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/land/land3.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/land/land4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/land/land4.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/land/land5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/land/land5.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/montain/montain0.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/montain/montain0.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/montain/montain1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/montain/montain1.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/montain/montain2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/montain/montain2.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/montain/montain3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/montain/montain3.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/montain/montain4.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/montain/montain4.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/scenario/montain/montain5.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/scenario/montain/montain5.bmp -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/several/gameover_text.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/several/gameover_text.png -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/several/replay_button.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/data/several/replay_button.png -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/data/synapses/3530_synapses.txt: -------------------------------------------------------------------------------- 1 | -0.10087195923894732 0.6188901536976055 0.7128553134103135 -0.4309197224545849 -0.6489331247131862 0.3742298200664882 -0.9021268786996364 0.564506537075625 0.8019830905003962 0.27656709231110166 -0.6448691883894642 0.7894757532604797 0.7927925106503535 0.7684748717996923 0.22593528845373112 0.744564905777934 -0.3703084112321626 -0.1601794641653127 0.36197819522308605 0.7323275489576553 0.5939114605766238 0.5331388864026334 0.5491955932892276 0.17034436363975702 -0.0744911146665288 -0.2731339313665744 0.776914665694032 0.7064909351726973 0.7981179855430192 0.5824393872352189 -0.003944967500455698 -0.3529919132739203 -0.7921268748163752 -0.4754132278956895 0.5523833570637529 0.901595717214861 0.3655976447269822 -0.2433878408815613 -0.18966223222875644 -0.3954833307879453 0.599112856439977 -0.06755989725116751 -0.004666266535618746 -0.09354256448181686 -0.5371505585223686 -0.246108820355448 -0.9156092921988552 -0.4186448596606449 0.8398651293116475 0.43745843782276683 -0.2560058389712754 0.589014773949281 -0.46779662603869077 0.058065304583503785 -0.10789178442534775 -0.6956344363947924 0.2746090666802268 -0.30046226467406933 0.7064683612304337 -0.03818389140398559 0.894489631686993 0.5852977595104707 0.47175724778732464 -0.10087195923894732 0.6188901536976055 0.06291878047976063 0.7787573177512104 -0.669576378448641 -0.911277563353579 -0.46338301924297043 0.4740144073018431 -0.915597812660081 0.27656709231110166 -0.5885185997293567 0.7894757532604797 0.7170855017276385 0.7684748717996923 0.22593528845373112 -0.17326096066481989 -0.3703084112321626 -0.1601794641653127 0.36197819522308605 0.7323275489576553 0.7613405545493981 0.5331388864026334 0.5491955932892276 0.5505507457123107 -0.0744911146665288 -0.8255376959880365 -0.8082450182307164 0.6324056505784847 -0.054517085492313155 0.5824393872352189 0.13330169487899846 0.8281052342805144 -0.7921268748163752 0.36406789043270327 -0.9008044735345111 -0.5024609029454188 0.5313671481819113 -0.2433878408815613 -0.40094417464607135 0.41781715793938745 0.599112856439977 -0.9192323687114756 -0.14474041838099372 0.4564758145959267 -0.3354363891091068 -0.246108820355448 0.029958570157177622 -0.9106940696671273 -0.42810250840881037 0.43745843782276683 -0.26718258523315175 0.589014773949281 0.25996939189520396 0.058065304583503785 0.45556265503418714 -0.6956344363947924 0.37305662911827864 0.8697821405227089 -0.18474240010641552 0.8919628580266108 0.894489631686993 0.30484515389815114 0.8354776812944029 0.12843390094528773 0.6188901536976055 0.0036961344271102536 -0.4309197224545849 0.7694226740647809 0.3742298200664882 -0.708809557302428 0.06799229065361301 0.7522010124058982 0.27656709231110166 -0.6448691883894642 0.7894757532604797 0.7927925106503535 0.16496318322364667 0.22593528845373112 0.744564905777934 0.013449133064666219 0.0685162958535559 0.37428847430217127 -0.8186632996270728 0.011923220765957643 0.5331388864026334 0.5491955932892276 -0.057891075584576956 -0.6643311491567654 -0.476016588120715 0.776914665694032 -0.8295285875251885 0.7981179855430192 -0.10504205452478299 -0.4096862940625019 -0.3529919132739203 -0.06712575178171143 0.3239842618807427 -0.061358007389552105 0.901595717214861 -0.4852151507995073 -0.26821201444535214 -0.18966223222875644 -0.3954833307879453 0.8961158889763556 -0.06755989725116751 -0.004666266535618746 -0.931724673841394 0.970250365369661 0.438981122947496 -0.9156092921988552 -0.14701351586628997 0.9814331501687763 0.4993031062969615 -0.2560058389712754 0.589014773949281 -0.1013317953022872 0.2905523555683909 -0.10789178442534775 0.32372713079689186 0.946017961071741 0.5917127787123613 0.14561907499232984 -0.03818389140398559 -0.9558111438930206 0.9201987108995451 0.06891037712420278 -------------------------------------------------------------------------------- /Chrome-Dino-Game-AI/trained.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/Chrome-Dino-Game-AI/trained.gif -------------------------------------------------------------------------------- /FlappyBirdAI/FlappyBird.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/FlappyBird.jar -------------------------------------------------------------------------------- /FlappyBirdAI/README.md: -------------------------------------------------------------------------------- 1 | ## FlappyBird - Artificial Intelligence 2 | 3 | Game Auto-learning using Neural Networks 4 | 5 | [![FlappyBirdAI](https://github.com/GustavoRolimSantos/Java/blob/master/FlappyBirdAI/data/FlappyBird-demo.gif)](https://www.youtube.com/watch?v=eHvFdgZAawI) 6 | 7 | ### About the project 8 | The idea is to use Neural Networks to find the best Bird by using Natural Selection (Random Mutations).
9 | The game was recreated from scratch (without engines) using Java. 10 | 11 | The Neural Network was created with 3 layers and Sigmoid as the activation function: 12 | - Input Layer with 4 sensors 13 | - Hidden layer with 4 neurons + 1 bias 14 | - Output layer with 1 neuron (Jump) 15 | 16 | The population size used to train was between 1000-2000 birds. 17 | 18 | The learning time was between 5 and 10 minutes. 19 | 20 | **For more information watch the [demonstration video](https://www.youtube.com/watch?v=eHvFdgZAawI).** 21 | 22 | ### Code 23 | Inside the "data" folder there is another folder called "synapses", the file inside this folder is the training. 24 | Delete this file if you want to train the Neural Network again. 25 | 26 | > COPYRIGHT BY GUSTAVO ROLIM DOS SANTOS 2020. -------------------------------------------------------------------------------- /FlappyBirdAI/constants/Constants.java: -------------------------------------------------------------------------------- 1 | package constants; 2 | 3 | public class Constants { 4 | 5 | public static final boolean BATTLE_MODE = false; 6 | public static final boolean SHOW_COLLISION_AREA = false; 7 | 8 | public static final int SCREEN_WIDTH = 1280, SCREEN_HEIGHT = 335; 9 | 10 | public static final double START_SPEED = 3, ACCELERATION = 0.001; 11 | 12 | public static int START_POPULATION = 2000; 13 | 14 | public enum GameState { 15 | START, PLAYING, GAME_OVER 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /FlappyBirdAI/data/FlappyBird-demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/FlappyBird-demo.gif -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/flappy_bird.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/flappy_bird.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/game_over.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/game_over.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/get_ready.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/get_ready.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/gold.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/gold.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/menu.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/menu.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/new.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/new.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/numbers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/numbers.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/play.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/play.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/player/bird1.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/player/bird1.bmp -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/player/bird2.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/player/bird2.bmp -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/player/bird3.bmp: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/player/bird3.bmp -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/scenario/enemies/pipe1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/scenario/enemies/pipe1.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/scenario/enemies/pipe2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/scenario/enemies/pipe2.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/scenario/ground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/scenario/ground.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/scenario/landscape.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/scenario/landscape.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/score.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/score.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/sprites/silver.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/FlappyBirdAI/data/sprites/silver.png -------------------------------------------------------------------------------- /FlappyBirdAI/data/synapses/3420_synapses.txt: -------------------------------------------------------------------------------- 1 | 0.6238786181854155 0.2874808514332723 -0.8752577349388493 -0.525823394585462 0.55340349824174 0.19875099860803846 0.04722869430102694 0.9877927899853529 0.5670149276314786 0.4392763763475944 -0.37141858448438025 0.30620919340853026 -0.5729914933891467 -0.9398201472723449 -0.8998481744642288 0.03114160072446892 0.8367114569750245 0.3437609576374887 0.8465149942693282 -0.17778930700009776 0.1165877650902234 0.9541872891428516 0.37896162657551424 0.9473386890982147 -0.7655120592745512 -0.9872125363744908 0.4271374208462435 -0.8752577349388493 -0.26090460729532805 0.55340349824174 -0.9186979860506208 -0.6995543488406453 -0.7599377993453063 -0.6876008023472013 0.09606786196755768 -0.37141858448438025 0.11479660740400188 0.6903393084306539 0.42756899673021986 0.9910897658488511 -0.12917839532267306 0.4833727795050595 0.5827540986313968 0.8465149942693282 -0.17778930700009776 0.9687084819028606 -0.7595566377314746 -0.0438660261844086 -0.872904627945009 0.15788001295499599 0.4937180089622808 0.12111810029138192 -0.40191676061024584 0.07867433157172554 0.7696294637003598 0.19875099860803846 0.04722869430102694 0.7449593922673883 -0.8703126524571787 -0.27741765433497223 0.8635355483541158 0.30620919340853026 -0.5729914933891467 -0.9623780020818369 0.6623890917052946 0.03114160072446892 0.8367114569750245 0.13543403176851343 0.13858095221326816 -0.17778930700009776 -0.08675817796534746 0.6445680221313277 0.300327830099848 0.7815975574097529 -0.18907130453135124 -------------------------------------------------------------------------------- /FlappyBirdAI/game/Game.java: -------------------------------------------------------------------------------- 1 | package game; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import constants.Constants; 8 | import constants.Constants.GameState; 9 | import game.display.Player; 10 | import maxtercreations.FlappyBird; 11 | 12 | public class Game { 13 | 14 | private ArrayList players = new ArrayList<>(); 15 | 16 | private GameState gameState = GameState.START; 17 | 18 | private Player bestPlayer; 19 | private String lastBestPlayer; 20 | private int deaths, bestScore, bestDistance; 21 | 22 | private double velocity = Constants.START_SPEED; 23 | 24 | private GameScreen gameScreen; 25 | 26 | public Game() { 27 | gameScreen = new GameScreen(this); 28 | } 29 | 30 | public ArrayList getPlayers() { 31 | return players; 32 | } 33 | 34 | public void addPlayer(Player player) { 35 | this.players.add(player); 36 | } 37 | 38 | public List getDied() { 39 | return players.stream().filter(dino -> !dino.isAlive()).collect(Collectors.toList()); 40 | } 41 | 42 | public GameState getGameState() { 43 | return gameState; 44 | } 45 | 46 | public void setGameState(GameState gameState) { 47 | this.gameState = gameState; 48 | } 49 | 50 | public Player getBestPlayer() { 51 | return bestPlayer; 52 | } 53 | 54 | public int getBestScore() { 55 | return bestScore; 56 | } 57 | 58 | public int getBestDistance() { 59 | return bestDistance; 60 | } 61 | 62 | public void updateBestPlayer(Player player) { 63 | if (player.getScore() > bestScore) { 64 | bestScore = player.getScore(); 65 | bestDistance = FlappyBird.getGame().getGameScreen().getGround().getScreenWidth(); 66 | } 67 | 68 | bestPlayer = player; 69 | lastBestPlayer = toString(); 70 | } 71 | 72 | public GameScreen getGameScreen() { 73 | return gameScreen; 74 | } 75 | 76 | public void setBestPlayer(Player player) { 77 | bestPlayer = player; 78 | } 79 | 80 | public String getFormattedScore() { 81 | return bestPlayer != null ? String.valueOf(bestPlayer.getScore()) : "0"; 82 | } 83 | 84 | public double getVelocity() { 85 | return velocity; 86 | } 87 | 88 | public void increaseVelocity() { 89 | velocity += Constants.ACCELERATION; 90 | } 91 | 92 | public void resetVelocity() { 93 | velocity = Constants.START_SPEED; 94 | deaths = 0; 95 | } 96 | 97 | public void increaseDeaths() { 98 | deaths++; 99 | } 100 | 101 | public int getDeaths() { 102 | return deaths; 103 | } 104 | 105 | @Override 106 | public String toString() { 107 | return bestPlayer == null ? (lastBestPlayer == null ? "Unknown" : lastBestPlayer) 108 | : "" + (bestPlayer.getNeuralNetwork().current_generation + 1) + " [" 109 | + (bestPlayer.getNeuralNetwork().current_genome + 1) + "/" 110 | + bestPlayer.getNeuralNetwork().genomes_per_generation + " genome]"; 111 | } 112 | 113 | } 114 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/GameScreen.java: -------------------------------------------------------------------------------- 1 | package game; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Graphics; 6 | import java.awt.Graphics2D; 7 | import java.awt.RenderingHints; 8 | import java.awt.image.BufferedImage; 9 | import java.text.DecimalFormat; 10 | 11 | import javax.swing.JPanel; 12 | 13 | import constants.Constants; 14 | import constants.Constants.GameState; 15 | import game.display.Player; 16 | import game.display.enemies.EnemiesManager; 17 | import game.display.scenario.Ground; 18 | import game.display.scenario.Landscape; 19 | import utils.Utils; 20 | 21 | @SuppressWarnings("serial") 22 | public class GameScreen extends JPanel implements Runnable { 23 | 24 | private Ground ground; 25 | private Landscape landscape; 26 | private EnemiesManager enemiesManager; 27 | private Thread thread; 28 | 29 | private BufferedImage replayButtonImage, gameOverButtonImage, logoImage; 30 | 31 | private Game game; 32 | 33 | private long startTime; 34 | 35 | private DecimalFormat decimalFormat = new DecimalFormat("#0.00"); 36 | 37 | public GameScreen(Game game) { 38 | this.game = game; 39 | 40 | setupGameMode(); 41 | initGraphics(); 42 | } 43 | 44 | public void gameUpdate() { 45 | 46 | if (game.getGameState().equals(GameState.GAME_OVER)) { 47 | try { 48 | Thread.sleep(500); 49 | game.setGameState(GameState.PLAYING); 50 | resetGame(); 51 | } catch (InterruptedException e) { 52 | e.printStackTrace(); 53 | } 54 | } 55 | 56 | if (game.getGameState().equals(GameState.PLAYING)) { 57 | game.increaseVelocity(); 58 | 59 | landscape.update(); 60 | enemiesManager.update(); 61 | ground.update(); 62 | 63 | for (Player player : game.getPlayers()) { 64 | player.update(); 65 | 66 | if (!enemiesManager.isCollision(player) || !player.isAlive()) 67 | continue; 68 | 69 | player.setAlive(false); 70 | 71 | if (game.getDeaths() == Constants.START_POPULATION) { 72 | ground.reset(); 73 | game.setGameState(GameState.GAME_OVER); 74 | player.getNeuralNetwork().getSaveLoad().saveToFile(player.getScore()); 75 | break; 76 | } 77 | } 78 | } 79 | } 80 | 81 | @Override 82 | public void paint(Graphics g) { 83 | Graphics2D g2d = (Graphics2D) g; 84 | 85 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 86 | 87 | g.setColor(Color.decode("#f7f7f7")); 88 | g.fillRect(0, 0, getWidth(), getHeight()); 89 | 90 | landscape.draw(g); 91 | enemiesManager.draw(g); 92 | ground.draw(g); 93 | 94 | for (Player player : game.getPlayers()) { 95 | if (game.getGameState().equals(GameState.PLAYING) && player.getScore() >= game.getBestScore()) { 96 | game.updateBestPlayer(player); 97 | } 98 | player.draw(g); 99 | } 100 | 101 | if (game.getGameState().equals(GameState.GAME_OVER)) { 102 | g.drawImage(gameOverButtonImage, 60, 450, null); 103 | g.drawImage(replayButtonImage, 100, 500, null); 104 | } 105 | 106 | int baseY = 30; 107 | 108 | g2d.setColor(Color.WHITE); 109 | g2d.fillRoundRect(Constants.SCREEN_WIDTH - 250, baseY, 340, 250, 30, 30); 110 | 111 | int logoX = ((Constants.SCREEN_WIDTH - 250) + 125 - (logoImage.getWidth() / 2)); 112 | 113 | g2d.drawImage(logoImage, logoX, baseY + 30, null); 114 | 115 | baseY += 75; 116 | 117 | g2d.setColor(Color.BLACK); 118 | g2d.setFont(new Font("Arial", 0, 16)); 119 | g2d.drawString("Score: " + game.getFormattedScore(), 1050, baseY += 25); 120 | g2d.drawString("Record:", 1050, baseY += 25); 121 | g2d.setColor(Color.BLUE); 122 | g2d.drawString(" " + game.getBestScore() + " points [" + game.getBestDistance() + "m]", 1110, baseY); 123 | g2d.setColor(Color.BLACK); 124 | g2d.drawString("Distance: " + ground.getScreenWidth() + " [" + decimalFormat.format(game.getVelocity()) + " m/s]", 1050, baseY += 25); 125 | g2d.drawString("Population: " + (Constants.START_POPULATION - game.getDied().size()) + "/" + Constants.START_POPULATION, 1050, baseY += 25); 126 | g2d.drawString("Generation:", 1050, baseY += 25); 127 | g2d.drawString(game.toString(), 1140, baseY); 128 | g2d.drawString("Time: ", 1050, baseY += 25); 129 | g2d.setColor(Color.RED); 130 | g2d.drawString(" " + Utils.compareTime(startTime, System.currentTimeMillis()), 1105, baseY); 131 | } 132 | 133 | @Override 134 | public void run() { 135 | 136 | int fps = 60; 137 | long msPerFrame = 1000 * 1000000 / fps; 138 | long lastTime = 0; 139 | long elapsed; 140 | 141 | int msSleep; 142 | // int nanoSleep; 143 | 144 | while (true) { 145 | gameUpdate(); 146 | repaint(); 147 | System.nanoTime(); 148 | elapsed = (lastTime + msPerFrame - System.nanoTime()); 149 | msSleep = (int) (elapsed / 1000000); 150 | // nanoSleep = (int) (elapsed % 1000000); 151 | if (msSleep <= 0) { 152 | lastTime = System.nanoTime(); 153 | continue; 154 | } 155 | try { 156 | // Thread.sleep(msSleep, nanoSleep); 157 | Thread.sleep(16); 158 | } catch (InterruptedException e) { 159 | e.printStackTrace(); 160 | } 161 | lastTime = System.nanoTime(); 162 | } 163 | } 164 | 165 | private void resetGame() { 166 | game.resetVelocity(); 167 | 168 | enemiesManager.reset(); 169 | 170 | for (Player player : game.getPlayers()) { 171 | player.reset(); 172 | } 173 | 174 | game.setBestPlayer(null); 175 | } 176 | 177 | private void setupGameMode() { 178 | if (Constants.BATTLE_MODE) { 179 | Constants.START_POPULATION = 2; 180 | game.addPlayer(new Player(game, false)); 181 | game.addPlayer(new Player(game, true)); 182 | } else { 183 | for (int i = 0; i < Constants.START_POPULATION; i++) { 184 | game.addPlayer(new Player(game, false)); 185 | } 186 | } 187 | } 188 | 189 | private void initGraphics() { 190 | ground = new Ground(Constants.SCREEN_WIDTH); 191 | enemiesManager = new EnemiesManager(); 192 | landscape = new Landscape(Constants.SCREEN_WIDTH); 193 | 194 | replayButtonImage = Utils.getImageResource("data/sprites/play.png"); 195 | gameOverButtonImage = Utils.getImageResource("data/sprites/game_over.png"); 196 | logoImage = Utils.getImageResource("data/sprites/flappy_bird.png"); 197 | 198 | game.setGameState(GameState.PLAYING); 199 | 200 | startTime = System.currentTimeMillis(); 201 | } 202 | 203 | /* Getters */ 204 | 205 | public Ground getGround() { 206 | return ground; 207 | } 208 | 209 | public EnemiesManager getEnimiesManager() { 210 | return enemiesManager; 211 | } 212 | 213 | public void startGame() { 214 | thread = new Thread(this); 215 | thread.start(); 216 | } 217 | 218 | } 219 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/controller/GameController.java: -------------------------------------------------------------------------------- 1 | package game.controller; 2 | 3 | import java.awt.event.KeyAdapter; 4 | import java.awt.event.KeyEvent; 5 | 6 | import constants.Constants; 7 | import constants.Constants.GameState; 8 | import game.Game; 9 | import game.display.Player; 10 | 11 | public class GameController extends KeyAdapter { 12 | 13 | private Game game; 14 | 15 | public GameController(Game gameScreen) { 16 | this.game = gameScreen; 17 | } 18 | 19 | @Override 20 | public void keyPressed(KeyEvent e) { 21 | if (!game.getGameState().equals(GameState.PLAYING)) 22 | return; 23 | 24 | if (Constants.BATTLE_MODE) { 25 | if (e.getKeyCode() == KeyEvent.VK_ENTER) { 26 | for (Player player : game.getPlayers()) { 27 | if (!player.isAlive()) { 28 | player.setAlive(false); 29 | } 30 | } 31 | } 32 | } 33 | 34 | for (Player player : game.getPlayers()) { 35 | if (player.isPlayingAsHuman()) { 36 | if (e.getKeyCode() == KeyEvent.VK_SPACE) 37 | player.jump(); 38 | } 39 | } 40 | 41 | } 42 | 43 | } 44 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/display/Player.java: -------------------------------------------------------------------------------- 1 | package game.display; 2 | 3 | import java.awt.Color; 4 | import java.awt.Graphics; 5 | import java.awt.Point; 6 | import java.awt.Rectangle; 7 | import java.io.File; 8 | import java.util.Random; 9 | 10 | import constants.Constants; 11 | import game.Game; 12 | import game.display.enemies.EnemiesManager; 13 | import game.display.enemies.entities.Pipe; 14 | import game.display.enemies.model.Enemy; 15 | import maxtercreations.FlappyBird; 16 | import neuralnetwork.NeuralNetwork; 17 | import utils.Animation; 18 | import utils.Utils; 19 | 20 | public class Player { 21 | 22 | /* Player constants */ 23 | 24 | private static final int LAND_POSY = 60; 25 | private static float GRAVITY = 0.55f; 26 | 27 | /* Variables */ 28 | 29 | private boolean alive = true, playAsHuman, hasJumped; 30 | 31 | private float posY, posX, speedY; 32 | 33 | private int id, score; 34 | 35 | private Rectangle rectBound = new Rectangle(); 36 | private Animation animation = new Animation(90); 37 | private Color randomColor; 38 | private NeuralNetwork neuralNetwork; 39 | private EnemiesManager enemiesManager; 40 | 41 | public Player(Game game, boolean playAsHuman) { 42 | id = game.getPlayers().size(); 43 | 44 | this.neuralNetwork = new NeuralNetwork(new int[] { 4, 4, 1 }, 3, 0.7, -1, 1); 45 | this.playAsHuman = playAsHuman; 46 | 47 | buildColorAndPosition(); 48 | 49 | animation.addFrame(Utils.changeColor(new File("data/sprites/player/bird1.bmp"), randomColor)); 50 | animation.addFrame(Utils.changeColor(new File("data/sprites/player/bird2.bmp"), randomColor)); 51 | animation.addFrame(Utils.changeColor(new File("data/sprites/player/bird3.bmp"), randomColor)); 52 | } 53 | 54 | public void draw(Graphics g) { 55 | if (!alive) 56 | return; 57 | 58 | g.drawImage(animation.getFrame(), (int) posX, (int) posY, null); 59 | 60 | if (!Constants.SHOW_COLLISION_AREA) 61 | return; 62 | 63 | Color color = g.getColor(); 64 | 65 | g.setColor(Color.RED); 66 | 67 | for (Enemy e : enemiesManager.getEnemies()) { 68 | int range = ((Pipe) e).getRange(); 69 | 70 | int x = (int) (e.getBound().getX() + (e.getBound().getWidth() / 2) - 5); 71 | int y = (int) Math.abs(e.getBound().getY() + e.getBound().getHeight() + (30 - range) + range); 72 | g.fillRect(x, y, 10, 10); 73 | } 74 | 75 | g.drawLine(0, 630, 1280, 630); 76 | g.setColor(color); 77 | 78 | } 79 | 80 | public void update() { 81 | if (!playAsHuman) { 82 | 83 | if (enemiesManager == null) 84 | enemiesManager = FlappyBird.getGame().getGameScreen().getEnimiesManager(); 85 | 86 | Object[] nextEnemy = enemiesManager.getNextEnemy(new Point((int) posX, (int) posY)); 87 | 88 | double distance = (double) nextEnemy[1]; 89 | 90 | Enemy enemy = (Enemy) nextEnemy[0]; 91 | 92 | if (distance == 9999) 93 | return; 94 | 95 | neuralNetwork.getOutputs(new double[] { distance, posY - enemy.getBound().getY(), 96 | posX + animation.getFrame().getWidth(), posY + animation.getFrame().getHeight() }); 97 | 98 | boolean jump = neuralNetwork.neurons[2][0] > 0.5; 99 | 100 | if (jump) 101 | jump(); 102 | } 103 | 104 | animation.updateFrame(); 105 | 106 | if (!hasJumped) 107 | return; 108 | 109 | if (posY < Constants.SCREEN_HEIGHT - 90 - animation.getFrame().getHeight()) { 110 | speedY += GRAVITY; 111 | posY += speedY; 112 | } else { 113 | posY = Constants.SCREEN_HEIGHT - 90; 114 | } 115 | } 116 | 117 | public Player playAsHuman() { 118 | playAsHuman = !playAsHuman; 119 | return this; 120 | } 121 | 122 | public boolean isPlayingAsHuman() { 123 | return playAsHuman; 124 | } 125 | 126 | public void jump() { 127 | if (posY < Constants.SCREEN_HEIGHT - animation.getFrame().getHeight() && posY >= (LAND_POSY + 30)) { 128 | speedY = -5f; 129 | posY += speedY; 130 | } 131 | hasJumped = true; 132 | } 133 | 134 | public Rectangle getBound() { 135 | rectBound = new Rectangle(); 136 | rectBound.x = (int) posX + 5; 137 | rectBound.y = (int) posY; 138 | rectBound.width = animation.getFrame().getWidth() - 10; 139 | rectBound.height = animation.getFrame().getHeight(); 140 | return rectBound; 141 | } 142 | 143 | public void reset() { 144 | posY = LAND_POSY; 145 | score = 0; 146 | alive = true; 147 | hasJumped = false; 148 | GRAVITY = 0.45f; 149 | speedY = GRAVITY; 150 | } 151 | 152 | public void upScore(int up) { 153 | if (alive) { 154 | score += up; 155 | 156 | if (FlappyBird.getGame().getBestPlayer() == null || score > FlappyBird.getGame().getBestPlayer().getScore()) 157 | FlappyBird.getGame().updateBestPlayer(this); 158 | } 159 | } 160 | 161 | private void buildColorAndPosition() { 162 | if (Constants.BATTLE_MODE) { 163 | if (playAsHuman) { 164 | randomColor = new Color(255, 57, 57); 165 | posX = (int) (50 + id * 0.087); 166 | } else { 167 | randomColor = new Color(239, 239, 239); 168 | posX = (int) (200 + id * 0.087); 169 | } 170 | } else { 171 | posX = (int) (13 + id * 0.087); 172 | 173 | Random rand = new Random(); 174 | 175 | randomColor = new Color(rand.nextFloat(), rand.nextFloat(), rand.nextFloat()); 176 | } 177 | 178 | posY = 60 + new Random().nextInt(200); 179 | } 180 | 181 | public int getScore() { 182 | return score; 183 | } 184 | 185 | public void setAlive(boolean alive) { 186 | this.alive = alive; 187 | 188 | if (!Constants.BATTLE_MODE) 189 | this.neuralNetwork.newGenome(score); 190 | 191 | FlappyBird.getGame().increaseDeaths(); 192 | } 193 | 194 | public boolean isAlive() { 195 | return alive; 196 | } 197 | 198 | public NeuralNetwork getNeuralNetwork() { 199 | return neuralNetwork; 200 | } 201 | 202 | } 203 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/display/enemies/EnemiesManager.java: -------------------------------------------------------------------------------- 1 | package game.display.enemies; 2 | 3 | import java.awt.Color; 4 | import java.awt.Graphics; 5 | import java.awt.Point; 6 | import java.util.ArrayList; 7 | import java.util.List; 8 | import java.util.Random; 9 | 10 | import constants.Constants; 11 | import game.display.Player; 12 | import game.display.enemies.entities.Pipe; 13 | import game.display.enemies.model.Enemy; 14 | import maxtercreations.FlappyBird; 15 | 16 | public class EnemiesManager { 17 | 18 | private List enemies = new ArrayList(); 19 | 20 | public EnemiesManager() { 21 | reset(); 22 | } 23 | 24 | public void update() { 25 | boolean isOut = false; 26 | 27 | for (Enemy e : enemies) { 28 | if (e.isOutOfScreen()) { 29 | e.reset(); 30 | isOut = true; 31 | } 32 | 33 | e.update(); 34 | } 35 | 36 | if (isOut) { 37 | FlappyBird.getGame().getPlayers().forEach(bird -> { 38 | bird.upScore(10); 39 | }); 40 | } 41 | } 42 | 43 | public void draw(Graphics g) { 44 | enemies.forEach(e -> { 45 | e.draw(g); 46 | 47 | if (Constants.SHOW_COLLISION_AREA) { 48 | g.setColor(Color.RED); 49 | g.fillRect((int) e.getBound().getX(), (int) e.getBound().getY(), (int) e.getBound().getWidth(), 50 | (int) e.getBound().getHeight()); 51 | } 52 | }); 53 | } 54 | 55 | public boolean isCollision(Player player) { 56 | if (player.getBound().getY() == Constants.SCREEN_HEIGHT - 90) 57 | return true; 58 | 59 | for (Enemy e : enemies) { 60 | if (player.getBound().intersects(e.getBound())) { 61 | return true; 62 | } 63 | } 64 | return false; 65 | } 66 | 67 | public void reset() { 68 | enemies.clear(); 69 | 70 | Random random = new Random(); 71 | 72 | for (int i = 1; i <= 8; i++) { 73 | int range = random.nextInt(100); 74 | 75 | enemies.add(new Pipe(700 + (i * 180), true, range)); 76 | enemies.add(new Pipe(700 + (i * 180), false, range)); 77 | } 78 | } 79 | 80 | public Object[] getNextEnemy(Point point) { 81 | double smallerDistance = 9999; 82 | 83 | Enemy enemy = enemies.get(0); 84 | 85 | for (Enemy e : enemies) { 86 | double currentDistance = point.distance(new Point((int) e.getBound().getX(), (int) e.getBound().getY())); 87 | 88 | if (currentDistance <= smallerDistance) { 89 | smallerDistance = currentDistance; 90 | enemy = e; 91 | } 92 | } 93 | return new Object[] { enemy, smallerDistance }; 94 | } 95 | 96 | public List getEnemies() { 97 | return enemies; 98 | } 99 | 100 | } 101 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/display/enemies/entities/Pipe.java: -------------------------------------------------------------------------------- 1 | package game.display.enemies.entities; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Rectangle; 5 | import java.awt.image.BufferedImage; 6 | import java.util.ArrayList; 7 | 8 | import constants.Constants; 9 | import game.display.enemies.model.Enemy; 10 | import maxtercreations.FlappyBird; 11 | import utils.Utils; 12 | 13 | public class Pipe extends Enemy { 14 | 15 | private static final int TOP_Y = 50, BOTTOM_Y = 280; 16 | 17 | public static final int MAX_TOP_PIPE = 150; 18 | 19 | public int startX, posX, posY, width, height, range; 20 | 21 | private ArrayList images = new ArrayList<>(); 22 | 23 | private BufferedImage currentImage; 24 | 25 | private Rectangle rectBound; 26 | 27 | private boolean image1, reseting; 28 | 29 | 30 | public Pipe(int posX, boolean image1, int range) { 31 | this.range = range; 32 | this.startX = posX; 33 | this.posX = posX; 34 | 35 | this.image1 = image1; 36 | 37 | images.add(Utils.getImageResource("data/sprites/scenario/enemies/pipe1.png")); 38 | images.add(Utils.getImageResource("data/sprites/scenario/enemies/pipe2.png")); 39 | 40 | rectBound = new Rectangle(); 41 | 42 | setup(); 43 | } 44 | 45 | @Override 46 | public void update() { 47 | if (rectBound.getX() == 0 && reseting) { 48 | reseting = false; 49 | return; 50 | } 51 | 52 | posX -= FlappyBird.getGame().getVelocity(); 53 | } 54 | 55 | @Override 56 | public void draw(Graphics g) { 57 | if (rectBound.getX() == 0 && reseting) { 58 | reseting = false; 59 | return; 60 | } 61 | 62 | g.drawImage(currentImage, posX, posY, null); 63 | 64 | if (Constants.SHOW_COLLISION_AREA) { 65 | g.fillRect(posX, posY, width, height); 66 | } 67 | } 68 | 69 | @Override 70 | public Rectangle getBound() { 71 | rectBound = new Rectangle(); 72 | rectBound.x = posX; 73 | rectBound.y = posY; 74 | rectBound.width = width; 75 | rectBound.height = height; 76 | return rectBound; 77 | } 78 | 79 | @Override 80 | public boolean isOutOfScreen() { 81 | if (posX <= -currentImage.getWidth()) { 82 | return true; 83 | } 84 | return false; 85 | } 86 | 87 | @Override 88 | public int score() { 89 | return 10; 90 | } 91 | 92 | @Override 93 | public void reset() { 94 | posX = Constants.SCREEN_WIDTH + 100; 95 | rectBound = new Rectangle(); 96 | reseting = true; 97 | } 98 | 99 | private void setup() { 100 | currentImage = images.get(image1 ? 0 : 1); 101 | 102 | this.width = currentImage.getWidth(); 103 | this.height = currentImage.getHeight(); 104 | 105 | posY = (image1 ? TOP_Y + range : BOTTOM_Y + range) - currentImage.getHeight(); 106 | } 107 | 108 | public int getRange() { 109 | return range; 110 | } 111 | 112 | } 113 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/display/enemies/model/Enemy.java: -------------------------------------------------------------------------------- 1 | package game.display.enemies.model; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Rectangle; 5 | 6 | public abstract class Enemy { 7 | 8 | public abstract void update(); 9 | 10 | public abstract void draw(Graphics g); 11 | 12 | public abstract Rectangle getBound(); 13 | 14 | public abstract boolean isOutOfScreen(); 15 | 16 | public abstract int score(); 17 | 18 | public abstract void reset(); 19 | 20 | } 21 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/display/scenario/Ground.java: -------------------------------------------------------------------------------- 1 | package game.display.scenario; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.image.BufferedImage; 5 | import java.util.ArrayList; 6 | 7 | import maxtercreations.FlappyBird; 8 | import utils.Utils; 9 | 10 | public class Ground { 11 | 12 | public static final int LAND_POSY = 250; 13 | 14 | private ArrayList images = new ArrayList<>(); 15 | private ArrayList listLand = new ArrayList<>(); 16 | 17 | private int screenWidth; 18 | 19 | private int width; 20 | 21 | public Ground(int width) { 22 | this.width = width; 23 | 24 | for (int i = 0; i < 7; i++) { 25 | images.add(Utils.getImageResource("data/sprites/scenario/ground.png")); 26 | } 27 | 28 | int currentWidth = 0, counter = 0; 29 | 30 | while (currentWidth < 1400) { 31 | ImageLand imageLand = new ImageLand(); 32 | imageLand.image = images.get(counter); 33 | imageLand.posX = currentWidth; 34 | 35 | listLand.add(imageLand); 36 | 37 | counter++; 38 | currentWidth += imageLand.image.getWidth(); 39 | 40 | if (counter == images.size()) 41 | counter = 0; 42 | } 43 | 44 | } 45 | 46 | public void update() { 47 | 48 | double velocity = FlappyBird.getGame().getVelocity(); 49 | 50 | for (int i = 0; i < velocity; i++) { 51 | listLand.forEach(imageLand -> { 52 | if (imageLand.posX < -imageLand.image.getWidth()) { 53 | imageLand.posX = width; 54 | } else { 55 | imageLand.posX -= 1; 56 | } 57 | }); 58 | } 59 | 60 | screenWidth += velocity; 61 | } 62 | 63 | public int getScreenWidth() { 64 | return screenWidth; 65 | } 66 | 67 | public void reset() { 68 | screenWidth = 0; 69 | } 70 | 71 | public void draw(Graphics g) { 72 | try { 73 | for (ImageLand imgLand : listLand) { 74 | g.drawImage(imgLand.image, (int) imgLand.posX, LAND_POSY, null); 75 | } 76 | } catch (Exception e) { 77 | 78 | } 79 | } 80 | 81 | private class ImageLand { 82 | float posX; 83 | BufferedImage image; 84 | } 85 | 86 | } 87 | -------------------------------------------------------------------------------- /FlappyBirdAI/game/display/scenario/Landscape.java: -------------------------------------------------------------------------------- 1 | package game.display.scenario; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.image.BufferedImage; 5 | import java.util.ArrayList; 6 | 7 | import utils.Utils; 8 | 9 | public class Landscape { 10 | 11 | public static final int LAND_POSY = -130; 12 | 13 | private ArrayList images = new ArrayList<>(); 14 | private ArrayList listLand = new ArrayList<>(); 15 | 16 | //private int width; 17 | 18 | public Landscape(int width) { 19 | //this.width = width; 20 | 21 | for (int i = 0; i < 9; i++) { 22 | images.add(Utils.getImageResource("data/sprites/scenario/landscape.png")); 23 | } 24 | 25 | int currentWidth = 0, counter = 0; 26 | 27 | while (currentWidth < 1400) { 28 | ImageLand imageLand = new ImageLand(); 29 | imageLand.image = images.get(counter); 30 | imageLand.posX = currentWidth; 31 | 32 | listLand.add(imageLand); 33 | 34 | counter++; 35 | currentWidth += imageLand.image.getWidth(); 36 | 37 | if (counter == images.size()) 38 | counter = 0; 39 | } 40 | 41 | } 42 | 43 | public void update() { 44 | /*for (int i = 0; i < Constants.VELOCITY; i++) { 45 | listLand.forEach(imageLand -> { 46 | if (imageLand.posX < -imageLand.image.getWidth()) { 47 | imageLand.posX = width; 48 | } else { 49 | imageLand.posX -= 1; 50 | } 51 | }); 52 | }*/ 53 | } 54 | 55 | public void draw(Graphics g) { 56 | try { 57 | for (ImageLand imgLand : listLand) { 58 | g.drawImage(imgLand.image, (int) imgLand.posX, LAND_POSY, null); 59 | } 60 | } catch (Exception e) { 61 | 62 | } 63 | } 64 | 65 | private class ImageLand { 66 | float posX; 67 | BufferedImage image; 68 | } 69 | 70 | } 71 | -------------------------------------------------------------------------------- /FlappyBirdAI/maxtercreations/FlappyBird.java: -------------------------------------------------------------------------------- 1 | package maxtercreations; 2 | 3 | import javax.swing.JFrame; 4 | 5 | import constants.Constants; 6 | import game.Game; 7 | import game.controller.GameController; 8 | 9 | @SuppressWarnings("serial") 10 | public class FlappyBird extends JFrame { 11 | 12 | private static Game game; 13 | 14 | public FlappyBird() { 15 | super("FlappyBird AI"); 16 | 17 | setSize(Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT); 18 | setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 19 | setLocationRelativeTo(null); 20 | setResizable(false); 21 | 22 | game = new Game(); 23 | 24 | addKeyListener(new GameController(game)); 25 | add(game.getGameScreen()); 26 | setVisible(true); 27 | 28 | game.getGameScreen().startGame(); 29 | } 30 | 31 | public static Game getGame() { 32 | return game; 33 | } 34 | 35 | public static void main(String args[]) { 36 | new FlappyBird(); 37 | } 38 | 39 | } 40 | -------------------------------------------------------------------------------- /FlappyBirdAI/neuralnetwork/NeuralNetwork.java: -------------------------------------------------------------------------------- 1 | package neuralnetwork; 2 | 3 | import static java.lang.Math.exp; 4 | 5 | import java.io.IOException; 6 | import java.util.Random; 7 | import java.util.logging.Level; 8 | import java.util.logging.Logger; 9 | 10 | import constants.Constants; 11 | 12 | public class NeuralNetwork { 13 | 14 | public double fits[], inputs[], neurons[][]; 15 | public int layers_amount, genomes_per_generation, current_genome, current_generation; 16 | public int neurons_amount[]; 17 | public double synapses[][][][]; 18 | 19 | private double random_mutation_probability, min_weight, max_weight; 20 | 21 | private NeuronRetrieve neuronRetrieve; 22 | 23 | public NeuralNetwork(int neurons_amount[], int genomes_per_generation, double random_mutation_probability, double min_weight, double max_weight) { 24 | 25 | this.neurons_amount = neurons_amount; 26 | this.genomes_per_generation = genomes_per_generation; 27 | this.random_mutation_probability = random_mutation_probability; 28 | this.min_weight = min_weight; 29 | this.max_weight = max_weight; 30 | 31 | layers_amount = neurons_amount.length; 32 | 33 | // Create fits array 34 | fits = new double[genomes_per_generation]; 35 | 36 | // Generate neurons 37 | neurons = new double[layers_amount][]; 38 | for (int i = 0; i < layers_amount; i++) { 39 | if (i != layers_amount - 1) { 40 | neurons_amount[i]++; // The last neuron is the bias. 41 | } 42 | neurons[i] = new double[neurons_amount[i]]; 43 | } 44 | 45 | // Set biases to 1 46 | for (int i = 0; i < layers_amount - 1; i++) { 47 | neurons[i][neurons_amount[i] - 1] = 1; 48 | } 49 | 50 | // Generate synapses 51 | synapses = new double[genomes_per_generation][][][]; 52 | for (int k = 0; k < genomes_per_generation; k++) { 53 | synapses[k] = new double[layers_amount - 1][][]; 54 | for (int i = 0; i < layers_amount - 1; i++) { 55 | synapses[k][i] = new double[neurons_amount[i]][]; 56 | for (int j = 0; j < neurons_amount[i]; j++) { 57 | if (i + 1 != layers_amount - 1) { 58 | synapses[k][i][j] = new double[neurons_amount[i + 1] - 1]; 59 | } else { 60 | synapses[k][i][j] = new double[neurons_amount[i + 1]]; 61 | } 62 | } 63 | } 64 | } 65 | 66 | neuronRetrieve = new NeuronRetrieve(this); 67 | 68 | // If the file exists, load it and make the crossover. Else, init randomly 69 | if (neuronRetrieve.fileExists()) { 70 | try { 71 | neuronRetrieve.loadFromFile(); 72 | 73 | if (!Constants.BATTLE_MODE) { 74 | crossover(); 75 | } 76 | } catch (IOException ex) { 77 | Logger.getLogger(NeuralNetwork.class.getName()).log(Level.SEVERE, null, ex); 78 | } 79 | } else { 80 | initSynapsesRandomly(); 81 | } 82 | } 83 | 84 | private void initSynapsesRandomly() { 85 | for (int l = 0; l < genomes_per_generation; l++) { 86 | for (int i = 0; i < layers_amount - 1; i++) { 87 | for (int j = 0; j < neurons_amount[i]; j++) { 88 | int m; 89 | if (i + 1 != layers_amount - 1) { 90 | m = neurons_amount[i + 1] - 1; 91 | } else { 92 | m = neurons_amount[i + 1]; 93 | } 94 | for (int k = 0; k < m; k++) { 95 | synapses[l][i][j][k] = randDouble(min_weight, max_weight); 96 | } 97 | } 98 | } 99 | } 100 | } 101 | 102 | public NeuronRetrieve getSaveLoad() { 103 | return neuronRetrieve; 104 | } 105 | 106 | public double[] getOutputs(double inputs[]) { 107 | this.inputs = inputs; 108 | 109 | setNeuronsValues(); 110 | 111 | return neurons[layers_amount - 1]; 112 | } 113 | 114 | public void newGenome(double current_genome_fit) { 115 | // Set current genome fit 116 | fits[current_genome] = current_genome_fit; 117 | 118 | // If all genomes have been executed, create a new generation 119 | if (current_genome + 1 == genomes_per_generation) { 120 | current_genome = 0; 121 | newGeneration(); 122 | } else { 123 | current_genome++; 124 | } 125 | } 126 | 127 | private void newGeneration() { 128 | boolean no_progress = true; 129 | 130 | // Check if the NN made any progress 131 | for (int i = 0; i < genomes_per_generation; i++) { 132 | if (fits[i] != 0) { 133 | no_progress = false; 134 | break; 135 | } 136 | } 137 | 138 | if (no_progress) { 139 | initSynapsesRandomly(); 140 | } else { 141 | crossover(); 142 | } 143 | 144 | current_generation++; 145 | } 146 | 147 | private void crossover() { 148 | // Sort 149 | int j_max; 150 | double fit_temp, synapses_temp[][][]; 151 | for (int i = 0; i < genomes_per_generation - 1; i++) { 152 | j_max = i; 153 | for (int j = i + 1; j < genomes_per_generation; j++) { 154 | if (fits[j] > fits[j_max]) { 155 | j_max = j; 156 | } 157 | } 158 | if (j_max != i) { 159 | fit_temp = fits[i]; 160 | synapses_temp = synapses[i]; 161 | fits[i] = fits[j_max]; 162 | synapses[i] = synapses[j_max]; 163 | fits[j_max] = fit_temp; 164 | synapses[j_max] = synapses_temp; 165 | } 166 | } 167 | 168 | // The best genome is now the first. We mix it with all the other genomes 169 | double prob_rand; 170 | for (int l = 1; l < genomes_per_generation; l++) { 171 | for (int i = 0; i < layers_amount - 1; i++) { 172 | for (int j = 0; j < neurons_amount[i]; j++) { 173 | int m; 174 | if (i + 1 != layers_amount - 1) { 175 | m = neurons_amount[i + 1] - 1; 176 | } else { 177 | m = neurons_amount[i + 1]; 178 | } 179 | for (int k = 0; k < m; k++) { 180 | // If this genome made any progress, mix it with the first genome or generate a 181 | // new number randomly or keep the current value 182 | if (fits[l] != 0) { 183 | prob_rand = randDouble(0, 1); 184 | if (prob_rand < random_mutation_probability) { 185 | synapses[l][i][j][k] = randDouble(min_weight, max_weight); 186 | } else { 187 | prob_rand = randDouble(0, 1); 188 | if (prob_rand < 0.5) { 189 | synapses[l][i][j][k] = synapses[0][i][j][k]; 190 | } 191 | // Else keep the current value (implicit) 192 | } 193 | } 194 | // Else mix it with the first genome or generate a new number randomly 195 | else { 196 | prob_rand = randDouble(0, 1); 197 | if (prob_rand < random_mutation_probability) { 198 | synapses[l][i][j][k] = randDouble(min_weight, max_weight); 199 | } else { 200 | synapses[l][i][j][k] = synapses[0][i][j][k]; 201 | } 202 | } 203 | } 204 | } 205 | } 206 | } 207 | } 208 | 209 | private void setNeuronsValues() { 210 | // Copy inputs 211 | for (int i = 0; i < neurons_amount[0] - 1; i++) { 212 | neurons[0][i] = inputs[i]; 213 | } 214 | 215 | // Init the other neurons to 0 216 | for (int i = 1; i < layers_amount; i++) { 217 | int m; 218 | if (i + 1 != layers_amount) { 219 | m = neurons_amount[i] - 1; 220 | } else { 221 | m = neurons_amount[i]; 222 | } 223 | for (int j = 0; j < m; j++) { 224 | neurons[i][j] = 0; 225 | } 226 | } 227 | 228 | // Multiply neurons and synapses and sum the results (calculate the next neurons 229 | // values) 230 | for (int i = 1; i < layers_amount; i++) { 231 | int m; 232 | if (i != layers_amount - 1) { 233 | m = neurons_amount[i] - 1; 234 | } else { 235 | m = neurons_amount[i]; 236 | } 237 | for (int j = 0; j < m; j++) { 238 | for (int k = 0; k < neurons_amount[i - 1]; k++) { 239 | neurons[i][j] += neurons[i - 1][k] * synapses[current_genome][i - 1][k][j]; 240 | } 241 | 242 | // Activation function 243 | neurons[i][j] = sigmoid(neurons[i][j]); 244 | } 245 | } 246 | } 247 | 248 | private double sigmoid(double x) { 249 | return 1 / (1 + exp(-x)); 250 | } 251 | 252 | private double randDouble(double min, double max) { 253 | Random r = new Random(); 254 | return min + (max - min) * r.nextDouble(); 255 | } 256 | 257 | } 258 | -------------------------------------------------------------------------------- /FlappyBirdAI/neuralnetwork/NeuronRetrieve.java: -------------------------------------------------------------------------------- 1 | package neuralnetwork; 2 | 3 | import java.io.BufferedReader; 4 | import java.io.File; 5 | import java.io.FileNotFoundException; 6 | import java.io.FileOutputStream; 7 | import java.io.FileReader; 8 | import java.io.IOException; 9 | import java.io.PrintWriter; 10 | import java.util.Arrays; 11 | import java.util.List; 12 | 13 | import constants.Constants; 14 | 15 | public class NeuronRetrieve { 16 | 17 | private final NeuralNetwork neuralNetwork; 18 | 19 | private String file_name = "data/synapses/"; 20 | private File file = new File(file_name); 21 | 22 | private boolean first_line = true; 23 | 24 | public NeuronRetrieve(NeuralNetwork nn) { 25 | this.neuralNetwork = nn; 26 | } 27 | 28 | protected boolean fileExists() { 29 | updateFile(); 30 | 31 | return file.exists() && !file.isDirectory(); 32 | } 33 | 34 | public void saveToFile(int score) { 35 | if (Constants.BATTLE_MODE) 36 | return; 37 | 38 | int biggerScore = updateFile(); 39 | 40 | if (file != null && score >= biggerScore) { 41 | save(score, file); 42 | } 43 | } 44 | 45 | private int updateFile() { 46 | int bigger = 0; 47 | File current = null; 48 | for (File file : new File(file_name).listFiles()) { 49 | try { 50 | Integer lastScore = Integer.valueOf(file.getName().split("_")[0]); 51 | 52 | if (lastScore >= bigger) { 53 | current = file; 54 | bigger = lastScore; 55 | } 56 | } catch (Exception e) { 57 | e.printStackTrace(); 58 | } 59 | } 60 | 61 | if (current != null) 62 | file = current; 63 | 64 | return bigger; 65 | } 66 | 67 | private void save(int score, File lastFile) { 68 | this.file = new File(file_name + score + "_synapses.txt"); 69 | try { 70 | try (PrintWriter writer = new PrintWriter(new FileOutputStream(file, true))) { 71 | if (!first_line) { 72 | writer.print("\n"); 73 | } else { 74 | first_line = false; 75 | } 76 | 77 | // Append the current generation at the end of the file 78 | for (int l = 0; l < neuralNetwork.genomes_per_generation; l++) { 79 | for (int i = 0; i < neuralNetwork.layers_amount - 1; i++) { 80 | for (int j = 0; j < neuralNetwork.neurons_amount[i]; j++) { 81 | int m; 82 | if (i + 1 != neuralNetwork.layers_amount - 1) { 83 | m = neuralNetwork.neurons_amount[i + 1] - 1; 84 | } else { 85 | m = neuralNetwork.neurons_amount[i + 1]; 86 | } 87 | for (int k = 0; k < m; k++) { 88 | writer.print(neuralNetwork.synapses[l][i][j][k] + " "); 89 | } 90 | } 91 | } 92 | } 93 | } 94 | lastFile.delete(); 95 | } catch (Exception e) { 96 | e.printStackTrace(); 97 | } 98 | } 99 | 100 | protected void loadFromFile() throws FileNotFoundException, IOException { 101 | String current_line, last_generation = null; 102 | 103 | @SuppressWarnings("resource") 104 | BufferedReader reader = new BufferedReader(new FileReader(file)); 105 | 106 | // Get the last line and store it into last_generation 107 | while ((current_line = reader.readLine()) != null) { 108 | last_generation = current_line; 109 | } 110 | 111 | // Split the string and store the numbers (as text) 112 | List values = Arrays.asList(last_generation.trim().split(" ")); 113 | 114 | // Init the synapsis 115 | int n = 0; 116 | for (int l = 0; l < neuralNetwork.genomes_per_generation; l++) { 117 | for (int i = 0; i < neuralNetwork.layers_amount - 1; i++) { 118 | for (int j = 0; j < neuralNetwork.neurons_amount[i]; j++) { 119 | int m; 120 | if (i + 1 != neuralNetwork.layers_amount - 1) { 121 | m = neuralNetwork.neurons_amount[i + 1] - 1; 122 | } else { 123 | m = neuralNetwork.neurons_amount[i + 1]; 124 | } 125 | for (int k = 0; k < m; k++) { 126 | neuralNetwork.synapses[l][i][j][k] = Double.parseDouble(values.get(n)); 127 | n++; 128 | } 129 | } 130 | } 131 | } 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /FlappyBirdAI/utils/Animation.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.util.ArrayList; 5 | import java.util.List; 6 | 7 | public class Animation { 8 | 9 | private List list; 10 | private long deltaTime, previousTime; 11 | private int currentFrame = 0; 12 | 13 | public Animation(int deltaTime) { 14 | this.deltaTime = deltaTime; 15 | this.list = new ArrayList(); 16 | this.previousTime = 0; 17 | } 18 | 19 | public void updateFrame() { 20 | if (System.currentTimeMillis() - previousTime >= deltaTime) { 21 | currentFrame++; 22 | 23 | if (currentFrame >= list.size()) 24 | currentFrame = 0; 25 | 26 | previousTime = System.currentTimeMillis(); 27 | } 28 | } 29 | 30 | public void addFrame(BufferedImage image) { 31 | list.add(image); 32 | } 33 | 34 | public BufferedImage getFrame() { 35 | if (currentFrame == list.size()) 36 | return list.get(0); 37 | 38 | return list.get(currentFrame); 39 | } 40 | 41 | } 42 | -------------------------------------------------------------------------------- /FlappyBirdAI/utils/ImageTool.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.awt.Color; 4 | import java.awt.Graphics; 5 | import java.awt.image.BufferedImage; 6 | import java.io.File; 7 | import java.io.IOException; 8 | 9 | import javax.imageio.ImageIO; 10 | 11 | public class ImageTool { 12 | 13 | private static final int THRESHOLD = 35, TRANSPARENT = 0; // 0x00000000; 14 | 15 | private File inputFile, outputFile; 16 | 17 | private BufferedImage outputImage; 18 | 19 | public ImageTool(File inputFile) { 20 | this.inputFile = inputFile; 21 | } 22 | 23 | public void setOutputFile(File outputFile) { 24 | this.outputFile = outputFile; 25 | } 26 | 27 | public void removeColor(Color replaceColor) { 28 | try { 29 | 30 | if (outputImage == null) 31 | outputImage = ImageIO.read(inputFile); 32 | 33 | int width = outputImage.getWidth(null), height = outputImage.getHeight(null); 34 | 35 | BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 36 | 37 | Graphics g = image.getGraphics(); 38 | 39 | g.drawImage(outputImage, 0, 0, null); 40 | 41 | for (int y = 0; y < height; y++) { 42 | for (int x = 0; x < width; x++) { 43 | int pixel = image.getRGB(x, y); 44 | Color color = new Color(pixel); 45 | 46 | int dr = Math.abs(color.getRed() - replaceColor.getRed()), dg = Math.abs(color.getGreen() - replaceColor.getGreen()), db = Math.abs(color.getBlue() - replaceColor.getBlue()); 47 | 48 | if (dr < THRESHOLD && dg < THRESHOLD && db < THRESHOLD) { 49 | image.setRGB(x, y, TRANSPARENT); 50 | } 51 | } 52 | } 53 | 54 | outputImage = image; 55 | } catch (Exception e) { 56 | e.printStackTrace(); 57 | } 58 | } 59 | 60 | public void changeColor(Color oldColor, Color newColor) { 61 | try { 62 | if (outputImage == null) 63 | outputImage = ImageIO.read(inputFile); 64 | 65 | int RGB_MASK = 0x00ffffff; 66 | 67 | int oldRGB = oldColor.getRed() << 16 | oldColor.getGreen() << 8 | oldColor.getBlue(); 68 | int toggleRGB = oldRGB ^ (newColor.getRed() << 16 | newColor.getGreen() << 8 | newColor.getBlue()); 69 | 70 | int w = outputImage.getWidth(); 71 | int h = outputImage.getHeight(); 72 | 73 | int[] rgb = outputImage.getRGB(0, 0, w, h, null, 0, w); 74 | for (int i = 0; i < rgb.length; i++) { 75 | if ((rgb[i] & RGB_MASK) == oldRGB) { 76 | rgb[i] ^= toggleRGB; 77 | } 78 | } 79 | outputImage.setRGB(0, 0, w, h, rgb, 0, w); 80 | 81 | } catch (Exception e) { 82 | e.printStackTrace(); 83 | } 84 | } 85 | 86 | public BufferedImage getImage() { 87 | return outputImage; 88 | } 89 | 90 | public void save(String fileType) throws Exception { 91 | if (outputFile == null) 92 | throw new Exception("The output file is null."); 93 | 94 | try { 95 | ImageIO.write(outputImage, fileType, outputFile); 96 | } catch (IOException e) { 97 | e.printStackTrace(); 98 | } 99 | } 100 | 101 | } -------------------------------------------------------------------------------- /FlappyBirdAI/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package utils; 2 | 3 | import java.awt.Color; 4 | import java.awt.image.BufferedImage; 5 | import java.io.File; 6 | import java.io.IOException; 7 | 8 | import javax.imageio.ImageIO; 9 | 10 | public class Utils { 11 | 12 | public static BufferedImage changeColor(File file, Color color) { 13 | ImageTool imageTool = new ImageTool(file); 14 | 15 | imageTool.changeColor(Color.BLACK, color); 16 | 17 | return imageTool.getImage(); 18 | } 19 | 20 | public static String compareTime(long current, long end) { 21 | long different = end - current; 22 | 23 | long secondsInMilli = 1000; 24 | long minutesInMilli = secondsInMilli * 60; 25 | long hoursInMilli = minutesInMilli * 60; 26 | long daysInMilli = hoursInMilli * 24; 27 | long mounthsInMilli = daysInMilli * 30; 28 | 29 | different = different % mounthsInMilli; 30 | 31 | long days = different / daysInMilli; 32 | different = different % daysInMilli; 33 | 34 | long hours = different / hoursInMilli; 35 | different = different % hoursInMilli; 36 | 37 | long minutes = different / minutesInMilli; 38 | different = different % minutesInMilli; 39 | 40 | long seconds = different / secondsInMilli; 41 | 42 | return days + "d " + hours + "h " + minutes + "min " + seconds + " sec"; 43 | } 44 | 45 | public static BufferedImage getImageResource(String path) { 46 | BufferedImage img = null; 47 | try { 48 | img = ImageIO.read(new File(path)); 49 | } catch (IOException e) { 50 | e.printStackTrace(); 51 | } 52 | return img; 53 | } 54 | 55 | } 56 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Java Projects 2 | 3 | ### Hey! 4 | Here are some of my public Java projects. 5 | 6 | ### FLAPPY BIRD GAME ARTIFICIAL INTELLIGENCE 7 | - [Watch a demo video](https://www.youtube.com/watch?v=eHvFdgZAawI)
8 | - [Read more](https://github.com/GustavoRolimSantos/Java/edit/master/FlappyBirdAI)

9 | [![Flappy Bird Game AI](https://github.com/GustavoRolimSantos/Java/blob/master/FlappyBirdAI/data/FlappyBird-demo.gif)](https://www.youtube.com/watch?v=eHvFdgZAawI) 10 | 11 | ### GOOGLE DINOSAUR GAME ARTIFICIAL INTELLIGENCE 12 | - [Watch a demo video](https://www.youtube.com/watch?v=szKEPME56y8)
13 | - [Read more](https://github.com/GustavoRolimSantos/Java/tree/master/Chrome-Dino-Game-AI)

14 | [![Google Dinosaur Game AI](https://github.com/GustavoRolimSantos/Java/blob/master/Chrome-Dino-Game-AI/trained.gif)](https://www.youtube.com/watch?v=szKEPME56y8&feature=youtu.be) 15 | 16 | ### JAVA RESPONSIVE SWING MATERIAL DESIGN FRAMEWORK 17 | - [Watch a demo video](https://www.youtube.com/watch?v=ZijJrgkgyUA)
18 | - [Read more](https://github.com/GustavoRolimSantos/Java/tree/master/ResponsiveSwingMaterialDesign)

19 | [![Java Responsive Swing Material Design Framework](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Form.png)](https://www.youtube.com/watch?v=ZijJrgkgyUA) 20 | 21 | > COPYRIGHT BY GUSTAVO ROLIM DOS SANTOS 2020. 22 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/README.md: -------------------------------------------------------------------------------- 1 | ## JAVA RESPONSIVE SWING MATERIAL DESIGN FRAMEWORK 2 | 3 | ### BEAULTY AND RESPONSIVE SWING COMPONENTS 4 | 5 | **COMPONENTS:** 6 | - INPUT FIELD (PREDEFINED VALIDATIONS: EMAIL, PHONE, MONEY. OBS: YOU CAN CREATE YOUR OWN MASK/VALIDATION) 7 | - PASSWORD FIELD 8 | - TEXT AREA 9 | - DATE FIELD 10 | - DATE PICKER 11 | - CHECK CIRCLE 12 | - COMBOBOX 13 | - IMAGE 14 | - BUTTON 15 | 16 | ### Sign Up Form developed using this framework 17 | https://www.youtube.com/watch?v=ZijJrgkgyUA&feature=youtu.be 18 | 19 | [![SignUp Form](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Form.png)](https://www.youtube.com/watch?v=ZijJrgkgyUA&feature=youtu.be) 20 | 21 | ### Responsive Layout (Default 1280x800) 22 | ```java 23 | // Create a responsive layout using ResponsiveLayout(frameWidth, frameHeight, columns, rows, jFrame) 24 | ResponsiveLayout rl = new ResponsiveLayout(12, 12, jFrame); 25 | ``` 26 | ![Responsive Layout](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_1.png) 27 | 28 | ```java 29 | public static void main(String[] args) { 30 | // You can create your jframe normally, using this class you can do it faster. 31 | // build(String name, int x, int y, int width, int height, boolean moveable) 32 | JFrame frame = FrameUtility.build("Java Responsive Swing Material Design", 0, 0, 1280, 900, true); 33 | 34 | ResponsiveLayout rl = new ResponsiveLayout(12, 12, frame); 35 | 36 | rl.add(new InputField("Email de contato", rl).email().getComponent(), 4, 1); 37 | rl.add(new InputField("Telefone de contato", rl).phone().getComponent(), 4, 1); 38 | rl.add(new InputField("Valor em reais", rl).money().getComponent(), 4, 1); 39 | rl.addRow(); 40 | rl.add(new PasswordField("Senha", rl).getComponent(), 6, 1); 41 | rl.add(new CheckCircle("Texto do Check", rl).getComponent(), 3, 1); 42 | rl.add(new CheckCircle("Texto do Check 2", rl).getComponent(), 3, 1); 43 | 44 | rl.add(new TextArea("Área de Texto", rl).getComponent(), 6, 4); 45 | rl.add(new TextArea("Área de Texto", rl).getComponent(), 6, 4); 46 | rl.add(new DateField("Data", rl).getComponent(), 6, 1); 47 | rl.add(new DateTimeField("Data e Hora", rl).getComponent(), 6, 1); 48 | 49 | frame.setVisible(true); 50 | frame.setLocationRelativeTo(null); 51 | } 52 | ``` 53 | 54 | ### Creating your own Theme 55 | 56 | ```java 57 | // Create theme model using ThemeModel 58 | ThemeModel theme = new ThemeModel("model_name", primaryColor, secondaryColor, errorColor, textColor, backgroundColor); 59 | 60 | // Add your theme into the framework 61 | ResponsiveSwingMaterialDesign.getThemesManager().addTheme(model); 62 | 63 | // Set the current theme using setCurrentTheme(model) or setCurrentTheme("themeName") 64 | ResponsiveSwingMaterialDesign.getThemesManager().setCurrentTheme("themeName"); 65 | ``` 66 | ### Applying themes 67 | 68 | Available themes: 69 | 1. Light 70 | 2. Darcula 71 | 3. Dark 72 | 73 | ```java 74 | // Set the current theme using setCurrentTheme(model) or setCurrentTheme("themeName") 75 | ResponsiveSwingMaterialDesign.getThemesManager().setCurrentTheme("themeName"); 76 | ``` 77 | 78 | ### Skipping Rows 79 | ```java 80 | // To Skip rows in responsive layout use addRow(). (There are some bugs to solve) 81 | rl.addRow(); 82 | ``` 83 | 84 | ### Input Fields 85 | 86 | ```java 87 | // There are some pre-validations that you can use on any input field you want. 88 | 89 | inputField.email(); 90 | inputField.phone(); 91 | inputField..money(); 92 | 93 | // To create your own mask use setMask(regex) 94 | setMask("(##) #####-####"); 95 | 96 | // To create your own validation rules use setRules(callback) 97 | 98 | inputField.setRules(new Callback() { 99 | @Override 100 | public String done() { 101 | String value = inputField.getText(); 102 | 103 | if (value.isEmpty()) 104 | return "Type something here."; 105 | 106 | return null; 107 | } 108 | }); 109 | 110 | ``` 111 | 112 | ### E-mail Field 113 | ```java 114 | // Add InputField component into ResponsiveLayout using rl.add(component, columns, rows) 115 | rl.add(new InputField("Email de contato", rl).email().getComponent(), 4, 1); // Using 4 columns and 1 row 116 | ``` 117 | ![E-mail Field](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_4.png) 118 | 119 | ### Phone Field 120 | ```java 121 | rl.add(new InputField("Telefone de contato", rl).phone().getComponent(), 4, 1); // Using 4 columns and 1 row 122 | ``` 123 | ![Phone Field](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_5.png) 124 | 125 | ### Money Field (price) 126 | ```java 127 | rl.add(new InputField("Valor em reais", rl).money().getComponent(), 4, 1); // Using 4 columns and 1 row 128 | ``` 129 | ![Value Field](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_6.png) 130 | 131 | ### Password Field 132 | ```java 133 | rl.add(new PasswordField("Senha", rl).getComponent(), 6, 1); // Using 6 columns and 1 row 134 | ``` 135 | ![Password Field](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_7.png) 136 | 137 | ### Text Area 138 | ```java 139 | rl.add(new TextArea("Área de Texto", rl).getComponent(), 6, 4); // Using 6 columns and 4 row 140 | ``` 141 | ![Text Area](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_8.png) 142 | 143 | ### Date Field 144 | ```java 145 | 146 | DateField dateField = new DateField("Data", rl).getComponent(); 147 | 148 | // To set date use setDate(Date date) 149 | dateField.setDate(new Date()); 150 | 151 | // To set date format use setDateFormat(String format) 152 | setDateFormat("dd/MM/yyyy"); 153 | 154 | // To get the Date use getDate() and getDateText() 155 | getDate(); 156 | 157 | rl.add(dateField, 6, 1); 158 | ``` 159 | ![Date Field](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_10.png) 160 | 161 | ### Date and Time Field 162 | ```java 163 | rl.add(new DateTimeField("Data e Hora", rl).getComponent(), 6, 1); // Using 6 columns and 1 row 164 | ``` 165 | ![Date and Time Field](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_11.png) 166 | 167 | ### Components (Dracula theme) 168 | ![Components Dracula theme](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Darkmode.png) 169 | 170 | ### Date Picker 171 | ![Date Picker](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/Screenshot_9.png) 172 | 173 | ### Date Picker (Dracula theme) 174 | ![Date Picker](https://github.com/GustavoRolimSantos/Java/blob/master/ResponsiveSwingMaterialDesign/images/DatePicker%20DarkMode.png) 175 | 176 | > COPYRIGHT BY GUSTAVO ROLIM DOS SANTOS 2020. 177 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/ResponsiveSwingMaterialDesign.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing; 2 | 3 | import java.awt.Color; 4 | 5 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout; 6 | import br.com.maxtercreations.responsiveswing.theme.ThemesManager; 7 | 8 | public class ResponsiveSwingMaterialDesign { 9 | 10 | private static final ThemesManager themesManager = new ThemesManager(); 11 | 12 | public static Color PRIMARY_COLOR = new Color(0, 110, 204); 13 | public static Color SECONDARY_COLOR = new Color(128, 134, 139); 14 | public static Color ERROR_COLOR = new Color(148, 82, 82); 15 | public static Color TEXT_COLOR = new Color(128, 134, 139); 16 | public static Color BACKGROUND_COLOR = new Color(246, 248, 250); 17 | 18 | public static ThemesManager getThemesManager() { 19 | return themesManager; 20 | } 21 | 22 | public static void setCurrentTheme(String themeName, ResponsiveLayout... layouts) { 23 | themesManager.setCurrentTheme(themeName); 24 | 25 | PRIMARY_COLOR = themesManager.getCurrentModel().getPrimaryColor(); 26 | SECONDARY_COLOR = themesManager.getCurrentModel().getSecondaryColor(); 27 | ERROR_COLOR = themesManager.getCurrentModel().getErrorColor(); 28 | TEXT_COLOR = themesManager.getCurrentModel().getTextColor(); 29 | 30 | BACKGROUND_COLOR = themesManager.getCurrentModel().getBackgroundColor(); 31 | 32 | for (ResponsiveLayout layout : layouts) { 33 | layout.update(); 34 | } 35 | } 36 | 37 | } 38 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/animation/AnimateComponent.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.animation; 2 | 3 | import java.awt.Font; 4 | import java.util.ArrayList; 5 | 6 | import javax.swing.JComponent; 7 | import javax.swing.Timer; 8 | 9 | import br.com.maxtercreations.responsiveswing.utils.Utils; 10 | 11 | public class AnimateComponent { 12 | 13 | private int fontIndex = 1; 14 | 15 | public void execute(int time, ArrayList animations) { 16 | fontIndex = 0; 17 | 18 | ArrayList fonts = new ArrayList<>(); 19 | 20 | Animation an = animations.get(0); 21 | double t = 0; 22 | 23 | while (t < an.getFont().getSize()) { 24 | int dif = (int) (an.getPoint1().getY() - an.getPoint2().getY()); 25 | 26 | t = (an.getFont().getSize() / dif * fontIndex); 27 | 28 | fonts.add(Utils.getMainFont((int) (t))); 29 | 30 | fontIndex++; 31 | } 32 | 33 | Timer timer = new Timer(time, null); 34 | 35 | timer.addActionListener(e -> { 36 | 37 | for (int i = 0; i < animations.size(); i++) { 38 | Animation animation = animations.get(i); 39 | JComponent c = animation.getComponent(); 40 | 41 | boolean stop = false; 42 | 43 | if (!stop && (animation.getYSkipper() == Animation.STEP && c.getY() <=( (int)animation.getPoint2().getY())) || (animation.getYSkipper() == -Animation.STEP && c.getY() > ((int)animation.getPoint2().getY()))) { 44 | new Thread(() -> { 45 | c.setBounds(c.getX(), c.getY() + animation.getYSkipper(), (int) c.getWidth(), (int) c.getHeight()); 46 | }).start(); 47 | 48 | new Thread(() -> { 49 | c.setFont(fonts.get(fontIndex - 1)); 50 | }).start(); 51 | } else { 52 | stop = true; 53 | } 54 | 55 | if (stop) { 56 | System.out.println("Animation finished."); 57 | 58 | if (animation.getCallback() != null) { 59 | animation.getCallback().done(); 60 | } 61 | 62 | timer.stop(); 63 | } 64 | } 65 | }); 66 | 67 | timer.start(); 68 | 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/animation/Animation.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.animation; 2 | 3 | import java.awt.Font; 4 | import java.awt.Point; 5 | 6 | import javax.swing.JComponent; 7 | 8 | import br.com.maxtercreations.responsiveswing.callback.Callback; 9 | import br.com.maxtercreations.responsiveswing.utils.Utils; 10 | 11 | public class Animation { 12 | 13 | private JComponent component; 14 | private Point point1, point2; 15 | private Font font; 16 | 17 | private Callback callback; 18 | 19 | public static final int STEP = 1; 20 | 21 | public Animation(JComponent component, Point point1, Point point2) { 22 | this.component = component; 23 | this.font = Utils.getMainFont(component.getFont().getSize() - (component.getFont().getSize() / 3)); 24 | this.point1 = point1; 25 | this.point2 = point2; 26 | } 27 | 28 | public JComponent getComponent() { 29 | return component; 30 | } 31 | 32 | public int getXSkipper() { 33 | return point1.getX() - point2.getX() < 0 ? -STEP : STEP; 34 | } 35 | 36 | public int getYSkipper() { 37 | return point1.getY() - point2.getY() < 0 ? STEP : -STEP; 38 | } 39 | 40 | public Point getPoint1() { 41 | return point1; 42 | } 43 | 44 | public Point getPoint2() { 45 | return point2; 46 | } 47 | 48 | public Font getFont() { 49 | return font; 50 | } 51 | 52 | public void setCallback(Callback callback) { 53 | this.callback = callback; 54 | } 55 | 56 | public Callback getCallback() { 57 | return callback; 58 | } 59 | 60 | } 61 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/callback/Callback.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.callback; 2 | 3 | public abstract class Callback { 4 | 5 | public abstract String done(); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/callback/CallbackT.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.callback; 2 | 3 | public interface CallbackT { 4 | 5 | public void done(Object object); 6 | 7 | } 8 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/buttons/MaterialButton.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.buttons; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Rectangle; 6 | import java.awt.event.ComponentAdapter; 7 | import java.awt.event.ComponentEvent; 8 | import java.awt.event.MouseAdapter; 9 | import java.awt.event.MouseEvent; 10 | 11 | import javax.swing.JLabel; 12 | import javax.swing.SwingConstants; 13 | 14 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 15 | import br.com.maxtercreations.responsiveswing.callback.CallbackT; 16 | import br.com.maxtercreations.responsiveswing.components.utils.RoundedBorder; 17 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout; 18 | import br.com.maxtercreations.responsiveswing.utils.Utils; 19 | 20 | public class MaterialButton { 21 | 22 | private final int RADIUS = 20; 23 | 24 | private ResponsiveLayout responsiveLayout; 25 | 26 | private RoundedButton backgroundButton; 27 | private JLabel textLabel; 28 | private Font defaultFont = Utils.getMainFont(20); 29 | 30 | private Color hoverColor; 31 | 32 | private Color primaryColor = new Color(0, 0, 0); 33 | 34 | @SuppressWarnings("serial") 35 | public MaterialButton(String text, ResponsiveLayout responsiveLayout, CallbackT eventCallback) { 36 | this.responsiveLayout = responsiveLayout; 37 | this.backgroundButton = new RoundedButton(text, defaultFont, ResponsiveSwingMaterialDesign.PRIMARY_COLOR, new Rectangle(), RADIUS, 1, eventCallback) { 38 | @Override 39 | public void repaint() { 40 | super.repaint(); 41 | if (backgroundButton != null && !primaryColor.equals(ResponsiveSwingMaterialDesign.PRIMARY_COLOR)) { 42 | primaryColor = ResponsiveSwingMaterialDesign.PRIMARY_COLOR; 43 | 44 | backgroundButton.recolor(ResponsiveSwingMaterialDesign.PRIMARY_COLOR, RADIUS, true); 45 | } 46 | } 47 | }; 48 | this.backgroundButton.setBorder(new RoundedBorder(RADIUS, ResponsiveSwingMaterialDesign.PRIMARY_COLOR, true)); 49 | 50 | double factor = 0.9; 51 | 52 | this.hoverColor = new Color(Math.max((int)(ResponsiveSwingMaterialDesign.PRIMARY_COLOR.getRed() *factor), 0), 53 | Math.max((int)(ResponsiveSwingMaterialDesign.PRIMARY_COLOR.getGreen()*factor), 0), 54 | Math.max((int)(ResponsiveSwingMaterialDesign.PRIMARY_COLOR.getBlue() *factor), 0), 55 | ResponsiveSwingMaterialDesign.PRIMARY_COLOR.getAlpha()); 56 | 57 | this.textLabel = new JLabel(text); 58 | this.textLabel.setForeground(Color.WHITE); 59 | this.textLabel.setFont(defaultFont); 60 | this.textLabel.setHorizontalAlignment(SwingConstants.CENTER); 61 | this.textLabel.setVerticalAlignment(SwingConstants.CENTER); 62 | this.textLabel.addMouseListener(new MouseAdapter() { 63 | @Override 64 | public void mouseClicked(MouseEvent e) { 65 | if (eventCallback != null) 66 | eventCallback.done(textLabel.getText()); 67 | } 68 | @Override 69 | public void mouseEntered(MouseEvent e) { 70 | primaryColor = ResponsiveSwingMaterialDesign.PRIMARY_COLOR; 71 | 72 | hoverColor = new Color( 73 | 74 | Math.max((int)(primaryColor.getRed() * factor), 0), 75 | Math.max((int)(primaryColor.getGreen() * factor), 0), 76 | Math.max((int)(primaryColor.getBlue() * factor), 0), 77 | primaryColor.getAlpha() 78 | 79 | ); 80 | 81 | backgroundButton.recolor(hoverColor, RADIUS, true); 82 | } 83 | @Override 84 | public void mouseExited(MouseEvent e) { 85 | backgroundButton.recolor(ResponsiveSwingMaterialDesign.PRIMARY_COLOR, RADIUS, true); 86 | } 87 | }); 88 | this.backgroundButton.addComponentListener(new ComponentAdapter() { 89 | public void componentResized(ComponentEvent componentEvent) { 90 | textLabel.setForeground(Color.WHITE); 91 | backgroundButton.recolor(ResponsiveSwingMaterialDesign.PRIMARY_COLOR, 20, true); 92 | textLabel.setBounds(backgroundButton.getX(), backgroundButton.getY() - 2, backgroundButton.getWidth(),backgroundButton.getHeight()); 93 | } 94 | }); 95 | 96 | } 97 | 98 | public RoundedButton getComponent() { 99 | responsiveLayout.add(textLabel); 100 | 101 | return backgroundButton; 102 | } 103 | 104 | public void seFont(Font font) { 105 | this.defaultFont = font; 106 | this.textLabel.setFont(font); 107 | } 108 | 109 | public String getCaption() { 110 | return textLabel.getText(); 111 | } 112 | 113 | public void setCaption(String caption) { 114 | this.textLabel.setText(caption); 115 | } 116 | 117 | } 118 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/buttons/RoundedButton.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.buttons; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Rectangle; 6 | import java.awt.event.MouseAdapter; 7 | import java.awt.event.MouseEvent; 8 | 9 | import javax.swing.JButton; 10 | 11 | import br.com.maxtercreations.responsiveswing.callback.CallbackT; 12 | import br.com.maxtercreations.responsiveswing.components.utils.RoundedBorder; 13 | 14 | @SuppressWarnings("serial") 15 | public class RoundedButton extends JButton { 16 | 17 | public RoundedButton(String text, Font font, Color color, Rectangle rectangle, CallbackT callbackT) { 18 | draw(text, font, color, null, rectangle, 50, 1, callbackT); 19 | } 20 | 21 | public RoundedButton(String text, Font font, Color color, Rectangle rectangle, int radius, CallbackT callback) { 22 | draw(text, font, color, null, rectangle, radius, 1, callback); 23 | } 24 | 25 | public RoundedButton(String text, Font font, Color color, Rectangle rectangle, int radius, int stroke, CallbackT callback) { 26 | draw(text, font, color, null, rectangle, radius, stroke, callback); 27 | } 28 | 29 | private void draw(String text, Font font, Color foreground, Color background, Rectangle rectangle, int radius, int stroke, CallbackT callback) { 30 | setOpaque(false); 31 | RoundedBorder border = new RoundedBorder(radius, background); 32 | border.setStroke(stroke); 33 | setBorder(border); 34 | 35 | if (rectangle != null) { 36 | setBounds(rectangle); 37 | } 38 | 39 | setForeground(foreground); 40 | setFont(font); 41 | setText(text); 42 | setContentAreaFilled(false); 43 | setFocusPainted(false); 44 | 45 | if (callback != null) { 46 | addMouseListener(new MouseAdapter() { 47 | @Override 48 | public void mouseClicked(MouseEvent e) { 49 | callback.done(getText()); 50 | } 51 | }); 52 | } 53 | } 54 | 55 | public void recolor(Color color, int radius, boolean fill) { 56 | RoundedBorder border = new RoundedBorder(radius, color, fill); 57 | border.setStroke(2); 58 | setBorder(border); 59 | } 60 | 61 | } 62 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/buttons/RoundedFillButton.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.buttons; 2 | 3 | import java.awt.Color; 4 | import java.awt.Font; 5 | import java.awt.Rectangle; 6 | import java.awt.event.MouseAdapter; 7 | import java.awt.event.MouseEvent; 8 | 9 | import javax.swing.JLabel; 10 | import javax.swing.JPanel; 11 | import javax.swing.SwingConstants; 12 | 13 | import br.com.maxtercreations.responsiveswing.callback.CallbackT; 14 | import br.com.maxtercreations.responsiveswing.components.utils.RoundedBorder; 15 | 16 | public class RoundedFillButton { 17 | 18 | private RoundedButton backgroundButton; 19 | private JLabel textLabel; 20 | private JPanel panel; 21 | 22 | public RoundedFillButton(String text, Font font, Color foreground, Color background, Rectangle rectangle, int radius, int stroke, JPanel panel, Boolean build, CallbackT callbackT) { 23 | this.panel = panel; 24 | this.backgroundButton = new RoundedButton(text, font, background, rectangle, radius, stroke, callbackT); 25 | this.backgroundButton.setBorder(new RoundedBorder(radius, background, true)); 26 | this.textLabel = new JLabel(text); 27 | 28 | if (rectangle != null) 29 | this.textLabel.setBounds(rectangle); 30 | 31 | this.textLabel.setForeground(foreground); 32 | this.textLabel.setFont(font); 33 | this.textLabel.setHorizontalAlignment(SwingConstants.CENTER); 34 | this.textLabel.setVerticalAlignment(SwingConstants.CENTER); 35 | this.textLabel.addMouseListener(new MouseAdapter() { 36 | @Override 37 | public void mouseClicked(MouseEvent e) { 38 | if (callbackT != null) 39 | callbackT.done(textLabel.getText()); 40 | } 41 | }); 42 | 43 | if (build) 44 | build(); 45 | } 46 | 47 | public void dispose() { 48 | panel.remove(backgroundButton); 49 | panel.remove(textLabel); 50 | } 51 | 52 | public void build() { 53 | panel.add(textLabel); 54 | panel.add(backgroundButton); 55 | } 56 | 57 | public void ajustText(int y) { 58 | textLabel.setBounds(textLabel.getX(), textLabel.getY() + y, textLabel.getWidth(), textLabel.getHeight()); 59 | } 60 | 61 | public void ajustText(int x, int y) { 62 | textLabel.setBounds(textLabel.getX() + x, textLabel.getY() + y, textLabel.getWidth(), textLabel.getHeight()); 63 | } 64 | 65 | public JLabel getTextLabel() { 66 | return textLabel; 67 | } 68 | 69 | public RoundedButton getBackgroundButton() { 70 | return backgroundButton; 71 | } 72 | 73 | public void setVisible(boolean visible) { 74 | textLabel.setVisible(visible); 75 | backgroundButton.setVisible(visible); 76 | } 77 | 78 | public boolean isVisible() { 79 | return textLabel.isVisible(); 80 | } 81 | 82 | public void setVerticalAlignment(int alignment) { 83 | textLabel.setVerticalAlignment(alignment); 84 | backgroundButton.setVerticalAlignment(alignment); 85 | } 86 | 87 | public void setHorizontalAlignment(int alignment) { 88 | textLabel.setHorizontalAlignment(alignment); 89 | backgroundButton.setHorizontalAlignment(alignment); 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/check/CheckCircle.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.check; 2 | 3 | import java.awt.Rectangle; 4 | 5 | import javax.swing.JLabel; 6 | import javax.swing.JPanel; 7 | import javax.swing.SwingConstants; 8 | 9 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 10 | import br.com.maxtercreations.responsiveswing.callback.CallbackT; 11 | import br.com.maxtercreations.responsiveswing.components.buttons.RoundedButton; 12 | import br.com.maxtercreations.responsiveswing.components.buttons.RoundedFillButton; 13 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout; 14 | import br.com.maxtercreations.responsiveswing.utils.Utils; 15 | 16 | public class CheckCircle { 17 | 18 | private JPanel card; 19 | 20 | private RoundedButton border; 21 | private RoundedFillButton button; 22 | private JLabel captionLabel; 23 | 24 | private CallbackT callbackT; 25 | 26 | @SuppressWarnings("serial") 27 | public CheckCircle(String caption, CallbackT changeStateEvent, ResponsiveLayout rl) { 28 | this.callbackT = changeStateEvent; 29 | 30 | card = new JPanel() { 31 | @Override 32 | public void repaint() { 33 | super.repaint(); 34 | 35 | if (captionLabel != null && !captionLabel.getForeground().equals(ResponsiveSwingMaterialDesign.SECONDARY_COLOR)) { 36 | captionLabel.setForeground(ResponsiveSwingMaterialDesign.SECONDARY_COLOR); 37 | border.recolor(ResponsiveSwingMaterialDesign.PRIMARY_COLOR, 25, false); 38 | button.getBackgroundButton().recolor(ResponsiveSwingMaterialDesign.PRIMARY_COLOR, 25, true); 39 | } 40 | } 41 | }; 42 | card.setLayout(null); 43 | card.setOpaque(false); 44 | 45 | border = new RoundedButton(null, null, ResponsiveSwingMaterialDesign.PRIMARY_COLOR, new Rectangle(0, card.getY() + (card.getHeight() / 2) + 21, 25, 25), 25, new CallbackT() { 46 | @Override 47 | public void done(Object s) { 48 | button.setVisible(!button.isVisible()); 49 | callbackT.done(button.isVisible()); 50 | } 51 | }); 52 | border.setVerticalAlignment(SwingConstants.CENTER); 53 | 54 | 55 | button = new RoundedFillButton(null, null, null, ResponsiveSwingMaterialDesign.PRIMARY_COLOR, new Rectangle(4, card.getY() + (card.getHeight() / 2) + 25, 17, 17), 17, 1, card, true, new CallbackT() { 56 | @Override 57 | public void done(Object s) { 58 | button.setVisible(!button.isVisible()); 59 | callbackT.done(button.isVisible()); 60 | } 61 | }); 62 | button.setVerticalAlignment(SwingConstants.CENTER); 63 | 64 | 65 | card.add(border); 66 | 67 | captionLabel = new JLabel(caption); 68 | captionLabel.setFont(Utils.getMainFont(15)); 69 | captionLabel.setVerticalAlignment(SwingConstants.CENTER); 70 | captionLabel.setBounds(40, 5, captionLabel.getFontMetrics(captionLabel.getFont()).stringWidth(caption) + 20, 50); 71 | captionLabel.setForeground(ResponsiveSwingMaterialDesign.SECONDARY_COLOR); 72 | card.add(captionLabel); 73 | } 74 | 75 | public void setCaption(String caption) { 76 | this.captionLabel.setText(caption); 77 | } 78 | 79 | public boolean isChecked() { 80 | return button.isVisible(); 81 | } 82 | 83 | public CheckCircle setChecked(boolean checked) { 84 | button.setVisible(checked); 85 | callbackT.done(checked); 86 | return this; 87 | } 88 | 89 | public JPanel getComponent() { 90 | return card; 91 | } 92 | 93 | } 94 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/combobox/AutoCompletion.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.combobox; 2 | 3 | import java.awt.event.ActionEvent; 4 | import java.awt.event.ActionListener; 5 | import java.awt.event.FocusAdapter; 6 | import java.awt.event.FocusEvent; 7 | import java.awt.event.FocusListener; 8 | import java.awt.event.KeyAdapter; 9 | import java.awt.event.KeyEvent; 10 | import java.awt.event.KeyListener; 11 | import java.beans.PropertyChangeEvent; 12 | import java.beans.PropertyChangeListener; 13 | 14 | import javax.swing.ComboBoxEditor; 15 | import javax.swing.ComboBoxModel; 16 | import javax.swing.JComboBox; 17 | import javax.swing.border.EmptyBorder; 18 | import javax.swing.text.AttributeSet; 19 | import javax.swing.text.BadLocationException; 20 | import javax.swing.text.JTextComponent; 21 | import javax.swing.text.PlainDocument; 22 | 23 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 24 | import br.com.maxtercreations.responsiveswing.components.utils.RoundedBorder; 25 | 26 | /* This work is hereby released into the Public Domain. 27 | * To view a copy of the public domain dedication, visit 28 | * http://creativecommons.org/licenses/publicdomain/ 29 | */ 30 | @SuppressWarnings("serial") 31 | public class AutoCompletion extends PlainDocument { 32 | JComboBox comboBox; 33 | ComboBoxModel model; 34 | JTextComponent editor; 35 | // flag to indicate if setSelectedItem has been called 36 | // subsequent calls to remove/insertString should be ignored 37 | boolean selecting = false; 38 | boolean hidePopupOnFocusLoss; 39 | boolean hitBackspace = false; 40 | boolean hitBackspaceOnSelection; 41 | 42 | KeyListener editorKeyListener; 43 | FocusListener editorFocusListener; 44 | 45 | public AutoCompletion(final JComboBox comboBox) { 46 | 47 | this.comboBox = comboBox; 48 | model = comboBox.getModel(); 49 | comboBox.addActionListener(new ActionListener() { 50 | public void actionPerformed(ActionEvent e) { 51 | if (!selecting) 52 | highlightCompletedText(0); 53 | } 54 | }); 55 | comboBox.addPropertyChangeListener(new PropertyChangeListener() { 56 | public void propertyChange(PropertyChangeEvent e) { 57 | if (e.getPropertyName().equals("editor")) 58 | configureEditor((ComboBoxEditor) e.getNewValue()); 59 | if (e.getPropertyName().equals("model")) 60 | model = (ComboBoxModel) e.getNewValue(); 61 | } 62 | }); 63 | editorKeyListener = new KeyAdapter() { 64 | public void keyPressed(KeyEvent e) { 65 | if (comboBox.isDisplayable()) 66 | comboBox.setPopupVisible(true); 67 | hitBackspace = false; 68 | switch (e.getKeyCode()) { 69 | // determine if the pressed key is backspace (needed by the remove method) 70 | case KeyEvent.VK_BACK_SPACE: 71 | hitBackspace = true; 72 | hitBackspaceOnSelection = editor.getSelectionStart() != editor.getSelectionEnd(); 73 | break; 74 | // ignore delete key 75 | case KeyEvent.VK_DELETE: 76 | e.consume(); 77 | comboBox.getToolkit().beep(); 78 | break; 79 | } 80 | } 81 | }; 82 | // Bug 5100422 on Java 1.5: Editable JComboBox won't hide popup when tabbing out 83 | hidePopupOnFocusLoss = System.getProperty("java.version").startsWith("1.5"); 84 | // Highlight whole text when gaining focus 85 | editorFocusListener = new FocusAdapter() { 86 | public void focusGained(FocusEvent e) { 87 | highlightCompletedText(0); 88 | comboBox.showPopup(); 89 | 90 | editor.setForeground(ResponsiveSwingMaterialDesign.SECONDARY_COLOR); 91 | 92 | comboBox.setBorder(new RoundedBorder(20, ResponsiveSwingMaterialDesign.PRIMARY_COLOR)); 93 | } 94 | 95 | public void focusLost(FocusEvent e) { 96 | // Workaround for Bug 5100422 - Hide Popup on focus loss 97 | if (hidePopupOnFocusLoss) 98 | comboBox.setPopupVisible(false); 99 | 100 | comboBox.setForeground(ResponsiveSwingMaterialDesign.SECONDARY_COLOR); 101 | comboBox.setBorder(new RoundedBorder(20, ResponsiveSwingMaterialDesign.SECONDARY_COLOR)); 102 | } 103 | }; 104 | configureEditor(comboBox.getEditor()); 105 | // Handle initially selected object 106 | Object selected = comboBox.getSelectedItem(); 107 | if (selected != null) 108 | setText(selected.toString()); 109 | highlightCompletedText(0); 110 | } 111 | 112 | public static void enable(JComboBox comboBox) { 113 | // has to be editable 114 | comboBox.setEditable(true); 115 | // change the editor's document 116 | new AutoCompletion(comboBox); 117 | } 118 | 119 | void configureEditor(ComboBoxEditor newEditor) { 120 | if (editor != null) { 121 | editor.removeKeyListener(editorKeyListener); 122 | editor.removeFocusListener(editorFocusListener); 123 | } 124 | 125 | if (newEditor != null) { 126 | editor = (JTextComponent) newEditor.getEditorComponent(); 127 | editor.addKeyListener(editorKeyListener); 128 | editor.addFocusListener(editorFocusListener); 129 | editor.setDocument(this); 130 | editor.setOpaque(false); 131 | editor.setBorder(new EmptyBorder(0, 30, 0, 3)); 132 | editor.setForeground(ResponsiveSwingMaterialDesign.SECONDARY_COLOR); 133 | comboBox.setBorder(new RoundedBorder(20, ResponsiveSwingMaterialDesign.SECONDARY_COLOR)); 134 | } 135 | } 136 | 137 | public void remove(int offs, int len) throws BadLocationException { 138 | // return immediately when selecting an item 139 | if (selecting) 140 | return; 141 | if (hitBackspace) { 142 | // user hit backspace => move the selection backwards 143 | // old item keeps being selected 144 | if (offs > 0) { 145 | if (hitBackspaceOnSelection) 146 | offs--; 147 | } else { 148 | // User hit backspace with the cursor positioned on the start => beep 149 | comboBox.getToolkit().beep(); // when available use: 150 | // UIManager.getLookAndFeel().provideErrorFeedback(comboBox); 151 | } 152 | highlightCompletedText(offs); 153 | } else { 154 | super.remove(offs, len); 155 | } 156 | } 157 | 158 | public void insertString(int offs, String str, AttributeSet a) throws BadLocationException { 159 | // return immediately when selecting an item 160 | if (selecting) 161 | return; 162 | // insert the string into the document 163 | super.insertString(offs, str, a); 164 | // lookup and select a matching item 165 | Object item = lookupItem(getText(0, getLength())); 166 | if (item != null) { 167 | setSelectedItem(item); 168 | } else { 169 | // keep old item selected if there is no match 170 | item = comboBox.getSelectedItem(); 171 | // imitate no insert (later on offs will be incremented by str.length(): 172 | // selection won't move forward) 173 | offs = offs - str.length(); 174 | // provide feedback to the user that his input has been received but can not be 175 | // accepted 176 | comboBox.getToolkit().beep(); // when available use: 177 | // UIManager.getLookAndFeel().provideErrorFeedback(comboBox); 178 | } 179 | setText(item.toString()); 180 | // select the completed part 181 | highlightCompletedText(offs + str.length()); 182 | } 183 | 184 | private void setText(String text) { 185 | try { 186 | // remove all text and insert the completed string 187 | super.remove(0, getLength()); 188 | super.insertString(0, text, null); 189 | } catch (BadLocationException e) { 190 | throw new RuntimeException(e.toString()); 191 | } 192 | } 193 | 194 | private void highlightCompletedText(int start) { 195 | try { 196 | editor.setCaretPosition(getLength()); 197 | editor.moveCaretPosition(start); 198 | } catch (Exception e) { 199 | try { 200 | editor.setCaretPosition(getLength()-1); 201 | editor.moveCaretPosition(start); 202 | } catch (Exception e2) { 203 | 204 | } 205 | } 206 | } 207 | 208 | private void setSelectedItem(Object item) { 209 | selecting = true; 210 | model.setSelectedItem(item); 211 | selecting = false; 212 | } 213 | 214 | private Object lookupItem(String pattern) { 215 | Object selectedItem = model.getSelectedItem(); 216 | // only search for a different item if the currently selected does not match 217 | if (selectedItem != null && startsWithIgnoreCase(selectedItem.toString(), pattern)) { 218 | return selectedItem; 219 | } else { 220 | // iterate over all items 221 | for (int i = 0, n = model.getSize(); i < n; i++) { 222 | Object currentItem = model.getElementAt(i); 223 | // current item starts with the pattern? 224 | if (currentItem != null && startsWithIgnoreCase(currentItem.toString(), pattern)) { 225 | return currentItem; 226 | } 227 | } 228 | } 229 | // no item starts with the pattern => return null 230 | return null; 231 | } 232 | 233 | // checks if str1 starts with str2 - ignores case 234 | private boolean startsWithIgnoreCase(String str1, String str2) { 235 | return str1.toUpperCase().startsWith(str2.toUpperCase()); 236 | } 237 | 238 | } -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/combobox/ComboBox.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.combobox; 2 | 3 | import java.awt.Color; 4 | import java.awt.event.ItemEvent; 5 | import java.awt.event.ItemListener; 6 | import java.util.ArrayList; 7 | 8 | import javax.swing.JComboBox; 9 | import javax.swing.UIManager; 10 | 11 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 12 | import br.com.maxtercreations.responsiveswing.callback.CallbackT; 13 | import br.com.maxtercreations.responsiveswing.components.combobox.render.MaterialComboBoxEditor; 14 | import br.com.maxtercreations.responsiveswing.components.combobox.render.MaterialComboBoxRenderer; 15 | import br.com.maxtercreations.responsiveswing.components.combobox.render.MaterialComboBoxUI; 16 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout; 17 | import br.com.maxtercreations.responsiveswing.utils.Utils; 18 | 19 | @SuppressWarnings({ "serial", "rawtypes" }) 20 | public class ComboBox extends JComboBox { 21 | 22 | @SuppressWarnings("unchecked") 23 | public ComboBox(ResponsiveLayout responsiveLayout, ArrayList itens) { 24 | 25 | try { 26 | UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 27 | } catch (Exception e) { 28 | 29 | } 30 | this.setEditor(new MaterialComboBoxEditor()); 31 | this.setRenderer(new MaterialComboBoxRenderer()); 32 | this.setUI(new MaterialComboBoxUI()); 33 | 34 | for (Object obj : itens) { 35 | this.addItem(obj.toString()); 36 | } 37 | 38 | this.setFont(Utils.getMainFont(22)); 39 | this.setBackground(new Color(0, 0, 0, 0)); 40 | } 41 | 42 | @Override 43 | public void repaint() { 44 | super.repaint(); 45 | 46 | if (getForeground() != null && !getForeground().equals(ResponsiveSwingMaterialDesign.PRIMARY_COLOR)) { 47 | setForeground(ResponsiveSwingMaterialDesign.TEXT_COLOR); 48 | } 49 | } 50 | 51 | public ComboBox getComponent() { 52 | return this; 53 | } 54 | 55 | public void addValueChangeListener(CallbackT valueChangeListener) { 56 | this.addItemListener(new ItemListener() { 57 | 58 | @Override 59 | public void itemStateChanged(ItemEvent e) { 60 | if (e.getStateChange() == ItemEvent.SELECTED) { 61 | Object item = e.getItem(); 62 | 63 | if (valueChangeListener != null) { 64 | valueChangeListener.done(item); 65 | } 66 | } 67 | } 68 | }); 69 | } 70 | 71 | } 72 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/combobox/render/MaterialComboBoxEditor.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.combobox.render; 2 | 3 | import java.awt.Component; 4 | 5 | import javax.swing.plaf.basic.BasicComboBoxEditor; 6 | 7 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 8 | 9 | public class MaterialComboBoxEditor extends BasicComboBoxEditor { 10 | 11 | @Override 12 | public Component getEditorComponent() { 13 | Component component = super.getEditorComponent(); 14 | component.setForeground(ResponsiveSwingMaterialDesign.TEXT_COLOR); 15 | return component; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/combobox/render/MaterialComboBoxRenderer.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.combobox.render; 2 | 3 | import java.awt.Component; 4 | 5 | import javax.swing.JLabel; 6 | import javax.swing.JList; 7 | import javax.swing.border.EmptyBorder; 8 | import javax.swing.plaf.basic.BasicComboBoxRenderer; 9 | 10 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 11 | 12 | @SuppressWarnings("serial") 13 | public class MaterialComboBoxRenderer extends BasicComboBoxRenderer { 14 | 15 | @SuppressWarnings("rawtypes") 16 | @Override 17 | public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) { 18 | super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 19 | 20 | Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus); 21 | 22 | if (c instanceof JLabel) { 23 | JLabel l = (JLabel) c; 24 | l.setBorder(new EmptyBorder(0, 30, 0, 3)); 25 | l.setBackground(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR); 26 | 27 | if (isSelected) { 28 | list.setSelectionForeground(ResponsiveSwingMaterialDesign.TEXT_COLOR); 29 | list.setSelectionBackground(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR); 30 | } else { 31 | l.setForeground(ResponsiveSwingMaterialDesign.PRIMARY_COLOR); 32 | } 33 | 34 | return l; 35 | } 36 | return c; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/combobox/render/MaterialComboBoxUI.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.combobox.render; 2 | 3 | import java.awt.BasicStroke; 4 | import java.awt.Cursor; 5 | import java.awt.Graphics; 6 | import java.awt.Graphics2D; 7 | 8 | import javax.swing.JButton; 9 | import javax.swing.JComponent; 10 | import javax.swing.plaf.basic.BasicComboBoxUI; 11 | 12 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 13 | import br.com.maxtercreations.responsiveswing.components.combobox.AutoCompletion; 14 | import br.com.maxtercreations.responsiveswing.components.utils.RoundedBorder; 15 | 16 | public class MaterialComboBoxUI extends BasicComboBoxUI { 17 | 18 | @Override 19 | public void installUI(JComponent c) { 20 | super.installUI(c); 21 | 22 | comboBox.setOpaque(false); 23 | comboBox.setForeground(ResponsiveSwingMaterialDesign.TEXT_COLOR); 24 | comboBox.setBorder(new RoundedBorder(20, ResponsiveSwingMaterialDesign.SECONDARY_COLOR)); 25 | comboBox.setLightWeightPopupEnabled(true); 26 | comboBox.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); 27 | 28 | AutoCompletion.enable(comboBox); 29 | } 30 | 31 | @SuppressWarnings("serial") 32 | @Override 33 | protected JButton createArrowButton() { 34 | return new JButton() { 35 | @Override 36 | public int getWidth() { 37 | return 0; 38 | } 39 | }; 40 | } 41 | 42 | @Override 43 | public void update(Graphics g, JComponent c) { 44 | g = MaterialDrawingUtils.getAliasedGraphics(g); 45 | Graphics2D g2d = (Graphics2D)g; 46 | 47 | g2d.setColor(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR); 48 | g2d.setStroke(new BasicStroke(4)); 49 | g2d.fillRoundRect(0, 0, comboBox.getWidth(), comboBox.getHeight(), 20, 20); 50 | 51 | paint(g2d, c); 52 | } 53 | 54 | @Override 55 | public void paint(Graphics arg0, JComponent arg1) { 56 | super.paint(arg0, arg1); 57 | 58 | 59 | comboBox.setBorder(new RoundedBorder(20, ResponsiveSwingMaterialDesign.SECONDARY_COLOR)); 60 | } 61 | 62 | } 63 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/combobox/render/MaterialDrawingUtils.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.combobox.render; 2 | 3 | import java.awt.Graphics; 4 | import java.awt.Graphics2D; 5 | import java.awt.RenderingHints; 6 | import java.awt.Toolkit; 7 | import java.util.Map; 8 | 9 | public class MaterialDrawingUtils { 10 | 11 | static { 12 | System.setProperty("awt.useSystemAAFontSettings", "on"); 13 | System.setProperty("swing.aatext", "true"); 14 | System.setProperty("sun.java2d.xrender", "true"); 15 | } 16 | 17 | public static Graphics getAliasedGraphics(Graphics g) { 18 | @SuppressWarnings("unchecked") 19 | Map hints = (Map) Toolkit.getDefaultToolkit ().getDesktopProperty ("awt.font.desktophints"); 20 | 21 | if(hints != null){ 22 | hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 23 | hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_DEFAULT); 24 | hints.put(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_DEFAULT); 25 | hints.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_LCD_HRGB); 26 | 27 | Graphics2D g2d = (Graphics2D) g; 28 | g2d.addRenderingHints(hints); 29 | return g2d; 30 | } 31 | 32 | return g; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/date/DatePicker.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.date; 2 | 3 | import java.util.ArrayList; 4 | import java.util.Calendar; 5 | import java.util.Date; 6 | 7 | import javax.swing.JLabel; 8 | import javax.swing.JPanel; 9 | import javax.swing.JWindow; 10 | 11 | import br.com.maxtercreations.responsiveswing.callback.CallbackT; 12 | import br.com.maxtercreations.responsiveswing.components.buttons.RoundedFillButton; 13 | 14 | public abstract class DatePicker { 15 | 16 | protected JWindow frame; 17 | protected Date currentDate; 18 | 19 | protected String[] months = { "Janeiro", "Fevereiro", "Março", "Abril", "Maio", "Junho", "Julho", "Agosto", "Setembro", "Outubro", "Novembro", "Dezembro" }; 20 | protected String[] days = { "Dom", "Seg", "Ter", "Qua", "Qui", "Sex", "Sáb" }; 21 | 22 | protected ArrayList buttons = new ArrayList<>(); 23 | 24 | protected JPanel panel; 25 | 26 | protected CallbackT callbackT; 27 | 28 | public DatePicker(CallbackT callbackT) { 29 | this.currentDate = new Date(); 30 | this.callbackT = callbackT; 31 | 32 | build(); 33 | } 34 | 35 | public DatePicker(Date currentDate, CallbackT callbackT) { 36 | this.currentDate = currentDate; 37 | this.callbackT = callbackT; 38 | 39 | build(); 40 | } 41 | 42 | @SuppressWarnings("deprecation") 43 | public int getYear() { 44 | return currentDate.getYear() + 1900; 45 | } 46 | 47 | @SuppressWarnings("deprecation") 48 | public int getDay() { 49 | return currentDate.getDay(); 50 | } 51 | 52 | @SuppressWarnings("deprecation") 53 | public int getMonth() { 54 | return currentDate.getMonth(); 55 | } 56 | 57 | public int getDayOfWeek() { 58 | Calendar c = Calendar.getInstance(); 59 | c.setTime(currentDate); 60 | int dayOfWeek = c.get(Calendar.DAY_OF_WEEK) - 1; 61 | return dayOfWeek; 62 | } 63 | 64 | public Date getValue() { 65 | return currentDate; 66 | } 67 | 68 | public Calendar getCalendar() { 69 | Calendar calendar = Calendar.getInstance(); 70 | calendar.setTime(currentDate); 71 | return calendar; 72 | } 73 | 74 | public JLabel next, last; 75 | 76 | public String lastYear = new String(); 77 | 78 | public abstract void build(); 79 | 80 | public String getLastMonthText() { 81 | return "
"; 82 | } 83 | 84 | public String getNextMonthText() { 85 | return "
"; 86 | } 87 | 88 | public abstract void displayDays(); 89 | 90 | } 91 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/date/fields/DateTimeField.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.date.fields; 2 | 3 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout; 4 | 5 | public class DateTimeField extends DateField { 6 | 7 | public DateTimeField(String caption, ResponsiveLayout responsiveLayout) { 8 | super(caption, responsiveLayout); 9 | setDateFormat("dd/MM/yyyy HH:mm:ss"); 10 | } 11 | 12 | 13 | } 14 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/image/ImageLabel.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.image; 2 | 3 | import java.awt.image.BufferedImage; 4 | import java.io.File; 5 | import java.io.IOException; 6 | 7 | import javax.imageio.ImageIO; 8 | import javax.swing.ImageIcon; 9 | import javax.swing.JComponent; 10 | import javax.swing.JLabel; 11 | import javax.swing.SwingConstants; 12 | 13 | import br.com.maxtercreations.responsiveswing.components.utils.ImageRoundedBorder; 14 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout; 15 | import br.com.maxtercreations.responsiveswing.utils.Utils; 16 | 17 | @SuppressWarnings("serial") 18 | public class ImageLabel extends JComponent { 19 | 20 | private BufferedImage bufferedImage; 21 | 22 | private JLabel label; 23 | 24 | private int imageWidth, imageHeight; 25 | 26 | private final int margin = 10; 27 | 28 | public ImageLabel(String src, ResponsiveLayout rl, int radius, int width, int height) { 29 | try { 30 | BufferedImage from = Utils.resize(ImageIO.read(new File(src)), height - margin, width - margin); 31 | 32 | bufferedImage = Utils.makeRoundedCorner(from, radius); 33 | 34 | imageWidth = width; 35 | imageHeight = height; 36 | 37 | label = new JLabel(); 38 | label.setIcon(new ImageIcon(bufferedImage)); 39 | 40 | label.setHorizontalAlignment(SwingConstants.CENTER); 41 | 42 | rl.add(label); 43 | } catch (IOException e) { 44 | e.printStackTrace(); 45 | } 46 | } 47 | 48 | public void setBorder(ImageRoundedBorder border) { 49 | label.setBorder(border); 50 | } 51 | 52 | public JComponent getComponent() { 53 | return this; 54 | } 55 | 56 | @Override 57 | public void repaint() { 58 | super.repaint(); 59 | 60 | if (label != null && getX() != 0 && label.getBounds() != getBounds()) { 61 | 62 | int x = getX() + (getWidth() / 2) - (imageWidth / 2); 63 | 64 | label.setBounds(x, getY() + (getHeight() / 2) - (imageHeight / 2), imageWidth, imageHeight); 65 | } 66 | } 67 | 68 | } 69 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/input/InputField.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/components/input/InputField.java -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/input/PasswordField.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/components/input/PasswordField.java -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/utils/ImageRoundedBorder.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.utils; 2 | 3 | import java.awt.BasicStroke; 4 | import java.awt.Color; 5 | import java.awt.Component; 6 | import java.awt.Graphics; 7 | import java.awt.Graphics2D; 8 | import java.awt.Insets; 9 | import java.awt.RenderingHints; 10 | 11 | import javax.swing.border.Border; 12 | 13 | public class ImageRoundedBorder implements Border { 14 | 15 | /* This class has the function to round the borders. */ 16 | 17 | private int radius, index = -1, stroke = 1; 18 | private Color color; 19 | private boolean fill = false; 20 | 21 | public ImageRoundedBorder(int radius) { 22 | this.radius = radius; 23 | } 24 | 25 | public ImageRoundedBorder(int radius, int index) { 26 | this.radius = radius; 27 | this.index = index; 28 | } 29 | 30 | public ImageRoundedBorder(int radius, Color color) { 31 | this.radius = radius; 32 | this.color = color; 33 | } 34 | 35 | public ImageRoundedBorder(int radius, Color color, boolean fill) { 36 | this.radius = radius; 37 | this.color = color; 38 | this.fill = fill; 39 | } 40 | 41 | private Insets defaultInsets; 42 | 43 | public Insets getBorderInsets(Component c) { 44 | int index = this.index != -1 ? this.index : this.radius / 10; 45 | 46 | if (defaultInsets == null) 47 | defaultInsets = new Insets(0, 0, 0, 0); 48 | 49 | Insets in = new Insets(index + 2 + defaultInsets.top, index + 1 + defaultInsets.left, index + 2 + defaultInsets.bottom, index + defaultInsets.right); 50 | 51 | return in; 52 | } 53 | 54 | public void setDefaultInsets(Insets defaultInsets) { 55 | this.defaultInsets = defaultInsets; 56 | } 57 | 58 | public boolean isBorderOpaque() { 59 | return true; 60 | } 61 | 62 | public void setStroke(int stroke) { 63 | this.stroke = stroke; 64 | } 65 | 66 | public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 67 | Graphics2D g2d = (Graphics2D)g; 68 | 69 | Color oldColor = g2d.getColor(); 70 | 71 | if (color != null) 72 | g2d.setColor(color); 73 | 74 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 75 | 76 | g2d.setStroke(new BasicStroke(stroke)); 77 | 78 | if (fill) 79 | g2d.fillRoundRect(x + (stroke * 2), y + (stroke * 2) - 2, width - (stroke * 4), height - (stroke * 4), radius, radius); 80 | else 81 | g2d.drawRoundRect(x + 5, y + 5, width - 10, height - 10, radius, radius); 82 | 83 | g2d.setColor(oldColor); 84 | } 85 | 86 | public Color getColor() { 87 | return color; 88 | } 89 | } -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/utils/RoundedBorder.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.utils; 2 | 3 | import java.awt.BasicStroke; 4 | import java.awt.Color; 5 | import java.awt.Component; 6 | import java.awt.Graphics; 7 | import java.awt.Graphics2D; 8 | import java.awt.Insets; 9 | import java.awt.RenderingHints; 10 | 11 | import javax.swing.border.Border; 12 | 13 | public class RoundedBorder implements Border { 14 | 15 | /* This class has the function to round the borders. */ 16 | 17 | private int radius, index = -1, stroke = 1; 18 | private Color color; 19 | private boolean fill = false; 20 | 21 | public RoundedBorder(int radius) { 22 | this.radius = radius; 23 | } 24 | 25 | public RoundedBorder(int radius, int index) { 26 | this.radius = radius; 27 | this.index = index; 28 | } 29 | 30 | public RoundedBorder(int radius, Color color) { 31 | this.radius = radius; 32 | this.color = color; 33 | } 34 | 35 | public RoundedBorder(int radius, Color color, boolean fill) { 36 | this.radius = radius; 37 | this.color = color; 38 | this.fill = fill; 39 | } 40 | 41 | private Insets defaultInsets; 42 | 43 | public Insets getBorderInsets(Component c) { 44 | int index = this.index != -1 ? this.index : this.radius / 10; 45 | 46 | if (defaultInsets == null) 47 | defaultInsets = new Insets(0, 0, 0, 0); 48 | 49 | Insets in = new Insets(index + 2 + defaultInsets.top, index + 1 + defaultInsets.left, index + 2 + defaultInsets.bottom, index + defaultInsets.right); 50 | 51 | return in; 52 | } 53 | 54 | public void setDefaultInsets(Insets defaultInsets) { 55 | this.defaultInsets = defaultInsets; 56 | } 57 | 58 | public boolean isBorderOpaque() { 59 | return true; 60 | } 61 | 62 | public void setStroke(int stroke) { 63 | this.stroke = stroke; 64 | } 65 | 66 | public void paintBorder(Component c, Graphics g, int x, int y, int width, int height) { 67 | Graphics2D g2d = (Graphics2D)g; 68 | 69 | Color oldColor = g2d.getColor(); 70 | 71 | if (color != null) 72 | g2d.setColor(color); 73 | 74 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 75 | 76 | g2d.setStroke(new BasicStroke(stroke)); 77 | 78 | if (fill) 79 | g2d.fillRoundRect(x + (stroke * 2), y + (stroke * 2) - 2, width - (stroke * 4), height - (stroke * 4), radius, radius); 80 | else 81 | g2d.drawRoundRect(x + (stroke * 2), y + (stroke * 2) - 2, width - (stroke * 4), height - (stroke * 4), radius, radius); 82 | 83 | g2d.setColor(oldColor); 84 | } 85 | 86 | public Color getColor() { 87 | return color; 88 | } 89 | } -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/utils/RoundedPane.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.utils; 2 | 3 | import java.awt.Color; 4 | import java.awt.Dimension; 5 | import java.awt.Graphics; 6 | import java.awt.Graphics2D; 7 | import java.awt.Insets; 8 | import java.awt.Rectangle; 9 | import java.awt.RenderingHints; 10 | import java.awt.geom.RoundRectangle2D; 11 | import java.awt.image.BufferedImage; 12 | 13 | import javax.swing.JPanel; 14 | 15 | import br.com.maxtercreations.responsiveswing.components.utils.filters.GaussianBlur; 16 | 17 | @SuppressWarnings("serial") 18 | public class RoundedPane extends JPanel { 19 | 20 | //private int shadowSize = 8; 21 | private Dimension dimension; 22 | private RoundRectangle2D roundRect; 23 | 24 | public RoundedPane(Dimension dimension, RoundRectangle2D roundRect) { 25 | this.dimension = dimension; 26 | this.roundRect = roundRect; 27 | setLayout(null); 28 | setOpaque(false); 29 | } 30 | 31 | @Override 32 | public Insets getInsets() { 33 | return new Insets(0, 0, 10, 10); 34 | } 35 | 36 | @Override 37 | public Dimension getPreferredSize() { 38 | return dimension; 39 | } 40 | 41 | @Override 42 | protected void paintComponent(Graphics g) { 43 | int width = getWidth() - 1, height = getHeight() - 1; 44 | 45 | Graphics2D graphics2d = (Graphics2D) g.create(); 46 | 47 | GaussianBlur.applyQualityProperties(graphics2d); 48 | 49 | Insets insets = getInsets(); 50 | Rectangle bounds = getBounds(); 51 | 52 | bounds.x = insets.left; 53 | bounds.y = insets.top; 54 | bounds.width = width - (insets.left + insets.right); 55 | bounds.height = height - (insets.top + insets.bottom); 56 | 57 | RoundRectangle2D shape = roundRect; 58 | BufferedImage bufferedImage = GaussianBlur.createTranslucityCompatibleImage(bounds.width, bounds.height); 59 | Graphics2D g2d = bufferedImage.createGraphics(); 60 | 61 | g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 62 | g2d.setColor(Color.BLACK); 63 | g2d.translate(-bounds.x, -bounds.y); 64 | g2d.fill(shape); 65 | g2d.dispose(); 66 | 67 | /* Lag BufferedImage shadow = GaussianBlur.generateShadow(bufferedImage, shadowSize, Color.BLACK, 0.3f); 68 | graphics2d.drawImage(shadow, shadowSize, shadowSize, this);*/ 69 | 70 | graphics2d.setColor(getBackground()); 71 | graphics2d.fill(shape); 72 | 73 | getUI().paint(graphics2d, this); 74 | 75 | graphics2d.setColor(Color.WHITE); 76 | graphics2d.draw(shape); 77 | graphics2d.dispose(); 78 | } 79 | 80 | } -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/components/utils/filters/BlackFilter.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.components.utils.filters; 2 | 3 | import java.awt.Color; 4 | import java.awt.Graphics; 5 | import java.awt.Graphics2D; 6 | import java.awt.RenderingHints; 7 | import java.awt.image.BufferedImage; 8 | 9 | import javax.swing.JFrame; 10 | import javax.swing.JPanel; 11 | import javax.swing.JRootPane; 12 | import javax.swing.SwingUtilities; 13 | 14 | public class BlackFilter { 15 | 16 | private JFrame frame; 17 | private JPanel blackPanel; 18 | private BufferedImage blackBuffer, currentGraphics; 19 | private boolean visible = false; 20 | 21 | public void build(JFrame frame) { 22 | this.frame = frame; 23 | 24 | SwingUtilities.invokeLater(new Runnable() { 25 | @Override 26 | public void run() { 27 | blackPanel = new BlackPanel(); 28 | 29 | frame.setGlassPane(blackPanel); 30 | frame.setVisible(true); 31 | 32 | JRootPane root = SwingUtilities.getRootPane(frame); 33 | 34 | blackBuffer = GaussianBlur.createCompatibleImage(frame.getWidth(), frame.getHeight()); 35 | 36 | Graphics2D graphics2D = blackBuffer.createGraphics(); 37 | 38 | root.paint(graphics2D); 39 | graphics2D.dispose(); 40 | 41 | blackBuffer = GaussianBlur.createThumbnailFast(blackBuffer, frame.getWidth() / 2); 42 | 43 | frame.getGlassPane().setVisible(true); 44 | currentGraphics = new BufferedImage(root.getWidth(), root.getHeight(), BufferedImage.TYPE_3BYTE_BGR); 45 | 46 | frame.getGlassPane().setVisible(false); 47 | 48 | blackPanel = new BlackPanel(); 49 | } 50 | }); 51 | } 52 | 53 | public void setVisible() { 54 | setVisible(false); 55 | } 56 | 57 | public void setVisible(boolean load) { 58 | if (load) 59 | frame.setGlassPane(blackPanel); 60 | 61 | frame.getGlassPane().setVisible(true); 62 | visible = true; 63 | } 64 | 65 | public void dispose() { 66 | frame.getGlassPane().setVisible(false); 67 | frame.getContentPane().setEnabled(true); 68 | frame.setVisible(true); 69 | visible = false; 70 | } 71 | 72 | public boolean isVisible() { 73 | return visible; 74 | } 75 | 76 | /* Support Classes */ 77 | 78 | @SuppressWarnings("serial") 79 | private class BlackPanel extends JPanel { 80 | public BlackPanel() { 81 | setOpaque(false); 82 | } 83 | 84 | @Override 85 | protected void paintComponent(Graphics g) { 86 | 87 | int width = frame.getContentPane().getWidth(), height = frame.getContentPane().getHeight() - 1; 88 | 89 | if (currentGraphics == null) 90 | return; 91 | 92 | Graphics2D graphics2D = currentGraphics.createGraphics(); 93 | graphics2D.drawImage(currentGraphics, 0, 0, null); 94 | graphics2D = (Graphics2D) g.create(); 95 | graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 96 | 97 | graphics2D.setColor(new Color(0, 0, 0, 150)); 98 | graphics2D.fillRect(0, 0, width, height); 99 | 100 | graphics2D.setColor(Color.WHITE); 101 | graphics2D.drawRect(0, 0, width, height); 102 | 103 | graphics2D.dispose(); 104 | } 105 | } 106 | 107 | } -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/constants/Constants.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.constants; 2 | 3 | public class Constants { 4 | 5 | public static final String RESOURCES_DIRECTORY = "/br/com/maxtercreations/responsiveswing/resources"; 6 | 7 | } 8 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/demo/Demo1_RegisterForm.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.demo; 2 | 3 | import java.util.ArrayList; 4 | import java.util.List; 5 | import java.util.stream.Collectors; 6 | 7 | import javax.swing.JFrame; 8 | 9 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 10 | import br.com.maxtercreations.responsiveswing.components.buttons.MaterialButton; 11 | import br.com.maxtercreations.responsiveswing.components.combobox.ComboBox; 12 | import br.com.maxtercreations.responsiveswing.components.date.fields.DateField; 13 | import br.com.maxtercreations.responsiveswing.components.image.ImageLabel; 14 | import br.com.maxtercreations.responsiveswing.components.input.InputField; 15 | import br.com.maxtercreations.responsiveswing.components.input.PasswordField; 16 | import br.com.maxtercreations.responsiveswing.components.utils.ImageRoundedBorder; 17 | import br.com.maxtercreations.responsiveswing.display.FrameUtility; 18 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout; 19 | import br.com.maxtercreations.responsiveswing.layouts.ResponsiveLayout.ResponsiveConstants; 20 | 21 | public class Demo1_RegisterForm { 22 | 23 | /* 24 | * 25 | * RSMDF - RESPONSIVE SWING MATERIAL DESIGN FRAMEWORK BEAULTY AND RESPONSIVE 26 | * SWING COMPONENTS 27 | * 28 | * COPYRIGHT BY GUSTAVO ROLIM DOS SANTOS 2020 VERSION ALPHA 1.3.0 29 | * 30 | * 31 | * THIS VERSION MAY CONTAINS BUGS. 32 | * 33 | * https://maxtercreations.com.br 34 | * 35 | */ 36 | 37 | public static void main(String[] args) { 38 | 39 | JFrame frame = FrameUtility.build("Java Responsive Swing Material Design", 0, 0, 1280, 900, true); 40 | 41 | ResponsiveLayout rl = new ResponsiveLayout(16, 12, frame); 42 | 43 | List comboBoxValues = ResponsiveSwingMaterialDesign.getThemesManager().getThemes().stream().map(theme -> "Tema " + theme.getName()).collect(Collectors.toList()); 44 | ComboBox comboBox = new ComboBox(rl, new ArrayList<>(comboBoxValues)); 45 | 46 | comboBox.addValueChangeListener(e -> { 47 | ResponsiveSwingMaterialDesign.setCurrentTheme(comboBox.getSelectedItem().toString().replace("Tema ", ""), rl); 48 | }); 49 | 50 | comboBox.setSelectedIndex(1); 51 | 52 | ImageLabel imageLabel = new ImageLabel(Demo1_RegisterForm.class.getResource("/github.png").getPath(), rl, 120, 120, 120); 53 | 54 | ImageRoundedBorder roundedBorder = new ImageRoundedBorder(120, ResponsiveSwingMaterialDesign.PRIMARY_COLOR); 55 | roundedBorder.setStroke(2); 56 | 57 | imageLabel.setBorder(roundedBorder); 58 | 59 | rl.add(imageLabel.getComponent(), 4, 1, ResponsiveConstants.CENTER); 60 | rl.addRow(); 61 | rl.add(new InputField("Email de contato", rl).email().getComponent(), 6, 1, ResponsiveConstants.CENTER); 62 | rl.addRow(); 63 | rl.add(new InputField("Telefone de contato", rl).setRequired(false).phone().getComponent(), 6, 1, ResponsiveConstants.CENTER); 64 | rl.addRow(); 65 | rl.add(new PasswordField("Senha", rl).setRequired(false).getComponent(), 6, 1, ResponsiveConstants.CENTER); 66 | rl.addRow(); 67 | rl.add(comboBox.getComponent(), 6, 1, ResponsiveConstants.CENTER); 68 | rl.addRow(); 69 | rl.add(new DateField("Data de Nascimento", rl).setRequired(false).getComponent(), 6, 1, ResponsiveConstants.CENTER); 70 | rl.addRow(); 71 | rl.add(new MaterialButton("Registrar", rl, null).getComponent(), 4, 1, ResponsiveConstants.CENTER); 72 | 73 | frame.setVisible(true); 74 | frame.setLocationRelativeTo(null); 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/demo/Demo2_General_Components.java: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/demo/Demo2_General_Components.java -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/display/FrameUtility.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.display; 2 | 3 | import javax.swing.JFrame; 4 | 5 | import br.com.maxtercreations.responsiveswing.utils.Utils; 6 | 7 | public class FrameUtility { 8 | 9 | public static JFrame build(String name, int x, int y, int width, int height, boolean moveable) { 10 | Utils.registerFont("GOTHIC.TTF", 1); 11 | 12 | JFrame frame = new JFrame(name); 13 | 14 | frame.setBounds(x, y, width, height); 15 | frame.setResizable(true); 16 | frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 17 | 18 | return frame; 19 | } 20 | 21 | } -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Darkmode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Darkmode.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/DatePicker DarkMode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/DatePicker DarkMode.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Form.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_1.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_1.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_10.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_10.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_11.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_11.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_2.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_3.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_4.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_4.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_5.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_5.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_6.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_6.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_7.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_7.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_8.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_8.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/images/Screenshot_9.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/images/Screenshot_9.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/layouts/LayoutInfo.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.layouts; 2 | 3 | public class LayoutInfo { 4 | 5 | private double columns, rows, skipColumns; 6 | 7 | public LayoutInfo(double columns, double rows, double skipColumns) { 8 | this.columns = columns; 9 | this.rows = rows; 10 | this.skipColumns = skipColumns; 11 | } 12 | 13 | public double getColumns() { 14 | return columns; 15 | } 16 | 17 | public double getRows() { 18 | return rows; 19 | } 20 | 21 | public double getSkipColumns() { 22 | return skipColumns; 23 | } 24 | 25 | } 26 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/layouts/ResponsiveLayout.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.layouts; 2 | 3 | import java.awt.Component; 4 | import java.awt.Dimension; 5 | import java.awt.Insets; 6 | import java.awt.event.ComponentAdapter; 7 | import java.awt.event.ComponentEvent; 8 | import java.awt.event.WindowEvent; 9 | import java.awt.event.WindowStateListener; 10 | import java.util.HashMap; 11 | 12 | import javax.swing.JComponent; 13 | import javax.swing.JFrame; 14 | import javax.swing.JLayeredPane; 15 | import javax.swing.JScrollPane; 16 | 17 | import com.sun.org.glassfish.gmbal.Description; 18 | 19 | import br.com.maxtercreations.responsiveswing.ResponsiveSwingMaterialDesign; 20 | import br.com.maxtercreations.responsiveswing.components.utils.filters.BlackFilter; 21 | 22 | @SuppressWarnings("serial") 23 | public class ResponsiveLayout extends JLayeredPane { 24 | 25 | private final BlackFilter blackFilter = new BlackFilter(); 26 | private final Insets heightInsets = new Insets(10, 10, 10, 10), margin = new Insets(50, 50, 50, 50); 27 | 28 | private JFrame frame; 29 | 30 | private JScrollPane scrollPane; 31 | 32 | private HashMap componentsInfo = new HashMap<>(); 33 | 34 | private int columnWidth, rowHeight, x, y, columns, width, height, currentColumnn; 35 | 36 | private double maxHeightInRow = 0; 37 | 38 | private boolean addRow = false; 39 | 40 | public enum ResponsiveConstants { 41 | RIGHT, LEFT, CENTER 42 | } 43 | 44 | public ResponsiveLayout(int rows, int columns, JFrame frame) { 45 | this.frame = frame; 46 | 47 | this.columns = columns; 48 | this.width = frame.getWidth(); 49 | this.height = frame.getHeight(); 50 | 51 | setBounds(0, 0, width, height); 52 | setLayout(null); 53 | setOpaque(true); 54 | 55 | columnWidth = width / columns; 56 | rowHeight = height / rows; 57 | 58 | rowHeight -= heightInsets.top; 59 | 60 | x = margin.left / 2; 61 | y = margin.top; 62 | 63 | blackFilter.build(frame); 64 | 65 | build(); 66 | } 67 | 68 | @Description("Add a new component into your Responsive Layout.") 69 | public void add(JComponent component, double columns, double rows, double skipColumns, ResponsiveConstants responsiveConstants) { 70 | 71 | if (addRow) { 72 | skipColumns = (ResponsiveLayout.this.columns - currentColumnn); 73 | currentColumnn = 0; 74 | } 75 | 76 | if (responsiveConstants != null) { 77 | if (responsiveConstants.equals(ResponsiveConstants.CENTER)) { 78 | double necessaryColumns = (ResponsiveLayout.this.columns / 2) - (columns / 2); 79 | 80 | skipColumns += necessaryColumns; 81 | 82 | currentColumnn += necessaryColumns; 83 | } else if (responsiveConstants.equals(ResponsiveConstants.RIGHT)) { 84 | double necessaryColumns = (ResponsiveLayout.this.columns / 2) - (columns / 2); 85 | 86 | skipColumns = necessaryColumns + (columns * 2); 87 | } else if (responsiveConstants.equals(ResponsiveConstants.LEFT)) { 88 | double necessaryColumns = (ResponsiveLayout.this.columns / 2) - (columns / 2); 89 | 90 | skipColumns = necessaryColumns - (columns * 2); 91 | } 92 | } 93 | 94 | LayoutInfo info = new LayoutInfo(columns, rows, skipColumns); 95 | 96 | displayComponent(component, info); 97 | 98 | componentsInfo.put(component, info); 99 | 100 | add(component); 101 | 102 | currentColumnn += columns; 103 | addRow = false; 104 | 105 | updateScroll(); 106 | } 107 | 108 | @Description("Add a new component into your Responsive Layout. Use ResponsiveConstants as LEFT, CENTER or RIGHT") 109 | public void add(JComponent component, double columns, double rows, ResponsiveConstants responsiveConstants) { 110 | add(component, columns, rows, 0, responsiveConstants); 111 | } 112 | 113 | @Description("Add a new component into your Responsive Layout. Use skipColumns as the number of columns you want to skip.") 114 | public void add(JComponent component, double columns, double rows, double skipColumns) { 115 | add(component, columns, rows, skipColumns, null); 116 | } 117 | 118 | @Description("Add a new component into your Responsive Layout.") 119 | public void add(JComponent component, double columns, double rows) { 120 | add(component, columns, rows, 0); 121 | } 122 | 123 | @Description("Make the Responsive Layout screen update all components bounds and sizes.") 124 | public void update() { 125 | this.width = frame.getWidth(); 126 | 127 | width = width + 7 - margin.left / 2; 128 | columnWidth = width / columns; 129 | 130 | x = margin.left / 2; 131 | y = margin.top; 132 | 133 | maxHeightInRow = 0; 134 | 135 | for (Component component : getComponents()) { 136 | if (componentsInfo.get(component) == null) 137 | continue; 138 | 139 | LayoutInfo info = componentsInfo.get(component); 140 | 141 | if (!component.getBackground().equals(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR)) { 142 | component.setBackground(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR); 143 | 144 | } 145 | 146 | displayComponent((JComponent) component, info); 147 | } 148 | 149 | scrollPane.getViewport().setBackground(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR); 150 | 151 | } 152 | 153 | // Display the component based on responsive info 154 | private void displayComponent(JComponent component, LayoutInfo layoutInfo) { 155 | skip(layoutInfo); 156 | 157 | double w = layoutInfo.getColumns() * columnWidth, h = layoutInfo.getRows() * rowHeight; 158 | 159 | w -= margin.left; 160 | h += heightInsets.top + heightInsets.bottom; 161 | 162 | if (x + (margin.left * 2) >= width || x + w > width) { 163 | 164 | y += (maxHeightInRow == 0 ? h : maxHeightInRow) + margin.bottom; 165 | 166 | x = margin.left / 2; 167 | currentColumnn = 0; 168 | maxHeightInRow = 0; 169 | } 170 | 171 | component.setBounds(x, y, (int) w, (int) h); 172 | 173 | x += w + margin.left; 174 | 175 | if (h > maxHeightInRow) { 176 | maxHeightInRow = h; 177 | } 178 | 179 | } 180 | 181 | // Skip rows and columns based on responsive info 182 | private void skip(LayoutInfo layoutInfo) { 183 | 184 | for (int i = 0; i < layoutInfo.getSkipColumns(); i++) { 185 | double w = columnWidth, h = layoutInfo.getRows() * rowHeight; 186 | 187 | h += heightInsets.top + heightInsets.bottom; 188 | 189 | x += w; 190 | 191 | if (x > width) { 192 | y += h + margin.bottom; 193 | x = x - width; 194 | } 195 | } 196 | } 197 | 198 | // Add the responsive layout to a scrollpane and add frame events to update 199 | // components 200 | private void build() { 201 | scrollPane = new JScrollPane(this); 202 | 203 | scrollPane.setOpaque(true); 204 | scrollPane.getVerticalScrollBar().setUnitIncrement(10); 205 | scrollPane.getVerticalScrollBar().setPreferredSize(new Dimension(0, 0)); 206 | scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); 207 | scrollPane.getViewport().setOpaque(true); 208 | scrollPane.getViewport().setBackground(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR); 209 | 210 | frame.setContentPane(scrollPane); 211 | frame.getContentPane().setBackground(ResponsiveSwingMaterialDesign.BACKGROUND_COLOR); 212 | 213 | frame.addComponentListener(new ComponentAdapter() { 214 | public void componentResized(ComponentEvent componentEvent) { 215 | update(); 216 | } 217 | }); 218 | 219 | frame.addWindowStateListener(new WindowStateListener() { 220 | @Override 221 | public void windowStateChanged(WindowEvent arg0) { 222 | update(); 223 | } 224 | }); 225 | 226 | frame.repaint(); 227 | } 228 | 229 | // Update scrollbar height based on most height component 230 | private void updateScroll() { 231 | int maxHeight = 0; 232 | 233 | for (Component component : this.getComponents()) { 234 | if (component.getY() + component.getHeight() > maxHeight) 235 | maxHeight = component.getY() + component.getHeight(); 236 | } 237 | 238 | this.setPreferredSize(new Dimension(this.getWidth(), maxHeight)); 239 | } 240 | 241 | @Description("Add a new row in your Responsive Layout.") 242 | public void addRow() { 243 | addRow = true; 244 | } 245 | 246 | @Description("Get the row height based on frame height and number of rows.") 247 | public int getRowHeight() { 248 | return rowHeight; 249 | } 250 | 251 | @Description("Get the column width based on frame width and number of columns.") 252 | public int getColumWidth() { 253 | return columnWidth; 254 | } 255 | 256 | @Description("Get the black filter to apply/dispose in your frame.") 257 | public BlackFilter getBlackFilter() { 258 | return blackFilter; 259 | } 260 | 261 | public JFrame getFrame() { 262 | return frame; 263 | } 264 | 265 | } -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/resources/GOTHIC.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/resources/GOTHIC.TTF -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/resources/GOTHICB.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/resources/GOTHICB.TTF -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/resources/GOTHICBI.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/resources/GOTHICBI.TTF -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/resources/GOTHICI.TTF: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/resources/GOTHICI.TTF -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/resources/components/icons/calendar-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/resources/components/icons/calendar-icon.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/resources/components/icons/check-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/resources/components/icons/check-icon.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/resources/components/icons/eye-icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GustavoRolimSantos/Java/0c52798e128afcc7552b2bc5287a831ac8c5cb6b/ResponsiveSwingMaterialDesign/resources/components/icons/eye-icon.png -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/theme/ThemeModel.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.theme; 2 | 3 | import java.awt.Color; 4 | 5 | public class ThemeModel { 6 | 7 | private String name; 8 | 9 | private Color primaryColor, secondaryColor, errorColor, textColor, backgroundColor; 10 | 11 | public ThemeModel(String name, Color primaryColor, Color secondaryColor, Color errorColor, Color textColor, Color backgroundColor) { 12 | super(); 13 | this.name = name; 14 | this.primaryColor = primaryColor; 15 | this.secondaryColor = secondaryColor; 16 | this.errorColor = errorColor; 17 | this.textColor = textColor; 18 | this.backgroundColor = backgroundColor; 19 | } 20 | 21 | public String getName() { 22 | return name; 23 | } 24 | 25 | public void setName(String name) { 26 | this.name = name; 27 | } 28 | 29 | public Color getPrimaryColor() { 30 | return primaryColor; 31 | } 32 | 33 | public void setPrimaryColor(Color primaryColor) { 34 | this.primaryColor = primaryColor; 35 | } 36 | 37 | public Color getSecondaryColor() { 38 | return secondaryColor; 39 | } 40 | 41 | public void setSecondaryColor(Color secondaryColor) { 42 | this.secondaryColor = secondaryColor; 43 | } 44 | 45 | public Color getErrorColor() { 46 | return errorColor; 47 | } 48 | 49 | public void setErrorColor(Color errorColor) { 50 | this.errorColor = errorColor; 51 | } 52 | 53 | public Color getTextColor() { 54 | return textColor; 55 | } 56 | 57 | public void setTextColor(Color textColor) { 58 | this.textColor = textColor; 59 | } 60 | 61 | public Color getBackgroundColor() { 62 | return backgroundColor; 63 | } 64 | 65 | public void setBackgroundColor(Color backgroundColor) { 66 | this.backgroundColor = backgroundColor; 67 | } 68 | 69 | @Override 70 | public String toString() { 71 | return this.name; 72 | } 73 | } 74 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/theme/ThemesManager.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.theme; 2 | 3 | import java.awt.Color; 4 | import java.util.ArrayList; 5 | 6 | public class ThemesManager { 7 | 8 | private ThemeModel currentModel; 9 | 10 | private ArrayList themes = new ArrayList<>(); 11 | 12 | public ThemesManager() { 13 | themes.add(new ThemeModel("Light", new Color(0, 110, 204), new Color(128, 134, 139), new Color(255, 0, 0), new Color(128, 134, 139), new Color(246, 248, 250))); 14 | themes.add(new ThemeModel("Dracula", new Color(148, 82, 126), new Color(93, 109, 154), new Color(148, 82, 82), new Color(255, 255, 255), new Color(40, 42, 54))); 15 | themes.add(new ThemeModel("Dark", new Color(59, 112, 222), new Color(128, 128, 128), new Color(148, 82, 82), new Color(255, 255, 255), new Color(23, 22, 22))); 16 | 17 | currentModel = themes.get(0); 18 | } 19 | 20 | public void addTheme(ThemeModel model) { 21 | this.themes.add(model); 22 | } 23 | 24 | public void removeTheme(ThemeModel model) { 25 | this.themes.remove(model); 26 | } 27 | 28 | public void setCurrentTheme(ThemeModel model) { 29 | this.currentModel = model; 30 | } 31 | 32 | public void setCurrentTheme(String themeName) { 33 | themes.forEach(theme -> { 34 | if (theme.getName().equalsIgnoreCase(themeName)) { 35 | currentModel = theme; 36 | } 37 | }); 38 | } 39 | 40 | public ThemeModel getCurrentModel() { 41 | return currentModel; 42 | } 43 | 44 | public ArrayList getThemes() { 45 | return themes; 46 | } 47 | 48 | } 49 | -------------------------------------------------------------------------------- /ResponsiveSwingMaterialDesign/utils/Utils.java: -------------------------------------------------------------------------------- 1 | package br.com.maxtercreations.responsiveswing.utils; 2 | 3 | import java.awt.AlphaComposite; 4 | import java.awt.Color; 5 | import java.awt.Font; 6 | import java.awt.Graphics2D; 7 | import java.awt.GraphicsEnvironment; 8 | import java.awt.Image; 9 | import java.awt.RenderingHints; 10 | import java.awt.geom.RoundRectangle2D; 11 | import java.awt.image.BufferedImage; 12 | import java.awt.image.WritableRaster; 13 | import java.io.IOException; 14 | import java.text.Normalizer; 15 | 16 | import javax.imageio.ImageIO; 17 | import javax.swing.ImageIcon; 18 | 19 | import br.com.maxtercreations.responsiveswing.constants.Constants; 20 | 21 | public class Utils { 22 | 23 | public static Font getMainFont(int size) { 24 | return new Font("Century Gothic", 0, size); 25 | } 26 | 27 | public static Font getBoldFont(int size) { 28 | return new Font("Century Gothic Bold", 0, size); 29 | } 30 | 31 | public static void registerFont(String fontName, float size) { 32 | try { 33 | Font customFont = Font.createFont(Font.TRUETYPE_FONT, Utils.class.getResourceAsStream(Constants.RESOURCES_DIRECTORY + "/" + fontName)); 34 | GraphicsEnvironment.getLocalGraphicsEnvironment().registerFont(customFont); 35 | } catch (Exception exception) { 36 | exception.printStackTrace(); 37 | } 38 | } 39 | 40 | public static String removeAccents(String text) { 41 | return Normalizer.normalize(text.trim(), Normalizer.Form.NFD).replaceAll("[^\\p{ASCII}]", "").trim(); 42 | } 43 | 44 | public static boolean isNumber(String s) { 45 | try { 46 | Integer.parseInt(s); 47 | return true; 48 | } catch (Exception e) { 49 | 50 | } 51 | return false; 52 | 53 | } 54 | 55 | public static ImageIcon convertImageColors(String directory, Color color) { 56 | BufferedImage image = null; 57 | try { 58 | image = ImageIO.read(Utils.class.getResource(directory)); 59 | } catch (IOException e) { 60 | e.printStackTrace(); 61 | } 62 | 63 | int width = image.getWidth(), height = image.getHeight(); 64 | WritableRaster raster = image.getRaster(); 65 | 66 | for (int xx = 0; xx < width; xx++) { 67 | for (int yy = 0; yy < height; yy++) { 68 | int[] pixels = raster.getPixel(xx, yy, (int[]) null); 69 | pixels[0] = color.getRed(); 70 | pixels[1] = color.getGreen(); 71 | pixels[2] = color.getBlue(); 72 | raster.setPixel(xx, yy, pixels); 73 | } 74 | } 75 | 76 | return new ImageIcon(image); 77 | } 78 | 79 | public static BufferedImage makeRoundedCorner(BufferedImage image, int cornerRadius) { 80 | int w = image.getWidth(), h = image.getHeight(); 81 | BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB); 82 | 83 | Graphics2D g2 = output.createGraphics(); 84 | 85 | g2.setComposite(AlphaComposite.Src); 86 | g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); 87 | g2.setColor(Color.WHITE); 88 | g2.fill(new RoundRectangle2D.Float(0, 0, w, h, cornerRadius, cornerRadius)); 89 | 90 | g2.setComposite(AlphaComposite.SrcAtop); 91 | g2.drawImage(image, 0, 0, null); 92 | 93 | g2.dispose(); 94 | 95 | return output; 96 | } 97 | 98 | public static BufferedImage resize(BufferedImage img, int height, int width) { 99 | Image tmp = img.getScaledInstance(width, height, Image.SCALE_SMOOTH); 100 | BufferedImage resized = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); 101 | Graphics2D g2d = resized.createGraphics(); 102 | g2d.drawImage(tmp, 0, 0, null); 103 | g2d.dispose(); 104 | return resized; 105 | } 106 | 107 | } 108 | --------------------------------------------------------------------------------