簡體   English   中英

如何在libgdx中創建自動操作? (scene2d)

[英]How do I create automatic actions in libgdx? (scene2d)

我是libgdx和android開發的新手。 我正在寫我的第一個游戲,一個娛樂原始的“西蒙”游戲的經驗。 我正在使用scene2d,使用每個按鈕作為actor,每個按鈕都在其構造函數中使用ClickListeners。

我現在正在努力的是如何“執行”AI序列,如:我需要在視覺上顯示計算機“按下”每個回合的按鈕。 我能夠播放聲音並將一個整數附加到ArrayList,但它似乎只會在繪制紋理之前執行此操作。 因此,當我啟動程序時,我會聽到一聲隨機的嘟嘟聲,並在日志中看到一個隨機數附加到我的ArrayList中,然后我終於看到我的演員已經准備好被點擊/觸摸了。 我對如何解決這個問題感到困惑。 這是我游戲中的一些代碼。 請原諒,因為我是初學者,這是一項正在進行的工作。 可能有更好的方法來處理我正在嘗試做的事情,但就目前而言,我只是想讓它發揮作用。

我已經學習了一些關於動作的內容,但我似乎無法讓它發揮作用。 看起來他們需要一些輸入來進行動作。

注意:我的未點亮和點亮的按鈕與最后創建的未點亮版本堆疊在一起,因此一旦我將未點亮按鈕的可見性設置為false,就會出現點亮的按鈕。 我意識到這可能不是最好的方法。

這是我的主要游戲類:

import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.viewport.FitViewport;
import java.util.ArrayList;


public class XimonGame extends Game {

    private SpriteBatch batch;
    private Stage stage;
    private OrthographicCamera camera;
    XimonButton actor_g;
    XimonButton actor_gLit;
    XimonButton actor_r;
    XimonButton actor_rLit;
    XimonButton actor_y;
    XimonButton actor_yLit;
    XimonButton actor_b;
    XimonButton actor_bLit;
    public static ArrayList<Integer> playerList;
    public static ArrayList<Integer> computerList;
    public static ButtonSequencer buttonSequencer;



    @Override
    public void create () {
        batch = new SpriteBatch();
        // Creating camera
        camera = new OrthographicCamera(800, 480);

        // Creating stage and actors
        stage = new Stage(new FitViewport(800, 480, camera));

        // Creating ArrayLists & ButtonSequencer
        playerList = new ArrayList<Integer>();
        computerList = new ArrayList<Integer>();
        buttonSequencer = new ButtonSequencer();

        // Appending initial random number to computerList:
        buttonSequencer.appendRandomNumber(1, 4, computerList);
        System.out.println("Created computer's ArrayList.\nInitial number is: "
        + computerList.toString());
        System.out.println("Size of computerList is currently " + computerList.size());

        // Creating (constructing) actors. Parameter info:
        // XimonButton("[png file]", x, y, width, height, "[name]")
        actor_g = new XimonButton("img/green.png", 190, 240, 210, 210, 1);
        System.out.println(actor_g.toString() + " created.");
        // Lit version of button
        actor_gLit = new XimonButton("img/green_on.png", 190, 240, 210, 210, 0);

        actor_r = new XimonButton("img/red.png", 400, 240, 210, 210, 2);
        System.out.println(actor_r.toString() + " created.");
        // Lit version of button
        actor_rLit = new XimonButton("img/red_on.png", 400, 240, 210, 210, 0);

        actor_y = new XimonButton("img/yellow.png", 190, 30, 210, 210, 3);
        System.out.println(actor_y.toString() + " created.");
        // Lit version of button
        actor_yLit = new XimonButton("img/yellow_on.png", 190, 30, 210, 210, 0);

        actor_b = new XimonButton("img/blue.png", 400, 30, 210, 210, 4);
        System.out.println(actor_b.toString() + " created.");
        // Lit version of button
        actor_bLit = new XimonButton("img/blue_on.png", 400, 30, 210, 210, 0);


//        ADDING ACTORS
//
        // Green buttons:
        stage.addActor(actor_gLit);
        stage.addActor(actor_g);
        // Red buttons:
        stage.addActor(actor_rLit);
        stage.addActor(actor_r);
        // Yellow buttons:
        stage.addActor(actor_yLit);
        stage.addActor(actor_y);
        // Blue buttons:
        stage.addActor(actor_bLit);
        stage.addActor(actor_b);

        Gdx.input.setInputProcessor(stage);

    }
    @Override
    public void render () {

        Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
        batch.setProjectionMatrix(camera.combined);
        batch.begin();
        super.render();
        batch.end();

        // Setting fullscreen
        Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

        // Restore stage's viewport
        stage.getViewport().update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);

        stage.act(Gdx.graphics.getDeltaTime());
        stage.draw();

    }



    @Override
    public void setScreen(Screen screen) {
        super.setScreen(screen);
    }

    @Override
    public Screen getScreen() {
        return super.getScreen();
    }

    @Override
    public void resize (int width, int height) {
            super.resize(width, height);
    }

    @Override
    public void pause () {
        super.pause();
    }

    @Override
    public void resume () {
        super.resume();
    }

    public void dispose () {
        stage.dispose();
    }




}

這是按鈕的Actor類:

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.audio.Sound;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.actions.RunnableAction;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.mygdx.game.XimonGame;

import java.util.ArrayList;

class XimonButton extends Actor {

    Sprite sprite;
    private Sound sound;
    private final int num;
    private int count;
    private final int code;
    public static boolean isComputerTurn = true;


