溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點(diǎn)擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

如何運(yùn)用surfaceviewAndroid進(jìn)行2d游戲貪吃蛇的開發(fā)

發(fā)布時(shí)間:2021-09-10 16:19:12 來源:億速云 閱讀:130 作者:柒染 欄目:開發(fā)技術(shù)

如何運(yùn)用surfaceviewAndroid進(jìn)行2d游戲貪吃蛇的開發(fā),針對這個(gè)問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個(gè)問題的小伙伴找到更簡單易行的方法。

我們先看一下這個(gè)同步框架,看看騷年你能不能自己領(lǐng)悟。

GameView.java(繼承自SurfaceView)

package com.next.eatsnake;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

import java.util.Random;

/**
 * Created by Next on 2016/3/24 0024.
 */
public class GameView extends SurfaceView implements SurfaceHolder.Callback,OnTouchListener,Runnable {

    enum GameState{
        Menu,
        Playing,
        Over;
    }
    GameState gameState;//游戲狀態(tài)
    Thread thread;//游戲線程
    Boolean flag;//游戲循環(huán)控制標(biāo)志
    Canvas canvas;//畫布
    Paint paint;//畫筆
    SurfaceHolder holder;//SurfaceView控制句柄
    Random random;//隨機(jī)數(shù)
    NextEvent nextEvent;//游戲輸入事件
    int scrW,scrH;//屏幕的寬和高
    public GameView(Context context) {
        super(context);
        gameState = GameState.Menu;
        flag = true;
        paint = new Paint();
        paint.setAntiAlias(true);//筆跡平滑
        thread = new Thread(this);
        random = new Random();
        nextEvent = new NextEvent();
        holder = this.getHolder();
        holder.addCallback(this);
        this.setOnTouchListener(this);
        setKeepScreenOn(true);
        scrW = ((MainActivity)context).getWindowManager().getDefaultDisplay().getWidth();
        scrH = ((MainActivity)context).getWindowManager().getDefaultDisplay().getHeight();
    }



    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            nextEvent.setDownX((int) event.getX());
            nextEvent.setDownY((int) event.getY());
        }else if (event.getAction() == MotionEvent.ACTION_UP) {
            nextEvent.setUpX((int) event.getX());
            nextEvent.setUpY((int) event.getY());
        }
        return true;
    }

    private void mLogic(){
        switch (gameState){
            case Menu:
                menuLogic();
                break;
            case Playing:
                playingLogic();
                break;
            case Over:
                overLogic();
                break;
        }
        nextEvent.init();//每次邏輯循環(huán)后,清空事件
    }

    private void menuLogic(){
        if(nextEvent.getUpX() > 0){
            gameState = GameState.Playing;
        }
    }

    private void playingLogic(){
        if(nextEvent.getDir() == NextEvent.DOWN){
            gameState = GameState.Over;
        }
    }

    private void overLogic(){
        if(nextEvent.getDir() == NextEvent.RIGHT){
            gameState = GameState.Menu;
        }
    }

    private void mDraw(){
        try {
            canvas = holder.lockCanvas();
            canvas.drawColor(Color.WHITE);
            switch (gameState){
                case Menu:
                    menuDraw(canvas);
                    break;
                case Playing:
                    playingDraw(canvas);
                    break;
                case Over:
                    overDraw(canvas);
                    break;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            holder.unlockCanvasAndPost(canvas);
        }
    }

    private void menuDraw(Canvas canvas){
        paint.setColor(Color.RED);
        paint.setTextSize(50);
        canvas.drawText("I am in menu.Touch me to next scence",100,100,paint);
    }

    private void playingDraw(Canvas canvas){
        paint.setColor(Color.RED);
        paint.setTextSize(50);
        canvas.drawText("I am in playing,Slide down to next scence ",100,100,paint);
    }

    private void overDraw(Canvas canvas){
        paint.setColor(Color.RED);
        paint.setTextSize(50);
        canvas.drawText("I am in over,Slide right to next scence",100,100,paint);
    }

    //這里就是同步觸發(fā)機(jī)制了
    //每一個(gè)時(shí)鐘周期,執(zhí)行一次邏輯方法和繪圖方法
    @Override
    public void run() {
        while(flag){
            mLogic();
            mDraw();
            try {
                Thread.sleep(500);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    //SurfaceView創(chuàng)建時(shí)調(diào)用
    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        thread.start();
    }

    //SurfaceView發(fā)生改變時(shí)調(diào)用
    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    //SurfaceView銷毀時(shí)調(diào)用
    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        flag = false;
    }

}

這只是一個(gè)游戲框架,還沒有往里寫任何內(nèi)容,但根據(jù)我的經(jīng)驗(yàn)(雖然我也沒有很多經(jīng)驗(yàn)),這里已經(jīng)包括了所有游戲(這里特指小游戲-_-)的主體框架代碼,有了這個(gè)框架,我們就只需要寫游戲的邏輯和繪圖方法了,不用糾結(jié)怎么搭建游戲框架了。
這里我還加了一個(gè)NextEvent的方法,在里面我封裝了上個(gè)游戲用到的滑動(dòng)手勢,在這個(gè)挨踢圈里,人們最常說的一句話就是:不要重復(fù)造輪子。當(dāng)我們看到寫了很多重復(fù)代碼時(shí),就是我們需要精簡的時(shí)候了。
上代碼:

NextEvent.java

package com.next.eatsnake;

/**
 * Created by Next on 2016/3/24 0024.
 */
public class NextEvent {
    public static final int LEFT = 1;
    public static final int RIGHT = 2;
    public static final int UP = 3;
    public static final int DOWN = 4;
    public static final int QUIET = -1;//沒有滑動(dòng)
    private int dir;
    private int downX,downY,upX,upY;
    public NextEvent()
    {
        init();
    }
    public void init(){
        this.dir = QUIET;
        this.downX = -1;
        this.downY = -1;
        this.upX = -1;
        this.upY = -1;
    }
    public int getDir(){
        float offsetX,offsetY;
        offsetX = upX - downX;
        offsetY = upY - downY;
        if (Math.abs(offsetX) > Math.abs(offsetY)) {
            if (offsetX > 5 ) {
                dir = RIGHT;
            }else if (offsetX < -5) {
                dir = LEFT;
            }
        }else {
            if (offsetY > 5) {
                dir = DOWN;
            }else if (offsetY < -5) {
                dir = UP;
            }
        }
        return dir;
    }

    public int getDownX() {
        return downX;
    }

    public void setDownX(int downX) {
        this.downX = downX;
    }

    public int getDownY() {
        return downY;
    }

    public void setDownY(int downY) {
        this.downY = downY;
    }

    public int getUpX() {
        return upX;
    }

    public void setUpX(int upX) {
        this.upX = upX;
    }

    public int getUpY() {
        return upY;
    }

    public void setUpY(int upY) {
        this.upY = upY;
    }
}

這個(gè)NextEvent是用來存儲(chǔ)用戶輸入事件的,我們只是存儲(chǔ),而沒有直接觸發(fā)游戲邏輯。那么什么時(shí)候用到讀取這個(gè)NextEvent呢?如果你仔細(xì)看了第一段代碼,應(yīng)該已經(jīng)知道了——在每一個(gè)時(shí)鐘周期的邏輯方法里判斷NextEvent,并由此改變游戲邏輯。這種就是同步機(jī)制,而用戶輸入事件游戲邏輯就隨之改變的就是異步機(jī)制。

下面我們用這個(gè)框架做一個(gè)貪吃蛇游戲,效果圖如下:

如何運(yùn)用surfaceviewAndroid進(jìn)行2d游戲貪吃蛇的開發(fā)

如何運(yùn)用surfaceviewAndroid進(jìn)行2d游戲貪吃蛇的開發(fā)

如何運(yùn)用surfaceviewAndroid進(jìn)行2d游戲貪吃蛇的開發(fā)

MainActivity.java

package com.next.eatsnake;

import android.app.Activity;
import android.os.Bundle;
import android.view.Window;
import android.view.WindowManager;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,WindowManager.LayoutParams.FLAG_FULLSCREEN);
        setContentView(new GameView(this));
    }
}

