LibGdx collision detection between sprites? - java

Using accelerometer my sprite image is moving left and right and if I touch my screen the sprite is moving to Y-axis.I want to make a collision detection between different sprites so that if the sprite pass through an object it will stop to hide in that object. I already watch a tutorial this https://www.youtube.com/watch?v=T1aN--vTqLc but nothings happen. What is the proper way to make collition detection? I don't know what's wrong with my coding.Any suggestion or much better tutorial Thank's and Advance
Here is my coding
private Rectangle rectangleCat;
private Rectangle rectangleShoes;
private float yPosition = -40;
Sprite
cat = new Texture(Gdx.files.internal("cat.png"));
catsprite = new Sprite(cat);
catX=300;
catY=0;
sprite_shoes = new Sprite(new Texture("equip/Shoes.png"));
sprite_shoes.setPosition(260,580);
rectangleShoes=new Rectangle(sprite_shoes.getX(),sprite_shoes.getY(),sprite_shoes.getWidth(),sprite_shoes.getHeight());
rectangleCat = new Rectangle(catsprite.getX(),catsprite.getY(),catsprite.getWidth(),catsprite.getHeight());
Render method
boolean isOverlaping = rectangleCat.overlaps(rectangleShoes);
if(!isOverlaping) {
System.out.println("not overlap");
yPosition = yPosition + (20 * delta);
}
My Sprite image and Object is not overlapping
Full source code http://pastebin.com/Dxfx9f65

First of all your sprite is not sharp Rectangle it's looks like polygon so you need to detect collision between two polygon.
Still if you want to detect collision between rectangle then get Bounding Rectangle of your sprite in render() method.
In render method
rectangleShoes=sprite_shoes.getBoundingRectangle();
rectangleCat=catsprite.getBoundingRectangle();
boolean isOverlaping = rectangleCat.overlaps(rectangleShoes);
if(!isOverlaping) {
System.out.println("not overlap");
yPosition = yPosition + (20 * delta);
}

Related

Processing - Method for Ellipse/Rect Collision

