I am trying to make slingshot type thing(like in angry birds) using LIBGDX(currently learning). So, how do I get the coordinates of the point where user touched the screen and dragged finger to other point n released . I want both co-ordinates initial and released point.
I also want to know how to achieve the above in Android SDK/NDK.
I have not tested this but this should be around about what you need
#Override
Public boolean onTouchEvent (MotionEvent event) {
int downx;
int downy;
int upx;
int upy;
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
downy = (int)event.gety();
downx = (int)event.getx();
case MotionEvent.ACTION_MOVE:
case MotionEvent.ACTION_UP:
upy = (int)event.gety();
upx = (int)event.getx();
}
return false;
}
public class TempScreen extends Screen
{
Game game; // the class which is implementing the InputProcessor
SpriteBatch batcher;
Vector3 touchPoint;
OrthographicCamera cam;
InputMultiplexer multiplexer;
GestureListener listener=new GestureListener()
{
#Override
public boolean zoom(float initialDistance, float distance)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(float x, float y, int pointer, int button)
{
cam.unproject(touchPoint.set(x, y, 0));
System.out.println(touchPoint);
return false;
}
#Override
public boolean tap(float x, float y, int count, int button)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2,
Vector2 pointer1, Vector2 pointer2)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean panStop(float x, float y, int pointer, int button)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean longPress(float x, float y)
{
// TODO Auto-generated method stub
return false;
}
#Override
public boolean fling(float velocityX, float velocityY, int button)
{
// TODO Auto-generated method stub
return false;
}
};
GestureDetector detector=new GestureDetector(listener)
{
public boolean touchUp(float x, float y, int pointer, int button)
{
cam.unproject(touchPoint.set(x, y, 0));
System.out.println(touchPoint);
return false;
}
};
public TempScreen(Game game,SpriteBatch batcher)
{
super(game);
this.batcher=batcher;
this.game=game;
touchPoint = new Vector3();
cam = new OrthographicCamera(GameConstants.CAMERA_WIDTH,GameConstants.CAMERA_HEIGHT);
cam.position.set(GameConstants.CAMERA_WIDTH / 2,GameConstants.CAMERA_HEIGHT / 2, 0);
multiplexer = new InputMultiplexer();
multiplexer.addProcessor(game);
multiplexer.addProcessor(detector);
Gdx.input.setInputProcessor(multiplexer);
}
#Override
public void render(float deltaTime)
{
update(deltaTime);
GLCommon gl = Gdx.gl;
gl.glClearColor(0, 0f, 1f, 0.1f);
gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
cam.update();
batcher.setProjectionMatrix(cam.combined);
batcher.enableBlending();
batcher.begin();
draw(deltaTime);
batcher.end();
}
#Override
public void draw(float deltaTime)
{
// TODO Auto-generated method stub
}
#Override
public void update(float deltaTime)
{
// TODO Auto-generated method stub
}
#Override
public void backKeyPressed()
{
// TODO Auto-generated method stub
}
}
Make an InputProcessor and a Vector3:
MyInputprocessor myInputprocessor;
Vector3 touchPoint = new Vector3();
Define the InputProcessor like this:
public class MyInputprocessor implements InputProcessor{
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button){
guicam.unproject(touchPoint.set(screenX, screenY, 0)); //Initial point coordinates
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer){
guicam.unproject(touchPoint.set(screenX, screenY, 0)); //current point coordinates (when you are dragging it)
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button){
guicam.unproject(touchPoint.set(screenX, screenY, 0)); //final/release point coordinates
return false;
}
#Override public boolean keyTyped(char character){return false;}
#Override public boolean mouseMoved(int screenX, int screenY){return false;}
#Override public boolean scrolled(int amount){return false;}
#Override public boolean keyDown(int keycode){return false;}
#Override public boolean keyUp(int keycode){return false;}
}
Create it and set it in your ini code:
myInputprocessor = new MyInputprocessor();
Gdx.input.setInputProcessor(myInputprocessor);
Related
I recently started programming an app in LibGDX. With this app, one can only now press on boxes which are then filled in blue.
In principle everything works. The problem is only if I move the orthographic camera, or start to zoom, then my input processor still remains in the same place.
In short. Because the camera is moved or zoomed, the input does not work properly.
I have two times here Schreenshots attached so you can see what I mean.
The red dots are always where I pressed.
Regards Timux ;D
Here it works correctly
No more
No problem when I move or zoom my camera, I've tested, you can check this.
May be you're not using unproject() method of camera that translate a point given in screen coordinates to world space.
public class GdxText extends ApplicationAdapter implements InputProcessor {
OrthographicCamera cam;
Texture texture;
Sprite firstSprite,secondSprite;
SpriteBatch spriteBatch;
Vector3 vector3;
#Override
public void create() {
vector3=new Vector3();
cam=new OrthographicCamera();
texture=new Texture("badlogic.jpg");
float w=Gdx.graphics.getWidth();
float h=Gdx.graphics.getHeight();
spriteBatch=new SpriteBatch();
firstSprite=new Sprite(texture);
firstSprite.setSize(100,100);
firstSprite.setPosition(w/2-150,h/2-50);
secondSprite=new Sprite(texture);
secondSprite.setSize(100,100);
secondSprite.setPosition(w/2+50,h/2-50);
Gdx.input.setInputProcessor(this);
}
#Override
public void render() {
Gdx.gl.glClearColor(1,1,1,1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
spriteBatch.setProjectionMatrix(cam.combined);
spriteBatch.begin();
firstSprite.draw(spriteBatch);
secondSprite.draw(spriteBatch);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
cam.setToOrtho(false,width,height);
cam.update();
}
#Override
public boolean keyDown(int keycode) {
if(keycode== Input.Keys.UP) {
cam.zoom -= cam.zoom * .1;
cam.update();
}else if(keycode==Input.Keys.DOWN) {
cam.zoom += cam.zoom * .1;
cam.update();
}
if(keycode== Input.Keys.LEFT) {
cam.position.add(2f,0,0);
cam.update();
}else if(keycode==Input.Keys.RIGHT) {
cam.position.add(-2f,0,0);
cam.update();
}
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
vector3.set(screenX,screenY,0);
Vector3 ori=cam.unproject(vector3);
if(firstSprite.getBoundingRectangle().contains(ori.x,ori.y))
System.out.println("Touch on First Sprite");
if(secondSprite.getBoundingRectangle().contains(ori.x,ori.y))
System.out.println("Touch on Second Sprite");
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
#Override
public void dispose() {
spriteBatch.dispose();
texture.dispose();
}
}
I have been detecting different kinds of input with the different implemented Gesture Detector methods. I do however want to change some of the preferences of the G.D by changing the parameters of the method below:
public GestureDetector(float halfTapSquareSize,
float tapCountInterval,
float longPressDuration,
float maxFlingDelay,
GestureDetector.GestureListener listener)
I got ^ code of http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/input/GestureDetector.html
I am especially interested in changing the value of "halfTapSquareSize"
How would I go about implementing that into my code below?
public class MyGdxGame extends ApplicationAdapter implements GestureDetector.GestureListener {
#Override
public void create() {
super.create();
//Doing stuff at create
}
#Override
public void resize(int width, int height) {
super.resize(width, height);
}
#Override
public void render() {
super.render();
//Rendering stuff
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void dispose() {
//disposing stufff
}
#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) {
// Doing stuff at tap
return true;
}
#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) {
//Doing stuff when paning
}
#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;
}
}
Your code only implements the GestureListener. This listener needs to be associated with a GestureDetector, and the GestureDetector then needs to be registered to handle input.
So within your MyGdxGame class, you'll need something like this:-
GestureDetector input = new GestureDetector(this); // 'this' refers to your MyGdxGame instance
Gdx.input.setInputProcessor(input);
Now you can either supply extra arguments to GestureDetector's constructor, as you have mentioned in your post, or use the GestureDetector's relevant methods, like so:
input.setTapSquareSize(someFloatValue);
I have written the following code. It is simple rectangle in middle of the screen. I want the rectangle to move -50 in y direction onClick (direction is just for illustration purposes only). Despite trying various methods. I cannot get the code to work. I am not sure if I am doing something fundamentally wrong. I would appreciate some direction from better learned minds.
package com.mygdx.gameobjects;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.math.Rectangle;
import com.badlogic.gdx.math.Vector2;
public class Hero extends Rectangle implements InputProcessor{
private Rectangle hero;
private Vector2 position;
public Hero(){
position = new Vector2(x, y);
hero = new Rectangle(position.x+68-10, position.y+204-30-20, 20, 20);
}
public void update (float delta) {
}
public void onClick() {
position.y = -50;
}
public Rectangle getHero() {
return hero;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
onClick();
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean keyDown(int keycode) {
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}
I have very simple question. But i couldnt solve. I just want to draw a texture on the tilemap. With theese codes i can see the map and move, but i cant see texture.
Here is the screen:
package com.adsiz.areyoualive.screen;
import com.adsiz.areyoualive.game.Player;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
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.maps.tiled.*;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
public class PlayScreen implements Screen, InputProcessor{
public ScreenManager screenManager;
public static float speed = 32;
//tilemap & camera
TiledMap tiledMap;
OrthographicCamera camera;
TiledMapRenderer renderer;
//player
Player player;
//spritebatch
SpriteBatch spriteBatch;
public PlayScreen(){
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, w, h);
camera.update();
tiledMap = new TmxMapLoader().load("map/untitled.tmx");
renderer = new OrthogonalTiledMapRenderer(tiledMap);
spriteBatch = new SpriteBatch();
camera.position.set(0, 3200, 0);
Gdx.input.setInputProcessor(this);
player = new Player(0, 3200);
spriteBatch.setTransformMatrix(camera.combined);
}
#Override
public void render(float delta) {
Gdx.graphics.getGL20().glClearColor( 1, 1, 1, 1 );
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.graphics.getGL20().glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
camera.update();
renderer.setView(camera);
renderer.render();
spriteBatch.setProjectionMatrix(camera.combined);
spriteBatch.begin();
player.draw(spriteBatch);
spriteBatch.end();
}
#Override
public void resize(int width, int height) {
// TODO Auto-generated method stub
}
#Override
public void show() {
// TODO Auto-generated method stub
}
#Override
public void hide() {
// TODO Auto-generated method stub
}
#Override
public void pause() {
// TODO Auto-generated method stub
}
#Override
public void resume() {
// TODO Auto-generated method stub
}
#Override
public void dispose() {
// TODO Auto-generated method stub
}
#Override
public boolean keyDown(int keycode) {
switch (keycode) {
case Keys.DOWN:
camera.translate(0, -1*speed);
player.moveDown();
break;
case Keys.UP:
camera.translate(0, speed);
player.moveUp();
break;
case Keys.LEFT:
camera.translate(-1*speed, 0);
player.moveLeft();
break;
case Keys.RIGHT:
camera.translate(speed, 0);
player.moveRight();
break;
}
return false;
}
#Override
public boolean keyUp(int keycode) {
return false;
}
#Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}
and here is my player.draw function:
public void draw(SpriteBatch batch){
batch.draw(playerTexture, getPosX(), getPosY(), playerTexture.getWidth(), playerTexture.getHeight());
}
i just want to show a simple texture and move it on the screen. What is wrong above there? May you help me?
Regards Guys!
I solved my own problem, I just changed map renderer to OrthogonalTileMapRenderer, and changed SpriteBatch's with Batch of OrthogonalTileMapRenderer.
package com.adsiz.areyoualive.screen;
import com.adsiz.areyoualive.game.Player;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.maps.tiled.*;
import com.badlogic.gdx.maps.tiled.renderers.OrthogonalTiledMapRenderer;
public class PlayScreen implements Screen, InputProcessor{
public ScreenManager screenManager;
public static float speed = 32;
//tilemap & camera
TiledMap tiledMap;
OrthographicCamera camera;
OrthogonalTiledMapRenderer renderer;
//player
Player player;
public PlayScreen(){
float w = Gdx.graphics.getWidth();
float h = Gdx.graphics.getHeight();
camera = new OrthographicCamera();
camera.setToOrtho(false, w, h);
camera.update();
tiledMap = new TmxMapLoader().load("map/untitled.tmx");
renderer = new OrthogonalTiledMapRenderer(tiledMap);
camera.position.set(0, 3200, 0);
Gdx.input.setInputProcessor(this);
player = new Player(0, 3200);
}
#Override
public void render(float delta) {
Gdx.graphics.getGL20().glClearColor( 1, 1, 1, 1 );
Gdx.gl.glBlendFunc(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
Gdx.graphics.getGL20().glClear( GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT );
camera.update();
renderer.setView(camera);
renderer.render();
renderer.getSpriteBatch().begin();
player.draw(renderer.getSpriteBatch());
renderer.getSpriteBatch().end();
}
I would like some suggestions for the implementation object of the player.
the player can have 2 textures that will be chosen depending on the button pressed, for example, the right arrow will display a texture to the left while another texture.
I have implemented the interface inputprocessor in the class of player but I do not know why it does not seem very fair and very dynamic, so I would like some suggestions from you
thank you very much
CODE:
public class Player implements InputProcessor {
private Texture up;
private Texture down;
private Sprite player;
public Player(Texture one,Texture two){
this.up=one;
this.down=two;
player=new Sprite(one);
}
#Override
public boolean keyDown(int keycode) {
// TODO Auto-generated method stub
player.setTexture(this.down);
return false;
}
#Override
public boolean keyUp(int keycode) {
// TODO Auto-generated method stub
player.setTexture(this.up);
return false;
}
#Override
public boolean keyTyped(char character) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
// TODO Auto-generated method stub
return false;
}
#Override
public boolean scrolled(int amount) {
// TODO Auto-generated method stub
return false;
}
}
I implement the player class in this way, but I would like some suggestions for implementing best.
I'd suggest you to subclass very useful Sprite class and use TextureAtlas to contain player textures. here is the stub of implementation:
public class Player extends Sprite {
TextureAtlas textureAtlas;
public Player(TextureAtlas atlas) {
super(atlas.getRegions().get(0));
textureAtlas = atlas;
}
public void setTexture(String textureName) {
setRegion(textureAtlas.findRegion(textureName)));
}
}
Here is a very nice tutorial explaining how to use TextureAtlas.
Also, instead of implementing whole InputProcessor, use InputAdapter which provides an empty implementation of this interface. This will be much more clearer. It can be a field in your Player class:
private InputProcessor inputProcessor = new InputAdapter() {
// Override only methods you need here
};
Of course, don't forget to register this InputProcessor:
Gdx.input.setInputProcessor(inputProcessor);
I will update my answer with examples when i get home in a few hours.
It doesnt seem a good practice to listen for keys in the player class. I implemented a player class in my game some time ago and it was like this:
in the render method of your game class you implement key listeners, that invoke player.up() or player.down() or for example player.jump().
in player class in those methods, for example in jump() you set textures/animations.
I will post code examples.
public class Player {
float x;
float y;
float xSpeed;
float ySpeed;
private Animation playerRun;
private Animation playerJump;
private Animation playerStand;
private Animation current;
private Rectangle bounds;
public Player(){
playerRun = new Animation(1/10f, Assets.atlas.findRegions("run"));
playerRun.setPlayMode(Animation.PlayMode.LOOP);
//set other animations in similar way
current = playerStand;
this.x = Gdx.graphics.getWidth()/2;
this.y = Gdx.graphics.getHeight()/2;
bounds = new Rectangle(x, y, 100, 100);
}
public Rectangle getBounds(){
return bounds;
}
public void setPos(float x, float y){
this.x = x;
this.y = y;
bounds.x = x;
bounds.y = y;
}
public void changePos(float x, float y){
this.x +=x;
this.y +=y;
bounds.x += x;
bounds.y += y;
}
public void move(){
changePos(xSpeed, ySpeed);
}
public Animation animate(){
return current;
}
public void run(){
current = playerRun;
ySpeed = 0;
}
public void jump(){
current = playerJump;
ySpeed = 10;
}
and the render method in my game class was only calling players methods:
if (Gdx.input.isTouched()){
player.jump();
}
oops, forgot the most important part :
batch.draw(player.animate().getKeyFrame(time += delta), player.x, player.y);