GameView.java

package com.next.eatsnake;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import android.view.View;
import android.view.View.OnTouchListener;

import java.util.ArrayList;
import java.util.Random;

/**
 * Created by Administrator on 2016/3/24 0024.
 */
public class GameView extends SurfaceView implements SurfaceHolder.Callback,OnTouchListener,Runnable {

    enum GameState{
        Menu,
        Playing,
        Over;
    }
    GameState gameState;//游戲狀態(tài)
    Thread thread;//游戲線程
    Boolean flag;//游戲循環(huán)控制標(biāo)志
    Canvas canvas;//畫布
    Paint paint;//畫筆
    SurfaceHolder holder;//SurfaceView控制句柄
    public static Random random;//隨機(jī)數(shù)
    NextEvent nextEvent;//游戲輸入事件
    int scrW,scrH;//屏幕的寬和高
    final int MAX_X = 15;
    int MAX_Y;//豎向tile數(shù)量根據(jù)MAX_X動(dòng)態(tài)計(jì)算,保證tile是正方形
    public static Tile[][] tiles;
    Snake snake;
    public static boolean isEatFood;
    public GameView(Context context) {
        super(context);
        gameState = GameState.Menu;
        flag = true;
        paint = new Paint();
        paint.setAntiAlias(true);//筆跡平滑
        paint.setTextAlign(Paint.Align.CENTER);//文字中間對齊
        thread = new Thread(this);
        random = new Random();
        nextEvent = new NextEvent();
        holder = this.getHolder();
        holder.addCallback(this);
        this.setOnTouchListener(this);
        setKeepScreenOn(true);
        scrW = ((MainActivity)context).getWindowManager().getDefaultDisplay().getWidth();
        scrH = ((MainActivity)context).getWindowManager().getDefaultDisplay().getHeight();
        Tile.width = scrW/MAX_X;
        MAX_Y = scrH/Tile.width;
        tiles = new Tile[MAX_X][MAX_Y];
        isEatFood = false;
    }

