I am having a bit of a problem with my collision. I have a dog object with two circles, one for his head, the other for his fat body, and a circle that represent a ball texture that hit\collides with the dog's circles (the first one it touches).
Now, all circles are a bit bigger than the texture the represent them.
When I draw them with the SpriteBatch it seem like the textures move inside each other before the collision affect happen, but when I draw the only the circles with ShapeRenderer, the collision affect take place the moment the circles hit\collide.
Why with the different between the SpriteBatch and ShapeRenderer?
EDIT MY CODE:
Dog's circles:
boundingCircleHead.set(position.x + 9.5f, position.y + 6, 6.5f);
boundingCircleBody.set(position.x + 9.5f, position.y + 16, 6.5f);
Ball's circle:
ball.x = MathUtils.random(0, 121);
ball.y = -13;
ball.radius = 11f;
Draw ball:
batcher.draw(BALL, ball.x, ball.y, 17, 19);
shapeRenderer.circle(ball.x, ball.y, ball.radius);
Draw dog:
batcher.draw(dogAnimation.getKeyFrame(runTime), dog.getX(), dog.getY(), dog.getWidth(), dog.getHeight());
shapeRenderer.circle(dog.getBoundingCircleHead().x, dog.getBoundingCircleHead().y, dog.getBoundingCircleHead().radius);
shapeRenderer.circle(dog.getBoundingCircleBody().x, dog.getBoundingCircleBody().y, dog.getBoundingCircleBody().radius);
Collision:
if (Intersector.overlaps(ball, dog.getBoundingCircleHead()) || Intersector.overlaps(ball, dog.getBoundingCircleBody())) {
gameOver();
}
Related
if(rect3.a+30>rect2.a){
ballright=false;
bounce++;
}
if(rect3.a-30<rect1.a){
ballright=true;
bounce++;
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d=(Graphics2D) g;
g.setColor(Color.BLACK);
g.fillRect(0, 0, 1080, 760);
g2d.setColor(Color.WHITE);
// g.fillOval(x, y, 30, 30);
g2d.fillRect(rect3.a, rect3.b, 30, 30);
g2d.setColor(Color.WHITE);
g2d.fillRect(rect1.a, rect1.b, 30, 200);
g2d.setColor(Color.WHITE);
g2d.fillRect(rect2.a, rect3.b-50, 30, 200);
g2d.fillRect(520, 0, 10, 760);
So I have these rectnagles to be the objects for a pong game. Except I cant seem to figure out how to make the ball (rect3) bounce of the paddles (rect1,2) and if the paddles is not there go to the edge of the window to score a point. The way I have it now it simply bounces of the whole y axis at 0 and 1080. Is there a way to make it bounce only when the paddle is there and if it is not score a point ?
Let's start with the basic objects here:
Left Paddle (left:top:height:width = x1, y1, h, w)
Right Paddle (left:top:height:width = x2, y2, h, w)
Ball (centreXpos:centreYpos:radius = bx, by, r)
Board (left:top:height:width = boardX, boardY, boardH, boardW)
Note:
- width here refers to the short side
- height refers to the length of the long side of rectangle
Now that we have the objects out the way let's identify edges against which you want to detect collision:
1. Left Paddle
- Collision surface would be the long right side
(i.e All pixels from x=(left + width) y=top to x=(left + width) y = (top + height))
2. Right Paddle
- Collision surface would be the long left side
(i.e All pixels from x=(left) y=top to x=(left) y = (top + height))
3. Ball
- Collision surface is all pixels on the edge of the circle
- so bx +/- radius and by +/- radius
4. Board
- Collision surface are the edges of the board
- Long edges should cause you to bounce
- short edges should end the rally
Collision detection
- if collision surface of the ball is >= collision surface of right side paddle
or
- if collision surface of the ball is <= collision surface of left side paddle
What to do when collision is detected?
- if collision is detected with left paddle change direction to move to right (change increments to bx and by to make it take a different direction)
- if collision is detected with left end but not the paddle stop animation
- if collision is detected with right paddle change direction to move to left
- if collision is detected with right end but not the paddle stop animation
Suggestion around Objects
It would help if you modelled your objects and then in your animation loop called collision detector with each surface that you care about
The collision detector could then respond with an enumeration. You can have another function act based on the enumeration
From what I see so far you would need
GameObjects
|-- Ball
|-- Paddle
|-- Left
|-- Right
|-- Board
you can choose to use inheritance.
CollisionDetector
iterate through all Game objects and Detect if ball has collided with any surfaces that interest you
Here you could get both object say, Ball and Left-Paddle and have specific collision routines written for each
(BTW.... with this you can even write test cases around Collision detection and ball movement rather than trying to play it everytime to see if it works as expected)
I believe this will make it simpler. If you have a running copy somewhere on github I am happy to help you with it.
Reading back on the above seems like a long-winded explanation for what you were looking for and something more.
The above does not really depend on Java.. you could do that in almost any language.
Hope this helps :)
you are only checking if ball.x + ball.width > paddle.x
you should also account for the case that ball.y is between paddle.y and paddle.y + paddle.height
I'm having problems plotting hitboxes in the center of rotating triangle sprites. When I spawn the triangles, I set the collision rectangle like this:
bullet.collisionRect.width = flashingTriangleSprite.getWidth() - 20;
bullet.collisionRect.height = flashingTriangleSprite.getHeight() - 14;
bullet.scale = 0.287f;
Updating is done as follows:
bullet.position.y += bullet.velocity.y;
// center collision rect over triangle sprite
bullet.collisionRect.x =
bullet.position.x + ((flashingTriangleSprite.getWidth() / 2) - bullet.collisionRect.getWidth() / 2);
bullet.collisionRect.y =
bullet.position.y + ((flashingTriangleSprite.getHeight() / 2) - bullet.collisionRect.getHeight() / 2);
if (bullet.scale < 1)
{
bullet.scale += 0.011f;
}
if (bullet.driftDirection == Globals.Direction.LEFT)
{
bullet.rotation -= 3.804f;
bullet.position.x -= bullet.velocity.x;
}
else // drift right
{
bullet.rotation += 3.804f;
bullet.position.x += bullet.velocity.x;
}
This is the result: http://imgur.com/rIvIT8K
As you can see, the hitboxes are not centered. In fact, the hitboxes seem to change position within the triangle sprites depending on the rotation of the triangle sprite. Any ideas what I'm doing wrong?
When determining your hitbox centre position you are targeting the centre of the triangle sprite (a square), but that is not the perfect centre of the drawn triangle.
Therefore your hitbox is always closer to one of the vertices of the triangle (depending on the rotation). Also, your hitboxes are never rotated with the triangle, instead they always appear to be standing vertically.
To place the hitbox in the middle of the triangle you should aim for 1/3 of the height of the sprite (if the triangle has one side flat at the bottom in the base sprite image) and when you are updating the sprite, attempt to update the hitbox rotation to match the sprite rotation.
You could also try making a more accurate triangle hitbox using the PolygonShape, but that's up to you.
I am having trouble with the movement of the player in my game. The game is a top-down shooter in which the location of the player is controlled with W, A, S, and D. I want to control the direction the player faces by moving the mouse.
I know I need to use the mouseMoved method to track the mouse, but I am lost in both calculating the angle and actually rotating the image.
The image is basically a circle with black line to represent the gun sticking out.
Any help is greatly appreciated!
You can calculate the angle using the player and mouse coordinates:
float angle = (float)(Math.atan2(player.y - mouse.y, player.x - mouse.x));
this will give you the angle in radians.
Then when you are drawing the object:
AffineTransform reset = new AffineTransform();
reset.rotate(0, 0, 0);
Graphics2D g2 = (Graphics2D)g;
g2.rotate(angle, player.x, player.y);
//draw the image here
g2.setTransform(reset);
CircleShape circle = new CircleShape();
circle.setRadius(1f);
...
using
...
batch.draw(textureRegion, position.x - 1, position.y - 1,
1f, 1f,
2, 2,
1, 1,
angle);
I use this to set the body for a Box2d collision but I get a silly circle shape around my texture in libGdx, i.e. my textured sprite (ball) has a circle over the top of it with a line running from center along the radius.
Any ideas on how to remove the overlying circle lines?
Not 100% sure, haven't used Box2d with libgdx in a while. But look if you have any Box2DDebugRenderer that renders the box2d world. If so, just don't call its render() method.
yes, uncomment the following line.
debugRenderer.render(world, viewport.getCamera().combined);
How can we rotate a Image Clockwise using LibGDX? what i am looking is when a image is loaded,suppose a star, i need to rotate it from beginning of screen to end of the screen horizontally, with star rotating,how can i do that in libgdx?
When you draw the Texture with your SpriteBatch, you can use one of the draw functions that includes rotation. This javadoc has all the draw functions: SpriteBatch
You can keep a variable for position and rotation, and increase the rotation and x component of the position each time you render to make it rotate while moving horizontally.
Libgdx gives you more then one way to do that:
You can use Scene2D and add an Image to your Stage. Image is a subclass of Actor, so you can add Actions to it:
Image myImage = new Image(myTexture);
myImage.addAction(Actions.parallel(Actions.moveTo(endX, endY, duration), Actions.rotateBy(degrees, duration)));
myImage.setPosition(startX, startY);
myImage.setOrigin(sizeX/2, sizeY/2);
stage.add(myImage);
In render you can then call stage.act(), which updates the position, rotation, scale... of all your Actors and then call stage.draw() which will call draw() for all your Actors.
Image allready handles the draw() so you don't need to care about that anymore.
You can also do it without scene2d, by updating everything yourself:
You can store a int rotationSpeed in degrees/sec
You can store a int moveSpeed in units/sec (maybe pixel but i would suggest to use camera or viewport and use your own unit, which is equal on all devices)
Store the float angle, which is the current rotation of your Texture
and store a Vector2 position, which contains the x and y position of your Texture.
If you want to move in x and y direction you can also store a Vector2 direction, which is a normalized Vector, giving the percent of movement in x and y direction, but thats a different story.
Then in your render(float delta) you update everything:
angle+=delta*rotationSpeed;
angl%=360; // Limits the angle to be <= 360
while (angle < 0) // Unfortunally the "modulo" in java gives negative result for negativ values.
angle+=360;
position.x+=direction.x*moveSpeed*delta;
position.y+=direction.y*movSpeed*delta;
spriteBatch.draw(yourTextureRegion, position.x, position.y, sizeX/2, sizeY/2, sizeX, sizeY, scaleX, scaleY, angle);
For clockwise rotation simply use a negative rotationSpeed or replace the angle+= with angle-=.
Hope it helps.
Following is the implementation to rotate any sprite
batch.draw(sprite,(Gdx.graphics.getWidth() - sprite.getRegionWidth()) / 2.0f,(Gdx.graphics.getHeight() - sprite.getRegionHeight()) / 2.0f,sprite.getRegionWidth()/2.0f,sprite.getRegionHeight()/2.0f, sprite.getRegionWidth(), sprite.getRegionHeight(), 1f, 1f,count, false);
if(count < 0.0f)
count = 360.0f;
else
count --;
Initially set counter to
private float count =360.0f;
You can also use the Scene2D actions. I have an example here with asteroid-type thing falling down the screen and rotating.
http://www.netthreads.co.uk/2012/02/09/libgdx-scene2d-demo-with-scene-transitions/
To rotate anticlockwise and horizontally..
create a textureRegion
then
Sprite sprite = new Sprite(textureRegion, 0, 0, 128, 128);
sprite.setPosition(++mX, 0);
angle++;
sprite.setRotation(angle);
sprite.draw(batcher);
You can do it too like this:
on your create method
sprite.setOrigin(sprite.getWitdh() /2f, sprite.getHeight() /2f);
sprite.setPosition( 0, 200 ); //200 it's a example
on your render(float delta)
sprite.setX( sprite.getX() + delta ).setRotation( sprite.getRotation() + delta );
Here is a simple to rotate an actor in libgdx. First you need to set the origin:
img.setOrigin(getWidth/2,getHeight/2);
And then you can rotate clockwise and anticlockwise according to your need:
img.rotate(2f); or img.rotate(-2f);
So the following sample worked for me (infinite rotation)
Method 1: (recommended)
loadingActor.addAction(Actions.repeat(RepeatAction.FOREVER, Actions.rotateBy(360, 1)));
Method 2:
Image loadingActor = new Image(AssetsController.getInstance().getLoading());
loadingActor.setOrigin(Align.center);
final SequenceAction infiniteRotate = Actions.sequence();
infiniteRotate.addAction(Actions.rotateTo(0 , 0f) );
infiniteRotate.addAction(Actions.rotateTo(360 , 1f) );
loadingActor.addAction(Actions.forever(infiniteRotate));