I don't know how I can clear the buffer in libGDX, in this case,
GL30.GL_COLOR_BUFFER_BIT doesn't work.
package com.mygdx.game.Screens;
import Artifacts.Champ;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.Game;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.*;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.Sprite;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.scenes.scene2d.*;
import com.badlogic.gdx.scenes.scene2d.ui.*;
import com.badlogic.gdx.scenes.scene2d.ui.ImageButton.ImageButtonStyle;
import com.badlogic.gdx.scenes.scene2d.utils.SpriteDrawable;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.viewport.ScreenViewport;
import com.mygdx.game.MyGdxGame;
import java.util.ArrayList;
public class GameScreen implements Screen {
private Stage stage;
private Game game;
ArrayList <Champ> champs=new ArrayList();;
public GameScreen(Game aGame) {
game = aGame;
stage = new Stage(new ScreenViewport());
ImageButton pj;
Table camp;
champs.add(new Champ("Ximet",new Texture("Champ/Ximet.png")));
champs.add(new Champ("Jordi",new Texture("Champ/Jordi.jpg")));
champs.add(new Champ("Camilo",new Texture("Champ/Camilo.jpg")));
champs.add(new Champ("Vicent",new Texture("Champ/Vicent.jpg")));
int x=100, y=250;
for (final Champ champ : champs) {
camp=new Table();
pj=new ImageButton(new SpriteDrawable(new Sprite(champ.getLogo())));
pj.setPosition(x, y);
camp.add(pj).size(100, 100);
camp.setPosition(x, y);
x=x+100;
camp.addListener(new InputListener(){
#Override
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
Label name = new Label(champ.nom, MyGdxGame.gameSkin,"big-black");
name.setPosition(10,400);
stage.addActor(name);
}
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
return true;
}
});
stage.addActor(camp);
}
Label title = new Label("Select Champ", MyGdxGame.gameSkin,"big-black");
title.setAlignment(Align.center);
title.setY(Gdx.graphics.getHeight()*2/3);
title.setWidth(Gdx.graphics.getWidth());
stage.addActor(title);
TextButton backButton = new TextButton("Back",MyGdxGame.gameSkin);
backButton.setWidth(Gdx.graphics.getWidth()/2);
backButton.setPosition(Gdx.graphics.getWidth()/2-backButton.getWidth()/2,Gdx.graphics.getHeight()/4-backButton.getHeight()/2);
backButton.addListener(new InputListener(){
#Override
public void touchUp (InputEvent event, float x, float y, int pointer, int button) {
game.setScreen(new Principal((MyGdxGame)game));
}
#Override
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
return true;
}
});
stage.addActor(backButton);
}
#Override
public void show() {
Gdx.app.log("MainScreen","show");
Gdx.input.setInputProcessor(stage);
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
stage.act();
stage.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() {
stage.dispose();
}
}
That screen shows you all the players and when you pick one of them, on the topside will appear her name, it works, but when I pick another different, the name still there.
P.S.1 I'm begginer, just learning LigGDX picking code, and I'm trying to do a rpg game.
P.S.2 For-loop prints on the screen the arraylist of champions, adding them to a button for select one of them, if you know another way more easy and optimized, I'll appreciate.
P.S.3 I know that initialize in the loop the table isn't recommended. If I initialize outside the loop, when I pick a champion, in the topside shows the name of all the objects in the arraylist.
Related
So I'm currently in the process of refactoring my code in my game for the player and started a player class:
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class Player
{
protected String name;
protected float health, maxHealth;
protected Texture texture;
protected int xPos, yPos;
public Player(String name, float maxHealth, Texture texture) {
this(name, maxHealth, texture, 0, 0);
}
public Player(String name, float maxHealth, Texture texture, int xPos, int yPos) {
this.name = name;
this.health = this.maxHealth = maxHealth;
this.texture = texture;
this.xPos = xPos;
this.yPos = yPos;
}
public Texture getTexture() {
return this.texture;
}
public int getX() {
return xPos;
}
public int getY() {
return yPos;
}
public String getName() {
return name;
}
public void draw(SpriteBatch spriteBatch) {
spriteBatch.begin();
spriteBatch.draw(texture, xPos, yPos, 0.5f, 0.5f, 0, 0,
texture.getWidth(), texture.getHeight(), false, false);
spriteBatch.end();
}
public void update(float delta) {
processMovement(delta);
}
public void processMovement(float delta) {
if(Gdx.input.isKeyPressed(Input.Keys.A)) {
xPos -= 50 * delta;
}
if(Gdx.input.isKeyPressed(Input.Keys.D)) {
xPos += 50 * delta;
}
}
}
I'm using an orthographic camera, I haven't added any terrain yet as I'm going to do that next, however I want the player to always stay in the center but have the player move around the terrain when I draw it.
The code I have for creating the camera and drawing my player is as follows:
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.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class GameState implements Screen
{
private PixelGame parent;
private OrthographicCamera camera;
private Player player;
private Texture playerTexture;
private SpriteBatch spriteBatch;
public GameState(PixelGame parent) {
this.parent = parent;
this.playerTexture = new Texture(Gdx.files.internal("player/sprite.png"));
this.player = new Player("Me", 20, playerTexture);
this.spriteBatch = new SpriteBatch();
}
#Override
public void render(float delta) {
camera.update();
spriteBatch.setProjectionMatrix(camera.combined);
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
player.draw(spriteBatch);
player.update(delta);
}
#Override
public void show() {
}
#Override
public void dispose() {
}
#Override
public void resize(int width, int height) {
float ratio = (float)width / (float)height;
camera = new OrthographicCamera(2f * ratio, 2f);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
}
The player sprite doesn't seem to move, but when i change the values to something >75 the player sprite sprints across the screen like no-ones business.
xPos and yPos in your class are ints. I would say that's the problem. Your processMovement() method is called like 100 times per second and 50 * delta is most likely smaller than 1 so it's rounded to 0 because value has to be stored in int variable. Try changing xPos and yPos to floats.
And if that doesn't help (can't be sure without trying out the code) do some debugging. Put break points. See if processMovement() is called at all and if it is then what value variable delta has. How calculation goes.
I'm currently having a problem creating a stretchedViewPort in libgdx.
As you can see in the image I added the gamescreen is not stretched over the whole screen and there are black spaces. I'm wondering what I'm doing wrong.
I provided the relevant parts of the code below.
Furthermore I also tried to use asign the viewport in to the stage in the oncreate function like this: m_stage = new Stage(m_viewport); But in that case I got a black screen and nothing was rendered (tough there were no compile errors).
Can someone point out what I'm doing wrong or what I'm missing.
Thanks in advance!
Kind regards,
Cavasta
package com.block.it;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
import com.badlogic.gdx.utils.viewport.StretchViewport;
public class GameMenu implements Screen {
private BlockIt m_blockIt;
private Texture m_btexture = new Texture(Gdx.files.internal("mainmenu1.png"));
private Image m_background = new Image(m_btexture);
private Texture m_starttexture = new Texture(Gdx.files.internal("buttons/c_start.png"));
private Image m_startGame = new Image(m_starttexture);
private Texture m_optionstexture = new Texture(Gdx.files.internal("buttons/c_controls.png"));
private Image m_options = new Image(m_optionstexture);
private Texture m_highscoretexture = new Texture(Gdx.files.internal("buttons/c_highscores.png"));
private Image m_highscore = new Image(m_highscoretexture);
private Texture m_continueTexture = new Texture(Gdx.files.internal("buttons/c_resume_game.png"));
private Image m_continue = new Image(m_continueTexture);
private Texture m_playerIcon = new Texture(Gdx.files.internal("player/player_move_front.png"));
private Image m_player = new Image(m_playerIcon);
private int m_buttonPressed = -1;
private boolean m_gameInProgress = false;
private StretchViewport m_viewport;
private PerspectiveCamera m_camera;
private Stage m_stage = new Stage();
public GameMenu(BlockIt blockIt, boolean gameInProgress) {
m_blockIt = blockIt;
m_camera = new PerspectiveCamera();
m_viewport = new StretchViewport(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), m_camera);
m_viewport.update(Gdx.graphics.getWidth(), Gdx.graphics.getHeight(), true);
m_stage = new Stage();
}
#Override
public void show() {
if (!m_gameInProgress) {
m_startGame.setX(227);
m_startGame.setY(270);
m_startGame.addListener(new ClickListener() {
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
// m_blockIt.startNewGame();
}
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
// switch to a new texture
/*Texture newTexture = new Texture(Gdx.files.internal("buttons/c_new_game.png"));
m_startGame.setDrawable(new SpriteDrawable(new Sprite(newTexture)));
*/
m_player.setX(-64);
m_player.setY(300);
m_stage.addActor(m_player);
m_buttonPressed = 0;
return true;
}
});
} else {
m_continue.setX(227);
m_continue.setY(270);
m_continue.addListener(new ClickListener() {
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
}
});
}
m_stage.addActor(m_background); //adds the image as an actor to the stage
if (m_gameInProgress) {
m_stage.addActor(m_continue);
} else {
m_stage.addActor(m_startGame);
}
Gdx.input.setInputProcessor(m_stage);
}
#Override
public void render(float delta) {
m_camera.update();
Gdx.gl.glClearColor(0, 0, 0, 1); //sets clear color to black
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT); //clear the batch
m_stage.act(); //update all actors
m_stage.draw(); //draw all actors on the Stage.getBatch()
}
#Override
public void resize(int width, int height
) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
You have to set the camera and viewport to the value u used to program the world:
eg. If your world is 800*480:
camera = new OrthographicCamera(800,480);
fitViewport = new FitViewport(800, 480, camera);
You have to update the viewport when the window is resized:
#Override
public void resize(int width, int height) {
m_viewport.update(width, height, true);
}
Just in process of making a space invaders style game for android.
I want the player to be able to touch the screen anywhere to right or left of character (at bottom of screen) to move him that direction.
The code compiles without error and the playe does move, but
A) he's moving much slower than I expected
B) The movement is 'jittery' even though I have multiplied the movement speed by deltatime in a few different ways.
Please could someone be kind enough to take a look at my code to say where I have gone wrong? :-
package com.moneylife.stashinvaders;
import com.badlogic.gdx.ApplicationAdapter;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
public class StashInvaders extends ApplicationAdapter {
GameManager gameManager;
#Override
public void create () {
gameManager = new GameManager();
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
gameManager.update();
gameManager.draw();
}
#Override
public void dispose () {
gameManager.spriteBatch.dispose();
}
}
GameManager class:
package com.moneylife.stashinvaders;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
/**
* Created by Dave on 12/08/2016.
*/
public class GameManager {
SpriteBatch spriteBatch;
Player player1;
public GameManager(){
spriteBatch = new SpriteBatch();
player1 = new Player();
}
public void update(){
player1.update();
}
public void draw(){
spriteBatch.begin();
player1.draw(spriteBatch);
spriteBatch.end();
}
}
Player class:
package com.moneylife.stashinvaders;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.input.GestureDetector;
import com.badlogic.gdx.math.Vector2;
/**
* Created by Dave on 12/08/2016.
*/
public class Player {
Vector2 position;
Texture texture;
int speed = 50;
float deltaTime;
public Player(){
Gdx.input.setInputProcessor(new GestureDetector(new MyGestureDetector()));
texture = new Texture("bazookaman.png");
position = new Vector2(Gdx.graphics.getBackBufferWidth() / 2 - texture.getWidth() / 2, 0);
}
public void update(){
deltaTime = Gdx.graphics.getDeltaTime();
}
public void draw(SpriteBatch spriteBatch){
spriteBatch.draw(texture, position.x, position.y);
}
public class MyGestureDetector implements GestureDetector.GestureListener {
#Override
public boolean touchDown(float x, float y, int pointer, int button) {
return false;
}
#Override
public boolean tap(float x, float y, int count, int button) {
return false;
}
#Override
public boolean longPress(float x, float y) {
return false;
}
#Override
public boolean fling(float velocityX, float velocityY, int button) {
return false;
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
if (x > position.x){
position.x += speed * deltaTime;
}
if (x < position.x){
position.x -= speed * deltaTime;
}
return false;
}
#Override
public boolean panStop(float x, float y, int pointer, int button) {
return false;
}
#Override
public boolean zoom(float initialDistance, float distance) {
return false;
}
#Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
return false;
}
#Override
public void pinchStop() {
}
}
}
Look closely at your logic.
if (x > position.x){
position.x += speed * deltaTime; //if close to touch point, position.x is now bigger than x
}
if (x < position.x){ //if we just moved right past the touch point, undo it
position.x -= speed * deltaTime;
}
Furthermore, this pan method will only be called on frames where the finger position was polled and was found to have moved. The finger position is not polled 60 times per second like your game is probably running, and movement will not always have occurred.
Instead, you should use the panning to modify a target position for your character. In the update() method you can always be moving towards that target position with some speed. It's up to you whether you should be using x or deltaX in the pan method to change your target X. Different types of gameplay.
I have a problem with particles in libGDX. Basicly they don't show at all and I have no idea why.
I use Scene2D and I created Particles actor: http://wklej.org/id/1534258/
I create it like this: particleTest = new ParticleEffectActor("test.p");
In my game I have 2 gui stages. I added particles to all of them in show() method of the screen:
menuStage.addActor(particleTest);
gameGuiStage.addActor(particleTest);
I also have another stage for my game (scaled by pixelPerMeter value). I tried to add it like this:
effect = new ParticleEffectActor("powerup.p");
gameWorld.getWorldStage().addActor(effect);
In this case I alsotried some tricks with positioning but still no effect.
What is wrong? Thanks for help
I finally managed to make a working version:
here's an actor;
package com.apptogo.runner.actors;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.g2d.Batch;
import com.badlogic.gdx.graphics.g2d.ParticleEffect;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
public class ParticleEffectActor extends Image {
private ParticleEffect effect;
public ParticleEffectActor(String particleName) {
super();
effect = new ParticleEffect();
effect.load(Gdx.files.internal("gfx/game/particles/" + particleName), Gdx.files.internal("gfx/game/particles"));
this.setVisible(false);
}
#Override
public void scaleBy(float scaleFactor){
effect.scaleEffect(scaleFactor);
}
#Override
public void setPosition(float x, float y){
super.setPosition(x, y);
effect.setPosition(x, y);
}
public void start() {
effect.start();
}
#Override
public void act(float delta) {
super.act(delta);
effect.update(delta);
}
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
effect.draw(batch);
}
public ParticleEffect getEffect(){ return this.effect; }
}
and this is how I use it:
effectActor = new ParticleEffectActor("test.p");
effectActor.scaleBy(1/PPM);
gameWorld.getWorldStage().addActor(effectActor);
and effectActor.setPosition(getX() + getWidth()/2, getY() + getHeight()/2);
in act()
EDIT:
Following Per's answer: I added this and it works fine :
private class GameScreen implements Screen {
private Stage mStage;
private InputMultiplexer inputMultiplexer = new InputMultiplexer();
public GameScreen() {
Gdx.input.setInputProcessor(inputMultiplexer);
mStage = new Stage(0, 0, true);
MyInput mi = new MyInput(){ //which implements inputProcessor
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
General.Log("gamescreen touchDown");
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
};
inputMultiplexer.addProcessor(mi);
inputMultiplexer.addProcessor(mStage);
}
I would like to detect a click on a ui actor, I registered stage as the inputProcessor
Gdx.input.setInputProcessor(stage);
And I added this to my actor:
setBounds(0, 0, texture.getWidth(), texture.getHeight());
But still no response...
It is hard to help you without getting more info on your setup. But this code snippet works fine for me, look and see what you do different. And if you cant get it right create a small project with just the code that fails, easier for us to help you then.
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.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
public class MyGame extends Game {
#Override
public void create() {
setScreen(new GameScreen());
}
private class GameScreen implements Screen {
private Stage mStage;
public GameScreen() {
mStage = new Stage(0, 0, true);
}
#Override
public void render(float delta) {
mStage.act(delta);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mStage.draw();
}
#Override
public void resize(int width, int height) {
Gdx.gl.glViewport(0, 0, width, height);
mStage.setViewport(width, height);
}
#Override
public void show() {
Texture texture = new Texture(Gdx.files.internal("data/libgdx.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 40, 40);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
Image imageActor = new Image(region);
imageActor.setPosition(x * 50, y * 50);
imageActor.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
System.out.println("clicked");
}
});
mStage.addActor(imageActor);
}
}
Gdx.input.setInputProcessor(mStage);
}
#Override
public void hide() {}
#Override
public void pause() {}
#Override
public void resume() {}
#Override
public void dispose() {}
}
}
With the ApplicationListener:
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.Texture.TextureFilter;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
import com.badlogic.gdx.scenes.scene2d.utils.ClickListener;
public class MyGame implements ApplicationListener {
private Stage mStage;
#Override
public void create() {
mStage = new Stage(0, 0, true);
Texture texture = new Texture(Gdx.files.internal("data/libgdx.png"));
texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
TextureRegion region = new TextureRegion(texture, 0, 0, 40, 40);
for (int y = 0; y < 4; ++y) {
for (int x = 0; x < 4; ++x) {
Image imageActor = new Image(region);
imageActor.setPosition(x * 50, y * 50);
imageActor.addListener(new ClickListener() {
public void clicked(InputEvent event, float x, float y) {
System.out.println("clicked");
}
});
mStage.addActor(imageActor);
}
}
Gdx.input.setInputProcessor(mStage);
}
#Override
public void resize(int width, int height) {
Gdx.gl.glViewport(0, 0, width, height);
mStage.setViewport(width, height);
}
#Override
public void render() {
mStage.act(Gdx.graphics.getDeltaTime());
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
mStage.draw();
}
#Override
public void pause() {}
#Override
public void resume() {}
#Override
public void dispose() {}
}