problems with multiple cameras and viewports in libgdx - java

so I am doing what is suppose to be a simple game but I think I might be complicating things. I have a camera for the GameScreen and a viewPort which follow the position of the player and when it reaches to points on the sides, the camera stops following the player and stays in one point.
This by itself works fine, but then I wanted to add the pause menu and some other features in the game, creating a hud class with its own camera and viewport as well as a Stage and a shapeRenderer.
The problem comes when I create the instance of this hud inside my gameScreen, the camera that I am looking while I am playing looks like is the hudCam, which does not follow the player and basically does not let me see the player when it reaches the edges of the screen.
This is my GameScreen Class:
public class GameScreen implements Screen {
WowInvasion game;
ScrollingBackground background;
private OrthographicCamera gameCam;
private Viewport gameViewPort;
/*
Basically I wanna keep the same sprites running while in the menu, playing and till dead
therefore, I'll have a switch statement with cases on where the games at, inside the functions needed. That way I'll keep
the game has a background for the menu and there's no need for running a second screen.
*/
public static final int MAIN_MENU = 0;
public static final int GAME = 1;
private static int state = 1; //current state. starts with MAIN_MENU //DEBUGGING GAME SCREEN
//STAGES
private GameStage gameStage; //game ui
private menuStage mainMenu; //Main menu of the game
private Hud hud;
//Resources
private TextureAtlas atlas; //for the textures most
private Skin skin; //for the styles and fonts
//Sprites
private Player player;
//Shapes
private float progressPower; //for the power to build up
private final float POWER_CHARGED = 1000; //limit to get power
private final float DECREASING_POWER = 20; //limit to get power
public GameScreen(WowInvasion game){
this.game = game;
gameCam = new OrthographicCamera();
gameCam.setToOrtho(false, WowInvasion.WIDTH, WowInvasion.HEIGHT);
gameViewPort = new StretchViewport(WowInvasion.WIDTH, WowInvasion.HEIGHT, gameCam);
progressPower = 0f;
game.wowAssetManager.loadTexturesGameScreen(); // tells our asset manger that we want to load the images set in loadImages method
game.wowAssetManager.loadSkins(); //load the needed skins
game.wowAssetManager.manager.finishLoading(); // tells the asset manager to load the images and wait until finsihed loading.
skin = game.wowAssetManager.manager.get("ui/menuSkin.json");
}
#Override
public void show() {
game.batch.setProjectionMatrix(gameCam.combined);
background = new ScrollingBackground();
atlas = game.wowAssetManager.manager.get(WowAssetManager.GAME_ATLAS); //declaring atlas
mainMenu = new menuStage(gameViewPort, game.batch, skin, game); //pass it so that we only use one batch and one same viewport
gameStage = new GameStage(gameViewPort, game.batch, skin, game);
hud = new Hud(game.batch, skin);
player = new Player(atlas.findRegion("player"), (int) gameCam.viewportWidth / 2, (int) gameCam.viewportHeight / 2);
switch(state){
case MAIN_MENU:
Gdx.input.setInputProcessor(mainMenu);
break;
case GAME:
background.setFixedSpeed(false); //does not work in here
}
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if(state == GAME) {
background.setFixedSpeed(false);
player.update(delta, gameCam.viewportWidth, gameCam.viewportHeight); //updating player for movement
//really cheap way to charge power with velocity
if(progressPower != POWER_CHARGED) {
progressPower += Math.abs(player.getVelocity().x) + Math.abs(player.getVelocity().y);
progressPower -= DECREASING_POWER;
}
else
progressPower = POWER_CHARGED / 4;
}
mainMenu.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f)); //updating while making sure delta won't be more than 1/30f.
gameStage.act(Math.min(Gdx.graphics.getDeltaTime(), 1 / 30f));
game.batch.begin();
background.updateAndRender(delta, game.batch); //updating scrolling background
player.draw(game.batch);
game.batch.end();
mainMenu.draw(); //draw the menu stage
gameStage.draw(); //draw the ui stage for the game
hud.getStage().draw();
hud.renderRotateMeter();
updateCamera(0, WowInvasion.WIDTH);
System.out.println(player.getPosition().x);
}
public void updateCamera(float startX, float endX){
Vector3 position = gameCam.position;
//linear interpolation : a + (b - a) * lerp
//b = player position
//a = current camera position
//lerp = interpolation factor
position.x = gameCam.position.x + (player.getPosition().x - gameCam.position.x) * .1f;
//making the camera stay when the player gets to close to the sides
if(position.x < startX) {
position.x = startX;
}
if(position.x > endX){
position.x = endX;
}
gameCam.position.set(position);
gameCam.update();
}
#Override
public void resize(int width, int height) {
gameViewPort.update(width, height);
//hud.getViewport().update(width, height);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
dispose();
}
#Override
public void dispose() {
mainMenu.dispose();
gameStage.dispose();
game.dispose();
hud.dispose();
}
public static void setState(int state) {
GameScreen.state = state;
}
}
And this is my HUD:
public class Hud implements Disposable{
private Stage stage;
private Viewport viewport;
Button buttonPause, buttonResume;
private OrthographicCamera hudCam;
private ShapeRenderer sp; //like a batch for shapes
public Hud(SpriteBatch sb, Skin skin){
hudCam = new OrthographicCamera();
hudCam.setToOrtho(false, WowInvasion.WIDTH, WowInvasion.HEIGHT);
viewport = new StretchViewport(WowInvasion.WIDTH, WowInvasion.HEIGHT, hudCam);
stage = new Stage(viewport, sb);
sp = new ShapeRenderer();
Table table = new Table();
table.top();
//this makes the table the size of the stage
table.setFillParent(true);
buttonPause = new Button(skin, "pause");
buttonPause.setTransform(true);
buttonPause.addListener(new ClickListener(){ //listener to handle event
#Override
public void clicked(InputEvent event, float x, float y) {
}
});
buttonResume = new Button(skin, "resume");
buttonResume.setTransform(true);
buttonResume.setScale(0.5f);
buttonResume.addListener(new ClickListener(){
#Override
public void clicked(InputEvent event, float x, float y) {
buttonResume.setVisible(false);
}
});
table.add(buttonPause);
table.row();
table.add(buttonResume);
stage.addActor(table);
}
public void renderRotateMeter(){
sp.setProjectionMatrix(hudCam.combined);
sp.begin(ShapeRenderer.ShapeType.Filled);
sp.setColor(Color.YELLOW);
sp.rect(hudCam.position.x,hudCam.position.y, WowInvasion.WIDTH / 2, 20);
sp.end();
}
public Viewport getViewport() {
return viewport;
}
public Stage getStage() {
return stage;
}
#Override
public void dispose() {
stage.dispose();
sp.dispose();
}
}
thanks in advance!
EDIT
so I tried passing the gameCam has a parameter to the hud and instead of making a new OrthographicCamera I used that one has the hudCamara as well and well, the movement with the player is perfect except now the thins from the Hud do not move at all..

