This question already has answers here:
Best way to detect the touched object (moving) from collection in libgdx
(2 answers)
Closed 8 years ago.
I started using libGDX soon, and I was making a game that has water droplets falling from the top of the screen and the user should tap them before they do touch the bottom of the screen. I have a problem in knowing if the user did tap the droplet to do something.
This is my Render method:
Gdx.gl.glClearColor(0/255.0f, 0/255.0f, 100/255.0f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
cam.update();
if (TimeUtils.millis() - lastDrop > 333)
spawnRainDrop();
Iterator<Rectangle> iter = raindrops.iterator();
while (iter.hasNext()) {
Rectangle raindrop = iter.next();
raindrop.y -= 300 * Gdx.graphics.getDeltaTime();
if (raindrop.y + 64 < 0) {
iter.remove();
}
if (Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
cam.unproject(touchPos);
if (Gdx.input.getX() == raindrop.x + 64 / 2 && Gdx.input.getY() == raindrop.y + 64 / 2) {
System.out.println("Tapped");
}
}
}
The tapping code doesn't seem to work.
I would really appreciate if someone did explain their answer.
Thanks
You are testing for touch at a single point and not in a bounding box around your object. Use the following to test for touch inside a bounding box:
if(Gdx.input.isTouched()) {
Vector3 touchPos = new Vector3();
cam.unproject(touchPos);
float halfWidth = 64 / 2.0f;
float halfHeight = 64 / 2.0f;
if( Gdx.input.getX() >= raindrop.x - halfWidth &&
Gdx.input.getX() <= raindrop.x + halfWidth &&
Gdx.input.getY() <= raindrop.y + halfHeight &&
Gdx.input.getY() >= raindrop.y - halfHeight ) {
System.out.println("Tapped");
}
}
I'm assuming a bottom/left origin so just change the signs accordingly if you use a different one.
In two dimensions, I used the following approach to detect where the player clicked: https://stackoverflow.com/a/24511980/2413303
But in your case, I think the problem is just that you used Gdx.input.getX() and Gdx.input.getY() instead of the coordinates you've obtained from cam.unproject(touchPos), according to this other answer on the same question: https://stackoverflow.com/a/24503526/2413303 .
Related
My problem is that when I press W and look like 45° to the right, I'm not moving into that direction, but mainly forward (I'm moving very slightly to the right). I looked up different resources which told me to do it the way I did. My current move code in my camera class looks as following:
[...]
var offsetZ = 0.0f
if(KeyboardInputHandler.isKeyDown(GLFW_KEY_W)) offsetZ -= speed
if(KeyboardInputHandler.isKeyDown(GLFW_KEY_S)) offsetZ += speed
if(offsetZ != 0.0f) {
position.x += -offsetZ * sin(degreeToRadiant(rotY))
position.z += offsetZ * cos(degreeToRadiant(rotY))
}
var offsetX = 0.0f
if(KeyboardInputHandler.isKeyDown(GLFW_KEY_A)) offsetX -= speed
if(KeyboardInputHandler.isKeyDown(GLFW_KEY_D)) offsetX += speed
if(offsetX != 0.0f) {
position.x += -offsetX * sin(degreeToRadiant(rotY - 90.0f))
position.z += offsetX * cos(degreeToRadiant(rotY - 90.0f))
}
[...]
How do I fix this issue?
Very stupid mistake from me: The rotY variable was already in radiant, so I basically put a radiant in a degreeToRadiant method, thats why it wasnt moving sideways.
I'm trying to rotate a TextureRegion around its centre, however whenever I try to rotate it the rotation point is either the bottom corners of the Texture Region or a far part of the screen.
this is the update method in my object class(the Texture Region will be emulating the movements of this Object.
public void update(float delta) {
if (velocity.x < 0) {
rotation -= 50*delta;
if (rotation > 25) {
rotation = 25;
}
}
if (velocity.x > 0){
rotation += 50*delta;
if (rotation > 25) {
rotation = 25;
}
}
}
this where I call the draw method to bring the Texture Region to screen
batcher.draw(AssetLoader.saum, sam.getX(), (gameHeight - (gameHeight / 3)), -(sam.getWidth()), (gameHeight - (gameHeight / 3)), -(sam.getWidth()), -(sam.getWidth()), 1, 1, sam.getRotation());
Use one of the batch.draw methods that has originX and originY parameters.
originX and originY should be set to width/2 and height/2.
See methods here.
I'm using Libgdx for a project and more precisely Box2DLights.
My problem is the following one : When I want to put a new "PointLight" it's always on the center of the screen. And if I change the coordinates, it doesn't work.
Inside my "show()" method :
Box2D.init();
world = new World(new Vector2(0, 0), true);
rh = new RayHandler(world);
rh.setAmbientLight(1.2f, 0.2f, 0.2f, 0.1f);
pl = new PointLight(rh, 100, new Color(1,1,1,1),(float) 0.5,0,0);
Inside my "render()" method :
Gdx.gl.glClearColor(0f, 0f, 0f, 1f);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
world.step(delta, 8, 3);
renderer.begin(ShapeType.Filled);
for (SolarSystem ss : solarSystemList)
{
if(ss.getColor() <= 15) colorSS = Color.YELLOW;
else if(ss.getColor() > 15 && ss.getColor() < 31) colorSS = Color.ORANGE;
else if(ss.getColor() > 30 && ss.getColor() < 46) colorSS = Color.RED;
else if(ss.getColor() > 45) colorSS = Color.CYAN;
renderer.setColor(colorSS);
renderer.circle(ss.getMapX(), ss.getMapY(), ss.getSize() - 3);
}
renderer.end();
rh.updateAndRender();
Result :
Now if I try to change coordinates :
pl = new PointLight(rh, 100, new Color(1,1,1,1),(float) 0.5, 50, 50);
... no light anymore
Do you know how it's possible to put the light where I want ?
EDIT : My screen size : width - 860px / height - 645px
if the (1,1) is the top right and the (0,0) is bottom left and the (0.5,0.5) is the middle of the screen, then i propose to do this :
insert the value that you want and divide it by the width and height of of your screen for example
( xPosition/Gdx.graphics.width, yPosition/Gdx.graphics.height )
Update :
sorry i didn't see that (0,0) was the center so i propse to you to use this instead :
width = Gdx.graphics.width;
height = Gdx.graphics.height;
((xPosition - width/2)/ width/2 , (yPosition - height/2)/ height/2)
Update 2 :
i think you are doing little arithmetic mistake assume that your
width = 860 and your height = 645 as you said
this is the equation :
x= ((xPosition - width/2)/ width/2)
y= (yPosition - height/2)/ height/2)
x = (50 - 860/2) / (860/2)
y = (50 - 645/2) / (645/2)
x = (50 - 430) / (430)
y = (50 - 322.5) / (322.5)
x = (50 - 430) / (430) = (-380) / (430)
y = (50 - 322.5) / (322.5) = (-272.5) / (322.5)
x = -0.88
y = -0.84
which is closer to (-1,-1) aka : the left bottom corner
hope it was helpful :)
If you take a distance of 0.5 and your light shines above half of the screen I just assume that a position of 50, 50 will not fit into this screen. Just try to change your position to a smaller value. Maybe your coordinates do not represent pixels but other units as it is recommended for box2d.
Edit: As I don't know your entire libgdx app I just recommend to have a deeper look into Camera, ViewPort and such. For example the box2dlights RayHandler can get your camera via setCombinedMatrix. You may also want to synchronize lights with bodies and the box2d world with your sprites.
So I am working on my first 3D project and everything went well till I decided to make the FPS character (camera) jump. I tried some methods and all of them didn't look well till I succeeded to do something that works most of the time. Now the problem is the "most of the time" - Which should be all the time.
The problem is that when I click the jump button continuously it starts to freak out. I tried to set the position always back to zero when I exceed it but it still freaks out sometimes although less often. Any suggestions how to do it in order for it to work all the time? (I am working with OpenGL and java without an engine)
The jumping part code:
if (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && !jumping
&& position.y >= temp) { //temp - floor height
jumping = true;
}
gravity = (float) ((walkingSpeed * 0.00003) * delta);//delta - time
//System.out.println(delta);
if (position.y < temp) { //In the air
speed = speed + gravity;
position.y = position.y + speed;
}
if (jumping) {
speed = speed - (float) ((walkingSpeed * 0.0006) * delta);
position.y = position.y + speed;
jumping = false;
}
if (position.y > temp) //**Supposed** to solve the problem
position.y = temp;
There are a number of issues in your code that don't synch up with what you are describing:
You have the sign reversed for virtually everything
You are testing for a condition that always evaluates to true (!jumping)
// Only start a jump while on the ground (position.y <= temp)
if (Keyboard.isKeyDown(Keyboard.KEY_SPACE) && position.y <= temp) {
speed = speed + (float) ((walkingSpeed * 0.0006));
// Don't care about the delta time when you jump, just add a fixed amount of
// positive vertical velocity (which gravity will work out over time).
}
// You had gravity going the wrong direction initially
gravity = (float) -((walkingSpeed * 0.00003) * delta);
//System.out.println(delta);
speed = speed + gravity;
position.y = position.y + speed;
if (position.y < temp) { // Don't sink into the ground
position.y = temp;
speed = 0.0; // Scrub off acceleration due to gravity
}
The bitmap A has a position which is its X/Y position is static, bitmap B is moving bitmap which moves from the bottom of the screen to where ever the user touches on screen. When the moving bitmap reaches the static bitmap however it is not recognized as a collision, the moving bitmap uses float which i round off and the static bitmap uses int. Below is a snippet of code, I want to figure out what is needed to be changed for my bitmaps crossing paths to be considered a collision
canvas.drawBitmap(rock2, 70, 32, null);
//this is where it checks to see if the moving bitmaps y coordinate is matched to the Y coordinate of the static bitmap
if(canvas.getHeight() - Math.round(animY*-1) == (canvas.getHeight() - (canvas.getHeight()-32))){
Log.d("ALERT", "COLLIDE");
}
//the Y value is *-1 because the moving bitmap is starting from the bottom of the screen so this converts the value to positive value
I wonder if my calculations are off, or I am going about this collision the wrong way. Below is my movement code snippet
//UP Y ANIMATION
if(animY*-1 < canvas.getHeight() && !bumpY){
animY += speedY;
//IF ROCK IS NOT AT EXTREME LEFT OR EXTREME RIGHT KEEP ON TRACK
if(animX < (canvas.getWidth()/2) || animX*-1 < (canvas.getWidth()/2) && !bumpX){
animX += speedX;
//IF ROCK HITS EDGE LEFT/RIGHT RETURN TO SENDER (INDICATE BUMP)
if(animX*-1 > (canvas.getWidth()/2) - rock.getWidth()/2 || animX > (canvas.getWidth()/2) - rock.getWidth()/2){
bumpX = true;
bumpY = true;
}
}
//IF Y HITS TOP OF SCREEN
if(animY*-1 > canvas.getHeight()){
bumpY = true;
}
}
//DOWN Y ANIMATION
if(animY < 0 && bumpY){
//REVERSE DIRECTION OF Y
animY -= speedY;
//IF ROCK HITS TOP OR SIDE REVERSE X DIRECTION
if(bumpX || bumpY)
animX -= speedX;
//IF AT STARTING POINT
if(animY > 0){
bumpY = false;
bumpX = false;
}
}
//in an ontouch method where the X and Y values are calculated
case MotionEvent.ACTION_UP:
finalX = event.getX() - (cross.getWidth() / 2);
finalY = event.getY() - (cross.getHeight() / 2);
moveToX = finalX - startX;
moveToY = finalY - startY;
speedX = moveToX / 50;
speedY = moveToY / 50;
break;
Any tips would be appreciated, thank you.
sorry if this is a dumb answer, but should your check be:
if(canvas.getHeight() - Math.round(animY*-1) >= (canvas.getHeight() - (canvas.getHeight()-32))){
instead? (change the "==" to ">=" ) otherwise you are only checking for when the rock lands EXACTLY on (canvas.getheight -32), rather than checking past it