LIBGDX - How to make the paddle not jumping in pong game? - java

I am making a Pong game and when I click on the screen the paddle jump to my cursor point. I want that I need to drag the cursor to move him and without jumping like normal Pong game. how can I do this?
This is my Paddle class:
public class Paddle {
private Vector3 position;
private int width, height;
private Texture texture;
public Paddle(int x, int y, int width, int height){
this.width = width;
this.height = height;
createTexture(width,height);
position = new Vector3(x, y, 0);
}
private void createTexture(int width, int height) {
Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
pixmap.setColor(Color.BLACK);
pixmap.fillRectangle(0, 0, width, height);
texture = new Texture(pixmap);
pixmap.dispose();
}
public void update(int y){
position.add(0, y - position.y,0);
position.y = y;
position.set(position.x, HeadGuns.HEIGHT - position.y, position.z);
}
public void draw(SpriteBatch sb){
sb.draw(texture, position.x, position.y, width,height);
}
This is my PlayState class:
public class PlayState extends State {
private Paddle myPaddle;
public PlayState(GameStateManager gsm) {
super(gsm);
myPaddle = new Paddle(25, HeadGuns.HEIGHT/2, 25, 150);
}
#Override
public void handleInput() {
if (Gdx.input.isTouched()){
//when I touched the screen
myPaddle.update(Gdx.input.getY());
}
}
#Override
public void update(float dt) {
handleInput();
}
#Override
public void render(SpriteBatch sb) {
sb.begin();
myPaddle.draw(sb);
sb.end();
}
#Override
public void dispose() {
}

You are reading touch position:
Gdx.input.getY()
and using it directly to set pad position - you can't do that.
You should use InputLister to get events.
First you should listen to touchDown and see is user touching your pad or not (compare touch coordinates with pad coordinates)
Then, for dragging you should use touchDragged() event...to update pad position when dragging happen, but only if touchDown detected that touch:
https://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/InputListener.html#touchDragged-com.badlogic.gdx.scenes.scene2d.InputEvent-float-float-int-

Related

Stage camera won't move

In my game, I have my objects represented as a actors, thus all of the game objects would be on a Stage. For some reason when I try to move the Stage's camera around, it won't work, or actually it doesn't seem to work. I have added a game Actor to the location of 0,0. When I translate the camera's position around, the Actor still stays at the bottom left corner, despite when I log the camera's position, it shows that the camera has moved.
public class Striker extends Actor {
private Sprite img;
private World worldRef;
private Body body;
//constructor
public Striker(float size, float x, float y, World world) {
img = new Sprite(new Texture(Gdx.files.internal("Striker.png")));
//mains the aspect size ratio
img.setSize((275f / 300f) * size, size);
img.setPosition(x, y);
worldRef = world;
//set up the physics
BodyDef bodyDef = new BodyDef();
bodyDef.type = BodyDef.BodyType.DynamicBody;
bodyDef.position.set(x,y);
body = world.createBody(bodyDef);
}
#Override
public void draw(Batch batch, float parentAlpha) {
img.draw(batch);
}
#Override
public void act(float delta) {
super.act(delta);
}
#Override
public float getX() {
return body.getPosition().x;
}
#Override
public float getY() {
return body.getPosition().y;
}
#Override
public float getWidth() {
return img.getWidth();
}
#Override
public float getHeight() {
return img.getHeight();
}
}
The results of the 2 logs show that the camera's positions have moved, but it doesn't look like it.
public class StrikerScreen implements Screen {
public static float WIDTH = 1920;
public static float HEIGHT = 1080;
public static float PPM = 200;
private Launcher launcherRef;
private OrthographicCamera camera;
private FitViewport viewport;
private World world;
private Box2DDebugRenderer debugRenderer;
private Striker striker;
private Stage gameStage;
//constructor
public StrikerScreen(Launcher launcher) {
launcherRef = launcher;
world = new World(new Vector2(0, -9.8f), true);
debugRenderer = new Box2DDebugRenderer();
gameStage = new Stage();
camera = (OrthographicCamera) gameStage.getCamera();
viewport = new FitViewport(WIDTH / PPM, HEIGHT / PPM, gameStage.getCamera());
viewport.apply();
gameStage.setViewport(viewport);
striker = new Striker(160f / PPM, 0, 0, world);
gameStage.addActor(striker);
gameStage.getCamera().translate(viewport.getWorldWidth() / 2f, 500f, 0);
viewport.apply();
camera.update();
Gdx.app.log("StrikerScreen.java", "Camera position: " + gameStage.getCamera().position.toString());
Gdx.app.log("StrikerScreen.java", "Camera size: " + gameStage.getCamera().viewportWidth + ", " + gameStage.getCamera().viewportHeight);
}
#Override
public void show() {
}
public void update(float delta) {
world.step(1 / 30f, 6, 2);
gameStage.act(delta);
}
#Override
public void render(float delta) {
update(delta);
debugRenderer.render(world, camera.combined);
gameStage.draw();
}
#Override
public void resize(int width, int height) {
viewport.update(width, height, true);
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
}
In the code you posted, the only times you move the camera are in the StrikerScreen constructor where you explicitly translate it, and in the resize method, where you have called viewport.update(width, height, true); Passing true to viewport.update tells it to move the camera to where (0, 0) is in the bottom left of corner of the viewport. Since resize is automatically called when you set your screen to this screen, that is the most recent position you have set the camera to.

Libgdx, Android, how to drag and move a texture

currently the method I used is to detect whether touch position (Gdx.input.getX() & Y()) is in the area whether the object texture is. If so I setPosition of the object texture to the mouse position as center. While this work but it is not robust. Because if my finger move faster than the update, as soon as the touched position is outside texture bound. It won't update any more.
There must be a more reliable way and please advice. Essentially, I want to touch on the texture and drag the texture to wherever my touch is moving.
Many thanks.
My current approach is like this:
public class PlayScreen implements Screen {
int scWidth, scHeight;
int playerWidth, playerHeight;
private SpriteBatch batch; // This is in the render.
Player player;
// Create a constructor
Game game;
public PlayScreen(Game game){
this.game = game;
}
#Override
public void show() {
batch = new SpriteBatch();
scWidth = Gdx.graphics.getWidth();
scHeight = Gdx.graphics.getHeight();
playerWidth = 180;
playerHeight = 240;
player = new Player("mario.png", new Vector2(250, 300),new Vector2(playerWidth, playerHeight)) ;
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
// Only draw if the mouse is hover on the image.
if (Gdx.input.getX() > player.getPosition().x && Gdx.input.getX() < player.getPosition().x + playerWidth){
if (scHeight - Gdx.input.getY() > player.getPosition().y && scHeight - Gdx.input.getY() < player.getPosition().y + playerHeight)
{
player.setPosition(new Vector2(Gdx.input.getX() - playerWidth/2,
scHeight - Gdx.input.getY() - playerHeight/2));
player.draw(batch);
} else{
player.draw(batch);
}
} else{
player.draw(batch);
}
batch.end();
player.update(); // Update the bound
}
}
Also the Player class is :
package com.jiajunyang.emosonicsgame;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.scenes.scene2d.ui.Image;
public class Player extends Image {
Vector2 position, size;
Texture player;
Rectangle bounds;
public Player(String fileName, Vector2 position, Vector2 size){
super(new Texture(Gdx.files.internal(fileName)));
this.position = position;
this.size = size;
bounds = new Rectangle(position.x, position.y, size.x, size.y);
// player = new Texture(Gdx.files.internal(fileName));
}
public void update(){
bounds.set(position.x, position.y, size.x, size.y);
}
public void draw(SpriteBatch batch){
batch.draw(player, position.x, position.y, size.x, size.y);
}
public Vector2 getPosition() {
return position;
}
public void setPosition(Vector2 position) {
this.position = position;
}
public Vector2 getSize() {
return size;
}
public void setSize(Vector2 size) {
this.size = size;
}
public Rectangle getBounds() {
return bounds;
}
public void setBounds(Rectangle bounds) {
this.bounds = bounds;
}
}
Jiajun, create a Stage and have your Player extend Image. Then call stage.addActor(player) in show. In render call stage.act() and stage.draw(). Use the Image's constructor to pass your Texture into. Finally, in Player's constructor, call this:
addListener(new DragListener() {
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
return true;
}
#Override
public void touchDragged(InputEvent event, float x, float y, int pointer) {
moveBy(x - getWidth()/2, y - getHeight()/2);
}
});

libgdx simple game is stuttering a lot

I just started with libgdx and so I created a simple test application where an image just moves. The problem is that even if its an extremly simple game the image is stuttering a lot while it moves. Here is the code:
public class Game extends ApplicationAdapter {
private Entity e;
private OrthographicCamera camera;
private SpriteBatch batch;
#Override
public void create () {
batch = new SpriteBatch();
e = new Entity(50,50,"badlogic.jpg");
camera = new OrthographicCamera();
camera.setToOrtho(false, 480, 800);
camera.update();
}
#Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
e.setX(e.getX()+100 * Gdx.graphics.getDeltaTime());
batch.setProjectionMatrix(camera.combined);
batch.begin();
e.draw(batch);
batch.end();
}
The entity class:
public class Entity {
private Texture texture;
private Rectangle hitbox;
private float x,y;
public Entity(float x,float y,String texture){
this.x=x;
this.y=y;
this.texture=new Texture(Gdx.files.internal(texture));
this.hitbox=new Rectangle(x,y,this.texture.getWidth(),this.texture.getHeight());
}
public void draw(SpriteBatch sb){
sb.draw(texture, x, y);
}
public boolean collidesWith(Entity e){
return this.hitbox.overlaps(e.getHitbox());
}
public Rectangle getHitbox() {
return hitbox;
}
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
Can someone explain me why this is stuttering?
getDeltaTime() is smoothed out over multiple frames so if a average frame takes .016 seconds and suddenly there is a frame taking .030 seconds then getDeltaTime() will just return .016. So in reality the game has progressed .030 seconds but you multiply your movement by .016.
getRawDeltaTime() gives you the real time passed since last frame. Try to use this as you multiplier. Otherwise try to log both and see if there are differences.
The benefit of using the smoothed getDeltaTime() is when frame drops happen the game will be still playable. While with getRawDeltaTime() if there would suddenly a second pass for the next frame then your velocity would get multiplied by 1 instead of .016 and could immediately go of screen or miss collision detection.

InputListener doesn't work with OrthographicCamera and Actors

I have a Stage with OrthographicCamera and also I have a Actor with InputListener setter by addListener (from actor class). The problem is that the actor doesn't proccess input, but if in my screen I delete OrthographicCamera the Actor proccess the input, so, with OrthographicCamera Actor doesn't proccess input but it works if I remove OrthographicCamera.
Any advice?
I have the following code
public class Test implements Screen {
private Game game;
private Stage stage;
private MemoryActor actor;
private AssetManager manager;
private boolean loaded = false;
float width, height;
private OrthographicCamera camera;
public Test(Game game){
this.game = game;
stage = new Stage();
manager = new AssetManager();
manager.load("img.png",Texture.class);
manager.load("img1.png",Texture.class);
InputMultiplexer im = new InputMultiplexer();
im.addProcessor(stage);
Gdx.input.setInputProcessor(im);
height = Gdx.graphics.getHeight();
width = Gdx.graphics.getWidth();
camera = new OrthographicCamera(width, height);
camera.position.set(((width / 2)), ((height / 2)), 0);
camera.update();
stage.setViewport(new ExtendViewport(300,300, camera));
}
public void createActor(){
Texture back = manager.get("img.png", Texture.class);
actor = new MemoryActor(manager.get("img1.png", Texture.class), back,0,0,50,50);
actor.setInputListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("down");
return true;
}
#Override
public void touchUp(InputEvent event, float x, float y, int pointer, int button) {
System.out.println("up");
}
});
stage.addActor(actor);
}
#Override
public void render(float delta) {
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
if (manager.update()){
if (!loaded){
createActor();
loaded = true;
}
}
stage.draw();
}
#Override
public void resize(int width, int height) {
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
}
}
and MemoryActor:
public class MemoryActor extends Actor {
...
public MemoryActor(){}
public MemoryActor(Texture texture, Texture texBack, float x, float y, float width, float height){
...
}
public void setInputListener(InputListener il){
addListener(il);
}
#Override
public void draw(Batch batch, float alpha){
...
}
}
Just registering the stage as an InputProcessor isn't enough. You also need to trigger the event processing of Stage via stage.act() in every frame.
Furthermore you need to properly update the stage's Viewport when a resize event occurs. This can be done via stage.getViewport().update(width, height, true). Otherwise the stage will process the events based on incorrect assumptions about the screen size and might also render your stage not the way you want it. The true is important because it will also center the camera on the new screen size, which is necessary in case of UIs.