It looks like you only set projectionMatrix to only HUD camera as seen in
sp.setProjectionMatrix(hudCam.combined);
Try to set it the same to other stuff outside of the HUD class prior to draw call too.
Another thing to keep in mind is that, when you involve using multiple Viewport and Camera in the game as most of the time it will be 1 Viewport matching with 1 Camera and work with another set as in your case. In draw call, you need to call apply() or apply(true) of Viewport class too to tell the system that you will draw based on which viewport thus in turn it will adhere to screen coordinate that was set up by viewport's attaching camera.
So assume you have 2 objects that needed to be called in different viewport consecutively, do it like the following code. The methods call is correct according to libgdx API but variable names are fictional.
// draw objA adhering to viewportA (thus cameraA) <-- assume it's player cam
sb.setProjectionMatrix(cameraA.combined);
viewportA.apply();
objA.draw();
// draw objB adhering to viewportB (thus cameraB) <-- assume it's HUD cam
sb.setProjectionMatrix(cameraB.combined);
viewportB.apply(true); // send in true as for HUD, we always want to center the screen
objB.draw();
In summary, 2 things to keep in mind when drawing objects that use multiple of camera and viewport in consecutive draw call.
Set projection matrix to either SpriteBatch or ShapeRenderer.
Call apply() or apply(true) of Viewport class to let it know you work with this viewport.

Related

Actor moves away from camera instead of moving on the X axis in LibGdx

