Please help me. I want that when pressing the left part of the screen the model moved to the left, and when pressing the right part of the screen, model moved to the right.
InputHandler class
public class InputHandler implements InputProcessor {
private Bird myBird;
//
public InputHandler(Bird bird) {
// myBird and bird
myBird = bird;
}
#Override
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
myBird.onClick();
return true;
}
#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 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;
}
Bird class
public class Bird {
private Vector2 position;
private Vector2 velocity;
private Vector2 acceleration;
private float rotation; // For handling bird rotation
private int width;
private int height;
public Bird(float x, float y, int width, int height) {
this.width = width;
this.height = height;
position = new Vector2(230, 650);
velocity = new Vector2(0, 0);
acceleration = new Vector2(200, 0);
}
public void update(float delta) {
velocity.add(acceleration.cpy().scl(delta));
if (velocity.x > 200) {
velocity.x = 200;
}
position.add(velocity.cpy().scl(delta));
// Turn
/*if (velocity.y < 0) {
rotation -= 600 * delta;
if (rotation < -20) {
rotation = -20;
}
}*/
/* Turn
if (isFalling()) {
rotation += 480 * delta;
if (rotation > 90) {
rotation = 90;
}
}*/
}
/*public boolean isFalling() {
return velocity.y > 110;
}*/
public void onClick() {
velocity.x = -140;
}
public float getX() {
return position.x;
}
public float getY() {
return position.y;
}
public float getWidth() {
return width;
}
public float getHeight() {
return height;
}
public float getRotation() {
return rotation;
}
Change your touchDown code to this and remove the comment tags
public boolean touchDown(int screenX, int screenY, int pointer, int button) {
if (screenX < WIDTH_OF_SCREEN / 2) {
myBird.setLeftMove(true);
} else {
myBird.setRightMove(true);
}
return true;
}
and then change your touchUp code to this
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
myBird.setLeftMove(false);
myBird.setRightMove(false);
return true;
}
You will need to replace the WIDTH_OF_SCREEN with the width of your screen. What this will do is it will check to see where the screen was pressed, the left being less than half the screen and the right being more than half the screen. When the finger is lifted it will stop moving them to the left and right.
Related
I'm new in Libgdx and I'm trying to make a map that can be explored using Camera. Fo that I implements GestureListener in my own Map class.
public class Map extends Stage implements GestureListener {
public String mapName;
private Sprite background;
public LocationPoint points[];
private OrthographicCamera camera;
private Batch batch;
public Music anbientSound;
public int numOfPoints;
public int locationsX[];
public int locationsY[];
public Map(Sprite background) {
this.background = background;
}
public Sprite getBackground() {
return background;
}
public void activate() {
InputMultiplexer inputChain = new InputMultiplexer();
if(points==null) {
points = new LocationPoint[numOfPoints];
for(int i = 0; i < numOfPoints; i++) {
points[i] = new LocationPoint(locationsX[i], locationsY[i]);
addActor(points[i]);
}
}
batch = GameUtils.batch;
camera = new OrthographicCamera(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
camera.position.set(camera.viewportWidth/2, camera.viewportHeight/2, 0);
camera.update();
Music music = GameUtils.addMusic(anbientSound);
music.setLooping(true);
music.play();
inputChain.addProcessor(this);
inputChain.addProcessor(new GestureDetector(this));
Gdx.input.setInputProcessor(inputChain);
}
public void draw() {
Gdx.gl20.glClearColor(0, 0, 0, 1);
Gdx.gl20.glClear(Gdx.gl20.GL_COLOR_BUFFER_BIT);
Batch batch = this.batch;
batch.setProjectionMatrix(camera.combined);
batch.begin();
background.draw(batch);
batch.end();
batch.begin();
for(int i = 0; i < numOfPoints; i++) {
points[i].draw(batch, 1);
addActor(points[i]);
}
batch.end();
}
public void dispose() {
GameUtils.stopMusic();
background.getTexture().dispose();
anbientSound.dispose();
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
camera.translate(-deltaX, deltaY);
float initialX = camera.viewportWidth / 2;
float initialY = camera.viewportHeight / 2;
GameUtils.limitBound(camera, initialX, initialY, background.getWidth(), background.getHeight());
camera.update();
return true;
}
#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 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() {}
}
The method activate() is used to activate the resources of the Map class. The class Map also have a ImageButtons called LocationPoints.
public class LocationPoint extends ImageButton {
private Monster monster;
private Trap trap;
public boolean occuped;
public boolean isTrap;
public int f = 20;
public int k = 20;
public LocationPoint(float x, float y) {
super(GameUtils.getLocationDrawable());
this.setSize(46, 46);
setPosition(x, y);
addListener(new InputListener(){
#Override
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
setPosition(f, k);
f += 10;
k += 10;
return super.touchDown(event, x, y, pointer, button);
}
});
}
public void occup(Monster monster) {
this.monster = monster;
occuped = true;
if(isTrap)
captured();
}
#Override
public void draw(Batch batch, float parentAlpha) {
super.draw(batch, parentAlpha);
}
public void empty() {
monster = null;
occuped = false;
}
public void captured() {
monster.capture();
}
public Monster getMonster() {
return monster;
}
}
In LocationPoint class I add a InputListener to make a thing when that LocationPoint is touched.
When a play the game on android both LocationPoints event and the Map pan event. But after I move the camera, when I touch on LocationPoint it don't fires that point event.
But when I return the camera to initial position the LocationPoints events works fine! Can you help me? (And sorry for my broken english...)
Actor is already a child so remove redundant call from draw() method.
for(int i = 0; i < numOfPoints; i++) {
points[i].draw(batch, 1);
addActor(points[i]); // <-- Not Should be in draw() call
}
Stage having own SpriteBatch that created by default constructor, use that one or pass own batch in Stage constructor.
Use getBatch() method of Stage if you want to draw something by yourself.
Creating camera in Map class also redundant, use getViewport().getCamera() that return camera of stage, you can typecast to OrthographicCamera
call super.dispose(); inside your dispose() method
Drawing all your Actor by yourself ? If you're not doing something beyond the scope, no need to override draw() method of Stage.
So i want it so that when user is touching the screen, the object follows the x-axis of the touchpos. When I'm doing this with polling (Gdx.input.getX()) it works like it has to. But with input processor, when touching on the screen, the object goes crazy all over the screen. I dont really get why. Here is the code
Player.java :
public class Player extends Entity
{
MyInputProcessor input;
public Player(float x, float y, Sprite sprite)
{
super(x, y, sprite);
input = new MyInputProcessor();
Gdx.input.setInputProcessor(input);
}
public void update(final Application app)
{
handleInput(app);
super.update();
}
public void handleInput(Application app)
{
if (input.touchDown)
{
Vector2 touchPos = app.viewport.unproject(input.screenTouchPos);
position.x = touchPos.x - sprite.getWidth() / 2;
}
}
}
MyInputProcessor.java :
public class MyInputProcessor implements InputProcessor
{
public boolean touchDown = false;
public Vector2 screenTouchPos;
public MyInputProcessor()
{
screenTouchPos = new Vector2();
}
#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 touchDown(int screenX, int screenY, int pointer, int button)
{
touchDown = true;
screenTouchPos.set(screenX, screenY);
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button)
{
touchDown = false;
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;
}
}
This line
Vector2 touchPos = app.viewport.unproject(input.screenTouchPos);
does not provide you a copy of the unprojected vector. It is modifying the input Vector2 and handing you back the same reference. Since your input processor only resets its Vector2 when you touch down, then as long as you hold your finger down, your Player class will unproject the same vector on every frame. Calling unproject on the same vector more than once will obviously start producing garbage results.
So instead, keep your own extra Vector 2 handy for this.
private final Vector2 unprojectedTouchPos = new Vector2();
Then copy the touch position vector into this vector on each frame and use this one instead:
public void handleInput(Application app)
{
if (input.touchDown)
{
unprojectedTouchPos.set(input.screenTouchPos);
app.viewport.unproject(unprojectedTouchPos);
position.x = unprojectedTouchPos.x - sprite.getWidth() / 2;
}
}
Edit:
Based on your comments, you also want the position to update in real-time as the finger drags, so add this to your InputProcessor's touchDragged method:
screenTouchPos.set(screenX, screenY);
What the title says basically.
The jump worked perfectly until I decided to make my game more object-oriented by adding a GameObject class. The sprite should jump whenever you tap the screen (added a print statement in jump() to verify that this method DOES get called). Can anyone spot the mistake?
The way I've coded the jump:
player is constantly decelerating until he reaches the ground
if the screen is tapped, the players ySpeed is increased by accelerationJump, then decreased slowly by g while he's in the air
Player:
public class Player extends GameObject implements InputProcessor {
private float g;
private float accelerationJump = 9f;
private boolean allowJump = true;
public Player(Sprite spr) {
super(spr);
setxPos(0);
setyPos(getHeight() / 6);
setxSpeed(5.5f);
setySpeed(0);
spr.setX(getxPos());
spr.setY(getyPos());
g = 0.2f;
accelerationX = 0.02f;
}
public void update() {
setySpeed(-g);
//have the sprite constantly moving
moveBy(getxSpeed(), getySpeed());
//if sprite reaches end of screen, move it to the start of the screen again
if (getxPos() > getWidth()) {
setxPos(0);
}
if (getyPos() < getHeight() / 6) {
moveTo(getSprite().getX(), getHeight() / 6);
}
//the player can only jump if he is on the ground. once player is on the ground, he must stop decelerating
if (onGround()) {
allowJump = true;
setySpeed(0);
}
}
public void jump() {
System.out.println("dasdasddadsdasd");
setySpeed(getySpeed() + accelerationJump);
}
// checks whether or not player is on the ground
public boolean onGround() {
return (getSprite().getY() == getHeight() / 6);
}
#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 touchDown(int screenX, int screenY, int pointer, int button) {
return true;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
//if (allowJump && isDragged == false) {
//System.out.println("dsdasdasd");
if(allowJump){
allowJump = false;
jump();
}
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
/*if (isDragged == false) {
isDragged = true;
}*/
return false;
}
#Override
public boolean mouseMoved(int screenX, int screenY) {
return false;
}
#Override
public boolean scrolled(int amount) {
return false;
}
}
GameObject
public abstract class GameObject {
private Sprite spr;
private float xSpeed;
private float ySpeed;
public GameObject(Sprite spr) {
this.spr=spr;
}
public void moveTo(float xPos2, float yPos2) {
setxPos(xPos2);
setyPos(yPos2);
}
public void moveBy(float dx, float dy) {
spr.setY(spr.getY() + dy);
spr.setX(spr.getX() + dx);
}
public float getxPos() {
return spr.getX();
}
public float getyPos() {
return spr.getY();
}
public void setxPos(float xPos2) {
spr.setX(xPos2);
}
public void setyPos(float yPos) {
spr.setY(yPos);
}
public float getxSpeed() {
return xSpeed;
}
public float getySpeed() {
return ySpeed;
}
public void setxSpeed(float xSpeed2) {
xSpeed = xSpeed2;
}
public void setySpeed(float ySpeed2) {
ySpeed = ySpeed2;
}
public int getWidth() {
return Gdx.graphics.getWidth();
}
public int getHeight() {
return Gdx.graphics.getHeight();
}
public void draw(SpriteBatch batch) {
spr.draw(batch);
}
public Sprite getSprite() {
return spr;
}
}
Any help is HIGHLY appreciated.
You are setting ySpeed to -g every update()
I am trying to create a simple app which allows you to load 3d model from .obj and zoom/rotate it by touching the screen.
I managed to write code which loads 3d model from file and detect gestures but now I am not sure what to do to enable zoom/rotate features by touching the screen.
Here is my code for now:
public class RenderObjApp implements ApplicationListener, GestureDetector.GestureListener {
public static int SCREEN_WIDTH = 800;
public static int SCREEN_HEIGHT = 600;
private static final String TAG = RenderObjApp.class.getSimpleName();
private Mesh model;
private PerspectiveCamera camera;
private float scale = 1f;
#Override
public void create() {
model = ObjLoader.loadObj(Gdx.files.internal("data/cessna.obj").read(), true);
Gdx.gl.glEnable(GL10.GL_DEPTH_TEST);
Gdx.input.setInputProcessor(new GestureDetector(this));
}
#Override
public void dispose() {
}
#Override
public void pause() {
}
#Override
public void render() {
Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT);
camera.update();
camera.apply(Gdx.gl10);
model.render(GL10.GL_TRIANGLES);
}
#Override
public void resize(int arg0, int arg1) {
float aspectRatio = (float) arg0 / (float) arg1;
camera = new PerspectiveCamera(75, 2f * aspectRatio, 2f);
camera.near = 0.1f;
camera.translate(0, 0, 0);
}
#Override
public void resume() {
}
#Override
public boolean touchDown(float x, float y, int pointer) {
Gdx.app.log(TAG, "touchDown: ");
return false;
}
#Override
public boolean tap(float x, float y, int count, int pointer, int button) {
Gdx.app.log(TAG, "tap: ");
return false;
}
#Override
public boolean longPress(float x, float y) {
Gdx.app.log(TAG, "zoom: ");
return false;
}
#Override
public boolean fling(float velocityX, float velocityY, int pointer, int button) {
Gdx.app.log(TAG, "fling: ");
return false;
}
#Override
public boolean pan(float x, float y, float deltaX, float deltaY) {
Gdx.app.log(TAG, "pan: ");
return false;
}
#Override
public boolean zoom(float initialDistance, float distance) {
Gdx.app.log(TAG, "zoom: initialDistance=" + initialDistance + ", distance=" + distance);
return false;
}
#Override
public boolean pinch(Vector2 initialPointer1, Vector2 initialPointer2, Vector2 pointer1, Vector2 pointer2) {
Gdx.app.log(TAG, "pinch: ");
return false;
}
}
So I am looking how to rotate the PerspectiveCamera and Mesh itself.
I have been working on a "Blender-style" camera that has pinch-to-zoom capability as well as (on desktop) most of the functionality you get with Blender's camera. It is a work in progress — it doesn't perfectly imitate the behavior of Blender's camera (yet). I think this will get you pointed in the right direction. Some things you should know:
You may have to translate your model so it sits on the origin. The camera remains pointed at the origin unless you translate it. (You can only translate on desktop and not on android so far);
I got most of the pinch-to-zoom handling code here: https://code.google.com/p/libgdx-users/wiki/PinchToZoom.
Sorry for the magic numbers. I will make those constants in the future.
If you or anyone else improves this code, I would love if you shared a copy with me.
The Abstract class:
/* Author: Christopher Grabowski, yourchristopher6334 gmail.com */
package ...;
import com.badlogic.gdx.InputProcessor;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.input.GestureDetector.GestureListener;
import com.badlogic.gdx.math.Vector2;
abstract public class ControllableCamera extends PerspectiveCamera implements InputProcessor{
abstract public void resize(int width, int height);
abstract public void render();
public ControllableCamera(int fieldOfView, int width, int height) {
super(fieldOfView, width, height);
}
#Override
public boolean keyDown(int keyCode) {
return false;
}
#Override
public boolean keyTyped(char arg0) {
return false;
}
#Override
public boolean keyUp(int arg0) {
return false;
}
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
return false;
}
#Override
public boolean touchDragged(int screenX, int screenY, int pointer) {
return false;
}
#Override
public boolean touchUp(int x, int y, int pointer, int button) {
return false;
}
#Override
public boolean mouseMoved(int arg0, int arg1) {
return false;
}
#Override
public boolean scrolled(int direction) {
return false;
}
}
The concrete class:
/* Author: Christopher Grabowski, yourchristopher6334 gmail.com */
package ...;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.math.Vector3;
/*
* the pause, resize, and render methods must be called within their corresponding
* methods in the ApplicationListener
*/
public class BlenderStyleCamera extends ControllableCamera {
public static final Vector3 ORIGIN = new Vector3(0, 0, 0);
private static boolean shiftIsPressed = false, controlIsPressed = false,
isScrollingUp = false, isScrollingDown = false,
isSingleTouched = false, justSingleTouched = false;
private float aspectRatio;
private int x = -1, y = -1;
private float dx = 0.0f, dy = 0.0f;
private final Vector3 tmp = new Vector3();
// fields related to pinch-to-zoom
private int numberOfFingers = 0;
private int fingerOnePointer;
private int fingerTwoPointer;
private float lastDistance = 0;
private final Vector3 fingerOne = new Vector3();
private final Vector3 fingerTwo = new Vector3();
public BlenderStyleCamera(int fieldOfView, int width, int height) {
super(fieldOfView, width, height);
aspectRatio = viewportHeight / viewportWidth;
Gdx.input.setInputProcessor(this);
up.set(0.0f, 1.0f, 0.0f);
position.set(0.0f, 0.0f, 30.0f);
far = 300.0f;
lookAt(0, 0, 0);
translate(0.0f, 0.0f, 2.1f);
lookAt(0, 0, 0);
update();
}
public void pause() {
numberOfFingers = 0;
}
#Override
public void resize(int width, int height) {
viewportWidth = width;
viewportHeight = height;
aspectRatio = viewportHeight / viewportWidth;
update();
}
#Override
public void render() {
if (isSingleTouched) {
// This gets the change in touch position and
// compensates for the aspect ratio.
if (x == -1 || y == -1 || justSingleTouched) {
x = Gdx.input.getX();
y = Gdx.input.getY();
} else {
dx = (x - Gdx.input.getX());
dy = (y - Gdx.input.getY()) / aspectRatio;
}
// This zooms when control is pressed.
if (controlIsPressed && dy > 0) {
scrollIn();
} else if (controlIsPressed && dy < 0) {
scrollOut();
}
// This translates the camera blender-style
// if shift is pressed.
// Note that this will look weird with a
// perspective camera.
else if (shiftIsPressed) {
translateTangentially();
}
// Default is to rotate the object
// (actually rotate the camera about a sphere
// that surrounds the object).
else {
travelAround();
}
x = Gdx.input.getX();
y = Gdx.input.getY();
justSingleTouched = false;
}
// this zooms when the mouse wheel is rotated
if (isScrollingUp) {
scrollIn();
isScrollingUp = false;
} else if (isScrollingDown) {
scrollOut();
isScrollingDown = false;
}
// Some key controls
if (Gdx.input.isKeyPressed(Keys.LEFT) || Gdx.input.isKeyPressed(Keys.A)) {
translateTangentially(1, 0);
} else if (Gdx.input.isKeyPressed(Keys.RIGHT)
|| Gdx.input.isKeyPressed(Keys.D)) {
translateTangentially(-1, 0);
}
if (Gdx.input.isKeyPressed(Keys.UP) || Gdx.input.isKeyPressed(Keys.W)) {
translateTangentially(0, 1);
} else if (Gdx.input.isKeyPressed(Keys.DOWN)
|| Gdx.input.isKeyPressed(Keys.S)) {
translateTangentially(0, -1);
}
update();
}
// These methods create the pinch zoom
// and set some flags for logic in render method.
#Override
public boolean touchDown(int x, int y, int pointer, int button) {
// for pinch-to-zoom
numberOfFingers++;
if (numberOfFingers == 1) {
isSingleTouched = true;
justSingleTouched = true;
fingerOnePointer = pointer;
fingerOne.set(x, y, 0);
} else if (numberOfFingers == 2) {
isSingleTouched = false;
fingerTwoPointer = pointer;
fingerTwo.set(x, y, 0);
float distance = fingerOne.dst(fingerTwo);
lastDistance = distance;
}
return true;
}
#Override
public boolean touchDragged(int x, int y, int pointer) {
if (numberOfFingers > 1) {
if (pointer == fingerOnePointer) {
fingerOne.set(x, y, 0);
}
if (pointer == fingerTwoPointer) {
fingerTwo.set(x, y, 0);
}
float distance = fingerOne.dst(fingerTwo);
if (lastDistance > distance) {
scrollOut();
} else if (lastDistance < distance) {
scrollIn();
}
lastDistance = distance;
update();
}
return true;
}
#Override
public boolean touchUp(int x, int y, int pointer, int button) {
isSingleTouched = false;
if (numberOfFingers == 1) {
Vector3 touchPoint = new Vector3(x, y, 0);
unproject(touchPoint);
}
numberOfFingers--;
// just some error prevention... clamping number of fingers (ouch! :-)
if (numberOfFingers < 0) {
numberOfFingers = 0;
}
lastDistance = 0;
return false;
}
// These methods set flags for logic in render method.
#Override
public boolean keyDown(int keycode) {
switch (keycode) {
case (Keys.SHIFT_LEFT):
case (Keys.SHIFT_RIGHT):
shiftIsPressed = true;
break;
case (Keys.CONTROL_LEFT):
case (Keys.CONTROL_RIGHT):
controlIsPressed = true;
break;
case (Keys.O):
this.up.set(0.0f, 1.0f, 0.0f);
this.position.set(0.0f, 0.0f, 30.0f);
this.lookAt(0, 0, 0);
this.update();
}
return true;
}
#Override
public boolean keyUp(int arg0) {
shiftIsPressed = controlIsPressed = false;
return true;
}
#Override
public boolean scrolled(int direction) {
if (direction == -1) {
isScrollingUp = true;
} else if (direction == 1) {
isScrollingDown = true;
}
return true;
}
// The rest of the methods translate the camera.
public void scrollIn() {
float magnitude = 1.0f;
scrollIn(magnitude);
}
public void scrollIn(float magnitude) {
if (position.dst2(ORIGIN) > 2.0f) {
tmp.set(position);
tmp.nor();
this.translate(-tmp.x * magnitude, -tmp.y * magnitude, -tmp.z
* magnitude);
update();
}
}
public void scrollOut() {
float magnitude = 1.0f;
scrollOut(magnitude);
}
public void scrollOut(float magnitude) {
tmp.set(position);
tmp.nor();
this.translate(tmp.x * magnitude, tmp.y * magnitude, tmp.z * magnitude);
update();
}
private void travelAround() {
tmp.set(up);
rotateAround(ORIGIN, tmp, dx);
tmp.crs(position).nor();
rotateAround(ORIGIN, tmp, dy);
}
private void translateTangentially() {
translateTangentially(dx, dy);
}
private void translateTangentially(float dx, float dy) {
tmp.set(up);
tmp.crs(position);
if (dx > 0) {
translate(tmp.x / 15.0f, tmp.y / 15.0f, tmp.z / 15.0f);
} else if (dx < 0) {
translate(-tmp.x / 15.0f, -tmp.y / 15.0f, -tmp.z / 15.0f);
}
if (dy > 0) {
translate(-up.x, -up.y, -up.z);
} else if (dy < 0) {
translate(up);
}
}
}
Please take a look at this: Mesh rendering issue libgdx.
Method render contains the code you need.
You either need to rotate the camera, or rotate the model.
I believe the libGDX Camera.rotateAround method does what you need. Leave the "point" as the center of your model and set the "axis" parameter based on which way the user is flinging/panning. The "angle" can either be a fixed value, or relative to the intensity of the fling/pan.
So in my Gameplay screen user has posibillity to click on menu button and then that menu button will pause the game and show the menu.
I tried to impelement menu as a new stage, but that just opens a new screen, sets the graphics of the menu like I want to and leaves the rest of the screen black.
Here's the image so you can see what I'm talking about:
I want this green part to smoothly slide into Gameplay scene and I wan't to get rid of this black part of the screen and instead leave that part transparent (I want it to show only the green part of a Image).
Tried to find some good tutorials about pause menus, but no luck.
Here's the code of my pause screen:
public class Menu implements Screen{
Stage menuStage = null;
private Image menu_bg = null;
private Main game = null;
public Menu(Main gm){
game = gm;
}
#Override
public void show() {
menuStage = new Stage(new StretchViewport(1920, 1080));
Gdx.input.setInputProcessor(menuStage);
menu_bg = new Image(new Texture(Gdx.files.internal("menuProba.png")));
menuStage.addActor(menu_bg);
menuButtons();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
menuStage.draw();
menuStage.act();
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
}
private void menuButtons(){
Table menuButtons = new Table();
menuButtons.setFillParent(true);
final Image resumeGame = new Image(new Texture(Gdx.files.internal("playbutton.png")));
final Image retryGame = new Image(new Texture(Gdx.files.internal("retrybutton.png")));
final Image homeButton = new Image(new Texture(Gdx.files.internal("homebutton.png")));
final Image exitButton = new Image(new Texture(Gdx.files.internal("exitbutton.png")));
resumeGame.addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
resumeGame.addAction(Actions.scaleTo(1, 1.1f,.1f));
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button){
resumeGame.addAction(Actions.scaleTo(1, 1,.1f));
}
});
retryGame.addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
retryGame.addAction(Actions.scaleTo(1, 1.1f,.1f));
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button){
retryGame.addAction(Actions.scaleTo(1, 1,.1f));
}
});
homeButton.addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
homeButton.addAction(Actions.scaleTo(1, 1.1f,.1f));
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button){
homeButton.addAction(Actions.scaleTo(1, 1,.1f));
game.setScreen(new MainMenu(game));
}
});
exitButton.addListener(new InputListener() {
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
exitButton.addAction(Actions.scaleTo(1, 1.1f,.1f));
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button){
exitButton.addAction(Actions.scaleTo(1, 1,.1f));
}
});
/*HorizontalGroup horizontalGroup = new HorizontalGroup();
horizontalGroup.addActor(resumeGame);
horizontalGroup.addActor(retryGame);
horizontalGroup.addActor(homeButton);
horizontalGroup.addActor(exitButton);
menuButtons.add(horizontalGroup);*/
menuButtons.add(resumeGame).expand().left().padLeft(40);
menuButtons.row();
menuButtons.add(retryGame).expand().left().padLeft(40);
menuButtons.row();
menuButtons.add(homeButton).expand().left().padLeft(40);
menuButtons.row();
menuButtons.add(exitButton).expand().left().padLeft(40);
menuStage.addActor(menuButtons);
}
}
And the Gameplay screen:
public class GameScreen implements Screen, InputProcessor {
boolean menuScreen;
private Texture menuImage = null;
public boolean buttonMenuTouched = false;
public InputMultiplexer multiplexer = null;
BitmapFont font;
//SCORE-------------------------------------
private SpriteBatch batch = null;
private OrthographicCamera mCamera = null;
private BitmapFont scoreFont = null;
private int score = 0;
//--------------------------------------------
Main game = null;
public Texture font_texture;
public GameScreen(Main gm){
game = gm;
}
Stage gameStage = null;
private Image game_bg = null, menu_bg = null;
private GameManager manager = null;
#Override
public void show() {
mCamera = new OrthographicCamera(1920, 1080);
font_texture = new Texture(Gdx.files.internal("font.png"));
font_texture.setFilter(Texture.TextureFilter.Linear, Texture.TextureFilter.Linear);
scoreFont = new BitmapFont(Gdx.files.internal("font.fnt"), new TextureRegion(font_texture), false);
batch = new SpriteBatch();
multiplexer = new InputMultiplexer();
gameStage = new Stage(new StretchViewport(1920, 1080));
multiplexer.addProcessor(this);
multiplexer.addProcessor(gameStage);
Gdx.input.setInputProcessor(multiplexer);
game_bg = new Image(new Texture(Gdx.files.internal("pozadinaGameScreen.png")));
gameStage.addActor(game_bg);
menuImage = new Texture("menuProba.png");
manager = new GameManager(game, this, gameStage);
manager.createPlayer();
manager.createBlueMonster();
manager.createHUDButtons();
manager.createGameOverStage();
gameScreenButtoni();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
gameStage.draw();
gameStage.act();
manager.checkButtons();
manager.checkCollisions();
batch.setProjectionMatrix(mCamera.combined);
batch.begin();
this.scoreFont.draw(batch, ""+manager.score, Gdx.graphics.getWidth() - 1070, Gdx.graphics.getHeight() - 580);
batch.end();
if (manager.gameOver == true){
manager.gameOverStage.draw();
manager.gameOverStage.act();
Gdx.input.setInputProcessor(manager.gameOverStage);
}
}
#Override
public void resize(int width, int height) {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void hide() {
}
#Override
public void dispose() {
manager.gameOverStage.dispose();
gameStage.dispose();
manager.dispose();
game.setScreen(game.mainMenu);
}
// METODE INPUT PROCESORA
#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 touchDown(int screenX, int screenY, int pointer, int button) {
return false;
}
#Override
public boolean touchUp(int screenX, int screenY, int pointer, int button) {
manager.shootBullet();
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;
}
public void gameScreenButtoni(){
//menuImage = new Image(new Texture(Gdx.files.internal("menuProba.png")));
Table buttoni = new Table();
buttoni.setFillParent(true);
final Image menuButton = new Image(new Texture(Gdx.files.internal("menubutton.png")));
menuButton.addListener(new InputListener(){
public boolean touchDown (InputEvent event, float x, float y, int pointer, int button){
menuButton.addAction(Actions.scaleTo(1, 1.1f,.1f));
buttonMenuTouched = true;
return true;
}
public void touchUp (InputEvent event, float x, float y, int pointer, int button){
menuButton.addAction(Actions.scaleTo(1, 1,.1f));
buttonMenuTouched = false;
game.setScreen(new Menu(game));
}
});
final Image scoreText = new Image(new Texture(Gdx.files.internal("score.png")));
buttoni.add(menuButton).expand().top().left().padLeft(20).padTop(20);
buttoni.add(scoreText).expand().top().right().padTop(30).padRight(140);
gameStage.addActor(buttoni);
}
public void menuScreen(){
Stage menu = new Stage(new StretchViewport(400,400));
menu_bg = new Image(new Texture(Gdx.files.internal("logoMali.png")));
menu.addActor(menu_bg);
}
}
I know that I'm doing this wrong, but how should I do it? Draw a rectangle when button is pressed or what?
In my game I make NavigationDrawer in libgdx as you can see:
You can make this with sample code, just follow a few steps:
1- Copy NavigationDrawer class into your project:
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.utils.Timer;
import com.badlogic.gdx.utils.Timer.Task;
/**
* Created by Crowni on 10/6/2015.
*/
public class NavigationDrawer {
// this value is suitable
private static final float INTERVAL_SEC = 0.001f;
// Some attributes for {#link NavigationDrawer}
private static float CAM_MAIN_POSITION;
public static float WIDTH;
public static float SPEED;
private static OrthographicCamera camera;
/**
* To ensure the {#link NavigationDrawerListener#onFinish()} called one time
**/
private static boolean isFinish = true;
private static Task task;
private static Timer timer = new Timer();
private static NavigationDrawerListener listener;
public interface NavigationDrawerListener {
public void onStart();
// May be you want to make some Actions here during sliding
public void onRun();
public void onFinish(float camX);
}
public static void initialize(Stage stage, NavigationDrawerListener listener) {
NavigationDrawer.listener = listener;
camera = ((OrthographicCamera) stage.getCamera());
setNavigationDrawerDefault(stage);
initializeTimerTask(false);
}
private static void setNavigationDrawerDefault(Stage stage) {
WIDTH = stage.getWidth() - stage.getWidth() / 3;
CAM_MAIN_POSITION = stage.getWidth() / 2;
SPEED = 2f;
}
private static Task initializeTimerTask(boolean show) {
task = new Task() {
public void run() {
if (!timer.isEmpty()) {
if (show)
camera.position.x -= SPEED;
else
camera.position.x += SPEED;
listener.onRun();
} else if (isFinish) {
listener.onFinish(setDefaultCameraEndPostion(show));
}
}
};
return task;
}
/**
* #param show
* : I passed it here because I know it is correct choice
**/
private static float setDefaultCameraEndPostion(boolean show) {
isFinish = false;
if (show)
return camera.position.x = CAM_MAIN_POSITION - WIDTH;
else
return camera.position.x = CAM_MAIN_POSITION;
}
private static boolean isOpened() {
return camera.position.x != CAM_MAIN_POSITION;
}
public static void show(boolean show) {
if ((isOpened() && !show) || (!isOpened() && show))
startTask(show);
}
private static void startTask(boolean show) {
if (timer.isEmpty()) {
isFinish = true;
listener.onStart();
timer.scheduleTask(initializeTimerTask(show), 0f, INTERVAL_SEC,
((int) (WIDTH / SPEED)));
}
}
}
2- In your Screen write the following:
#Override
public void show() {
stage = new Stage(new StretchViewport(1080, 1920));
// May be you want to make some Actions with NavigationDrawer state
NavigationDrawerListener listener = new NavigationDrawerListener() {
#Override
public void onStart() {
System.out.println("onStart");
}
#Override
public void onRun() {
System.out.println("onRun");
}
#Override
public void onFinish(float camX) {
System.out.println("onFinish: " + camX);
}
};
// You must be initialize NavigationDrawer Firstly
NavigationDrawer.initialize(stage, listener);
// This image is sample to show how navigationDrawer look like on the screen
Image background= new Image(new Texture(Gdx.files.internal("background.jpg")));
background.addListener(new ClickListener() {
private int clicked = 0;
public void clicked(InputEvent event, float x, float y) {
if (clicked % 2 == 0) {
clicked++;
NavigationDrawer.show(true);
} else {
clicked++;
NavigationDrawer.show(false);
}
}
});
background.setFillParent(true);
stage.addActor(background);
Gdx.input.setInputProcessor(stage);
}
3- The result of sample code look like that:
4- Finally you can create images, labels, ... actors in navigation width which their positions into off-screen i.e. with negative positions. Enjoy!
UPDATE
This Navigation Drawer More performance and beauty sliding.