I'm starting to create my World with Box2d in Libgdx and I have to create shapes for different game objects. The tutorial I've read said I should dispose my shapes when I'm done using them.
So, I started keeping references like that:
private CircleShape circle;
private PolygonShape ground;
private PolygonShape wall;
private PolygonShape box;
//...
//(getters)
And disposing my objects like that:
#Override
public void dispose()
{
circle.dispose();
ground.dispose();
wall.dispose();
box.dispose();
world.dispose();
}
I decided to change this to a list for expansion but the problem is somewhere else in my code, I'm adding bodies on click so I need to let the access to some shapes from external classes. I could create extra shapes and let access to my list but I don't like the idea of creating a giant list of disposable objects.
A solution would be to create a ShapeManager object that has an internal list of shapes. I could dispose this object and it would wrap the shapes constructors letting me return an already existing shape if it fit the need.
However, this solution seem too heavy. Why Box2d (or LibGDX) made the shapes objects that need to be disposed ? Is there a class like I described already included in LibGDX ? Is there a better solution ?
You can dispose after making the definition of your body.
Related
I have a Canvas in JavaFX, and I would like to draw, say, a Circle, or Polygon, with stroke inside.
This is what I would usually do:
class MyClass {
fun draw(ctx: GraphicsContext, points: List<Point>) {
ctx.beginPath()
points.forEach {
ctx.lineTo(it.x, it.y)
}
ctx.closePath()
ctx.fill()
ctx.stroke()
}
}
But the problem is, this method will draw the shape with the stroke on path, like on the left on this picture:
I need it to draw the stroke inside the path.
I know that this is possible in JavaFX Shapes with their javafx.scene.shape.StrokeType patameter, but I would like to avoid using them as they need to be manually added to the Node as children (and manually removed if I need to change something).
Also, I know that I can use ctx.clip() to imitate the desired effect. But this method, if used frequently (which is my case), causes unacceptable lags to the application.
I searched everywhere to find a Canvas analog of StrokeType parameter, but haven't found anything.
I'm doing an assignment for school and I can't get my head around the logic I need to use to solve this. I hope some of you can point me in the right direction.
I have some classes to draw simple shapes:
Class Diagram 1
Extended Class Diagram
According to the assignment every deferred class under DrawingItem needs a paint() method to be able to paint the particular (Oval, Spline etc..) independent from GraphicsContext. For Oval, my guess is this method would be something like:
public void paint(Graphics g){
g.setColor(super.getColor());
g.drawOval(
(int) dw.getAnchor().getX(), (int) dw.getAnchor().getY(),
(int)this.width, (int)this.height
);`
}
Extended class diagram shows an interface IPaintable which I have created with a method for every shape. The JavaFX side (DrawingTool) implements this interface and all of its methods. These methods want the shape object as argument. I use these methods to draw the shapes in javaFX, again the oval example:
strokeOval(
oval.getHeight(), oval.getWidth(), oval.getAnchor().getX(), oval.getAnchor().getY()
);
The main questions I have are these:
Am I going in the right direction with the paint() methods in the shape subclasses and if so how do I call them from the JavaFX side?
How can I "implement" the paint(paintable:IPaintable) method in the Drawing and DrawingItem classes?
There are 2 design patterns easily identifiable in the class diagrams:
The IPaintable is supposed to be a wrapper(Facade) for the GUI drawing operations allowing you to use the classes in Class Diagram 1 independent from the GUI library used. You should only use the methods provided by IPaintable in the paint methods.
The classes in Class Diagram 1 are the command part of the Command Pattern; DrawingTool is the invoker/client and IPaintable is the receiver.
The DrawingTool class should contain code like this:
IPaintable paintable = new JavaFXPaintable(canvas.getGraphicsContext());
and use it like this, if the drawing needs to be redrawn:
drawing.paint(paintable);
Implementing the paint methods
Since a Oval can be drawn using IPaintable's methods, it should implement paint like this:
public void paint(IPaintable paintable) {
paintable.setColor(color);
paintable.paintOval(this);
}
Polygon would use the paintLine methods of the IPaintable passed to it's paint method for drawing itself, Drawing.paint would clear the IPaintable and draw all it's items ect.
In JavaFxPaintable the paintOval method would be implemented like this:
public void paintOval(Oval oval) {
Point anchor = oval.getAnchor();
graphics.strokeOval(anchor.getX(), anchor.getY(), oval.getWidth(), oval.getHeight());
}
You may need to modify this a bit, if anchor denotes the top-left instead of the the center.
Thanks fabian, pointing me in this direction realy helped a lot (as cleaning up my post for readability did too).
Now I have implemented these pointers and they seem to work. With the draw() method in Drawingtool I call the paint(IPaintable paintable) method in the Drawing class, which loops through the list of drawingitems in this class like so:
public void paint(IPaintable paintable){
for (DrawingItem test : drawingitems){
if (test instanceof Oval){
paintable.paintOval((Oval) paintable);
} else if (test instanceof Image){
paintable.paintImage((Image) paintable);
This should paint the shapes and seem to work. The last part is adding them to the canvas initialized in the DrawingTool class. I can't seem to figure out how to do this. I've tried to add them while going through the list with drawing items but this does not seem to work (or I'm handling it wrong).
I'd like to create a btConvexHullShape for my game with libgdx.
When I tried to do so with the sample code from github:
public static btConvexHullShape createConvexHullShape (final Model model, boolean optimize) {
final Mesh mesh = model.meshes.get(0);
final btConvexHullShape shape = new btConvexHullShape(mesh.getVerticesBuffer(), mesh.getNumVertices(), mesh.getVertexSize());
if (!optimize) return shape;
// now optimize the shape
final btShapeHull hull = new btShapeHull(shape);
hull.buildHull(shape.getMargin());
final btConvexHullShape result = new btConvexHullShape(hull);
// delete the temporary shape
shape.dispose();
hull.dispose();
return result;
}
this did not work.
My 3D object was just an object which looked like a demolished cube with unnecessary vertices and lines (tested with debugdrawer).
Then I tried to enter the second item of the array and built a convex hull from it with
final Mesh mesh = model.meshes.get(1)
this did give me another part of my 3D object which was a gutter of a bowling alley. But also this was demolished and too small.
Finally I tried two other methods I found online:
obtain a btCollisionShape via Bullet.obtainStaticNodeShape(model.nodes);
which resulted in a perfect collision shape, but did not detect collision.
Another problem with that is that it is only for static shapes, which are not intended to move and in my gamer are several objects which need to move.
The last possible and most cumbersome try I made was creating a .bullet file of my model with blender export and load it in libgdx (method can be seen in http://www.badlogicgames.com/forum/viewtopic.php?f=11&t=15263).
This gives me the right CollisionShape and if you set the Gravity in blender to the right one even the objects fall the right way, from up to down the screen.
The only problem with that is as soon as a collision is detected the program crashes.
Unfortunately I can not approximate my shape using primitives as it was suggested in multiple forums. Is there any possibility to create a correct btConvexHullShape in libgdx maybe by manually write a method to create a btConvexHullShape from a set of vertices?
I appreciate your help
EDIT:
You are right for this one as the alley itself does not need to be dynamic. But unfortunately the collsion of the bowling ball (which has a sphere collision shape) was not detected with the static collision shape of the bowling alley I got with Bullet.obtainStaticNodeShape(...), so I thought I'd need another approach to that and I'd also like to know just for educational purposes how it is possible to create a btConvexHullShape from any object I enter.
Currently I'm trying to load an .obj, create a Mesh from it and then tried to create a btconvexHullShape with
final btConvexHullShape shape = new btConvexHullShape(mesh.getVerticesBuffer(), mesh.getNumVertices(), mesh.getVertexSize());
At the moment I think, I'M close to the solution but I still don't got it right, as the cube I'm exporting from blender (as a test object) does not create the right collisionshape (it looks like a damaged cube again).
This method seems to work though, because when creating a mesh like in the link: https://github.com/libgdx/libgdx/blob/master/tests/gdx-tests/src/com/badlogic/gdx/tests/gles2/Shapes.java#L24, and creating a btConvexHullShape from it, I get the correct collisionShape.
This is a bonus question on my homework assignment.
The title says it all, I've built custom shape classes and need to define the draw() method for each one and I'm having a bit of trouble finding a good source tutorial for how to go about doing this.
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html
This explains exactly what I'm attempting to do but there's no guidance beyond what I already had so if anyone has any additional sources that I can utilize, I'd really appreciate the links.
As far as what I currently have:
abstract public void draw();
I've defined my draw function in my Shape class like so, and within each of my inherited shapes I've put:
public void draw(){}
So they currently do nothing. That is where my problem lies. I'm not sure where to continue from here, as far as actual implementations go, for instructing the shape to draw onto the jframe window and additionally, how I will eventually call the functions themselves in order to draw them on the actual window.
Any links, sources or other posts are more than welcome as my brain is rather mushy right now.
Thanks!
Edit 1: So looking over the typical 2D graphics stuff I realized I couldn't use the normal implementations because of how my shapes are made. They're constructed using a Point reference and then built based on those points, so for instance my Circle looks something like this:
class Circle extends Shape{
private static final double PI = Math.PI;
private Point point;
private double radius;
public Circle (Point p, double rad){
point = p;
radius = rad;
}
}
So I'm not able to use the normal oval(int,int,int,int) format. Sorry for not including this earlier, brain mush.
Currently I am having static reference to all my sprites and loading and initializing them in my OnCreateResource mthod of SimpleBaseGameActivity, But now I have to override onAreaTouched listener on spirtes and the way I can override it while Initializing the Sprite. But I have a static method creating Atlas and Texture Region for every sprite. And I am using these sprites in my scene class and I want to override onAreaTouched there. I can registerTouchArea for that specific sprite in my scene so that can be done But I want to Override OnAreaTouched in a way so that Code reusability can be done.
Here is how I am currently creating and loading sprites.
defualtCageSprite = createAndLoadSimpleSprite("bg.png", this, 450, 444);
And this is my Method createAndLoadSimpleSprite.
public static Sprite createAndLoadSimpleSprite(String name,
SimpleBaseGameActivity activity, int width, int height) {
BitmapTextureAtlas atlasForBGSprite = new BitmapTextureAtlas(
activity.getTextureManager(), width, height);
TextureRegion backgroundSpriteTextureRegion = BitmapTextureAtlasTextureRegionFactory
.createFromAsset(atlasForBGSprite, activity, name, 0, 0);
Sprite sprite = new Sprite(0, 0, backgroundSpriteTextureRegion,
activity.getVertexBufferObjectManager());
activity.getTextureManager().loadTexture(atlasForBGSprite);
return sprite;
}
Now How Can I override onAreaTouched for some sprites while not losing the code reusability.
Is there any reason you need to load the textures at runtime? The normal way is to load the required textures all onto a single atlas while loading the application so that you can then quickly use them later.
As for the code reusability, Todilo's idea about enums seems to be pretty much what you need. Say for example that you have two kinds of objects - objects that disappear when you touch them and objects that fly up when you touch them. You enumerate both categories and put a piece of code into the touch event handling code that checks whether the object should disappear or fly up.
If you don't know what the objects should be doing on touch before running the application, there is a more dynamic way of achieving the same result. Just create two lists at runtime and put a reference to the object in one of the lists according to what the object should do when touched. Then in touch event handling do something like this:
if (disappearList.contains(touchedObject)) {
disappear(object)
}
if (flyUpList.contains(touchedObject)) {
flyUp(object)
}
Too bad AndEngine does not allow users to set listeners on sprites, it would make things a bit easier.
EDIT:
Added explanation of the use of BlackPawnTextureBuilder:
Your Atlas must be of type BuildableBitmapTextureAtlas, then you add all textures like this
BitmapTextureAtlasTextureRegionFactory.createFromAsset(buildableAtlas, this, "image.png"));
and after that
try {
this.buildableAtlas.build(new BlackPawnTextureBuilder<IBitmapTextureAtlasSource, BitmapTextureAtlas>(1));
} catch (final TextureAtlasSourcePackingException e) {
Debug.e(e);
}
I don't know whether this will work for animated Sprites or not, you will have to try it.
Also, there is no overriding onTouch, you will have to do that in the onAreaTouched method. One example of such condition is
if (pSceneMotionEvent.getAction() == MotionEvent.ACTION_DOWN && disappearList.contains(pTouchArea)) {disappear();}
Are you sure you dont want more functionality than override ontouch? How about creating a class inheriting for sprite for those that need onarea to be overriden and all other needs.