    private void newGame(){
        for (int x = 0;x < MAX_X;x++){
            for (int y = 0;y < MAX_Y;y++){
                if (x == 0||y == 0||x == MAX_X-1||y == MAX_Y-1){
                    tiles[x][y] = new Tile(x,y,Tile.TYPE_WALL);
                }else {
                    tiles[x][y] = new Tile(x,y,Tile.TYPE_NULL);
                }
            }
        }
        snake = new Snake(tiles[4][4],tiles[5][4],tiles[6][4], NextEvent.DOWN);
        addFood();
        addFood();
        addFood();
    }

    public void addFood(){
        ArrayList<Tile> nullList = new ArrayList<Tile>();
        for (int x = 0;x < MAX_X;x++){
            for (int y = 0;y < MAX_Y;y++){
                if (tiles[x][y].getType() == Tile.TYPE_NULL){
                    nullList.add(tiles[x][y]);
                }
            }
        }
        if (nullList.size()!=0){
            nullList.get(random.nextInt(nullList.size())).setType(Tile.TYPE_FOOD);
        }
    }

    @Override
    public boolean onTouch(View v, MotionEvent event) {
        if (event.getAction() == MotionEvent.ACTION_DOWN) {
            nextEvent.setDownX((int) event.getX());
            nextEvent.setDownY((int) event.getY());
        }else if (event.getAction() == MotionEvent.ACTION_UP) {
            nextEvent.setUpX((int) event.getX());
            nextEvent.setUpY((int) event.getY());
        }
        return true;
    }

    private void mLogic(){
        switch (gameState){
            case Menu:
                menuLogic();
                break;
            case Playing:
                playingLogic();
                break;
            case Over:
                overLogic();
                break;
        }
        nextEvent.init();//每次邏輯循環(huán)后,清空事件
    }

    private void menuLogic(){
        if(nextEvent.getUpX() > 0){
            gameState = GameState.Playing;
            newGame();
        }
    }

    private void playingLogic(){
        if (nextEvent.getDir()!=NextEvent.QUIET){
            snake.setDir(nextEvent.getDir());
        }
        snake.move();
        if (isEatFood){
            addFood();
            isEatFood = false;
        }
        if(!snake.isAlive()){
            gameState = GameState.Over;
        }
    }

    private void overLogic(){
        if(nextEvent.getUpX() > 0){
            gameState = GameState.Playing;
            newGame();
        }
    }

    private void mDraw(){
        try {
            canvas = holder.lockCanvas();
            canvas.drawColor(Color.WHITE);
            switch (gameState){
                case Menu:
                    menuDraw(canvas);
                    break;
                case Playing:
                    playingDraw(canvas);
                    break;
                case Over:
                    overDraw(canvas);
                    break;
            }
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            holder.unlockCanvasAndPost(canvas);
        }
    }