I am programming a game of sorts which would be kinda long to explain, but in short the player is an ellipse() and follows the mouse around, whilst the rect() is the obstacle that moves down the screen and needs to be dodged by the player, otherwise it's game over. There are multiple rect as I am using an ArrayList to store each obstacle object.
Currently, the player can just pass straight through the rect without anything happening to it. I have tried to solve it multiple times but it got extremely messy and I couldn't understand much due to being extremely new to Java (only 1 week of experience), so I have just placed the empty code below.
tldr; I need to figure out how to get an ellipse/rect collision to work (in its own method). I only have 1 week of Processing/Java experience. I've cut out most of the code that you don't need to look at, mainly just kept the variables used to define the shapes and the code for the shapes just in case you need that. Also, if possible could the collision method could be placed inside the Enemy Class.
Enemy Class (all the variables used to define the rect)
class Enemy {
int enemyNumber; // used to determine enemy type
//VARIABLES FOR ENEMY
boolean redEnemy = false; // determine enemy colour
color enemyColour = color(#B9B9E8); // sets default colour to blue
PVector position, velocity;
float xDist, yDist; // x and y distance for Bar
float smallCircleRad, bigCircleRad; // radius for circles
// **************************************************************************
Enemy() { //CONSTRUCTOR
position = new PVector(width/2, random(-300000, -250));
//println(position.y);
velocity = new PVector(0, 10);
smallCircleRad = 200;
bigCircleRad = 400;
xDist = width;
yDist = 200;
enemyNumber = int(random(1, 6));
}
// **************************************************************************
void redBar(float xPos, float yPos, float xDist, float yDist) {
redEnemy = true;
noStroke();
enemyColour = color(#E38585);
fill(enemyColour);
rect(xPos, yPos, xDist, yDist);
}
void blueBar(float xPos, float yPos, float xDist, float yDist) {
redEnemy = false;
noStroke();
enemyColour = color(#B9B9E8);
fill(enemyColour);
rect(xPos, yPos, xDist, yDist);
}
Player Class (all the variables used to define the ellipse)
class Player {
int r = 50; //player radius
float playerX = width/2; //starting x coordinate
float playerY = height/2+500; //starting y coordinate
float speed = 20; //player speed
float angle; //angle used to calculate trajectory for player
void playerChar() { //method for player model and general rules
stroke(10);
rectMode(CENTER);
fill(playerColour);
ellipse(playerX, playerY, r*2, r*2);
}
Make your life easier by treating the player as a rectangle instead of a circle. You can still draw them as a circle, but for collision detection, use a rectangle. This is called a bounding box and is very popular in collision detection.
Then you can use rectangle-rectangle collision detection, which is much simpler.
Some basic google searches return these results:
Axis-Aligned Bounding Box
What is the fastest way to work out 2D bounding box intersection?
Processing Collision Detection
If for some reason you absolutely need the player to be a circle when calculating the collision, then I'd start by googling something like "circle rectangle collision detection".
If you still can't get it figured out, please post a MCVE in a new question and we'll go from there. Good luck.

How to zoom into mouse position with correct translation

I'm trying to zoom a grid in Processing and I am having trouble with applying the correct translation such that zooming is centered around the mouse position. I have searched the web for a while but nothing I try seems to work.
The screen size is width and height and the mouse position is mouseX and mouseY.
The code I have at the moment is below, but it zooms the grid (controlled by player.zoom) from the top left corner which is not what I want. To update the translation of the grid, player has the 2d vector player.translate.
void mouseWheel(MouseEvent event) {
float zoomFactor = 200.0f;
float scroll = event.getCount();
player.zoom -= scroll * player.zoom / zoomFactor;
// player.translate.x += something;
// player.translate.y += something;
}
If you need more details to answer I can link the repo with the source code.
I have created a very simple mock-up for you which will hopefully point you in the right direction into applying this to your player.
So this little demo shows the zooming in to the centre of an ellipse whilst keeping it as the central focus.
float scale = 1;
// displacement left/right
float xPan = 720;
// displacement up/down
float yPan = 450;
boolean zoomIn = true;
void setup() {
size(1440, 900);
}
void draw() {
// allows us to zoom into the center of the screen rather than the corner
translate(width/2, height/2);
scale(scale);
translate(-xPan, -yPan);
background(200);
// draws the ellipse in the center
ellipse(width/2, height/2, 100, 100);
// does the zooming
if (zoomIn) {
scale *= 1.01;
}
}
I suggest you to copy this into a new project and then comment out specific lines to try to understand what's going on and how you can transfer this over to your own project.
The same principles still apply, I didn't do this with mouse input in the effort of making the program as simple as possible.

libGdx collision detection Polygons

I started learning LibGdx and Java recently, and it has been going well so far.
I'm facing an issue with collision detection.
I have two sprites which can be represented as two shapes, a polygon and a circle, which will collide/intersect at any given moment. Once these two shapes collide, something will get triggered.
So far, this is what I have done. It kinda works but it is not accurate. This is called inside the Render() function:
public boolean CollectPowerUp(PowerUps powerUp) {
if (powerUp.position.dst(position) < Constants.PLAYER_HEIGHT -3) {
Gdx.app.log("Collected PowerUp", "TRUE");
EnablePowerUp(powerUp);
return true;
}
return false;
I have searched many websites, and most of the solutions include other softwares like 2DCube or PhysicsEditor. Is it possible to perform this intersection solely by using LibGdx and Java? If so, what should I look into?
Thanks
Intersector class having many static method that can be used for collision detection.
If your polygon is rectangle you can use :
Intersector.overlaps(Circle c, Rectangle r)
else
Polygon polygon=new Polygon();
polygon.setVertices(new float[]{0,0,.......});
Circle circle=new Circle(x, y, radius);
float points[]=polygon.getTransformedVertices();
for (int i=0;i<points.length;i+=2){
if(circle.contains(points[i],points[i+1])){
System.out.println("Collide");
}
}
EDIT
Above code only detect collision if polygon vertices are inside circle, what if
circle is completely inside polygon
some part of circle is inside polygon but vertices are outside the circle
Create a polygon for circle that act as circle in view and polygon in model
float radius=100;
FloatArray floatArray=new FloatArray();
int accuracy=24; // can be use 1 for complete circle
for (int angle=0;angle<360;angle += accuracy){
floatArray.add(radius * MathUtils.cosDeg(angle));
floatArray.add(radius * MathUtils.sinDeg(angle));
}
Polygon circle=new Polygon(floatArray.toArray()); // This is polygon whose vertices are on circumference of circle
float[] circularPoint=circle.getTransformedVertices();
for (int i=0;i<circularPoint.length;i+=2){
if(polygon.contains(circularPoint[i],circularPoint[i+1])){
System.out.println("Collide With circumference");
break;
}
}
There's a nice article on collision detection on www.gamedevelopment.blog which shows how to detect collisions with most shapes. This is the Libgdx circle, polygon collision detection method shown in the article.
public boolean contains (Polygon poly, Circle circ) {
final float[] vertices = poly.getTransformedVertices(); // get all points for this polygon (x and y)
final int numFloats = vertices.length; // get the amount of points(x and y)
// loop through each point's x and y values
for (int i = 0; i < numFloats; i += 2) {
// get the first and second point(x and y of first vertice)
Vector2 start = new Vector2(vertices[i],vertices[i + 1]);
// get 3rd and 4th point (x and y of second vertice) (uses modulo so last point can use first point as end)
Vector2 end = new Vector2(vertices[(i + 2) % numFloats], vertices[(i + 3) % numFloats]);
// get the center of the circle
Vector2 center = new Vector2(circ.x, circ.y);
// get the square radius
float squareRadius = circ.radius * circ.radius;
// use square radius to check if the given line segment intersects the given circle.
return Intersector.intersectSegmentCircle (start, end, center, squareRadius);
}
}
There are many useful methods in the Intersector class which can be used for collision detection.

Best way to detect the touched object (moving) from collection in libgdx

This is my first attempt in game development. I just started experimenting libgdx and understanding the different aspects of game programming. I looked at the sample projects, i can understand the overall architecture of the libgdx game. But to get hold of the basics of game dynamics, i started playing with low level stuff like how to draw simple shapes, how to move them, how to handle collision like that.
So i planned to write a dead simple android game(Its not even a game for sure). This is the idea
1. Create random shapes and make it fly (move)
2. When user touches the shape, it ll explode or hide or play simple animation
3. Has to show Hit & Miss count
Initially i thought of going to try libgdx stage & actor concept, but ruled out that to do without the scene API. And I started this to experiment with different aspects of basic gaming and better understand the concepts behind libgdx. So i made this simple app, i am able to make objects fall random.
public class A1GameScreen implements Screen {
OrthographicCamera camera;
ShapeRenderer debugRenderer = new ShapeRenderer();
Array<Rectangle> boxes;
long lastFlew;
int fliesCaught;
A1GameScreen(){
camera = new OrthographicCamera();
camera.setToOrtho(false, 800, 480);
boxes=new Array<Rectangle>();
throwboxes();
}
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0.2f, 1);
Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT);
camera.update();
debugRenderer.setProjectionMatrix(camera.combined);
debugRenderer.begin(ShapeType.Line);
for (Rectangle fly : boxes) {
debugRenderer.rect(fly.x, fly.y, fly.width, fly.height);
}
debugRenderer.end();
//Handle the user input
if (Gdx.input.isTouched()){
hit(Gdx.input.getX(),Gdx.input.getY());
}
if (TimeUtils.nanoTime() - lastFlew > 1000000000)
throwboxes();
Iterator<Rectangle> iter = boxes.iterator();
while (iter.hasNext()) {
Rectangle fly = iter.next();
fly.x -= 2;
if (fly.x + 32 < 0)
iter.remove();
}
}
//Method to create flies at random interval
private void throwBoxes(){
Rectangle fly = new Rectangle();
fly.y = MathUtils.random(0, 480 - 32);
fly.x = 800;
fly.width = 32;
fly.height = 32;
boxes.add(fly);
lastFlew = TimeUtils.nanoTime();
}
private boolean hit (float x, float y) {
boolean found=false;
for (Rectangle fly : boxes) {
found = fly.contains(x,y);
if (found){
found = true;
fly.width=100;
break;
}
}
return found;
}
}
But i couldn't able to find out the touched item from the falling objects. This is what i am doing to find out whether the box is in touched range
Loop through all the boxes in the array
Check if the touch co-ordinates falls within the box co-ordinates
I passed touch co-ordinates to contains method of the Rectangle (Box) to figure out that
something like this
for (Rectangle fly : boxes) {
found = fly.contains(x,y);
if (found){
found = true;
fly.width=100;
break;
}
}
But its not working. I think i figured the problem. Its
Box is moving 2px in x axis each frame, to make flying effect
But i am assuming, some frames has passed since the touch event. Thats why i am not getting the expected result
My questions are
How to solve this issue?
Whats the best way to detect collision in libgdx?
Update
I see lot of mismatch between the touch co-ordinates and box co-ordinates. None of the boxes in the touch range. Hows that possible. Below the sample trace
Touch coords: x-651.0 y-362.0
Fly coords: x-384.0 y-277.0
Fly coords: x-504.0 y-34.0
Fly coords: x-624.0 y-103.0
Fly coords: x-744.0 y-238.0
Touch coords: x-441.0 y-193.0
Fly coords: x-52.0 y-34.0
Fly coords: x-172.0 y-103.0
Fly coords: x-292.0 y-238.0
Fly coords: x-414.0 y-261.0
Fly coords: x-534.0 y-109.0
Fly coords: x-656.0 y-283.0
Fly coords: x-776.0 y-323.0
Touch coords: x-568.0 y-162.0
Fly coords: x-42.0 y-267.0
Fly coords: x-162.0 y-166.0
Fly coords: x-282.0 y-266.0
Fly coords: x-404.0 y-52.0
Fly coords: x-526.0 y-296.0
Fly coords: x-646.0 y-64.0
Fly coords: x-766.0 y-16.0
public static boolean pointInRectangle (Rectangle r, float x, float y) {
return r.x <= x && r.x + r.width >= x && r.y <= y && r.y + r.height >= y;
}
In your update-
if(pointInRectangle(flyRectangle, Gdx.input.getX(), Gdx.input.getY())){
// Do whatever you want to do with the rectangle. maybe register them for effect
}
You can also look into Intersector class.
Now for collision, if your game is fast-paced, with lots of enemies moving around that the player can collide with, sooner or later you will use a box2d type library because if the movement speed is high, you might not get any collision callback. Things might go through each other. You can try predicting the collision before it happens using the velocity and deltaTime, but it's still not going to be enough and you will end up reinventing the wheel.
Mario's SuperJumper is a great demo to start libGDX. Try it.
EDIT:
Have an instance member-
Vector3 touchPoint;
On create-
touchPoint = new Vector3();
On update-
camera.unproject(touchPoint.set(Gdx.input.getX(), Gdx.input.getY(), 0));
if (Gdx.input.justTouched()) {
if (pointInRectangle(rectangle, touchPoint.x, touchPoint.y)) {
}
}
Please take note of the coordinate system in libGDX. For testing, create one rectangle on screen. On click, print/debug the coordinates of both the rectangle and touchPoint.
I've solved the problem by making an invisible rectangle which will follow the tap location and I made an if statement checking for overlapping of the invisible rectangle and checking for if the screen was just tapped.
Here is the code:
if(Gdx.input.isTouched()) {
Vector3 pointerPos = new Vector3();
pointerPos.set(Gdx.input.getX(), Gdx.input.getY(), 0);
cam.unproject(pointerPos);
touchPos.x = pointerPos.x /*+ 64 / 2*/;
touchPos.y = pointerPos.y /*+ 64 / 2*/;
}
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(raindrop.overlaps(touchPos) && Gdx.input.justTouched()) {
iter.remove();
dropSound.play();
}
all of this code is in the render method.
P.S: Change raindrops to the fly objects you want

How to use MouseListener and MouseMotionListener in java3D to rotate 3D object?

I m making desktop app in java swing. i made 3D image from my 2D image using PointArray[]. now i want to rotate image using MouseListener and MouseMotionListener.I used MouseRotate object to rotate myImage, but it not works well for that, MouseRotate rotate image with origin(0,0,0). but i want to rotate image using center point of image. means rotate image using center point not origin point. So, How can i do that?
Hmm, it's hard to tell without code, but I think you can just set up a transformation matrix and rotate it with that. Assuming the image is facing the front of the screen, you can try something like this:
public void mouseDragged(MouseEvent e)
{
int dx = e.getX() - x; //x should be a global variable
int dy = e.getY() - y; //same applies here
x = e.getX(); //to set x for the next update loop
y = e.getY();
double rotation = Math.sqrt(Math.pow(dx, 2) + Math.pow(dy, 2));
Transform3D transform = new Transform3D();
Matrix3d matrix = new Matrix3d();
transformG.getTransform(transform); //assuming the TransformGroup your image is in is transformG
transform.getRotationScale(matrix);
transform.rotZ(rotation);
transformG.setTransform(transform);
}
You can set up the rotation amount differently if you want, but this should give you an idea

Categories