I want a camera to follow an Actor. I've watched a lot of tutorials on how to do this but I get a weird bug.
The Actor i created called "skeleton" seems to move away from the camera and not on the X axis.
The camera moves over static sprites fine.
I used 3 different types of moving the actor. None of them seem to work.
Sry for the bad code aswell.
Playscreen:
public class PlayScreen implements Screen {
OrthographicCamera camera;
Table table;
Stage stage;
Viewport viewport;
private MyGdxGame game;
skeleton skeleton;
public PlayScreen(MyGdxGame game){
this.game = game;
camera = new OrthographicCamera(1f, (Gdx.graphics.getHeight()/Gdx.graphics.getWidth()));
viewport =new FitViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(),camera);
skeleton = new skeleton();
stage = new Stage(new ScreenViewport());
skeleton.setPosition((Gdx.graphics.getWidth()/2)-(skeleton.getWidth()/2),((Gdx.graphics.getHeight()/1.75f)-(skeleton.getHeight()/1.4f)));
stage.addActor(skeleton);
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1,0,0,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
skeleton.moveRight();
camera.position.x = skeleton.getX() + skeleton.getOriginX();
camera.position.y = skeleton.getY() + skeleton.getOriginY();
camera.update();
game.batch.setProjectionMatrix(camera.combined);
Gdx.input.setInputProcessor(stage);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void resize(int width, int height) {
viewport.update(width,height);
}
Skeleton Actor:
public class skeleton extends Actor {
SpriteBatch batch;
Texture img;
int frame = 0;
int zeile = 0;
TextureRegion[][] regions;
public Sprite sprite;
public skeleton(){
batch = new SpriteBatch();
img = new Texture(Gdx.files.internal("Warrior Skeleton Animations/Walking/walk.png"));
//ANIMATION
regions = TextureRegion.split(img,572,953);
sprite = new Sprite(regions[0][0]);
code to make it an animation...
(works fine don't wont to enlarge the code here any further)
setBounds(sprite.getX(),sprite.getY(),sprite.getWidth(),sprite.getHeight());
}
public void moveRight(){
//First way of moving
MoveByAction mba = new MoveByAction();
mba.setAmount(10f,0f);
mba.setDuration(1/10f);
skeleton.this.addAction(mba);
//Second way of moving
//this.setPosition(this.getX()+10,this.getY());
//setBounds(sprite.getX(),sprite.getY(),sprite.getWidth(),sprite.getHeight());
//Third way of moving
//sprite.translateX(1);
//setBounds(sprite.getX(),sprite.getY(),sprite.getWidth(),sprite.getHeight());
}
#Override
protected void positionChanged() {
sprite.setPosition(getX(),getY());
super.positionChanged();
}
#Override
public void draw(Batch batch, float parentAlpha){
sprite.draw(batch);
}
#Override
public void act(float delta) {
super.act(delta);
}
}
I've tried moving the camera independently from the skeleton actor like this: camera.position.x = camera.position.x + 100; And the actor still moves away from the camera even if the camera moves faster than the actor.
I also tried moving the camera with the coordinates of the sprite itself from the skeleton actor. Same error though.
Thanks in advance.
I found a way to fix it for me.
If i move the camera itself and not the actor, I get the effect of the actor being moved. This proofs that my actor is bound to my Camera.
I would still love to know why that is and how to fix it though.

LibGdx Understanding the viewports and associtate it with a Scene2D

Whenever I try to set my viewport to a Stage, the actors, that I puting into the Scene are blured and very large. I want to set my Game world size as a rectangle of 50x100 units and then scale everything (Sprites, actors, labels, fonts) according that units. Every state inharitate form a class State which provides render function etc.
public abstract class State {
public static final float GAME_SIZE_WIDTH = 50 ;
public static final float GAME_SIZE_HEIGHT = 100 ;
protected OrthographicCamera camera;
protected GameStateManager gsm;
protected Viewport viewport;
public State(GameStateManager gsm) {
this.gsm = gsm;
camera = new OrthographicCamera();
viewport = new ExtendViewport(GAME_SIZE_WIDTH, GAME_SIZE_HEIGHT, camera);
viewport.apply();
camera.position.set(GAME_SIZE_WIDTH / 2, GAME_SIZE_HEIGHT / 2, 0);
}
public abstract void handleInput();
public abstract void update(float dt);
public abstract void render (SpriteBatch sb);
public abstract void dispose();
public abstract void resize(int width, int height) ;
}
In every State I want to add the Stage and pass the viewPort for my State class according to keep the GAME_SIZE_WIDTH /GAME_SIZE_HEIGHT dimension, but Ive got unadjusted backgrounds (even if its full HD picture the white border on the left) and the Buttons are blured with unadjusted text on it.
public class MenuState extends State implements InputProcessor {
private Skin skin;
private Stage stage;
private Sprite background;
private Table table;
private TextButton startButton,quitButton;
private Sprite flappyButton;
private Sprite chodzenieButton;
private Sprite memoryButton;
private Sprite rememberSquare;
private static final String TAG = "kamil";
private Vector3 touchPoint;
public MenuState(GameStateManager gsm) {
super(gsm);
skin = new Skin(Gdx.files.internal("button/uiskin.json"));
stage = new Stage(viewport);
table = new Table();
table.setWidth(stage.getWidth());
table.align(Align.center | Align.top);
table.setPosition(0,GAME_SIZE_HEIGHT);
startButton = new TextButton("New Game",skin);
quitButton = new TextButton("Quit Game",skin);
startButton.addListener(new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log("Clicked button","Yep, you did");
event.stop();
}
});
table.padTop(5);
table.add(startButton).padBottom(5).size(20,10);
table.row();
table.add(quitButton).size(20,10);
stage.addActor(table);
background =new Sprite(new Texture(Gdx.files.internal("backgrounds/bg.jpg")));
background.setSize(GAME_SIZE_WIDTH,GAME_SIZE_HEIGHT);
background.setPosition(0,0);
touchPoint= new Vector3();
InputMultiplexer im = new InputMultiplexer(stage,this);
Gdx.input.setInputProcessor(im);
flappyButton=new Sprite(new Texture("menuButton/floopyBirdButtonTexture.png"));
chodzenieButton =new Sprite(new Texture("menuButton/swipeMovementsButtonTexture.png"));
memoryButton =new Sprite(new Texture("menuButton/memory.png"));
rememberSquare = new Sprite(new Texture("menuButton/rememberSquare.png"));
rememberSquare.setSize(20,10);
flappyButton.setSize(20,10);
chodzenieButton.setSize(20,10);
memoryButton.setSize(20,10);
flappyButton.setPosition(GAME_SIZE_WIDTH/2-flappyButton.getWidth()/2,GAME_SIZE_HEIGHT/2-flappyButton.getHeight()/2);
chodzenieButton.setPosition(GAME_SIZE_WIDTH/2-flappyButton.getWidth()/2,flappyButton.getY()- chodzenieButton.getHeight() -2);
memoryButton.setPosition(chodzenieButton.getX(),chodzenieButton.getY()- flappyButton.getHeight() -2);
rememberSquare.setPosition(flappyButton.getX(),flappyButton.getY()+flappyButton.getHeight()+2);
}
#Override
public void render(SpriteBatch sb) {
sb.setProjectionMatrix(camera.combined);
sb.begin();
background.draw(sb);
flappyButton.draw(sb);
chodzenieButton.draw(sb);
memoryButton.draw(sb);
rememberSquare.draw(sb);
sb.end();
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
#Override
public void dispose() {
flappyButton.getTexture().dispose();
chodzenieButton.getTexture().dispose();
background.getTexture().dispose();
}
#Override
public void resize(int width, int height) {
Gdx.app.log("kamil","Resize");
viewport.update(width,height);
}
#Override
public void handleInput() {
if(Gdx.input.justTouched())
{
//
viewport.unproject(touchPoint.set(Gdx.input.getX(),Gdx.input.getY(),0));
if(flappyButton.getBoundingRectangle().contains(touchPoint.x,touchPoint.y)) {
gsm.set(new FlopyBirdState(gsm));
}
else if (chodzenieButton.getBoundingRectangle().contains(touchPoint.x,touchPoint.y)){
gsm.set(new ChodzenieState(gsm));
}
else if (memoryButton.getBoundingRectangle().contains(touchPoint.x,touchPoint.y)){
gsm.set(new MemoryState(gsm));
}
else if (rememberSquare.getBoundingRectangle().contains(touchPoint.x,touchPoint.y)){
gsm.set(new FoodEaterState(gsm));
}}
}
blured and very large : This is due to font size you're using.
Blured when some font scaled in appropriate manner, doesn't matter it is by you or by viewport.
You're using 50 and 100 as world width and height of viewport, and you're using BitmapFont from skin that having greater size as compare to 50 and 100. so when you update viewport by screenwidth and height then BitmapFont also scale up so look very large and blurry too.
Solution:
Use some greater world width and height of viewport by comparing your BitmapFont that you're using.
Use small size of your BitmapFont or you can scale down so that not scaled too much and look ugly.
skin.get("font-name",BitmapFont.class).getData().setScale(.25f);
you're using Table so you may need to check where your Actor is in cell/Table. You can enable debugging by this flag stage.setDebugAll(true);
EDIT
You're using ExtendViewport, from wiki
The ExtendViewport keeps the world aspect ratio without black bars by extending the world in one direction. The world is first scaled to fit within the viewport, then the shorter dimension is lengthened to fill the viewport.
Let's suppose you're device width and height is 400 and 640, then what happen when you update viewport by 400 and 640. First your background Sprite scaled in height and set his height to 640(because viewport worldheight is equal to background height) done, now it's time for width of background Sprite because you set width is half of height so scaled and set size 640/2 = 320. done
Your problem arrive, my device width is 400 but my background sprite size is only 320 rest (40*2 unit is white from both side).
Use 48*80(most of devices is in this ratio) instead of 50*100

Libgdx Switching Screens and Viewports

I am having an issue when switching screens in libgdx. I am building a asteroids game clone. So first my MainMenuScreen class (which uses a Fitviewport) is rendered and then I call setScreen() to GameScreen (GameScreen doesn't use a Fitviewport) and that works except that the second screen renders as if its using a Fitviewport. If I resize the second screen then the whole window is used for rendering. Why is this happening? Here are some pictures:
MainMenuScreen class:
GameScreen class after switching screens, the screen has black bars on the side (I colored the boundary in red for you) which I don't want:
I want the GameScreen to use all the window area for rendering, and not have black bars like the MainMenu. I am not using any Fitviewport in GameScreen also.
Here are relevant parts of my MainMenuScreen class:
public class MainMenuScreen implements Screen
{
private static final String TAG = "MainMenu";
private static final int VIRTUAL_WIDTH = 400;
private static final int VIRTUAL_HEIGHT = 400;
MyGdxGame game;
...
public MainMenuScreen(MyGdxGame game)
{
this.game = game;
viewport = new FitViewport(VIRTUAL_WIDTH, VIRTUAL_HEIGHT);
stage = new Stage(viewport);
// Play button listener
btnPlay.addListener( new ClickListener() {
#Override
public void clicked(InputEvent event, float x, float y) {
Gdx.app.log(TAG, "PLAY");
MainMenuScreen.this.game.setScreen(MainMenuScreen.this.game.gameScreen);
};
});
....
}
Here is my GameScreen class:
MyGdxGame game;
OrthographicCamera guiCam;
World world;
WorldRenderer renderer;
public GameScreen(MyGdxGame game, SpriteBatch batch)
{
this.game = game;
guiCam = new OrthographicCamera(400, 400);
guiCam.position.set(400 / 2, 400 / 2, 0);
world = new World();
renderer = new WorldRenderer(game, batch, world);
}
public void draw()
{
GL20 gl = Gdx.gl;
gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderer.render();
}
#Override
public void show()
{
world.createLevel();
}
#Override
public void render(float delta)
{
draw();
}
#Override
public void resize(int width, int height)
{
}
#Override
public void pause()
{
}
#Override
public void resume()
{
}
#Override
public void hide()
{
}
#Override
public void dispose()
{
}
The problem is this line of code:
public void resize(int width, int height)
{
viewport.update(width, height, true);
}
Whenever you update the viewport, you are also updating the underlying opengl viewport and this causes the black bars to persist to the second screen (https://github.com/libgdx/libgdx/wiki/Viewports). Thus if you want to reset it back to normal you must use the following line of code in your second screen show() method (https://github.com/libgdx/libgdx/wiki/Scene2d):
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());

Interaction between 2 classes maybe

I'm trying to make a mini game with 2 classes: the menu and the play. I am trying to randomly change the image of an object in the play class by clicking a button in the menu class.
So, in the menu class I add a button and add input listener so that when I click
playbutton.addListener(new InputListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
game.setScreen(new lessonclass (game));
lessonclass.currentlevel = MathUtils.random(2);
return true;
}
});
in the play class, I add static int level, an object
public grid ( Vector2 position, Vector2 size) {
texture0 = new Texture (Gdx.files.internal("zero.jpg"));
texture1 = new Texture (Gdx.files.internal("one.jpg"));
texture2 = new Texture (Gdx.files.internal("two.jpg"));
texture3 = new Texture (Gdx.files.internal("three.jpg"));
this.position = position;
this.size = size;
}
public void update(){
}
public void draw0(SpriteBatch batch) {
batch.draw(texture0, position.x, position.y, size.x, size.y);
}
public void draw1(SpriteBatch batch) {
batch.draw(texture1, position.x, position.y, size.x, size.y);
}
public void draw2(SpriteBatch batch) {
batch.draw(texture2, position.x, position.y, size.x, size.y);
}
if (TouchDown) {System.out.println ("" + level);}
When I run the program, the level value VARIES between 0 and 1 but the object always draw image batch.
If I change the code in the menu class so that it only brings me to play class and the in play class I change the level to
public static int level = MathUtils.random(1);
then my level value varies and the object randomly draws either batch image or batch1 image.
However, I want to do this from the menu class. Since the program runs and I cant think of the logic error, I am stuck now. Why can't I change my object image by clicking the button in the menu class?

Libgdx adding a UI button separated from the gamescreen

I've got a GameScreen where I have 100 "dots" randomly bounce around the screen. I'm currently adding a UI button in order to rotate the screen; one on the left and one on the right. The button works, however, the button is "linked" to the camera because as the screen rotates (the playing field for the dots spins because the camera rotates), the button rotates with it. I want the button(s) to be fixed to the device screen, and not rotate with the underlying field of dots.
Do I have to unproject the button somehow, or create a separate stage for any UI elements (buttons, statusbar title alone the top, etc)? Many thanks.
Here's my code:
public class GameScreen implements Screen {
final jGdxDots game;
final MyGestureListener myGestureListener;
OrthographicCamera camera;
private Skin skin;
final int NUMBER_OF_DOTS = 100;
int dotTotal;
private Stage stage;
FPSLogger fpsLogger;
float cameraRotate = 0f;
public GameScreen(final jGdxDots gam) {
this.game = gam;
fpsLogger = new FPSLogger();
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480); //boolean = YDOWN or YUP axis.
//create stage
stage = new Stage(Gdx.graphics.getWidth(),Gdx.graphics.getHeight(),true);
//set stage to handle the inputs
//Gdx.input.setInputProcessor(stage);
stage.setCamera(camera);
//stage.setViewport(800, 480, true);
//multiplex the gesture listeners (both for stage and my listener)
myGestureListener = new MyGestureListener();
GestureDetector gd = new GestureDetector(myGestureListener);
InputMultiplexer im = new InputMultiplexer(gd, stage); // Order matters here!
Gdx.input.setInputProcessor(im);
//UI button
skin = new Skin(Gdx.files.internal("data/uiskin.json"));
final TextButton button = new TextButton("Rotate", skin, "default");
button.setWidth(100f); //200f
button.setHeight(100f); //20f
button.setPosition(10f, 10f);
button.addListener(new ClickListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
cameraRotate = 1f;
return super.touchDown(event, x, y, pointer, button);
}
#Override
public void touchUp(InputEvent event, float x, float y,
int pointer, int button) {
// TODO Auto-generated method stub
super.touchUp(event, x, y, pointer, button);
cameraRotate = 0f;
}
});
stage.addActor(button);
spawnDots(stage);
}
private void spawnDots(Stage theStage) {
//Rectangle raindrop = new Rectangle();
for (int i=0; i < NUMBER_OF_DOTS; i++) {
DotActor dot = new DotActor();
dot.setOrigin(8,8); //(dot.getWidth()/2, dot.getHeight()/2);
dot.vector.set(MathUtils.random(1,4), MathUtils.random(1,4));
dot.actorX = MathUtils.random(0, 800 - dot.getWidth());
dot.actorY = MathUtils.random(0, 480 - dot.getHeight());
stage.addActor(dot);
}
dotTotal = NUMBER_OF_DOTS;
}
#Override
public void dispose() {
stage.dispose();
}
#Override
public void render(float delta) {
//clear screen
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
//logger
fpsLogger.log();
//camera.zoom += 0.005f;
camera.rotate(cameraRotate); //(1.0f);
camera.update();
//run act() method of each actor
stage.act(Gdx.graphics.getDeltaTime());
//run each actor's draw() method who are members of this stage
stage.draw();
}
}
I had this problem too. Create a separate stage, or you might just want to draw directly with a sprite batch in a 'renderer' class
Mine looks something like this:
public OverlayRenderer()
{
this.spriteBatch = new SpriteBatch();
this.loadTextures();
}
public void render(String _message)
{
this.spriteBatch.begin();
this.spriteBatch.draw(TEXTURES.UI, 0, 0);
....
}
and directly after your
stage.draw();
line, I would add
overLayRenderer.render();

Categories

Resources