貪吃蛇小游戲—手把手教你會你寫貪吃蛇(java)

貪吃蛇小游戲—手把手教你會你寫貪吃蛇(java)

? ? 首先說一下,經(jīng)典游戲貪吃蛇–原理很簡單不羅嗦,我們是來看東西的。

? ? 游戲需要一個容器來承載,其次是我們需要為游戲準(zhǔn)備一些必要的東西,貪吃蛇首先的要有蛇–準(zhǔn)備蛇的圖片素材,為了便于開發(fā)建議蛇的每個部位的圖片大小一樣;

? ? 1,準(zhǔn)備好上述素材之后開始創(chuàng)建容器–Jframe

看代碼–

package com.snake;

import javax.swing.*;

import java.awt.*;

/**

* @Auther: GavinLim

* @Date: 2021/7/5 - 07 - 05 - 8:27

* @Description: com.snake

* @version: 1.0

*/

public class StartGame {

? ? public static void main(String[] args) {

? ? ? ? //創(chuàng)建窗體

? ? ? ? JFrame jFrame= new JFrame();

? ? ? ? //設(shè)置窗口標(biāo)題

? ? ? ? jFrame.setTitle("貪吃蛇游戲? designed by Gavin");

? ? ? ? //設(shè)置窗體大小,由于要考慮到不同的屏幕尺寸,所以首先要獲得運行時電腦的屏幕參數(shù)

? ? ? ? int? height =Toolkit.getDefaultToolkit().getScreenSize().height;

? ? ? ? int width =Toolkit.getDefaultToolkit().getScreenSize().width;

? ? ? ? jFrame.setBounds((width-800)/2,(height-800)/2,800,800);

? ? ? ? //設(shè)置窗體大小不可調(diào)節(jié)

? ? ? ? jFrame.setResizable(false);

? ? ? ? //默認(rèn)窗體不可見,設(shè)置成可見的

? ? ? ? jFrame.setVisible(true);

? ? }

}

但是關(guān)閉窗體后程序并沒有結(jié)束


————————————————

我們想要的是–程序關(guān)閉后游戲即退出–不然占內(nèi)存呀?。?/p>

完善之后的代碼—

package com.snake;

import javax.swing.*;

import java.awt.*;

public class StartGame {

? ? public static void main(String[] args) {

? ? ? ? //創(chuàng)建窗體

? ? ? ? JFrame jFrame = new JFrame();

? ? ? ? //設(shè)置窗口標(biāo)題

? ? ? ? jFrame.setTitle("貪吃蛇游戲? designed by Gavin");

? ? ? ? //設(shè)置窗體大小,由于要考慮到不同的屏幕尺寸,所以首先要獲得運行時電腦的屏幕參數(shù)

? ? ? ? int height = Toolkit.getDefaultToolkit().getScreenSize().height;

? ? ? ? int width = Toolkit.getDefaultToolkit().getScreenSize().width;

? ? ? ? jFrame.setBounds((width - 800) / 2, (height - 800) / 2, 800, 800);

? ? ? ? //設(shè)置窗體大小不可調(diào)節(jié)

? ? ? ? jFrame.setResizable(false);

? ? ? ? //設(shè)置窗體關(guān)閉游戲退出

? ? ? ? jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

? ? ? ? //默認(rèn)窗體不可見,設(shè)置成可見的

? ? ? ? jFrame.setVisible(true);

? ? }

}

? ?

? ? ,2,接下來—封裝小蛇—這是一種思想,如果要把圖片、文件等加載到程序中就要將他封裝成具體的對象,封裝是先通過封裝地址,在通過地址封裝為具體對象的;封裝之前先導(dǎo)入素材–可以單獨創(chuàng)建一個包用來存放素材;


————————————————

這里是用一個包專門來放素材的—方便查找;

封裝之前我們要明白代碼是經(jīng)過編譯之后運行的,所以我們存放素材的地址并不是編譯之后的地址–做一個測試類–

import java.net.URL;

/**

* @Auther: GavinLim

* @Date: 2021/7/5 - 07 - 05 - 8:45

* @Description: com.snake

* @version: 1.0

*/

public class UrlTest {

? ? public static void main(String[] args) {

? ? ? ? URL headerUrl=SnakeImages.class.getResource("/");

? ? ? ? System.out.println(headerUrl);

? ? }

}

執(zhí)行結(jié)果如下—

Picked up JAVA_TOOL_OPTIONS: -Dfile.encoding=UTF-8

file:/C:/Users/Administrator/IdeaProjects/SnakeEatGame/out/production/SnakeEatGame/

?