libgdx drag and drop

Im trying to add drag and drop functionality to several images in Libgdx. I have looked at this example: https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/DragAndDropTest.java but Its still not working. The images do not drag and drop. Would anyone be able to give me some pointers in why its not working?
Thanks
private void createButton() {
stage = new Stage();
Gdx.input.setInputProcessor(stage);
skin = new Skin();
skin.add("up", new Texture(Gdx.files.internal("assets/data/up.png")));
skin.add("def", new Texture(Gdx.files.internal("assets/data/Goal.png")));
final Image up = new Image(skin, "up");
up.setBounds(1090, 630, 40, 40);
stage.addActor(up);
Image def = new Image(skin, "def");
def.setBounds(1090, 585, 40, 40);
stage.addActor(def);
DragAndDrop dragAndDrop = new DragAndDrop();
dragAndDrop.addSource(new Source(up) {
public Payload dragStart (InputEvent event, float x, float y, int pointer) {
Payload payload = new Payload();
payload.setObject(payload);
payload.setDragActor(up);
payload.setDragActor(new Label("up", skin));
Label validLabel = new Label("up", skin);
validLabel.setColor(0, 1, 0, 1);
payload.setValidDragActor(validLabel);
return payload;
}
});
dragAndDrop.addTarget(new Target(def) {
public boolean drag (Source source, Payload payload, float x, float y, int pointer) {
getActor().setColor(Color.GREEN);
return true;
}
public void reset (Source source, Payload payload) {
getActor().setColor(Color.WHITE);
}
public void drop (Source source, Payload payload, float x, float y, int pointer) {
System.out.println("Accepted: " + payload.getObject() + " " + x + ", " + y);
}
});
render();
}
public void render () {
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
Table.drawDebug(stage);
}
I implemented your code on a project of mine.
I removed your render and used the one below. Also, you shouldn't need the assets/ prefix to your image import.
skin.add("up", new Texture(Gdx.files.internal("images/coin.png")));
skin.add("def", new Texture(Gdx.files.internal("images/coin.png")));
#Override
public void render(float delta) {
super.render(delta);
stage.draw();
stage.act(Gdx.graphics.getDeltaTime());
}
Another way to do drag in a better way...
public class CaveInterection implements ApplicationListener {
private OrthographicCamera camera;
private SpriteBatch batch;
private Texture bgTexture;
private Sprite sprite;
private Stage stage;
private Texture mirrTexture;
private MyActor mirrorActor;
Sprite img1,img2;
#Override
public void create() {
camera = new OrthographicCamera(1024, 550);
camera.position.set(1024 / 2, 550 / 2, 0);
batch = new SpriteBatch();
stage = new Stage(1024, 550, false);
//bgTexture = new Texture(Gdx.files.internal("data/cave.jpg"));
//bgTexture = new Texture(Gdx.files.internal("data/bg.jpg"));
mirrTexture = new Texture(Gdx.files.internal("data/mirror.png"));
mirrTexture
.setFilter(TextureFilter.Linear, TextureFilter.Linear);
mirrorActor = new MyActor(new TextureRegion(mirrTexture));
mirrorActor.setPosition(700, 400);
mirrorActor.setOrigin(mirrorActor.getWidth()/2, mirrorActor.getHeight()/2);
stage.addActor(mirrorActor);
// finally stage as the input process
Gdx.input.setInputProcessor(stage);
}
#Override
public void dispose() {
batch.dispose();
//bgTexture.dispose();
}
#Override
public void render() {
// clear the screen, update the camera and make the sprite batch
// use its matrices.
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
//batch.draw(bgTexture, 0,0);
// Gdx.app.log("arvind","X :"+mirrorActor.getX()+ " Y :"+mirrorActor.getY());
//batch.draw(bgTexture, 0, 0);
batch.end();
// tell the stage to act and draw itself
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
public class MyActor extends Actor {
TextureRegion region;
float lastX;
float lastY;
public MyActor (TextureRegion region) {
this.region = region;
setWidth(region.getRegionWidth());
setHeight(region.getRegionHeight());
addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button) {
Gdx.app.log("arv", "pointer1+"+pointer);
// we only care for the first finger to make things easier
if (pointer != 0) return false;
// record the coordinates the finger went down on. they
// are given relative to the actor's corner (0, 0)
Gdx.app.log("arvind", "touchDown");
Gdx.app.log("arv", "pointer2+"+pointer+""+x+"::::"+y);
lastX = x;
lastY = y;
return true;
}
public void touchDragged (InputEvent event, float x, float y, int pointer) {
// we only care for the first finger to make things easier
if (pointer != 0) return;
Gdx.app.log("arv", "touchDragged");
// adjust the actor's position by (current mouse position - last mouse position)
// in the actor's coordinate system.
translate(x - lastX, y - lastY);
// rotate(2);
// save the current mouse position as the basis for the next drag event.
// we adjust by the same delta so next time drag is called, lastX/lastY
// are in the actor's local coordinate system automatically.
lastX = x - (x - lastX);
lastY = y - (y - lastY);
}
});
}
#Override
public void draw (SpriteBatch batch, float parentAlpha) {
//batch.draw(region, getX(), getY());
batch.draw(region, getX(), getY(), mirrorActor.getOriginX(), mirrorActor.getOriginY(), mirrorActor.getWidth(), mirrorActor.getHeight(), 1, 1,getRotation(), true);
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
}

Categories

Resources