    public XimonButton (String file, int x, int y, int w, int h, final int colorCode) {
        sprite = new Sprite(new Texture(Gdx.files.internal(file)));
        this.setBounds(x, y, w, h);
        this.num = colorCode;
        count = 0;
        code = colorCode;

            if (colorCode == 1) {
                sound = Gdx.audio.newSound(Gdx.files.internal("sounds/Green.wav"));
            }
            else if (colorCode == 2) {
                sound = Gdx.audio.newSound(Gdx.files.internal("sounds/Red.wav"));
            }
            else if (colorCode == 3) {
                sound = Gdx.audio.newSound(Gdx.files.internal("sounds/Yellow.wav"));
            }
            else if (colorCode == 4) {
                sound = Gdx.audio.newSound(Gdx.files.internal("sounds/Blue.wav"));
            }

        setTouchable(Touchable.disabled);

//        Perform the AI's turn:
        try {
            performAISequence();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }


        // Used to handle touch input
        addListener(new ClickListener() {

            @Override
            public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                sound.play(0.4f);
                if (XimonButton.this.isVisible()) XimonButton.this.setVisible(false);


//                System.out.println("Current player list contains:");
//                for (int i=0; i < playerList.size(); i++) {
//                    System.out.println(playerList.get(i));
//                }

                return true;
            }

            @Override
            public void touchUp(InputEvent event, float x, float y, int pointer, int button) {

//                Stop the sound and "turn off" the button light
                sound.stop();
                XimonButton.this.setVisible(true);


//                 Count the number of touches for this turn
                XimonGame.buttonSequencer.incrementCount();
                System.out.println("Count is: " + XimonGame.buttonSequencer.getCount());
                System.out.println("Color code is: " + colorCode);

//                 Append the colorCode to the playerList.
//                 Loop through the computer list to check if current touch matches
//                 the computer's num for the index in the ArrayList.
                XimonGame.playerList.add(colorCode);
                System.out.println("Player list is: " + XimonGame.playerList.toString() + "\n");
//

            }


        });


    }

    public void performAISequence () throws InterruptedException {

        setTouchable(Touchable.disabled);

        for (int i = 0; i < XimonGame.computerList.size(); i++) {

            if (code == XimonGame.computerList.get(i)) {
                sound.play(0.4f);
                XimonButton.this.setVisible(false);
                Thread.sleep(XimonGame.buttonSequencer.getRandomInt(400,600));
                sound.stop();
                XimonButton.this.setVisible(true);
                Thread.sleep(XimonGame.buttonSequencer.getRandomInt(100,150));

            }

        }
        setTouchable(Touchable.enabled);
    }


    @Override
    public void draw (Batch batch, float parentAlpha) {
        batch.draw(sprite, this.getX(), this.getY(), this.getWidth(), this.getHeight());

    }

    @Override
    public void act(float delta) {
        super.act(delta);





    }
}

也:

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

public class ButtonSequencer {

    public Random rand;
    private int turn = 0;
    private int count;


//    public static void addPlayerNums(int code) {
//        XimonGame.playerList.add(code);
//    }

    public int getCount() {
        return count;
    }

    public void incrementCount() {
        count++;
    }

    public void appendRandomNumber(int min, int max, ArrayList<Integer> computerList) {
        rand = new Random();
        int random = rand.nextInt((max - min) + 1) + min;
        computerList.add(random);
        turn++;

    }


    public int getRandomInt(int min, int max) {
        rand = new Random();
        return rand.nextInt((max - min) + 1) + min;
    }



}

很抱歉粘貼了這么多代碼,但如果出現問題,我不知道它在哪里或做什么,所以我認為分享大部分內容是個好主意。

那里有太多代碼可供我評論所有內容,但我看到的最大的明顯錯誤是使用Thread.sleep 這將導致游戲凍結,直到線程完成睡眠。

Libgdx不是為多線程而構建的,因此您需要考慮在計時器上設置內容。 需要一段時間的事件需要在渲染循環的每次運行時減少計時器,並在計時器運行時觸發它們的事件。

由於您正在使用stage2d,因此這很容易,因為Actions會保留自己的計時器,您可以按順序將它們鏈接在一起。 閱讀stage2d的Actions系統 您可以創建自己的動作,並將SequenceAction與DelayActions一起鏈接在一起。

這是一個例子。 我不是很熟悉你的整個游戲結構,所以我不確定這是否適用於你的代碼,但它應該讓你基本了解如何做到這一點。

public void performAISequence (){

        //Get a sequence action from the pool (to avoid unnecessary allocation)
        //and give it the first action
        SequenceAction sequence = Actions.sequence(Actions.touchable(Touchable.disabled));

        for (int i = 0; i < XimonGame.computerList.size(); i++) {

            if (code == XimonGame.computerList.get(i)) {
                sequence.addAction(Actions.runnable(playSoundRunnable));
                sequence.addAction(Actions.hide());
            }

            //Want to delay it for every item in list, because it may need to wait for other buttons
            sequence.addAction(Actions.delay(BUTTON_DELAY_TIME));

            if (code == XimonGame.computerList.get(i)) {
                sequence.addAction(Actions.show());
                sequence.addAction(Actions.runnable(stopSoundRunnable));
            }

            sequence.addAction(Actions.touchable(Touchable.enabled));

        }

        this.addAction(sequence);

    }

Runnable playSoundRunnable = new Runnable(){
    public void run(){
        sound.play(0.4f);
    }
};

Runnable stopSoundRunnable = new Runnable(){
    public void run(){
        sound.stop();
    }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM