import javax.swing.; import java.awt.; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.LinkedList; import java.util.Random; public class SnakeGame extends JPanel implements ActionListener { private static final int TILE_SIZE = 30; // Tamanho de cada quadrado (tile) private static final int WIDTH = 600; // Largura do campo de jogo private static final int HEIGHT = 400; // Altura do campo de jogo private static final int NUM_TILES_X = WIDTH / TILE_SIZE; private static final int NUM_TILES_Y = HEIGHT / TILE_SIZE; private LinkedList snake; // A cobrinha private Point food; // A comida private boolean isGameOver; // Condição de fim de jogo private char direction; // Direção atual da cobrinha private Timer timer; // Timer para atualizar o jogo public SnakeGame() { this.setPreferredSize(new Dimension(WIDTH, HEIGHT)); this.setBackground(Color.BLACK); this.setFocusable(true); snake = new LinkedList<>(); snake.add(new Point(NUM_TILES_X / 2, NUM_TILES_Y / 2)); // Inicia a cobrinha no centro direction = 'R'; // Direção inicial (direita) generateFood(); // Listener para as teclas direcionais addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent e) { switch (e.getKeyCode()) { case KeyEvent.VK_UP: if (direction != 'D') direction = 'U'; // Para não ir para a direção oposta break; case KeyEvent.VK_DOWN: if (direction != 'U') direction = 'D'; break; case KeyEvent.VK_LEFT: if (direction != 'R') direction = 'L'; break; case KeyEvent.VK_RIGHT: if (direction != 'L') direction = 'R'; break; } } }); // Timer para chamar a atualização do jogo timer = new Timer(100, this); timer.start(); } @Override public void actionPerformed(ActionEvent e) { if (isGameOver) { return; // Se o jogo acabou, não faz nada } moveSnake(); checkCollisions(); repaint(); } private void moveSnake() { Point head = snake.getFirst(); // A cabeça da cobra Point newHead = null; // Movendo a cobra de acordo com a direção switch (direction) { case 'U': // Cima newHead = new Point(head.x, head.y - 1); break; case 'D': // Baixo newHead = new Point(head.x, head.y + 1); break; case 'L': // Esquerda newHead = new Point(head.x - 1, head.y); break; case 'R': // Direita newHead = new Point(head.x + 1, head.y); break; } // Adicionando a nova cabeça snake.addFirst(newHead); // Verificando se a cobra comeu a comida if (newHead.equals(food)) { generateFood(); // Gerar nova comida } else { snake.removeLast(); // Remover a cauda se não comer a comida } } private void checkCollisions() { Point head = snake.getFirst(); // Checar se a cabeça da cobra bateu nas paredes if (head.x < 0 || head.x >= NUM_TILES_X || head.y < 0 || head.y >= NUM_TILES_Y) { isGameOver = true; } // Checar se a cobra bateu em si mesma for (int i = 1; i < snake.size(); i++) { if (head.equals(snake.get(i))) { isGameOver = true; } } } private void generateFood() { Random rand = new Random(); int x = rand.nextInt(NUM_TILES_X); int y = rand.nextInt(NUM_TILES_Y); food = new Point(x, y); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); // Desenhar a cobra g.setColor(Color.GREEN); for (Point p : snake) { g.fillRect(p.x * TILE_SIZE, p.y * TILE_SIZE, TILE_SIZE, TILE_SIZE); } // Desenhar a comida g.setColor(Color.RED); g.fillRect(food.x * TILE_SIZE, food.y * TILE_SIZE, TILE_SIZE, TILE_SIZE); // Desenhar o texto de fim de jogo if (isGameOver) { g.setColor(Color.WHITE); g.setFont(new Font("Arial", Font.BOLD, 30)); g.drawString("Game Over!", WIDTH / 3, HEIGHT / 2); } } public static void main(String[] args) { JFrame frame = new JFrame("Jogo da Cobrinha"); SnakeGame gamePanel = new SnakeGame(); frame.add(gamePanel); frame.pack(); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setVisible(true); } }javac SnakeGame.java