I'm making a game where you start by drawing your map. At the moment it works by having an Area instance variable and then when the player clicks/drags the mouse it adds Ellipse2Ds to it. Here's what I mean:
Area land = new Area();
And then in the MouseDragged method
Point2D mouse = e.getPoint();
Ellipse2D ter = new Ellipse2D.Double(mouse.getX() - drawRad, mouse.getY() - drawRad, drawRad*2, drawRad*2);
land.add(new Area(ter));
And then basically the same except land.subtract(new Area(ter)) for erasing.
My problem with this is that after doing a lot of drawing it becomes very slow to draw the Area. the other problem is that I would like to be able to easily get the outline of the drawing, and I haven't found a good way of doing that using Areas. Using area.getPathIterator is not nearly accurate enough.
So I'm wondering what other ways of saving drawings are? I can't just have an array of Ellipses because then erasing wouldn't work.
Thanks!
If you are drawing the same thing over and over it may be worth while to draw it to an image once or load it from a file at start up and then just paint the image rather than painting all the individual shapes.
To load from a file, put your picture file in the same directory as your .java file and load:
BufferedImage img = ImageIO.read(this.getClass().getResource("picture.png"));
To draw on the image once:
BufferedImage img = new BufferedImage(width,height, BufferedImage.TYPE_4BYTE_ABGR);
Graphics2D g = img.createGraphics();
In your paintComponent method you draw the image somewhere.
g.drawImage(img, 0, 0, this);
If you have something moving over a background, instead of adding and subtracting the moving item. Just draw the background and then draw the thing that moves, drawing the background will effectively erase the old position with less computation.
Related
I want to rotate the text present on my JComponent to vertical, JComponent also contains border painted in paintComponent method, I don't want to rotate that border, only text.
I already used graphics2D rotate function, but it rotate component border as well, which fails when my component is rectangle.
Please suggest me any approch to rotate only text.
This is currently my JComponent :
And what I want :
Actually it's not duplicate. I already used below code:
Graphics2D g2 = (Graphics2D) g;
g2.rotate(Math.PI / 4, bi.getWidth() / 2, bi.getHeight() / 2);
but problem is that, it also rotate border, I don't want that.
All the solutions given are not working, it rotate the border as well. I don't want to rotate the border, only text.
This is what I get after rotate with some angle:
Remember that the Graphics object has a lot of state in it. This includes the current transformation. Your current code modifies the state and does not restore it to the original situation.
After drawing your image, you should "undo" the rotation. This can be done either by rotating in the other the direction or by creating a new graphics object (g2.create()) specifically to draw the rotated content. If you do the latter, make sure to dispose() the temporary graphics object you created.
I recently watched a YouTube video of Notch coding the game "Minicraft" from scratch for the Lundum Dare competition. The game is in Java, and what confused me is that he has a BufferedImage object that he modifies and draws to the screen like this:
private BufferedImage img = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
then
g.drawImage(img, extra parameters of the coordinates, etc);
When I was learning how to use the Java Graphics object, I learned to separately draw all the things that I wanted on my screen like this:
g.drawImage(player, ...);
g.drawImage(background, ...);
etc...
But it seems he builds the BufferedImage based on what each of the individual parts look like (player, background, ...) and then just draws that only. What is the value in doing this? What is the difference between drawing one image instead of individually drawing all the images?
I'm developing a java application for draw through the drag of the mouse.
I need the JPanel to be transparent, but in this way lose the function rubber.
With the getBackground() can set the transparent color to use, but the path is not going to erase what was previously drawn.
Drawing with transparent means... drawing with transparent, so the previous color stays intact. What you want is clearing a part of the image (you're drawing on an image surface, right?). That can be done using the clearing rule of AlphaComposite.
// Assuming Graphics2D g, maybe from BufferedImage
g.setComposite(AlphaComposite.Clear);
// drawing now clears
I have a Canvas class, which is an extension of JPanel. I need to draw multiple custom shapes on it and be able to resize them. I finished drawing all the elements, I did the logic for selecting those elements and drawing a section rectangle, but I can't resize them. I tried using affine transformation and the scale() method, but when I scale using those methods, it scales all elements on the canvas, not just one. Any idea how could I make it scale only one element, without scaling others?
Assuming your painting your elements within the paintComponent method...
Create a new copy of the Graphics context...
Graphics2D g2d = (Graphics2D)g.create();
Create and apply you affine transformation...
AffineTransform at = anew AffineTransform();
at.translate(...);
at.scale(...);
g2d.setTransform(at);
Paint your element(s) and dispose of the Graphics context you have created...
//... Paint...
g2d.dispose();
Repeat as required.
The other method might be to get the current transformation and re-apply it when your done...
AffineTransform currenrAT = g2d.getTransform();
// Apply new transform and paint...
g2d.setTransform(currentAT);
I have written a game, and now I would like to learn how to manipulate camera.
My drawing consists of this:
private void render()
{
// CREATE THE GRAPHICS
Graphics2D g = (Graphics2D) bufferStrategy.getDrawGraphics();
// MAKE THE PICTURE WHERE WE WILL PAINT EVERYTHING AT ONCE
g.clearRect(0, 0, WIDTH, HEIGHT);
// PAINT ANYTHING WE NEED HERE
render(g);
g.dispose();
// SHOW THE WHOLE IMAGE RATHER THAN PAININT ONE OBJECT AT A TIME
bufferStrategy.show();
}
My BufferStrategy is created like so:
canvas = new Canvas();
// once again I add 1 because java is stupid that's why
canvas.setBounds(0, 0, WIDTH+1, HEIGHT+1);
//canvas.setBounds(bounds);
canvas.setIgnoreRepaint(true);
// SET GRAPHICS DEVICE
canvas.createBufferStrategy(2);
bufferStrategy = canvas.getBufferStrategy();
In the render function I draw my game world with all the platforms where they should be. Now if the game world is bigger than the window size, and I would like to be able to focus on the character and draw the part of the world where character is, how would I do that? So let's say my window is 300 x 300, and my game world is 900 x 900, and my character is located in the middle so that I would like to display the part of the graphics where x is 150 y is 150 and the width and height is 300 x 300.
So how would I go about taking that Graphics2D and shifting it over by specified values? I am very sorry if this question has been answered or is easy, but I am new to this and really would like some help.
Thanks for any help in advance.
I have tried all I know to no avail.
So how would I go about taking that Graphics2D and shifting it over by specified values?
Why must you shift the Graphics2D? Why not create an image that extends beyond the viewport and simply shift the viewport. Then if the user gets close to the edge of the viewport, add an image to the leading edge and lop off a portion on the trailing edge.
This is what affine transformations are for.
http://docs.oracle.com/javase/1.4.2/docs/api/java/awt/geom/AffineTransform.html
Shift the character to the center of the screen by applying a shift.
In your paint component, save the current transformation.
Create a new transformation that will then shift the screen to where you would like it to be.
Set Graphics2D to use your new transformation.
Draw the character at the original coordinates
Set Graphics2D to use the original transformation.