lundi 23 février 2015

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



I'm new to libgdx and android development. I'm writing my first game, a recreation the original "Simon" game for experience. I am using scene2d, using each button as an actor, each with ClickListeners in their constructors.


What I am really struggling on right now is how to "perform" the AI sequence, as in: I need to visually display the computer "pressing" the buttons for each turn. I am able to get the sounds to play and to append an integer to an ArrayList, but it seems that it will only do this before it draws my textures. So when I launch the program, I will hear a random beep, and see a random number appended to my ArrayList in the log, and THEN I will finally see my actors ready to be clicked/touched. I'm confused on how to fix this. Here is some code from my game. Please excuse the sloppiness, as I am a beginner and it is a work in progress. There are probably better ways to approach what I'm trying to do, but for right now, I just want it to work.


I have learned a bit about Actions, but I can't seem to get it to work. It seems like they require some input for an action to take place.


Note: I have my unlit and lit buttons stacked with the unlit version created last, so that the lit button appears once I set the unlit button's visibility to false. I realize it might not be the best way to do this.


Here is my main game class:



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




}


And here is my Actor class for the buttons:



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





}
}


Also:



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



}


Sorry for pasting so much code, but if there's something wrong, I don't know where it is or what to do, so I figured it would be a good idea to share most of it.




Aucun commentaire:

Enregistrer un commentaire