Android贪吃蛇游戏实现

说明:贪吃蛇游戏是一款比较经典的休闲游戏,这是我做的第一个Android项目,会存在一些问题,文章包括项目的部分源码以及运行界面的一些图片,项目也参考学习了许多大佬的文章,会在文章最后面贴出参考文章,包括源码的链接,有什么问题也请大家指正。

登录与注册

登录界面和注册界面的后台数据采用了Android自带的sqlite数据库进行存储,通过sqlite的助手类对用户添加和用户的登录进行操作,这里贴一些关于登录和注册的方法。

 //添加新用户,即注册public long insertUserData(UserData userData) {String userName=userData.getUserName();String userPwd=userData.getUserPwd();ContentValues values = new ContentValues();values.put(USER_NAME, userName);values.put(USER_PWD, userPwd);return mSQLiteDatabase.insert("users", ID, values);}//根据用户名找用户,可以判断注册时用户名是否已经存在public int findUserByName(String userName){int result=0;String Query = "Select * from users where USER_NAME =?";Cursor cursor = mSQLiteDatabase.rawQuery(Query,new String[] { userName });if(cursor!=null){result=cursor.getCount();Log.w("result=",String.valueOf(result));cursor.close();}return result;}//根据用户名和密码找用户,用于登录public int findUserByNameAndPwd(String userName,String pwd){int result=0;String Query = "Select * from users where USER_NAME =? and USER_PWD =?";Cursor mCursor = mSQLiteDatabase.rawQuery(Query,new String[] { userName,pwd});if(mCursor!=null){result=mCursor.getCount();mCursor.close();}return result;}

游戏界面

在这里插入图片描述

一、主游戏界面

主游戏界面包括了小蛇的运动界面,上方的暂停对话框、分数显示的TextView,以及下方的方向键采用了ImageButton。主要说一下小蛇运动界面的实现,这是我参考了一位大佬的做法,先在Android写一个View的子类,将界面划分为32*32的小方格坐标存储在一个二维数组中,然后新建一个蛇运动的界面类,将界面的一些图片填入到方格中。

    Bitmap[] mTileArray;            //放置图片的数组int[][] mTileGrid;              //存放各坐标对应的图片
    //加载三幅小图片,包括墙,蛇身,蛇头public void loadTile(int key, Drawable tile) {Bitmap bitmap = Bitmap.createBitmap(mTileSize, mTileSize, Bitmap.Config.ARGB_8888);Canvas canvas = new Canvas(bitmap);tile.setBounds(0, 0, mTileSize, mTileSize);tile.draw(canvas);mTileArray[key] = bitmap;}@Overridepublic void onSizeChanged(int w, int h, int oldw, int oldh){//地图数组初始化mXTileCount = (int) Math.floor(w / mTileSize);mYTileCount = (int) Math.floor(h / mTileSize);//够分成一格的分成一格, 剩下不够一格的分成两份,左边一份,右边一份mXOffset = ((w - (mTileSize * mXTileCount)) / 2);mYOffset = ((h - (mTileSize * mYTileCount)) / 2);mTileGrid = new int[mXTileCount][mYTileCount];clearTiles();}//给界面的二维数组赋值,坐标存放想要放的图片public void setTile(int tileindex, int x, int y) {mTileGrid[x][y] = tileindex;}

二、食物的生成

