java swing實(shí)現(xiàn)貪吃蛇雙人游戲
本文實(shí)例為大家分享了java swing實(shí)現(xiàn)貪吃蛇游戲的具體代碼,供大家參考,具體內(nèi)容如下
游戲截圖
代碼 Java14寫的哦低版本會(huì)報(bào)錯(cuò)
文件列表
package Sys; import javax.swing.*; import java.awt.*; import java.awt.event.*; import java.util.LinkedList; import java.util.Timer; import java.util.TimerTask; public class MainFame extends JFrame implements Runnable { private Snake snake;//蛇 private Snake snake1;//蛇 private JPanel jpanel;//游戲棋盤 private Node[] food;//食物 private int signSnake = 1;//標(biāo)記蛇 final Object cluck = 2; private boolean moveBoolean = true; // private boolean firstTime = true; public MainFame() { // 初始化框體 initFrame(); // 初始化網(wǎng)格 initGamePanel(); // 初始化蛇 initSnake(); // 初始化食物 initFood(); setVisible(true); try { Thread.sleep(500); } catch (InterruptedException e) { e.printStackTrace(); } // 初始化定時(shí)器 // initTimer(); // 鍵盤監(jiān)聽 setKyeListener(); // 啟動(dòng)多線程 // Runnable R = this;----- // new Thread(R).start(); // new Thread(R).start(); } private void initFood() { food = new Node[3]; for (int i = 0; i < food.length; i++) { food[i] = new Node(); food[i].random(); } } //鍵盤監(jiān)聽 private void setKyeListener() { addKeyListener(new KeyAdapter() { // 按下鍵盤 @Override public void keyPressed(KeyEvent e) { if(moveBoolean){ switch (e.getKeyCode()) { case KeyEvent.VK_UP -> snake.setDirection(Direction.UP); case KeyEvent.VK_DOWN -> snake.setDirection(Direction.DOWN); case KeyEvent.VK_LEFT -> snake.setDirection(Direction.LEFT); case KeyEvent.VK_RIGHT -> snake.setDirection(Direction.RIGHT); case KeyEvent.VK_W -> snake1.setDirection(Direction.UP); case KeyEvent.VK_S -> snake1.setDirection(Direction.DOWN); case KeyEvent.VK_A -> snake1.setDirection(Direction.LEFT); case KeyEvent.VK_D -> snake1.setDirection(Direction.RIGHT); } } moveBoolean = true; } }); } // 多線程船艦蛇 @Override public void run() { if (signSnake == 1) { signSnake++; Thread.currentThread().setName("->紅色方<-"); initTimer(snake, snake1, Thread.currentThread().getName()); } else if (signSnake == 2) { Thread.currentThread().setName("->綠色方<-"); initTimer(snake1, snake, Thread.currentThread().getName()); } } // 初始化定時(shí)器 private void initTimer(Snake snake, Snake snake1, String name) { // 創(chuàng)建定時(shí)器對(duì)象 //定時(shí)器 Timer timer = new Timer(); // 初始化定時(shí)任務(wù) TimerTask timerTask = new TimerTask() { @Override public void run() { if (snake.getIslive()) { synchronized (cluck) { snake.move(snake1);//1, moveBoolean = true; } // 吃食物,臨界區(qū)處理 Node head = snake.getBody().getFirst(); for (Node node : food) { if (head.getX() == node.getX() && head.getY() == node.getY()) { snake.eat(); node.random(); } } // 更新棋盤 jpanel.repaint(); } else { timer.cancel(); System.out.println("蛇線程" + name + "結(jié)束?。。?); System.out.println("蛇線程" + name + "得分:" + snake.scor); } } }; // 每100毫秒執(zhí)行一次定時(shí)任務(wù) timer.scheduleAtFixedRate(timerTask, 0, 100); } private void initSnake() { this.snake = new Snake(18); this.snake1 = new Snake(22); } // 初始化網(wǎng)格 private void initGamePanel() { jpanel = new JPanel() { @Override public void paint(Graphics g) { super.paint(g); // 清空棋盤 g.clearRect(0, 0, 600, 600); // 畫線 for (int i = 0; i < 40; i++) { g.drawLine(0, 15 * i, 600, 15 * i); g.drawLine(15 * i, 0, 15 * i, 600); } // 繪制蛇 g.setColor(Color.blue); LinkedList<Node> body = snake.getBody(); for (int i = 1; i <= body.size(); i++) { if(i == body.size()){ g.setColor(Color.RED); } g.fillRect(body.get(body.size() - i).getX() * 15, body.get(body.size() - i).getY() * 15, 15, 15); } // for (Node node : body) { // if(p == 1){ // g.setColor(Color.MAGENTA); // p++; // }else{ // g.setColor(Color.RED); // } // g.fillRect(node.getX() * 15, node.getY() * 15, 15, 15); // } g.setColor(Color.PINK); LinkedList<Node> body1 = snake1.getBody(); for (int i = 1; i <= body1.size(); i++) { if(i == body1.size()){ g.setColor(Color.GREEN); } g.fillRect(body1.get(body1.size() - i).getX() * 15, body1.get(body1.size() - i).getY() * 15, 15, 15); } // for (Node node : body1) { // if(p == 1){ // g.setColor(Color.PINK); // p++; // }else{ // g.setColor(Color.GREEN); // } // g.fillRect(node.getX() * 15, node.getY() * 15, 15, 15); // } // 繪制食物 g.setColor(Color.BLACK); for (Node node : food) { g.fillRect(node.getX() * 15, node.getY() * 15, 15, 15); } } }; // 添加網(wǎng)格到框體中 add(jpanel); } // 初始化框體 public void initFrame() { // 標(biāo)題 setTitle("胡柯洋的貪吃蛇"); // 大小 setSize(616, 639); // 不可調(diào)節(jié)大小 setResizable(false); // 設(shè)置位置 setLocation(0, 200); // 點(diǎn)x關(guān)閉 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void start(){ JFrame jFrame = new JFrame(); JButton jButton = new JButton("點(diǎn)擊開始單人游戲"); JButton jButton1 = new JButton("點(diǎn)擊開始雙人游戲"); jButton.addActionListener(e -> { Runnable R = new MainFame(); new Thread(R).start(); }); jButton1.addActionListener(e -> { Runnable R = new MainFame(); new Thread(R).start(); new Thread(R).start(); }); jFrame.setLayout(new FlowLayout(FlowLayout.CENTER, 20, 20)); jFrame.add(jButton1); jFrame.add(jButton); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jFrame.pack(); jFrame.setVisible(true); jFrame.setLocation(900, 200); } public static void main(String[] args) { start(); System.out.println("主線程結(jié)束?。?!"); } }
package Sys; import java.util.LinkedList; public class Snake { //方向 private Direction direction = Direction.LEFT; //蛇身體 private LinkedList<Node> body; //蛇生命 private boolean islive = true; //分?jǐn)?shù) int scor = 0; // int sign; // Snake snake1; public Snake(int y) { initSnake(y); } // 有移動(dòng)蛇 public void move(Snake snake1) {//int sign, if (islive) {//&& sign == 1 // 獲取蛇頭 Node head = body.getFirst(); Node newHead; body.removeLast();//去掉蛇尾 switch (direction) { case UP -> { newHead = new Node(head.getX() % 40, (head.getY() - 1 + 40) % 40); body.addFirst(newHead); } case LEFT -> { newHead = new Node((head.getX() - 1 + 40) % 40, head.getY() % 40); body.addFirst(newHead); } case DOWN -> { newHead = new Node(head.getX() % 40, (head.getY() + 1) % 40); body.addFirst(newHead); } case RIGHT -> { newHead = new Node((head.getX() + 1) % 40, head.getY() % 40); body.addFirst(newHead); } } head = body.getFirst(); if (head.getX() < 0 || head.getY() < 0 || head.getX() >= 40 || head.getY() >= 40) { this.islive = false; } // for (int i = 1; i < body.size(); i++) { // Node node = body.get(i); // if (node.getX() == head.getX() && node.getY() == head.getY()) { // this.islive = false; // } // } int t = snake1.getBody().size(); for (int i = 0; i < t; i++) { Node node = snake1.getBody().get(i);//error if (node.getX() == head.getX() && node.getY() == head.getY()) { this.islive = false; break; } } } } // 初始化蛇 private void initSnake(int y) { // 初始化蛇的實(shí)例 body = new LinkedList<>(); // 添加節(jié)點(diǎn) body.add(new Node(16, y)); body.add(new Node(17, y)); body.add(new Node(18, y)); // body.add(new Node(19, 20)); // body.add(new Node(20, 20)); // body.add(new Node(21, 20)); // body.add(new Node(22, 20)); } public LinkedList<Node> getBody() { return body; } public void setDirection(Direction direction) { this.direction = direction; } public Direction getDirection() { return direction; } // 吃食物 public void eat() { scor ++; // 獲取蛇頭 Node head = body.getFirst(); Node newHead; switch (direction) { case UP -> { newHead = new Node(head.getX(), head.getY() - 1); body.addFirst(newHead); } case LEFT -> { newHead = new Node(head.getX() - 1, head.getY()); body.addFirst(newHead); } case DOWN -> { newHead = new Node(head.getX(), head.getY() + 1); body.addFirst(newHead); } case RIGHT -> { newHead = new Node(head.getX() + 1, head.getY()); body.addFirst(newHead); } } } public boolean getIslive() { return islive; } }
package Sys; import java.util.Random; public class Node { private int x; private int y; // public boolean isEat = false; public Node() { } public Node(int x, int y) { this.x = x; this.y = y; } public int getX() { return x; } public void setX(int x) { this.x = x; } public int getY() { return y; } public void setY(int y) { this.y = y; } public void random() { Random r = new Random(); this.x = r.nextInt(34) + 3; this.y = r.nextInt(34) + 3; } }
package Sys; public enum Direction{ UP, DOWN, LEFT, RIGHT; }
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java 使用json-lib處理JSON詳解及實(shí)例代碼
這篇文章主要介紹了Java 使用json-lib處理JSON詳解及實(shí)例代碼的相關(guān)資料,需要的朋友可以參考下2017-02-02Spring boot自定義http反饋狀態(tài)碼詳解
這篇文章主要給大家介紹了Spring boot自定義http反饋狀態(tài)碼的相關(guān)資料,文中介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面跟著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-06-06jvm細(xì)節(jié)探索之synchronized及實(shí)現(xiàn)問題分析
這篇文章主要介紹了jvm細(xì)節(jié)探索之synchronized及實(shí)現(xiàn)問題分析,涉及synchronized的字節(jié)碼表示,JVM中鎖的優(yōu)化,對(duì)象頭的介紹等相關(guān)內(nèi)容,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-11-11Maven將代碼及依賴打成一個(gè)Jar包的方式詳解(最新推薦)
這篇文章主要介紹了Maven將代碼及依賴打成一個(gè)Jar包的方式,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-05-05Java 數(shù)據(jù)結(jié)構(gòu)與算法系列精講之排序算法
排序算法是《數(shù)據(jù)結(jié)構(gòu)與算法》中最基本的算法之一。排序算法可以分為內(nèi)部排序和外部排序,內(nèi)部排序是數(shù)據(jù)記錄在內(nèi)存中進(jìn)行排序,而外部排序是因排序的數(shù)據(jù)很大,一次不能容納全部的排序記錄,在排序過程中需要訪問外存2022-02-02java高并發(fā)ThreadPoolExecutor類解析線程池執(zhí)行流程
這篇文章主要為大家介紹了java高并發(fā)ThreadPoolExecutor類解析線程池執(zhí)行流程,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09Java實(shí)現(xiàn)短信驗(yàn)證碼詳細(xì)過程
這篇文章主要給大家介紹了關(guān)于Java實(shí)現(xiàn)短信驗(yàn)證碼的相關(guān)資料, 在業(yè)務(wù)需求中我們經(jīng)常會(huì)用到短信驗(yàn)證碼,比如手機(jī)號(hào)登錄、綁定手機(jī)號(hào)、忘記密碼、敏感操作等,需要的朋友可以參考下2023-09-09maven關(guān)于pom文件中的relativePath標(biāo)簽使用
在Maven項(xiàng)目中,子工程通過<relativePath>標(biāo)簽指定父工程的pom.xml位置,以確保正確繼承父工程的配置,這個(gè)標(biāo)簽可以配置為默認(rèn)值、空值或自定義值,默認(rèn)情況下,Maven會(huì)向上一級(jí)目錄尋找父pom;若配置為空值2024-09-09