Snake/Java

From Rosetta Code
Revision as of 19:45, 21 May 2023 by IZzSaken (talk | contribs)

package zug;

import javax.swing.*; import java.awt.*; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.LinkedList; import java.util.List; import java.util.Random;

import static java.lang.String.format;

   public class zug extends JPanel implements Runnable {
       enum Dir {
           up(0, -1), right(1, 0), down(0, 1), left(-1, 0);
           Dir(int x, int y) {
               this.x = x; this.y = y;
           }
           final int x, y;
       }
       static final Random rand = new Random();
       static final int WAND = -1;
       volatile boolean gameOver = true;
       Thread gameThread;
       int score, highScore;
       int nRows = 108;
       int nCols = 192;
       Dir dir;
       int[][] wand;
       List<Point> zug, passagiere;
       Font smallFont;
       public zug() {
           setPreferredSize(new Dimension(1920, 1080));
           setBackground(Color.darkGray);
           setFont(new Font("Arial", Font.BOLD, 48));
           setFocusable(true);
           smallFont = getFont().deriveFont(Font.BOLD, 18);
           mauerErzeugen();
           addMouseListener(
                   new MouseAdapter() {
                       @Override
                       public void mousePressed(MouseEvent e) {
                           if (gameOver) {
                               starteNeuesSpiel();
                               repaint();
                           }
                       }
                   });
           addKeyListener(
                   new KeyAdapter() {
                       @Override
                       public void keyPressed(KeyEvent e) {
                           switch (e.getKeyCode()) {
                               case KeyEvent.VK_UP:
                                   if (dir != Dir.down)
                                       dir = Dir.up;
                                   break;
                               case KeyEvent.VK_LEFT:
                                   if (dir != Dir.right)
                                       dir = Dir.left;
                                   break;
                               case KeyEvent.VK_RIGHT:
                                   if (dir != Dir.left)
                                       dir = Dir.right;
                                   break;
                               case KeyEvent.VK_DOWN:
                                   if (dir != Dir.up)
                                       dir = Dir.down;
                                   break;
                           }
                           repaint();
                       }
                   });
       }
       public static void zeigeFenster(String text) {
           
           JFrame fenster = new JFrame("Deutsche Bahn");
   
           
           JLabel label = new JLabel(text);
   
           
           fenster.getContentPane().add(label);
   
           
           fenster.setSize(600, 200);
   
           
           fenster.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
   
           
           fenster.setVisible(true);
       }
       void starteNeuesSpiel() {
           gameOver = false;
           stop();
           mauerErzeugen();
           passagiere = new LinkedList<>();
           dir = Dir.left;
           if (score > highScore)
               highScore = score;
           score = 0;
           zug = new ArrayList<>();
           for (int x = 0; x < 7; x++)
               zug.add(new Point(nCols / 2 + x, nRows / 2));
           do
               addPassagiere();
           while(passagiere.isEmpty());
           (gameThread = new Thread(this)).start();
       }


       void stop() {
           if (gameThread != null) {
               Thread tmp = gameThread;
               gameThread = null;
               tmp.interrupt();
           }
       }
       void mauerErzeugen() {
           wand = new int[nRows][nCols];
           for (int r = 0; r < nRows; r++) {
               for (int c = 0; c < nCols; c++) {
                   if (c == 0 || c == nCols - 1 || r == 0 || r == nRows - 1)
                       wand[r][c] = WAND;
               }
           }
       }
       @Override
       public void run() {
           while (Thread.currentThread() == gameThread) {
               try {
                   Thread.sleep(Math.max(75 - score, 25));
               } catch (InterruptedException e) {
                   return;
               }
               if (trifftWand() || trifftZug() || score == 15) {
                   gameOver();
               } else {
                   if (sammeltPassagiereEin()) {
                       score++;
                       verlängereZug();
                   }
                   bewegeZug();
                   addPassagiere();
               }
               repaint();
           }
       }
       boolean trifftWand() {
           Point head = zug.get(0);
           int nextCol = head.x + dir.x;
           int nextRow = head.y + dir.y;
           return wand [nextRow][nextCol] == WAND;
       }
       boolean trifftZug() {
           Point head = zug.get(0);
           int nextCol = head.x + dir.x;
           int nextRow = head.y + dir.y;
           for (Point p : zug)
               if (p.x == nextCol && p.y == nextRow)
                   return true;
           return false;
       }
       boolean sammeltPassagiereEin() {
           Point head = zug.get(0);
           int nextCol = head.x + dir.x;
           int nextRow = head.y + dir.y;
           for (Point p : passagiere)
               if (p.x == nextCol && p.y == nextRow) {
                   return passagiere.remove(p);
               }
           return false;
       }
       void gameOver() {
           gameOver = true;
           zeigeFenster("Gut gemacht ! Der Code für die Bombe ist dein Score: "+score+ " " + "Suche nun nach 2 weiteren NFC Tags !");
           stop();
       }
       void bewegeZug() {
           for (int i = zug.size() - 1; i > 0; i--) {
               Point p1 = zug.get(i - 1);
               Point p2 = zug.get(i);
               p2.x = p1.x;
               p2.y = p1.y;
           }
           Point head = zug.get(0);
           head.x += dir.x;
           head.y += dir.y;
       }
       void verlängereZug() {
           Point tail = zug.get(zug.size() - 1);
           int x = tail.x + dir.x;
           int y = tail.y + dir.y;
           zug.add(new Point(x, y));
       }
       void addPassagiere() {
           if (passagiere.size() < 10) {
               if (rand.nextInt(10) == 0) { // 1 in 10
                   if (rand.nextInt(4) != 0) {  // 3 in 4
                       int x, y;
                       while (true) {
                           x = rand.nextInt(nCols);
                           y = rand.nextInt(nRows);
                           if (wand[y][x] != 0)
                               continue;
                           Point p = new Point(x, y);
                           if (zug.contains(p) || passagiere.contains(p))
                               continue;
                           passagiere.add(p);
                           break;
                       }
                   } else if (passagiere.size() > 1)
                       passagiere.remove(0);
               }
           }
       }
       void zeichneWand(Graphics2D g) {
           g.setColor(Color.black);
           for (int r = 0; r < nRows; r++) {
               for (int c = 0; c < nCols; c++) {
                   if (wand[r][c] == WAND)
                       g.fillRect(c * 10, r * 10, 10, 10);
               }
           }
       }
       void zeichneZug(Graphics2D g) {
           g.setColor(Color.red);
           for (Point p : zug)
               g.fillRect(p.x * 10, p.y * 10, 10, 10);


           Point head = zug.get(0);
           g.fillRect(head.x * 10, head.y * 10, 10, 10);
       }
       void zeichnePassagiere(Graphics2D g) {
           g.setColor(Color.pink);
           for (Point p : passagiere)
               g.fillRect(p.x * 10, p.y * 10, 10, 10);
       }
       void zeichneStartbildschirm(Graphics2D g) {
           g.setColor(Color.white);
           g.setFont(getFont());
           g.drawString("Sammle die Passagiere ein",650, 250);
           g.setColor(Color.white);
           g.setFont(smallFont);
           g.drawString("Beliebige Maustaste zum Starten drücken", 780, 300);
       }
       void zeichnePunktestand(Graphics2D g) {
           int h = getHeight();
           g.setFont(smallFont);
           g.setColor(Color.white);
           String s = format("HighScore: %d    Score: %d", highScore, score);
           g.drawString(s, 30, h - 30);
       }


       public void paintComponent(Graphics gg) {
           super.paintComponent(gg);
           Graphics2D g = (Graphics2D) gg;
           g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                   RenderingHints.VALUE_ANTIALIAS_ON);
           zeichneWand(g);
           if (gameOver) {
               zeichneStartbildschirm(g);
           } else {
               zeichneZug(g);
               zeichnePassagiere(g);
               zeichnePunktestand(g);
           }
       }
   }



 public static void main(String[] args) {
       SwingUtilities.invokeLater(
               () -> {
                   JFrame mainFrame = new JFrame();
                   mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                   mainFrame.setTitle("Deutsche Bahn");
                   mainFrame.setResizable(true);
                   mainFrame.add(new zug(), BorderLayout.CENTER);
                   mainFrame.pack();
                   mainFrame.setLocationRelativeTo(null);
                   mainFrame.setVisible(true);
               });
   }

}