所以在封裝之前我們要預(yù)編譯一下看圖片被加載到哪里了;



預(yù)編譯之后我們會發(fā)存放class文件的out文件夾下多了一個文件夾—

這個snakeImages就是存放圖片的位置;


————————————————

圖片編譯前存放位置(絕對路徑)

C:\Users\Administrator\IdeaProjects\SnakeEatGame\src\snakeImage\header.png

圖片編譯后存放位置(絕對路徑)

C:/Users/Administrator/IdeaProjects/SnakeEatGame/out/production/SnakeEatGame/

對比后我們發(fā)現(xiàn)的確不一樣,由于運行時看的是編譯后的地址,所以要先找地址而不能直接封裝圖片。

? ? 3,接下來開始封裝—

package com.snake;

import javax.swing.*;

import java.awt.*;

import java.net.URL;

import java.sql.SQLOutput;

/**

* @Auther: GavinLim

* @Date: 2021/7/5 - 07 - 05 - 8:44

* @Description: com.snake

* @version: 1.0

*/

public class SnakeImages {

? ? public static URL headerUrl = SnakeImages.class.getResource("/snakeImage/header.png");

? ? public static ImageIcon headerImg = new ImageIcon(headerUrl);

? ? public static URL upUrl = SnakeImages.class.getResource("/snakeImage/up.png");

? ? public static ImageIcon upImg = new ImageIcon(upUrl);

? ? public static URL downUrl = SnakeImages.class.getResource("/snakeImage/down.png");

? ? public static ImageIcon downImg = new ImageIcon(downUrl);

? ? public static URL rightUrl = SnakeImages.class.getResource("/snakeImage/right.png");

? ? public static ImageIcon rightImg = new ImageIcon(rightUrl);

? ? public static URL leftUrl = SnakeImages.class.getResource("/snakeImage/left.png");

? ? public static ImageIcon leftImg = new ImageIcon(leftUrl);

? ? public static URL bodyUrl = SnakeImages.class.getResource("/snakeImage/body.png");

? ? public static ImageIcon bodyImg = new ImageIcon(bodyUrl);

? ? public static URL foodUrl = SnakeImages.class.getResource("/snakeImage/food.png");

? ? public static ImageIcon foodImg = new ImageIcon(foodUrl);


}

? ? 4, 封裝完畢之后,要畫一個面板,可以把窗體理解為容器,面板才是游戲運行是的界面–

新建一個面板類–并不是隨便一個類就可以成為面板,需要繼承Jpanel類

面板中定義蛇的廚師位置等信息

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.Random;

/**

* @Auther: GavinLim

* @Date: 2021/7/5 - 07 - 05 - 9:07

* @Description: com.snake

* @version: 1.0

*/