食物是通过random产生随机坐标,存放到食物的Arraylist中,然后调用父类的方法将图片画在view上。

    private ArrayList<Coordinate> mFoodList = new ArrayList<Coordinate>(); // 存储食物的所有坐标的数组private static final Random RNG = new Random();//随机生成食物的坐标
 private void updateFood() {for (Coordinate c : mFoodList) {setTile(snakebody, c.x, c.y);}}private void addRandomFood() {Coordinate newCoord = null;boolean found = false;while (!found) {int newX = 1+RNG.nextInt(28);//坐标0-22+1int newY = 3+RNG.nextInt(20);//坐标0-23+3newCoord = new Coordinate(newX, newY);boolean collision = false;int snakelength = mSnakeTrail.size();//遍历snake, 看新添加的apple是否在snake体内, 如果是,重新生成坐标for (int index = 0; index < snakelength; index++) {if (mSnakeTrail.get(index).equals(newCoord)) {collision = true;}}for (int index = 0; index < mObstacle.size(); index++) {if (mObstacle.get(index).equals(newCoord)) {collision = true;}}found = !collision;}mFoodList.add(newCoord);//储存已产生坐标}

三、蛇的移动和死亡

实际上蛇的移动是通过界面的重新绘制实现的,通过handle控制界面重新绘制的时间,点击方向键就改变蛇头的坐标,往某一方向进行x坐标或y坐标的增加。通过遍历食物和障碍物的Arraylist进行检测是否吃到食物或撞到障碍物,围墙的控制是通过边界坐标来控制的,如果超过边界坐标,那么游戏结束。

    private ArrayList<Coordinate> mSnakeTrail = new ArrayList<Coordinate>(); // 存储蛇的所有坐标的数组private ArrayList<Coordinate> mObstacle = new ArrayList<>();//存储障碍物坐标
    private void updateObstacle() {for (Coordinate c : mObstacle) {setTile(wall, c.x, c.y);}}private void addrandomObstacle(int count) {Coordinate newCoord = null;if(count ==4){int newX = 1+RNG.nextInt(28);//坐标0-22+1int newY = 3+RNG.nextInt(20);//坐标0-23+3newCoord = new Coordinate(newX, newY);//遍历snake, 看新添加的apple是否在snake体内, 如果是,重新生成坐标mObstacle.add(newCoord);//储存已产生坐标}}
    private void updateSnake() {boolean growSnake = false;Coordinate head = mSnakeTrail.get(0);Coordinate newHead = new Coordinate(1, 1);mDirection = mNextDirection;switch (mDirection) {//蛇移动的方向case RIGHT: {newHead = new Coordinate(head.x + 1, head.y);break;}case LEFT: {newHead = new Coordinate(head.x - 1, head.y);break;}case UP: {newHead = new Coordinate(head.x, head.y - 1);break;}case DOWN: {newHead = new Coordinate(head.x, head.y + 1);break;}}//检测投是否撞墙if ((newHead.x < 1) || (newHead.y < 3) || (newHead.x > mXTileCount-2 )|| (newHead.y > mYTileCount-9 )) {setMode(LOSE);return;}//检测蛇头是否撞到自己int snakelength = mSnakeTrail.size();for (int snakeindex = 0; snakeindex < snakelength; snakeindex++) {Coordinate c = mSnakeTrail.get(snakeindex);if (c.equals(newHead)) {setMode(LOSE);return;}}//检测蛇头撞见障碍物for(int index = 0;index < mObstacle.size();index++ ){Coordinate c = mObstacle.get(index);if (c.equals(newHead)) {setMode(LOSE);return;}}//检测蛇是否吃到食物int foodcount = mFoodList.size();for (int foodindex = 0; foodindex < foodcount; foodindex++) {Coordinate c = mFoodList.get(foodindex);if (c.equals(newHead)) {mFoodList.remove(c);addRandomFood();mScore++;mMoveDelay *= 0.95;  //蛇每迟到一个食物,延时就会减少,蛇的速度就会加快growSnake = true;if(mMoveDelay<150) {count++;Log.w("count", "" + count);if (count == 4) {addrandomObstacle(count);count = 0;}}}}mSnakeTrail.add(0, newHead);if (!growSnake) {mSnakeTrail.remove(mSnakeTrail.size() - 1);}//添加蛇的图片int index = 0;for (Coordinate c : mSnakeTrail) {if (index == 0) {setTile(snakehead, c.x, c.y);} else {setTile(snakebody, c.x, c.y);}index++;}}

四、游戏界面的布局xml

在布局中引入前面做好游戏界面,同时添加暂停,分数显示等。

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"xmlns:app="http://schemas.android.com/apk/res-auto"xmlns:tools="http://schemas.android.com/tools"android:layout_width="match_parent"android:layout_height="match_parent"android:background="@drawable/dark"android:orientation="vertical"tools:context=".GameActivity"><LinearLayoutandroid:id="@+id/linearlayout"android:layout_width="wrap_content"android:layout_height="wrap_content"android:orientation="horizontal"app:layout_constraintStart_toStartOf="parent"app:layout_constraintTop_toTopOf="parent"><ImageButtonandroid:id="@+id/pause"android:layout_width="50dp"android:layout_height="50dp"android:layout_marginStart="30dp"android:layout_marginTop="15dp"android:background="@drawable/pause" /><TextViewandroid:id="@+id/showscore"android:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_marginStart="100dp"android:layout_marginTop="15dp"android:text="10"android:textSize="35sp" /></LinearLayout><com.example.snake.Snakespaceandroid:id="@+id/snakeview"android:layout_width="match_parent"android:layout_height="480dp"android:layout_marginTop="10dp"app:layout_constraintTop_toBottomOf="@id/linearlayout"app:layout_constraintStart_toStartOf="parent"/><ImageButtonandroid:id="@+id/up"android:layout_width="75dp"android:layout_height="75dp"android:layout_gravity="center"android:layout_marginTop="20dp"android:background="@drawable/up"app:layout_constraintBottom_toBottomOf="@id/snakeview"app:layout_constraintStart_toStartOf="@id/snakeview"app:layout_constraintEnd_toEndOf="@id/snakeview"/><LinearLayoutandroid:layout_width="wrap_content"android:layout_height="wrap_content"android:layout_gravity="center"android:orientation="horizontal"app:layout_constraintTop_toBottomOf="@id/up"app:layout_constraintStart_toStartOf="@id/up"app:layout_constraintEnd_toEndOf="@id/up"><ImageButtonandroid:id="@+id/left"android:layout_width="75dp"android:layout_height="75dp"android:background="@drawable/left" /><ImageButtonandroid:id="@+id/down"android:layout_width="75dp"android:layout_height="75dp"android:background="@drawable/down" /><ImageButtonandroid:id="@+id/right"android:layout_width="75dp"android:layout_height="75dp"android:background="@drawable/right" /></LinearLayout>
</androidx.constraintlayout.widget.ConstraintLayout>

五、Mainactivity

在窗体中设置一些按键的监听,以及dialog的实现。

public class GameActivity extends AppCompatActivity implements View.OnClickListener {private static final String ICICLE_KEY = "aa";ImageButton pause;private  Snakespace snakeview;private ImageButton mLeft,mRight,mUp,mDown,out;private static final int UP = 1;private static final int DOWN = 2;private static final int RIGHT = 3;private static final int LEFT = 4;private SharedPreferences sp;private SharedPreferences.Editor editor;@Overrideprotected void onCreate(Bundle savedInstanceState) {supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏显示super.onCreate(savedInstanceState);setContentView(R.layout.activity_game);snakeview = findViewById(R.id.snakeview);sp = getSharedPreferences("difficulty",MODE_PRIVATE);mMoveDelay = sp.getInt("model",500);mMode = 2;textView = findViewById(R.id.showscore);//方向键控制移动mLeft = findViewById(R.id.left);mRight = findViewById(R.id.right);mUp = findViewById(R.id.up);mDown = findViewById(R.id.down);mLeft.setOnClickListener(this);mUp.setOnClickListener(this);mRight.setOnClickListener(this);mDown.setOnClickListener(this);//点击暂停弹出对话框pause = findViewById(R.id.pause);pause.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {mMode = 1;mydialog();}});}public  void gameover(){Intent it = new Intent(GameActivity.this,MainActivity.class);startActivity(it);}public void onClick(View v) {switch (v.getId()) {// 使界面上的方向按钮起作用case R.id.left:if (mDirection != RIGHT) {mNextDirection = LEFT;}break;case R.id.right:if (mDirection != LEFT) {mNextDirection = RIGHT;}break;case R.id.up:if (mDirection != DOWN) {mNextDirection = UP;}break;case R.id.down:if (mDirection != UP) {mNextDirection = DOWN;}break;default:break;}}private void mydialog() {final Dialog dialog = new Dialog(this);dialog.setCanceledOnTouchOutside(true);//点击外部 dialog 消失dialog.setContentView(R.layout.dialog);//添加自定义布局dialog.getWindow().setBackgroundDrawableResource(android.R.color.transparent);//设置背景透明dialog.show();Window dialogWindow = dialog.getWindow();dialogWindow.setGravity(Gravity.LEFT | Gravity.CENTER);//继续游戏final ImageButton start = dialog.findViewById(R.id.game_start);start.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {snakeview.setMode(RUNNING);Toast.makeText(GameActivity.this, "继续游戏", Toast.LENGTH_SHORT).show();snakeview.update();dialog.dismiss();}});//重新开始游戏ImageButton restart = dialog.findViewById(R.id.game_restart);restart.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {Toast.makeText(GameActivity.this, "重新开始", Toast.LENGTH_SHORT).show();restart(dialog);}});//停止游戏ImageButton over = dialog.findViewById(R.id.game_over);over.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {snakeview.setMode(QUIT);dialog.dismiss();Toast.makeText(GameActivity.this, "停止游戏", Toast.LENGTH_SHORT).show();Intent it = new Intent(GameActivity.this,choice.class);startActivity(it);}});}public void restart(Dialog dialog){mMoveDelay=sp.getInt("model",0);Log.w("nandu",String.valueOf(mMoveDelay));snakeview.initNewGame();snakeview.setMode(RUNNING);snakeview.update();dialog.dismiss();}@Overridepublic void onSaveInstanceState(Bundle outState) {//保存游戏状态super.onSaveInstanceState(outState);outState.putBundle(ICICLE_KEY, snakeview.saveState());}
}

其他

上面大概就是主界面实现的一些思路,除了主界面的实现,我也做了一些其他设置,像游戏得分排行榜,背景音乐设置,难度设置,内容比较多,这里只贴部分源码和程序界面图。

//排行榜界面的oncreat方法protected void onCreate(Bundle savedInstanceState) {supportRequestWindowFeature(Window.FEATURE_NO_TITLE);//去掉标题栏getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);//全屏显示super.onCreate(savedInstanceState);setContentView(R.layout.activity_rank);spinner = findViewById(R.id.spinner);  //将可选内容与ArrayAdapter连接起来adapter = new ArrayAdapter<>(this,android.R.layout.simple_spinner_item,m);adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);//设置下拉列表的风格spinner.setAdapter(adapter);//将adapter 添加到spinner中spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {@Overridepublic void onItemSelected(AdapterView<?> parent, View view, int position, long id) {mode2 =m[position];setrank(mode2);}@Overridepublic void onNothingSelected(AdapterView<?> parent) {mode2 ="'简单'";setrank(mode2);}});//添加事件Spinner事件监听spinner.setVisibility(View.VISIBLE);  //设置默认值lv = findViewById(R.id.lv);home = findViewById(R.id.home);home.setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View v) {finish();}});}
//音乐设置 采用service和Mediaplayer@Overridepublic int onStartCommand(Intent intent, int flags, int startId) {int music = intent.getIntExtra("music",0);Log.w("music=",String.valueOf(music));switch (music){case 1:this.mediaPlayer = MediaPlayer.create(this,R.raw.music1);break;case 2:this.mediaPlayer = MediaPlayer.create(this,R.raw.music2);break;case 3:this.mediaPlayer = MediaPlayer.create(this,R.raw.music3);break;default:break;}this.mediaPlayer.seekTo(0);this.mediaPlayer.setLooping(true);this.mediaPlayer.start();return super.onStartCommand(intent, flags, startId);}

在这里插入图片描述在这里插入图片描述
参考文章链接:
https://www.jb51.net/article/89477.htm
https://blog.csdn.net/linzekai100/article/details/80582116
源文件链接:
https://download.csdn.net/download/weixin_44799020/12604804

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/65411.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

VC版的贪吃蛇游戏

学C的时候&#xff0c;课程设计编写了C版的贪吃蛇游戏&#xff0c;当时&#xff0c;将很多的东西都分装在了Snake类中&#xff0c;所以&#xff0c;将其移植到VC中&#xff0c;只需将Snake类稍作修改&#xff0c;然后添加到VC中即可。 此处&#xff0c;我感受到复用性的好处&am…

微信小程序:贪吃蛇

微信小程序&#xff1a;贪吃蛇 wx.js var startX 0; var startY 0; var moveX 0; var moveY 0; //移动位置和开始位置的坐标差值 var X 0; var Y 0; //蛇的对象 var snake {x: 0,y: 0,color: "#ff0000", w: 20,h: 20, } //食物对象 var food {x: 0,y: 0,co…

贪吃蛇的小程序

1 创建项目 1.打开微信开发者工具如图所示的界面&#xff0c;点击“ 2.填写项目以后&#xff0c;点击确定即可。如图所示&#xff1a; 2 编程 1.编写index.wxml的代码如下&#xff1a; <view class"container"><canvas style"width:100%;height:1…

【Python游戏】贪吃蛇升级版——双人贪吃蛇小游戏 | 附带源码

前言 之前做过一个单人版的贪吃蛇&#xff0c;所以常常就是我只能看着别人玩&#xff0c;或者别人看着我玩&#xff0c;却没法两个人一起愉快地玩耍。 由此产生了做一个可以双人玩的贪吃蛇想法&#xff0c;并且从小时候一直到现在&#xff0c;之前python还没有那么火的时候&am…

html版贪吃蛇

<!doctype html><html><head></head><body> <div id"box" style"width:256px;font:25px/25px 宋体;background:#000;color:#9f9;"></div><script> var arr[15]; var next10;//最好判断一下arr[1]!arr[0]x…

贪吃蛇智能版(高级)

说明&#xff1a; 在贪吃蛇智能版&#xff08;中级&#xff09;的基础之上&#xff0c;增加了判断小食物是否安全的方法&#xff0c;并且增加了在寻找食物路径失败和寻找尾巴失败之后&#xff0c;会进行一小段的随机溜达&#xff0c;直到重新找到路径为止&#xff0c;当然这段…

贪吃蛇微信小程序源码

每日分享两个小程序源码 下载地址&#xff1a;无极低码&#xff1a;wheart.cnhttps://wheart.cn/so/home?mdw&ridf6d836c8-d54a-11ed-96fa-52540016e6ac <!--snake.wxml--> <view class"control" bindtouchstart"tapStart" bindtouchmove&qu…

win10系统激活提示无法连接到你组织的激活服务器如何解决

1、在桌面新建一个文本文档&#xff0c;把以下代码复制进去&#xff0c;如图所示&#xff1a; slmgr /ipk W269N-WFGWX-YVC9B-4J6C9-T83GX slmgr /skms kms.03k.org slmgr /ato 2、点击文件选择“另存为”&#xff0c;在弹出的界面中&#xff0c;将保存位置选择在桌面&#xff…

无法在此设备上激活WINDOWS因为无法连接到你的组织的激活服务器

在搜索框里搜索 cmd&#xff0c; 使用管理员权限运行&#xff0c;执行一句命令&#xff1a; slmgr /skms http://kms.03k.org点完回车以后&#xff0c;再打一句命令激活 slmgr /ato查激活日期 按下Windows R &#xff0c;输入cmd&#xff0c;出来dos对话框后&#xff0c;输入…

microsoft微软登录新账户/切换账户失败,一直转圈,提示“你似乎没有连接到internet”

无论有没有微软账户&#xff0c;是切换账户还是新电脑登录&#xff0c;原理都是一样的&#xff0c;先使用一个账号注册/登录/设置好微软账户&#xff0c;然后再进行你原本的操作。 在可以进入到桌面并且联网的情况下&#xff0c;登录不上微软账户的几种常用解决方法&#xff1…

登录微软账号时无法连接到网络

登录微软账号时无法连接到网络 关闭代理&#xff0c;手动设置ipv4DNS地址&#xff08;微软dns服务器&#xff1a;4.2…2.1)&#xff0c;改完记得改回来。

解决微软newbing chat的Sorry, looks like your network settings are preventing access to this featur问题

2023.03.25最近大家都有疑惑&#xff0c;已经"魔法"了&#xff0c;突然newbing chat用不了&#xff0c;弹出“Sorry, looks like your network settings are preventing access to this featur”&#xff0c; 已下是解决方法&#xff08;步骤操作的前提&#xff1a;…

成功解决长时间挂起虚拟机后再次打开无法连接网络,并提示网络激活失败(亲测有效)

成功解决长时间挂起虚拟机后再次打开无法连接网络&#xff0c;并提示网络激活失败&#xff08;亲测有效&#xff01;&#xff09; 之前做区块链的一个虚拟机很久没打开&#xff0c;一直处于挂起状态&#xff0c;一直提示网络连接激活失败。试了很多种方法没解决&#xff0c;更…

专治疑难系列 - 无法激活网络的解决方法

‍‍&#x1f3e1;博客主页&#xff1a; Passerby_Wang的博客_CSDN博客-系统运维,云计算,Linux基础领域博主 &#x1f310;所属专栏&#xff1a;『转治疑难系列』 &#x1f30c;上期文章&#xff1a; 无 &#x1f4f0;如觉得博主文章写的不错或对你有所帮助的话&#xff0c;还…

Nature综述:应对新出现的抗真菌耐药性对人类健康的威胁

编译&#xff1a;微科盟小木&#xff0c;编辑&#xff1a;微科盟居居、江舜尧。 微科盟原创微文&#xff0c;欢迎转发转载&#xff0c;转载须注明来源《微生态》公众号。 导读 侵袭性真菌感染对公共健康构成了重大威胁&#xff0c;是抗菌素耐药性的一个未得到充分认识的组成部分…

在传染病中,肠道微生物-免疫力-营养在优化治疗策略中的作用

谷禾健康 传染病&#xff0c;肠道微生物&#xff0c;营养 传染病和感染目前是许多地区尤其是低收入国家主要死亡原因&#xff0c;也是婴儿和老年人等弱势群体的主要风险。免疫系统在这些感染的易感性、持续性和清除中起着至关重要的作用。由于 70-80% 的免疫细胞存在于肠道中&a…

Microbiome:人类肠道和病原菌的可移动抗性组驱动环境中抗生素抗性增长

点击蓝字 关注我们 编译&#xff1a;张璐 校稿&#xff1a;张慧林 论文ID 原名&#xff1a;Mobile resistome of human gut and pathogen drives anthropogenic bloom of antibiotic resistance 译名&#xff1a;人类肠道和病原菌的可移动抗性组驱动环境中抗生素抗性增长 第…

抗生素对微生物组和人体健康的影响

谷禾健康 说起抗生素&#xff0c;可能会觉得有些抽象&#xff0c;那如果说阿莫西林、头孢、红霉素、阿奇霉素等等这些日常生活经常使用的药物&#xff0c;会不会有一些熟悉的感觉。当我们发现身体有一些小炎症(如头痛发热、喉咙痒疼、咳嗽)的时候&#xff0c;首先会想到要使用这…

肠道菌群、性激素与疾病:探索它们的交互作用

谷禾健康 我们的身体中有很多不同的器官&#xff0c;组织&#xff0c;腺体等会产生许多信号分子来精确控制和影响身体的反应和活动&#xff0c;这些信号分子包括激素、神经递质、生长因子、细胞因子等。它们可以促进或抑制细胞的生长和分化&#xff0c;调节细胞间的相互作用和通…

抗生素对肠道微生物群的影响

在与细菌性疾病的斗争中&#xff0c;抗生素是不可避免的。抗生素是人类使用了几十年的治疗细菌感染的救命药物。 虽然抗生素挽救了数百万人的生命&#xff0c;但它们也会消灭一些常驻细菌。现有文献已经确定了与抗生素相关的肠道微生物群失调&#xff08;多样性降低&#xff09…