2015-02-23 56 views
0

我是新来的libgdx和android开发。我正在写我的第一场比赛,这是一场娱乐赛事,是原创的“西蒙”体验游戏。我使用的是scene2d,每个按钮都是一个actor,每个按钮的构造函数都带有ClickListeners。如何在libgdx中创建自动操作? (scene2d)

我现在真正挣扎的是如何“执行”AI序列,如下所示:我需要直观地显示计算机“按下”每个回合的按钮。我能够播放声音并将一个整数附加到ArrayList,但它似乎只会在绘制纹理之前执行此操作。 所以当我启动程序时,我会听到一个随机的嘟嘟声,并在日志中看到一个附加到我的ArrayList中的随机数,然后我终于会看到我的演员准备好被点击/触摸了。我很困惑如何解决这个问题。这里是我的游戏的一些代码。请原谅,因为我是初学者,这是一项正在进行的工作。有可能有更好的方法来处理我想要做的事情,但现在我只想让它工作。

我已经学到了一些关于Actions的知识,但是我似乎无法使其发挥作用。看起来他们需要一些输入来进行行动。

注意:我有我的未点亮和点亮的按钮堆叠在最后创建的未点亮版本,因此一旦将未点亮按钮的可见性设置为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(); 
    } 




} 

这里是我的按钮演员类:

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; 
    } 



} 

对不起,粘贴这么多的代码,但如果有什么问题,我不知道它在哪里或做什么,所以我觉得分享m是个好主意它的东西。

回答

0

有太多的代码让我评论一切,但我看到的最大的明显错误是使用Thread.sleep。这会导致你的游戏冻结,直到线程完成睡眠。

Libgdx不是为多线程构建的,因此您需要考虑设置定时器的东西。需要一段时间的事件需要定时器在渲染循环的每次运行时递减,并在定时器运行时触发它们的事件。

由于您使用stage2d,这变得非常简单,因为动作会保留自己的计时器,您可以按顺序将它们链接在一起。请阅读stage2d's Actions system。您可以创建自己的操作,并将它们与具有DelayActions的SequenceAction链接在一起。

下面是一个例子。我对你的整个游戏结构并不十分熟悉,所以我不确定这是否适合你的代码,但它应该给你一个关于如何做到这一点的基本想法。

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(); 
    } 
}; 
+0

这真的很有帮助,谢谢!我一定会深入研究Actions。感谢您的帮助..但是我仍然难以接触我必须调用performAISequence()的地方。将它放置在主按钮的ClickListener之前是有意义的,但似乎并不奏效。我会睡觉,然后从那里出发 – OlympusBrons 2015-02-23 22:46:08