    private void menuDraw(Canvas canvas){
        paint.setColor(Color.BLACK);
        paint.setTextSize(50);
        canvas.drawText("Eat Snake,Touch me and start",scrW/2,scrH/2,paint);
    }

    private void playingDraw(Canvas canvas){
        for (int x = 0;x < MAX_X;x++){
            for (int y = 0;y < MAX_Y;y++){
                tiles[x][y].draw(canvas,paint);
            }
        }
    }

    private void overDraw(Canvas canvas){
        paint.setColor(Color.BLACK);
        paint.setTextSize(50);
        canvas.drawText("Your score is:"+snake.getLength(),scrW/2,scrH/4,paint);
        canvas.drawText("Touch me and try again",scrW/2,scrH/2,paint);
    }

    @Override
    public void run() {
        while(flag){
            mLogic();
            mDraw();
            try {
                Thread.sleep(500);
            }catch (Exception e){
                e.printStackTrace();
            }
        }
    }

    @Override
    public void surfaceCreated(SurfaceHolder holder) {
        thread.start();
    }

    @Override
    public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {

    }

    @Override
    public void surfaceDestroyed(SurfaceHolder holder) {
        flag = false;
    }

}

Tile.java

package com.next.eatsnake;

import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;

/**
 * Created by Next on 2016/3/26 0026.
 */
public class Tile {
    public static final int TYPE_NULL = 0;//空
    public static final int TYPE_WALL = 1;//墻
    public static final int TYPE_HEAD = 2;//蛇頭
    public static final int TYPE_BODY = 3;//蛇身
    public static final int TYPE_TAIL = 4;//蛇尾
    public static final int TYPE_FOOD = 5;//食物
    private int x,y;
    private int type;
    public static int width;

    public Tile(int x, int y, int type) {
        this.x = x;
        this.y = y;
        this.type = type;
    }

    public void draw(Canvas canvas,Paint paint){
        switch (type){
            case TYPE_NULL:
                break;
            case TYPE_WALL:
                paint.setColor(Color.BLACK);
                canvas.drawCircle(x*width+width/2,y*width+width/2,width/2,paint);
                break;
            case TYPE_HEAD:
                paint.setColor(Color.MAGENTA);
                canvas.drawCircle(x*width+width/2,y*width+width/2,width/2,paint);
                paint.setColor(Color.WHITE);
                canvas.drawCircle(x*width+width/2,y*width+width/2,width/8,paint);
                break;
            case TYPE_BODY:
                paint.setColor(Color.MAGENTA);
                canvas.drawCircle(x*width+width/2,y*width+width/2,width/2,paint);
                break;
            case TYPE_TAIL:
                paint.setColor(Color.MAGENTA);
                paint.setStrokeWidth(10);
                canvas.drawLine(x * width, y * width + width / 2, x * width + width / 2, y * width, paint);
                canvas.drawLine(x*width+ width / 2,y*width,x*width+width,y*width+width/2,paint);
                canvas.drawLine(x*width+width,y*width+width/2,x*width+width/2,y*width+width,paint);
                canvas.drawLine(x*width+width/2,y*width+width,x*width,y*width+ width / 2,paint);
                break;
            case TYPE_FOOD:
                switch (GameView.random.nextInt(3)){
                    case 0:
                        paint.setColor(Color.YELLOW);
                        break;
                    case 1:
                        paint.setColor(Color.GREEN);
                        break;
                    case 2:
                        paint.setColor(Color.CYAN);
                        break;
                }
                canvas.drawCircle(x*width+width/2,y*width+width/2,width/2,paint);
                break;

        }
    }

    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 int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }
}

Snake.java

package com.next.eatsnake;

import java.util.ArrayList;

/**
 * Created by Administrator on 2016/3/26 0026.
 */
public class Snake {
    private ArrayList<Tile> snake;
    private int dir;
    private boolean isAlive;


    public Snake(Tile head,Tile body,Tile tail,int dir){
        snake = new ArrayList<Tile>();
        head.setType(Tile.TYPE_HEAD);
        body.setType(Tile.TYPE_BODY);
        tail.setType(Tile.TYPE_TAIL);
        snake.add(head);
        snake.add(body);
        snake.add(tail);
        isAlive = true;
        this.dir = dir;
    }

    public void move(){
        if (!isAlive)
            return;
        switch (dir){
            case NextEvent.LEFT:
                switch (GameView.tiles[snake.get(0).getX()-1][snake.get(0).getY()].getType()){
                    case Tile.TYPE_WALL:
                    case Tile.TYPE_BODY:
                    case Tile.TYPE_TAIL:
                        isAlive = false;
                        break;
                    case Tile.TYPE_FOOD:
                        GameView.tiles[snake.get(0).getX()-1][snake.get(0).getY()].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX() - 1][snake.get(0).getY()]);
                        GameView.isEatFood = true;
                        break;
                    case Tile.TYPE_NULL:
                        GameView.tiles[snake.get(0).getX()-1][snake.get(0).getY()].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX() - 1][snake.get(0).getY()]);
                        snake.get(snake.size()-1).setType(Tile.TYPE_NULL);
                        snake.remove(snake.size()-1);
                        snake.get(snake.size()-1).setType(Tile.TYPE_TAIL);
                        break;
                }
                break;
            case NextEvent.RIGHT:
                switch (GameView.tiles[snake.get(0).getX()+1][snake.get(0).getY()].getType()){
                    case Tile.TYPE_WALL:
                    case Tile.TYPE_BODY:
                    case Tile.TYPE_TAIL:
                        isAlive = false;
                        break;
                    case Tile.TYPE_FOOD:
                        GameView.tiles[snake.get(0).getX()+1][snake.get(0).getY()].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX() + 1][snake.get(0).getY()]);
                        GameView.isEatFood = true;
                        break;
                    case Tile.TYPE_NULL:
                        GameView.tiles[snake.get(0).getX()+1][snake.get(0).getY()].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX() + 1][snake.get(0).getY()]);
                        snake.get(snake.size()-1).setType(Tile.TYPE_NULL);
                        snake.remove(snake.size() - 1);
                        snake.get(snake.size()-1).setType(Tile.TYPE_TAIL);
                        break;
                }
                break;
            case NextEvent.UP:
                switch (GameView.tiles[snake.get(0).getX()][snake.get(0).getY()-1].getType()){
                    case Tile.TYPE_WALL:
                    case Tile.TYPE_BODY:
                    case Tile.TYPE_TAIL:
                        isAlive = false;
                        break;
                    case Tile.TYPE_FOOD:
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()-1].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX()][snake.get(0).getY()-1]);
                        GameView.isEatFood = true;
                        break;
                    case Tile.TYPE_NULL:
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()-1].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX()][snake.get(0).getY()-1]);
                        snake.get(snake.size()-1).setType(Tile.TYPE_NULL);
                        snake.remove(snake.size()-1);
                        snake.get(snake.size()-1).setType(Tile.TYPE_TAIL);
                        break;
                }
                break;
            case NextEvent.DOWN:
                switch (GameView.tiles[snake.get(0).getX()][snake.get(0).getY()+1].getType()){
                    case Tile.TYPE_WALL:
                    case Tile.TYPE_BODY:
                    case Tile.TYPE_TAIL:
                        isAlive = false;
                        break;
                    case Tile.TYPE_FOOD:
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()+1].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX()][snake.get(0).getY() + 1]);
                        GameView.isEatFood = true;
                        break;
                    case Tile.TYPE_NULL:
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()+1].setType(Tile.TYPE_HEAD);
                        GameView.tiles[snake.get(0).getX()][snake.get(0).getY()].setType(Tile.TYPE_BODY);
                        snake.add(0, GameView.tiles[snake.get(0).getX()][snake.get(0).getY()+1]);
                        snake.get(snake.size()-1).setType(Tile.TYPE_NULL);
                        snake.remove(snake.size()-1);
                        snake.get(snake.size()-1).setType(Tile.TYPE_TAIL);
                        break;
                }
                break;
        }
    }

    public void setDir(int dir){
        if (this.dir == dir||this.dir == -dir||dir == NextEvent.QUIET)
            return;
        else
            this.dir = dir;
    }

    public boolean isAlive(){
        return isAlive;
    }

    public int getLength(){
        return snake.size();
    }
}

NextEvent.java

就是剛開始介紹的那個(gè)類,這里就不重復(fù)貼出了

關(guān)于如何運(yùn)用surfaceviewAndroid進(jìn)行2d游戲貪吃蛇的開發(fā)問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注億速云行業(yè)資訊頻道了解更多相關(guān)知識(shí)。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI