How to handle collision with ShapeRenderer in LibGDX - java

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.

Related

LibGDX - Basic 2D lighting, don't know what to do

It's my first time attempting to create a basic light system that uses a black texture with a white circle on top. I read various threads about the issue but I just don't know what I am doing wrong.
What I want is the ambient to be dark and the light to be well white but changing the spritebatch color to something darker will cause the light to be darker to EVEN if I reset the color when drawing the light texture
So this is what I want (did this by forcing the light texture draw 5 times but that isn't a solution, it's an hack):
This is what I get (only 1 light texture is drawn but isn't very visible):
This is what I get without darkening the spritebatch:
Main code:
Game.sb.begin();
//Make stuff darker
Game.sb.setColor(0.1f, 0.1f, 0.1f,1f);
sb.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
lvl.render();
//Reset color
Game.sb.setColor(1f, 1f, 1f,1f);
sb.setBlendFunction(GL20.GL_DST_COLOR, GL20.GL_SRC_ALPHA);
//This draws all lights by drawing a texture with the above blending function
lightM.render();
Game.sb.end();
Light object draw method:
Game.sb.setColor(c.r,c.b,c.g, 1f);
Utils.drawTexture(Assets.get("sprites/lightcircle2.png", Texture.class), pos, size, true);
Game.sb.setColor(1,1,1,1);
Am I making some kind of error with the setcolor? I been considering using a FrameBuffer but I am not sure if it will give me the light effect I want
By the way this is my light texture (it's CC0):
You can achieve your requirement by these ways :
By using Shaders. Here is a small video and article on that video.
By use FBO and Blending, Here is one of my answer on this topic.
You can use box2dlight, even without using box2dbody(if you don't want any shadows)
World world = new World(new Vector2(0,0),false);
RayHandler rayHandler = new RayHandler(world);
rayHandler.setCombinedMatrix(stage.getCamera().combined); //<-- pass your camera combined matrix
new PointLight(rayHandler,1000, Color.WHITE,radius,x_position,y_position);
And at last call rayHandler.updateAndRender(); after all your rendering in your render() method.

Detect collision between ShapeRenderer line and sprite in LibGdx

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.

Disappearing a sprite during boundary collision in libgdx

I have a rectangular group that holds a bunch of sprites. Sprites are moving (say up). As they reach the top, they collide with the boundary. I have set up logic that kills the sprites as they exit the group. However, the way it is now, I can see the sprite leaving the group. I want to make it so that as the sprite is crossing the boundary, it's gradually disappearing until it's out (and dead).
Here's a crude mockup of what I want to achieve.
I was playing around with cameras thinking I have to modify the viewport, but it's not working. What's the proper way of achieving this effect?
Thanks!
EDIT:
My camera was set up like this:
camera = new OrthographicCamera(width, height);
camera.setToOrtho(false, width, height);
camera.position.set(width/2, height/2, 0);
Right now it's operating from the group's parent level (layer). Width and height are Gdx.graphics.getWidth(), etc.
My update():
camera.position.x = (width / 2) - resolver.getxPixelOffset()*parallax;
camera.update();
batch.setProjectionMatrix(camera.combined);
batch.begin();
g.drawGroup(batch);
batch.end();
I moved my camera controls to my group class. I then changed the width and height to groupWidth and groupHeight. Since the group is not the entire screen, I figured it has to be smaller. This made the group massive. I don't want to change the size (or zoom?) of the group :(
I haven't tested this myself, but I believe the proper way of doing this would be using scissors. Basically, the scissors allow you to clip a region out of your picture, and only allow things in that region to be drawn, so you would probably do something like similar to what they do in the demo here:
Rectangle scissors = new Rectangle();
Rectangle clipBounds = new Rectangle(x,y,w,h);
ScissorStack.calculateScissors(camera, spriteBatch.getTransformMatrix(), clipBounds, scissors);
ScissorStack.pushScissors(scissors);
spriteBatch.draw(...);
spriteBatch.flush();
ScissorStack.popScissors();
You may need to draw and flush your background image (if you have one) before you draw with the scissors.

Moving and rotating a Collision rectangle

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.

LWJGL Confusing Texture Mappings

I've been working on a very simple game, and I've decided to include some basic textures. I was experimenting with the code, and for some reason, I have no idea why, I cannot get the textures to map correctly. Right now, I am simply trying to map a green rectangle (512 x 64 .png file) to the bottom of a screen of size 640 x 480. This green rectangle is supposed to represent the ground. Here is an image of my failed attempt:
Here is the relevent code:
In the Boot class I have created I call this function:
public void initGL() {
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, gameWidth, gameHeight, 0, 1, -1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glEnable(GL11.GL_TEXTURE_2D);
}
In the ground class I have created, I call a draw function. The texture is loaded in the Boot class, and set as a protected variable which I bind and use in the ground.draw() function.
public void draw() {
this.texture.bind();
GL11.glLoadIdentity();
GL11.glTranslatef(0, 0, 0);
GL11.glBegin(GL11.GL_QUADS);
GL11.glTexCoord2f(0, 0);
GL11.glVertex2f(0, 480 - height);
GL11.glTexCoord2f(1, 0);
GL11.glVertex2f(640, 480 - height);
GL11.glTexCoord2f(1, 1);
GL11.glVertex2f(640, 480);
GL11.glTexCoord2f(0, 1);
GL11.glVertex2f(0, 480);
GL11.glEnd();
}
Also, if you'll note above I have a GL11.glTranslatef call. I can get my ground texture in the right position if I simply make the 2nd argument for this function large enough to displace it further in the y direction, however I don't wish to do it this way. I really don't know how the texture ended up in this location in the first place, and I would like to figure out why.
I think there is a problem with your matrices :
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, gameWidth, gameHeight, 0, 1, -1);
I never really used OpenGL fixed pipeline but what I see or actually DON"T SEE is where you multiply your matrices. You must multiply the model matrix of your quad with projection matrix which is glOrtho(). ( glPushMatrix/glPopMatrix )
So in your scenario you should :
Push Ortho matrix.
Push camera(view) matrix (if exists).
Push Model Matrix.
Pop Model Matrix.
Pop camera (view) matrix (if exists).
Pop Ortho matrix.
If the Ortho never changes I think you need to push it only once.
Also make sure you take into account ortho coordinates changes because depending on glOrtho() setup the world center going to be different from the center of the screen.Usually top left or bottom left corner.
The bottom line is : while I don't recommend you using the old and deprecated OpenGL at all, you should take a look how the transformations are done the right way in the numerous online tutorials.Also here

Categories

Resources