Adding a method draw() to custom shape classes - java

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.

Related

Java & Slick2d - Object Interaction

In a game I am creating with slick2d to learn Java, I have multiple levels each with one Footballer and multiple other units I want the footballer to be able to interact with. I also want the other units to interact with each other (for example multiple Balls colliding with eachother) (note, some of these units are sometimes of the same class as one another e/g multiple Defenders). I am unsure, however how to detect these interactions and update the units appropriately. For example, I have my Footballer:
public class Footballer extends Unit {
public Footballer(float x, float y){
super("res/ballerpicture", x, y)
}
}
And within this class I have an update function which overrides the update function in the Unit class (allowing me to move the one Footballer according to my input - this is working without issue other than collision detection).
I could then, for example, have loaded on my map 5 balls:
public class Ball extends Unit {
public Ball(float x, float y){
super("res/ballpicture", x, y)
}
}
For an example, I would like to know how to update any one of the balls upon collision with the Footballer, moving them one tile away from the player each time they collide.
My Unit class includes a move method which moves the unit based on an integer direction (left = 1, right = 2 etc...).
Apologies if I have oversaturated this question or haven't included enough information - I'm relatively new to java.
What you are looking for is collision detection.
All objects which are able to interact with each other can have a hitbox, that's in the easiest way one geometrical shape which represents the body of an object. We could for example assume that your ball has a circle as hitbox with the radius of 8 px and your footballer has a hitbox of a rectangle with width 32 px and height 32 px.
When both objects are now moving you have to check whether the boundaries of your hitbox are intersecting with each other, if so: do something, if not keep moving.
In Slick2D all shapes have a method called intersects(Shape s), it returns true if the boundaries of two shapes are intersecting. So basically you just have to implement hitboxes for your objects (make sure to update the hitbox when your object is moving) and then check for intersecting. There are a lot of different ways of implementing collision detection and the internet is providing a lot of ressourcing regarding that topic. I also recommend to take a look at the Shape documentation of Slick2D. It's hard to write a solution for you since I don't know your code but I'm sure you will figure it out and Slick2D provides an easy preimplemented solution for your problem with the intersecting method.
It could look somewhat like the following:
Edit, for multiple balls:
//in your update method
for(Ball ball : allBalls){
if(footballer.getHitbox().intersects(ball.getHitbox()){
//get direction of footballer
ball.move(...)
}
}

How to dispose box2d shapes properly?

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.

drawing simple shapes -> paint method and interface for JavaFX

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 don't understand why my line is going at an angle

I am in this AP class in highschool and we are using the program JAVA or OOP, I don't even know what it is. In the class we don't have a teacher so we basically have to self teach our self from a packet. I am learning how to draw a face and i am kind off struggling.
Well first off, the prompt here- http://mrlanda.com/ecs/unit%205/Happy%20Face.htm
Look at the picture below to see how it looks like.
MY QUESTION-- Well here is what i got so far and it is stressing me out so much, I DON'T KNOW WHY BUT MY LINE KEEPS GOING IN AN ANGLE. Why does it go in an angle when I am not telling it too.. I am also having a problem with the nose i can't seem to find the spot i want to put it at it keeps going into an angle for some reason.
My code so far
import apcslib.*;
public class DrawSquare
{
public static void main(String[] args)
{
DrawingTool marker;
SketchPad poster;
poster= new SketchPad(600,600);
marker= new DrawingTool(poster);
//left side of box
marker.up();
marker.move(0,0);
marker.down();
marker.turnRight(180);
marker.forward(200);
//mouth
marker.up();
marker.move(40,60);
marker.down();
marker.turnRight(90);
marker.forward(100);
//nose
marker.up();
marker.move(100,100);
marker.down();
marker.turnRight(90);
marker.forward(100);
}
}
According to the API docs for DrawingTool the method move(double, double) changes the direction of your drawing tool.
Hence if you perform the move to (40,60) from the endpoint (-200,0) of your previous forward move your new direction vector will be (240,60). When rotating this by 90 degrees you will head in direction of (60,-240).
I've made a sketch showing the behaviour (not exactly to scale - I hope I haven't mixed coordinates)...
So you have the following options to fix this:
instead moving to (40,60) directly you could move to a temporary point before forcing the move to have your desired direction:
// mouth
marker.up();
marker.move(40,50);
marker.move(40,60); // now you have direction "up"
marker.down();
marker.forward(100);
or you could just use move instead of `forward
// mouth
marker.up();
marker.move(40,60);
marker.down();
marker.move(40,160); // or whatever your expected target is...

How to create custom shape in java

I am doing some java games, and I figure it would be cool if the game is made without importing images. Therefore I need to create custom shapes and hand it to Graphics object to draw. The major character in my game will be a dango which is much like a slime, composing from a imperfect circle and two vertical lines as eyes. I should be able to construct dango by given a parameter indicating size. Also, it will be better if I can modify the position of the eyes, or the bottom curve to present the interaction with the floor. Further more, I would be glad if I can fill it with color and give it some texture or something. But all things start from a circle and two lines.
I checked some APIs including Shape, GeneralPath, PathIterator, Area, Ellipse, and some source code. I learnt how to use GeneralPath to draw straight line, quadratic curve, and bezier curve. But still I don't know how to implement my custom shape. I found this question in stackoverflow but no good answer is posted.
In case someone just read the title and skips the content of this question, I shall emphasize that this question is about create the custom shape, which means to implement the 'Shape' interface. Not just to draw a shape.
So after a day of research, I finally did it. For anyone who holds the same problem with me, I recommend you to do what I have done.
First, refer to the java api source code, here I chose the source code of Ellipse2D.class. Following the source code, you may ignore the 2 inner static class Ellipse2D.Double, Ellipse2D.Float, they are not so important at this point.
To implement the Shape interface, the most important method is
public PathIterator getPathIterator(AffineTransform at) {
return new EllipseIterator(this, at);
}
this method is called by paintComponent to get a PathIterator to draw. So as what the source code does, you may create your own ShapeIterator.
Then the source code of EllipseIterator. As you can see, there are 4 methods (excluding the constructor and the duplicate). You may leave getWindingRule() for furthur research. While isDone() and next() are rather simple to understand.
Then let's focus on public int currentSegment(float[] args).
The return values is int, which should be the static final int fields: SEG_CLOSE, SEG_CUBICTO, etc.. They give instructions on drawing your shape. SEG_MOVE will move the start point, SEG_LINETO will draw a straight line from start point to end point. There are few more like the quatratic curve and Bezier curve, you may check the details at java api.
The argument float[] args should also be regarded as return value statement. It delivers the parameters for the instructions above. For SEG_MOVETO, SEG_LINETO, you need 2 params, so modify args[0] and args[1] ( x and y). For SEG_QUADTO, you need 4 params, and SEG_CUBICTO needs 6.
Carefully follows the source code, it won't be hard to create a shape. I haven't complete all the methods in Shape interface yet, but the shape can already be drawn by a g2d instance.

Categories

Resources