public class GamePanel extends JPanel {

? ? int length;//蛇的長度

? ? //蛇的坐標(biāo)

? ? int snakeX[] = new int[10000];

? ? int snakeY[] = new int[10000];

? ? //蛇頭的方向

? ? String direction;

? ? //游戲是否開始--默認(rèn)沒開始

? ? boolean isStart = false;

? ? //蛇是否死亡---開始時候默認(rèn)活著

? ? boolean isDie = false;

? ? //定時器,用于啟動小蛇

? ? Timer timer;

? ? //定義食物位置

? ? int foodX;

? ? int foodY;

? ? //定義分?jǐn)?shù)

? ? int score;

? ? //定義初始化方法---在構(gòu)造方法中初始化并不太好,所以拿到外面來方便直接調(diào)用;

? ? public void reset() {

? ? ? ? //初始化蛇的長度

? ? ? ? length = 4;

? ? ? ? //初始化蛇的位置

? ? ? ? snakeX[0] = 200;

? ? ? ? snakeY[0] = 275;

? ? ? ? snakeX[1] = 175;

? ? ? ? snakeY[1] = 275;

? ? ? ? snakeX[2] = 150;

? ? ? ? snakeY[2] = 275;

? ? ? ? snakeX[3] = 125;

? ? ? ? snakeY[3] = 275;

? ? ? ? //初始化食物位置

? ? ? ? foodX = 400;

? ? ? ? foodY = 500;

? ? ? ? //初始化蛇頭位置

? ? ? ? direction = "R";

? ? }

?

? ? 5,接下來定義面板構(gòu)造方法–承接上面代碼,構(gòu)造方法中有監(jiān)聽器,同時有判斷的邏輯

? ? public GamePanel() {

? ? ? ? reset();

//程序運行之后要將焦點挪到游戲界面

? ? ? ? this.setFocusable(true);

//加入按鍵監(jiān)聽--

? ? ? ? ? /*public interface KeyListener extends EventListener {

? ? ? ? ? ? KeyListener 是一個接口,實現(xiàn)接口需要全部實現(xiàn)*/

? ? ? /*this.addKeyListener(new KeyListener() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void keyTyped(KeyEvent e) {

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void keyPressed(KeyEvent e) {

? ? ? ? ? ? }

? ? ? ? ? ? @Override

? ? ? ? ? ? public void keyReleased(KeyEvent e) {

? ? ? ? ? ? }

? ? ? ? });*/

? ? ? ? /*----public abstract class KeyAdapter implements KeyListener {

? ? ? ? KeyAdapter實現(xiàn)了KeyListener接口,同時又是一個抽象類,可以根據(jù)自己需要進(jìn)行覆寫*/

? ? ? ? this.addKeyListener(new KeyAdapter() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void keyPressed(KeyEvent e) {

? ? ? ? ? ? ? ? super.keyPressed(e);

? ? ? ? ? ? ? ? //通過監(jiān)聽按鍵來控制游戲--每一個按鍵對應(yīng)一個ASCII碼,通過此來判斷用戶按了哪個鍵

? ? ? ? ? ? ? ? int input = e.getKeyCode();

? ? ? ? ? ? ? ? //監(jiān)聽空格以開始游戲

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_SPACE) {

//? ? ? ? ? ? ? ? ? ? 同時要判斷小蛇是否死亡

? ? ? ? ? ? ? ? ? ? if (isDie) {//如果死了,那么恢復(fù)初始狀態(tài)

? ? ? ? ? ? ? ? ? ? ? ? reset();

? ? ? ? ? ? ? ? ? ? ? ? //重新賦予小蛇生命

? ? ? ? ? ? ? ? ? ? ? ? isDie = false;

? ? ? ? ? ? ? ? ? ? } else {//沒死的話,開始--暫停進(jìn)行切換

? ? ? ? ? ? ? ? ? ? ? ? isStart = !isStart;

? ? ? ? ? ? ? ? ? ? ? ? repaint();//重繪

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? //這個監(jiān)聽完畢之后開始監(jiān)聽上下左右箭頭---當(dāng)然可以監(jiān)聽wasd,

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_UP) {

? ? ? ? ? ? ? ? ? ? direction = "U";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_W) {

? ? ? ? ? ? ? ? ? ? direction = "U";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_DOWN) {

? ? ? ? ? ? ? ? ? ? direction = "D";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_S) {

? ? ? ? ? ? ? ? ? ? direction = "D";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_RIGHT) {

? ? ? ? ? ? ? ? ? ? direction = "R";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_D) {

? ? ? ? ? ? ? ? ? ? direction = "R";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_LEFT) {

? ? ? ? ? ? ? ? ? ? direction = "L";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? if (input == KeyEvent.VK_A) {

? ? ? ? ? ? ? ? ? ? direction = "L";

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

//按鍵釋放--沒有相應(yīng)操作--所以不用動他

? ? ? ? ? ? @Override

? ? ? ? ? ? public void keyReleased(KeyEvent e) {

? ? ? ? ? ? ? ? super.keyReleased(e);

? ? ? ? ? ? }

? ? ? ? });

? ? 6,寫完上述代碼,小蛇還沒有動,這時候需要啟動定時器

? ? ? ? timer = new Timer(200, new ActionListener() {

? ? ? ? ? ? @Override

? ? ? ? ? ? public void actionPerformed(ActionEvent e) {

? ? ? ? ? ? ? ? if (isStart == true && isDie == false) {//游戲開始狀態(tài)

? ? ? ? ? ? ? ? ? ? //蛇動----蛇尾開始動,然后開始蛇頭--俗稱guyong'

? ? ? ? ? ? ? ? ? ? for (int i = length - 1; i > 0; i--) {

? ? ? ? ? ? ? ? ? ? ? ? //后一節(jié)依次往前挪一位

? ? ? ? ? ? ? ? ? ? ? ? snakeX[i] = snakeX[i - 1];

? ? ? ? ? ? ? ? ? ? ? ? snakeY[i] = snakeY[i - 1];

? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? //頭部比較復(fù)雜一下,因為要上下左右動

? ? ? ? ? ? ? ? ? ? if ("R".equals(direction)) {

? ? ? ? ? ? ? ? ? ? ? ? snakeX[0] += 25;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if ("L".equals(direction)) {

? ? ? ? ? ? ? ? ? ? ? ? snakeX[0] -= 25;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if ("U".equals(direction)) {

? ? ? ? ? ? ? ? ? ? ? ? snakeY[0] -= 25;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if ("D".equals(direction)) {

? ? ? ? ? ? ? ? ? ? ? ? snakeY[0] += 25;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? //防止越界后? ? 回不來了

? ? ? ? ? ? ? ? ? ? if (snakeX[0] > 750) {

? ? ? ? ? ? ? ? ? ? ? ? snakeX[0] = 25;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if (snakeX[0] < 25) {

? ? ? ? ? ? ? ? ? ? ? ? snakeX[0] = 750;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if (snakeY[0] < 100) {

? ? ? ? ? ? ? ? ? ? ? ? snakeY[0] = 725;

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? if (snakeY[0] > 725) {

? ? ? ? ? ? ? ? ? ? ? ? snakeY[0] = 100;

? ? ? ? ? ? ? ? ? ? }


? ? ? ? ? ? ? ? ? ? //檢測碰撞動作--吃食物

? ? ? ? ? ? ? ? ? ? //這里一定要注意是25的倍數(shù),不然會哦出現(xiàn)吃不到食物的尷尬

? ? ? ? ? ? ? ? ? ? if (snakeX[0] == foodX && snakeY[0] == foodY) {

? ? ? ? ? ? ? ? ? ? ? ? //吃到食物后蛇產(chǎn)古增加,積分增加

? ? ? ? ? ? ? ? ? ? ? ? length++;

? ? ? ? ? ? ? ? ? ? ? ? //吃到食物后,食物會重新產(chǎn)生--隨機

? ? ? ? ? ? ? ? ? ? ? ? foodX = ((int) (Math.random() * 30) + 1) * 25;

? ? ? ? ? ? ? ? ? ? ? ? foodY = ((new Random().nextInt(26) + 4) * 25);

? ? ? ? ? ? ? ? ? ? ? ? score += 10;

? ? ? ? ? /**蛇長度增加后要馬上修改該節(jié)身子的位置--不然會在游戲左上角,當(dāng)蛇每吃到一顆食物就會閃一下,可以把以下代碼注釋掉試一下,出現(xiàn)的原因是每次增加的時候沒有立馬給定增加的身體部分位置,所以默認(rèn)為位置為 (0,0),加上一下兩行代碼就解決了;*/

? ? ? ? ? ? ? ? ? ? ? ? snakeX[length - 1] = snakeX[length - 2];

? ? ? ? ? ? ? ? ? ? ? ? snakeY[length - 1] = snakeY[length - 2];

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? //判定死亡的方法--蛇頭跟任意一節(jié)身子碰撞就是死亡

? ? ? ? ? ? ? ? ? ? for (int i = 1; i < length; i++) {

? ? ? ? ? ? ? ? ? ? ? ? if (snakeX[0] == snakeX[i] && snakeY[0] == snakeY[i]) {

? ? ? ? ? ? ? ? ? ? ? ? ? ? isDie = true;

? ? ? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? }

? ? ? ? ? ? ? ? ? ? repaint();//重繪制

? ? ? ? ? ? ? ? }

? ? ? ? ? ? }

? ? ? ? });

//? ? ? ? 以上寫完小蛇還沒動--因為沒有開啟定時器

? ? ? ? timer.start();

? ? }

?

? ? 7,接下來要不斷繪制圖像界面才能使得人眼看到動的小蛇

? ? @Override//覆寫該方法

? ? public void paintComponent(Graphics g) {

? ? ? ? super.paintComponent(g);//這是一個畫筆

? ? ? ? //設(shè)置游戲區(qū)面板顏色

? ? ? ? this.setBackground(new Color(195, 253, 4));

? ? ? ? // 加載圖片--header--m默認(rèn)位置,不需要動

? ? ? ? SnakeImages.headerImg.paintIcon(this, g, 0, 5);

? ? ? ? //設(shè)置畫筆顏色

? ? ? ? g.setColor(new Color(193, 255, 183));

? ? ? ? //填充游戲界面,可以找個好看的圖片

? ? ? ? //SnakeImages.backImg.paintIcon(this,g,8,70);//由于太丑,所以不加載背景圖了

? ? ? ? g.fillRect(10, 70, 770, 685);

? ? ? ? //下面加載蛇頭和身子

? ? ? ? if ("R".equals(direction)) {

? ? ? ? ? ? SnakeImages.rightImg.paintIcon(this, g, snakeX[0], snakeY[0]);

? ? ? ? }

? ? ? ? if ("L".equals(direction)) {

? ? ? ? ? ? SnakeImages.leftImg.paintIcon(this, g, snakeX[0], snakeY[0]);

? ? ? ? }

? ? ? ? if ("U".equals(direction)) {

? ? ? ? ? ? SnakeImages.upImg.paintIcon(this, g, snakeX[0], snakeY[0]);

? ? ? ? }

? ? ? ? if ("D".equals(direction)) {

? ? ? ? ? ? SnakeImages.downImg.paintIcon(this, g, snakeX[0], snakeY[0]);

? ? ? ? }

//? ? ? ? 畫完蛇頭畫蛇身

? ? ? ? for (int i = 1; i < length; i++) {

? ? ? ? ? ? SnakeImages.bodyImg.paintIcon(this, g, snakeX[i], snakeY[i]);

? ? ? ? }

? ? ? ? if (isStart == false) {

? ? ? ? ? ? //設(shè)置畫筆顏色

? ? ? ? ? ? g.setColor(new Color(255, 173, 0));

? ? ? ? ? ? //畫一個文字

? ? ? ? ? ? g.setFont(new Font("微軟雅黑", Font.BOLD, 40));

? ? ? ? ? ? g.drawString("點擊空格開始游戲", 250, 300);

? ? ? ? }

? ? ? ? //畫食物

? ? ? ? SnakeImages.foodImg.paintIcon(this, g, foodX, foodY);

//畫積分

? ? ? ? g.setColor(new Color(255, 0, 19));

? ? ? ? g.setFont(new Font("微軟雅黑", Font.BOLD, 20));

? ? ? ? g.drawString("積分:" + score, 620, 40);

? ? ? ? //死亡狀態(tài):

? ? ? ? if (isDie) {

? ? ? ? ? ? g.setColor(new Color(255, 82, 68));

? ? ? ? ? ? g.setFont(new Font("微軟雅黑", Font.BOLD, 20));

? ? ? ? ? ? g.drawString("小蛇死亡,游戲停止,按下空格重新開始游戲", 200, 330);

? ? ? ? ? ? score = 0;

? ? ? ? }

? ? }

}

?

以上代碼寫完,運行后發(fā)現(xiàn)少了點什么,-----在游戲啟動界面沒有添加還面板,接下來就是補充和完善代碼了-

package com.snake;

import javax.swing.*;

import java.awt.*;

public class StartGame {

? ? public static void main(String[] args) {

? ? ? ? //創(chuàng)建窗體

? ? ? ? JFrame jFrame = new JFrame();

? ? ? ? //設(shè)置窗口標(biāo)題

? ? ? ? jFrame.setTitle("貪吃蛇游戲? designed by Gavin");

? ? ? ? //設(shè)置窗體大小,由于要考慮到不同的屏幕尺寸,所以首先要獲得運行時電腦的屏幕參數(shù)

? ? ? ? int height = Toolkit.getDefaultToolkit().getScreenSize().height;

? ? ? ? int width = Toolkit.getDefaultToolkit().getScreenSize().width;

? ? ? ? jFrame.setBounds((width - 800) / 2, (height - 800) / 2, 800, 800);

? ? ? ? //設(shè)置窗體大小不可調(diào)節(jié)

? ? ? ? jFrame.setResizable(false);

? ? ? ? //設(shè)置窗體關(guān)閉游戲退出

? ? ? ? jFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);

? ? ? ? GamePanel gamePanel= new GamePanel();

? ? ? ? jFrame.add(gamePanel);

? ? ? ? //默認(rèn)窗體不可見,設(shè)置成可見的

? ? ? ? jFrame.setVisible(true);

? ? }

}

?

運行結(jié)果的一些截圖–

啟動界面–


運行界面


死亡界面


如果你有大塊時間完全可以在完善一下此代碼,添加一些模式–

1,急速模式–調(diào)節(jié)啟動器的時間間隔即可

2,在窗口中再來一條蛇–與多線程結(jié)合

3,在豐富一些設(shè)置內(nèi)容–比如選擇模式等

重新游戲時記得積分清零哦。。。

? ? 總結(jié)—雖然現(xiàn)在swing編程很low了,但是該學(xué)習(xí)的地方還是有的—

? ? 1,要學(xué)會將外部對象導(dǎo)入到程序中并封裝成相應(yīng)的類

? ? 2,練習(xí)監(jiān)聽器的思想

? ? 3,檢測自己學(xué)過的基礎(chǔ)知識–數(shù)組,循環(huán)以及邏輯思維;

? ? 4,重要的是游戲的開發(fā)思維—動效來自于不斷的刷新;

? ? 5,代碼中多次用到了匿名對象—如果該對象只用一次,可以這樣用,如果多次那么就要去實例化他了

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

友情鏈接更多精彩內(nèi)容