I'm developing a simple game in which I need to detect collision between objects, I already know how to detect collision between 2 sprites, but now I need to detect collision between a sprite an a line drawn using the ShapeRenderer technique. Let's say I have a sprite defined like this:
Texture texture = new Texture(myPath);
TextureRegion textureRegion = new TextureRegion(texture, w, h);
and a line like this:
shapeRenderer.begin(ShapeType.Line);
shapeRenderer.line(x1, y1, x2, y2);
shapeRenderer.end();
Is there a way to detect when those 2 two objects collide?
Without knowing how you're detecting your sprite collisions, I'd suggest a couple of different options that may work.
If you're using box2d for your current collision detection, and you don't have many lines to render with the shapeRenderer, you could consider creating a body/fixture to represent the line, make it a sensor and use the contact listener like you do for other bodies.
Or perhaps a more simplistic approach may be to use libgdx's Intersector class and poke around there for methods that may help you. For instance,
public static boolean intersectLinePolygon(Vector2 p1, Vector2 p2, Polygon polygon)
may work for you, where p1 is your (x1,y1), p2 is your (x2, y2) and polygon maps to your textureRegion.
Related
I'm trying to make a little game for Android with LibGDX and am having a hard time with collision detection.
So, I have two shapes :
The first one is a rectangle (the player) :
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.BLACK);
shapeRenderer.rect(position.x, position.y, width, height);
shapeRenderer.end();
The second one is the following, kind of a cage :
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.BLACK);
shapeRenderer.rect(0, 0, 50, Gdx.graphics.getHeight());
shapeRenderer.rect(0, 0, Gdx.graphics.getWidth(), 50);
shapeRenderer.rect(Gdx.graphics.getWidth()-50, 0, 50, Gdx.graphics.getHeight());
shapeRenderer.rect(0, Gdx.graphics.getHeight()-50, Gdx.graphics.getWidth(), 50);
shapeRenderer.end();
My question is :
How can I detect collision between these two objects ? The only way I know, how to detect collision is with the intersect method from the Rectangle class but I would like to make more complex shapes than rectangles.
Thank you for your help !
According to documentation ShapeRenderer isn't efficient and shouldn't be used intensively.
Renders points, lines, rectangles, filled rectangles and boxes. This
class is not meant to be used for performance sensitive applications
but more oriented towards debugging.
A better approach might be to allocate a Sprite with a small white texture that you upscale to the appropriate size. Set tint and alpha with setColor(..) method.
For collision getBoundingRectangle() of Sprite return bounding axis aligned Rectangle, that will help you in collision.
You can manually create a texture by using pixmap.
public static Texture createBgTexture() {
Pixmap pixmap = new Pixmap(1, 1, Format.RGBA8888);
pixmap.setColor(Color.WHITE);
pixmap.fill();
Texture texture = new Texture(pixmap); // must be manually disposed
pixmap.dispose();
return texture;
}
For more complex shape use Physics Body Editor, that will return vertex point of your shape in readable file format, use that points and create Polygon.
Libgdx having Intersector class, containing many static method for collision detection like intersectPolygons(....) and more.
On the other hand If you want a realistic collision detection, You can use box2d in your game. Inside box2d API there is a ContactListener interface that will tell you when two body collide.
I am writing a simple game, or so it seemed, that has a functionality of rotating a Rectangle as the mouse moves. This did not seem like a problem at first but it just became a problem. What the Rectangle should do is rotate around a point as the mouse moves around on the Panel.
If you look at the picture, when the mouse moves the Rectangle will rotate. I know you can use the rotate functionality with Graphics2D.
g2d.rotate(angle, centerx, centery);
This is not very help full because I can not get the coordinates of the moving rectangle. This rotates the full graphics! How will I be able to draw this Rectangle so that it does this. I don't have an idea as on how to start. Please help.
Some more code and context would be nice, but based on the current question: You could create a transformed shape. Particularly, Rectangle and Rectangle2D implement the Shape interface. And you can create an AffineTransform that represents the rotation that you are currently doing to your Graphics. So the relevant part of the code should roughly look like
Rectangle2D rectangle = ...
AffineTransform at = AffineTransform.getRotateInstance(
angle, centerx, centery);
Shape rotatedRectangle = at.createTransformedShape(rectangle);
g2d.draw(rotatedRectangle);
You mentioned "collision" in the title. If you intend to use this rectangle in some sort of collision detection, you should note that it is not directly possible to intersect two arbitrary Shape objects. Particulary, you can not intersect the Shape rotatedRectangle with another Shape otherRotatedRectangle, but only with a Rectangle otherRectangle. If this is an issue, you have several options, but this would rather fit into a dedicated question.
I'm beginning to develop games for android and I have what I believe a pretty simple question. I'm trying to replicate the game 'The Impossible Game' which is shown below for some practice. I'm having trouble with the white line the player uses as the "ground". When I want to create it, should I create is as its own texture and draw it like that on a texture atlas map and then put it into my game level picture and use collision detection, or should I just create that line in the background image and say if players position y = number, then stop falling? And then scroll the camera upwards when the player goes higher so the line doesn't always stay at that part of the screen. Which is an easier approach? hanks guys. I'm just not sure what's easier.
You can use the ShapeRenderer to draw a line like this:
//x,y your first point, x2,y2 your second point
shapeRenderer.line(x, y, x2, y2);
If you want to have the same effect like in the image you posted (with the limits of the line fading), you can divide it in 3 lines, one small going from full transparency color to white, one all white being the longest of them, and one going from full white to full transparency in the other end.
Something like this:
white = new Color(1,1,1,1);
transp = new Color(1,1,1,0);
shapeRenderer.line(x, y, x2, y2, transp, white); //Transp. to white
shapeRenderer.line(x2, y2, x3, y3, white, white); //all White
shapeRenderer.line(x3, y3, x4, y4, white, transp); //White to transp
Just set the correct points. (And do not create new Colors every frame!)
Of course you can also make a TextureRegion inside your atlas all white (even a 1x1 will do the trick). And just render that at the size and position you want.
batch.draw(whiteregion, x, y, width, height);
I need to make it so that when sprites that I have created collide with each (I have already figured out the collision) other they teleport to the last x and y position they were on before they collided so that they don't go through each other. I have tried to use this code.
double x, y, x2, y2;
if(!r1.intersects(r2)){
x = z.getX();
y = z.getY();
x2 = z2.getX();
y2 = z2.getY();
}
if(r1.intersects(r2)){
z.setX(x);
z.setY(y);
z2.setX(x2);
z2.setY(y2);
}
But it doesn't work because all the sprites is inside each other. I have also tried to use this.
if(r1.intersects(r2)){
z.setX(z.getX() - 1);
z.setY(z.getY() - 1);
z2.setX(z2.getX() + 1);
z2.setY(z2.getY() + 1);
}
That code makes it so that the sprites can't go through each other but it will make it so that the first sprites that spawn becomes alot faster than the later ones because in the beginning it's more sprites that collide with each other.
I assume these sprites are more complex than simple circles? I am also assuming that you have implemented some "bounding box" collision detection.
If that's the case then I would calculate a vector after the collision is detected. The vector would be a magnitude of how much each sprite has intersected each other by, relative to their center points. You can then move each sprite in opposite directions along the vector, scaling by how far they have intersected. This would position each sprite so they are just touching.
This is a nice solution because if each sprite is moving at more than 1 pixel per frame, the last positions of each sprite could be a 10's of pixels away. It would never look like they actually collided.
..This would work for both complex sprites and simple circles.
I am attempting to draw a triangular portion of a bitmap. I already know how to draw a filled triangle using path, and I already know that the answer may involve something called BitmapShader, but I can not find any clear documentation or examples to put it all together.
EDIT: After much flailing and experimentation, I am now nearly there. My code looks like this:
Paint paint;
Path path = new Path();
BitmapShader bms = new BitmapShader(shrub_bitmap,TileMode.REPEAT ,TileMode.REPEAT );
paint.setStyle(Style.FILL);
paint.setShader(bms);
path.reset();
path.setFillType(Path.FillType.EVEN_ODD);
path.moveTo(x1,y1);
path.lineTo(x2,y2);
path.lineTo(x3,y3);
path.close();
canvas.drawPath(path, paint);
paint.setShader(null);
The only remaining problem is that the bitmap from which the triangle is drawn is rooted to the screen coordinates. This means that when the triangle is being animated (i.e. being drawn at various points around the screen), it has the appearance of being a window allowing us to see a static image underneath. What I actually want is for the bitmap to be tied to the triangle so that the triangle looks like a solid object moving around. Any idea how to fix that?
for your second question:
try using canvas.translate(x1, y1) and moveTo(0, 0), lineTo(x2 - x1, y2 - y1) ...