java graphics - a shape with two colours - java

(this is java) I have an oval, representing a unit. I want the colour of the oval to represent the unit's health. So a perfectly healthy unit will be all green. and with the unit's health decreasing the oval starts filling with red from the bottom. so, on 50% health the oval would be red in bottom half and green in the top half, and fully red when the unit's dead.
I'm sure the solution here must be obvious and trivial , but I just can't see it.
thanks a lot

You can draw a red oval in the background, then draw a green intersection of an oval and a rectangle, where the rectangle starts below the oval, then moves further to the top to reveal more of the red oval beneath.
You might like to read up on how to construct complex shapes out of primitives here

Override the paint method something like this:
public void paint(Graphics graphics)
{
super.paint(graphics);
Rectangle originalClipBounds = graphics.getClipBounds();
try
{
graphics.clipRect(100, 100, 100, 25);
graphics.setColor(Color.RED);
graphics.fillOval(100, 100, 100, 100);
}
finally
{
graphics.setClip(originalClipBounds);
}
try
{
graphics.clipRect(100, 125, 100, 75);
graphics.setColor(Color.BLUE);
graphics.fillOval(100, 100, 100, 100);
}
finally
{
graphics.setClip(originalClipBounds);
}
}
Might want to enhance it with some double buffering but you get the gist.

You can set the clip on the graphics when you draw the green. Only things within the clip actually get painted.
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g.create();
g2d.setColor(Color.RED);
g2d.fillOval(10, 10, 200, 100);
g2d.setColor(Color.GREEN);
g2d.setClip(10, 10, 200, 50);
g2d.fillOval(10, 10, 200, 100);
}

Related

Can a RadialGradientPaint have multiple center points?

I am currently trying to add a day/night cycle to my game, and I am having trouble with lighting. If there is a light source, I want it to create a circle of light around its area. I've made night time by drawing a black rectangle over the screen that becomes less transparent when its night time. That makes the whole screen darker. The code that I have works for one light source, but if I have a light source that overlaps another light source, it makes a strange darker ring. I understand what is causing that ring, but nothing I have tried is removing the ring.
public void render(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(new Color(20, 20, 20, transparency));
float[] dist = { 0.5f, 1.0f };
Color[] color = { new Color(230, 230, 180, 150), new Color(20, 20, 20, transparency) };
//Color[] color = { new Color(230, 230, 180, 150), new Color(0, 0, 0, 0) }; //Old unused color for the gradient
Area a = new Area(new Rectangle(0, 0, Main_Game.WIDTH, Main_Game.HEIGHT));
for (int i = 0; i < lightList.size(); i++) {
RadialGradientPaint p = new RadialGradientPaint(lightList.get(i).center, lightList.get(i).size, dist, color);
g2d.setPaint(p);
g2d.fillOval(lightList.get(i).center.x - lightList.get(i).size, lightList.get(i).center.y - lightList.get(i).size, lightList.get(i).size*2, lightList.get(i).size*2);
a.subtract(new Area(new Ellipse2D.Double(lightList.get(i).center.x - lightList.get(i).size, lightList.get(i).center.y - lightList.get(i).size, lightList.get(i).size*2, lightList.get(i).size*2)));
}
g2d.setColor(new Color(20, 20, 20, transparency));
g2d.fill(a);
}
That code has a linked list that holds all the light sources. And the transparency variable stores the transparency the box that darkens the screen when it's night time.
The ideal way to fix this would be to combine all the RadialGradientPaint objects for each light into one paint object and that way, the lights wouldn't overlap weirdly.
Here is what it looks like when it works with only one light source:
Here is a picture of the weirdness of lighting that I'm getting at night time (there is no issue during the daytime of the game) when there are two light sources close to each other:
Any sort of help or recommendation to setup this lighting would be greatly appreciated :)
I have tried subtracting one lighting circle from another so that they aren't overlapping, but that made the two lights not merge very nicely. I tried drawing the lights as a rectangle instead of an oval but that made a similar issue.

How to draw a filled oval on a graphics object?

How can I draw a filled oval of color red on a Graphics object created with BufferedImage which is filled with the color black?
What I have tried:
public void draw(){
BufferedImage bufferedImage = new BufferedImage(4, 5, BufferedImage.TYPE_INT_ARGB);
Graphics g = bufferedImage.createGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, 4, 5);
g.setColor(Color.RED);
g.fillOval(1, 1, 2, 2);
g.dispose();
}
The result is a filled red rectangle in a filled black rectangle:
But I want that filled red rectangle to be a filled red oval. How can I do that?
I want to use that image as a mouse cursor.
It looks like a red rectangle because it is only 1 pixel tall and 2 pixels wide. Since there isn't enough space to simulate a curve, you won't get one. Try a bigger oval like g.fillOval(100, 100, 200, 200);

How to use a simple way to rotate a rectangle or triangle in java?

I'm currently working on a project with the theme of earth hour, and we are only allowed to use rectangles, circles and triangles. Here's the image i'm tring to create (not exactly, mine will be much more simplified!):
https://www.google.com/search?q=earth+hour&biw=1366&bih=586&source=lnms&tbm=isch&sa=X&ved=0ahUKEwj__5H0vtvQAhXLrlQKHTi8BagQ_AUIBygC#imgrc=fQkBxn0a8LnwbM%3A
(not sure if you could see the link)
But when i'm coding it, i'm running into trouble to rotate those rectangles to stand on the tangent line of the circle. I'm a student just learnt some basics of java, like loops and arrays. So my quesiton is that if there's some understandable way that doesn't involve some complex and exotic methods that could rotate those rectangles? I know it will probably involve some complicated solutions that is beyond my knowledge. But any help is much appreciated.
this is part of the code that i build the building standing perpendicularly to the circle(earth):
// create mid buildings
Color blc = new Color(0, 0, 0);
Rectangle midBld = new Rectangle(240, 220, 20, 40, blc);
midBld.draw(g);
Rectangle midBld1 = new Rectangle(242, 190, 16, 30, blc);
midBld1.draw(g);
Triangle midBld2 = new Triangle(250, 160, 8, 30, blc);
midBld2.draw(g);
Triangle midBld3 = new Triangle(250, 160, -8, 30, blc);
midBld3.draw(g);
A Rectangle cannot be rotated, its edges are always in parallel to the axis. But you can rotate and translate the coordinate system in witch you draw the shapes. From Graphics2D API doc.
All coordinates passed to a Graphics2D object are specified in a device-independent coordinate system called User Space, which is used by applications. The Graphics2D object contains an AffineTransform object as part of its rendering state that defines how to convert coordinates from user space to device-dependent coordinates in Device Space.
Graphics2D also provide two methods that are useful in this task: translate that moves the origin of the coordinates and rotate that, well, rotates the system.
package graphics;
import javax.swing.*;
import java.awt.*;
/**
* Earth Hour
*/
public class RotateRect extends JFrame {
private static final int WIDTH = 400;
private static final int HEIGHT = 400;
public RotateRect() {
this.setSize(WIDTH, HEIGHT);
this.setTitle("Rotate Rectangles");
this.setContentPane(new JPanel() {
#Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// Background: White
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, this.getWidth(), this.getHeight());
// Draw "Earth": Center(200, 400), Radius=200
g2.setColor(Color.BLACK);
g2.fillOval(0, 200, 400, 400);
// Move origin to center of the canvas (surface of earth)
g2.translate(200, 200);
// Rotate the coordinate system, relative to the center of earth.
// note x, y are in the translated system
// Transforms are accumulative
g2.rotate(-Math.PI/6, 0, 200);
// Fill a rectangle with top-left corner at (-20, 80) in the rotated system
// It's important to make the rectangle symmetrical to the y-axis, otherwise the building looks
// funny.
// Also, make the building "sunk" a little, so that it's fully on the ground.
g2.fillRect(-20, -80, 40, 100);
g2.rotate(Math.PI/3, 0, 200);
g2.fillRect(-20, -80, 40, 100);
g2.rotate(-Math.PI/6, 0, 200);
g2.fill(new Rectangle(-20, -80, 40, 100));
}
});
}
public static void main(String [] args) {
RotateRect rr = new RotateRect();
rr.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
EventQueue.invokeLater(()->rr.setVisible(true));
}
}

How to fade out the edges of a Java2D Area object?

I have a method that creates shadows based on where things are on the screen and the final product of that method is an Area, which I then draw onto the screen and it contains all shadows on screen in the same Area. This is because the drawn shadows are a low opacity so if it is not all one thing they will overlap and the opacity will make it look weird.
The issue that I want the shadows to look like they fade out, but I have absolutely no idea how, or if that would even be possible. Is there a way to soften the edges of the Area or make them gradient fade out? I tried to do graphics2D.setPaint(new GradientPaint[a gradient effect]) but it did nothing.
Thanks in advance
EDIT: Here is a screenshot of the program making a shadow around a 'building' rectangle. The green rectangle is to show the effect of the shadow. The end result I want is instead of the shadow abruptly ending, it should fade out.
i guess you have problems setting up the proper colors for the gradient:
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillRect(30, 30, 50, 20);
Graphics2D g2d = (Graphics2D) g;
Polygon p = new Polygon(new int[]{10,20,50,50,40,10}, new int[]{10,10,40,50,50,20}, 6);
Area a = new Area(p);
Color b = new Color(0xFF000000, true); //using colors with transparency!!!
Color w = new Color(0x00FFFFFF, true); //using colors with transparency!!!
//try to use proper values for the x/y values - both, start and end
GradientPaint gradient = new GradientPaint(0, 0, b, 40, 40, w);
g2d.setPaint(gradient);
g2d.fill(a); // fill your area!
}
result is a gradient with alpha (Transparency) ...
Area drawn in red <==> Area drawn with Gradient
don't forget to set the alpha value 0xAARRGGBB to FF for 100% opaque (0xFF000000 is black 100%opaque) to 0 (0x00FFFFFF white, 100% transparent)

Create a House using java

Okay I was wondering three things so right now my house background is white how do I make it part blue and green for the grass bottom part. Also my line is going downward how do I make go up toward northeast to make the triangle for the ceiling of the house? Last thing what about adding a tree do I make a bunch of arcs to get the "bush curviness" of the tree?
import java.awt.Color;
import java.awt.Canvas;
import java.awt.Graphics;
import java.awt.Polygon;
public class House extends Canvas {
public House() {
setBackground(Color.WHITE);
}
public void paint(Graphics window) {
window.setColor(Color.BLUE);
window.drawRect(250, 300, 50, 125);
window.fillRect(350, 300, 50, 135);
window.setColor(Color.PINK);
window.drawRect(200, 150, 350, 300);
window.fillRect(200, 150, 350, 300);
window.setColor(Color.GREEN);
Polygon poly = new Polygon();
poly.addPoint(100, 200);
poly.addPoint(200, 400);
poly.addPoint(300, 200);
window.fillPolygon(poly);
}
}
how do I make it part blue and green for the grass bottom part
Don't use "magic" numbers, use absolute known values, like getWidth and getHeight, for example:
window.setColor(Color.BLUE);
window.fillRect(0, 0, getWidth(), getHeight() / 2);
window.setColor(Color.GREEN);
window.fillRect(0, getHeight() / 2, getWidth(), getHeight() / 2);
Also my line is going downward how do I make go up toward northeast to make the triangle for the ceiling of the house?
It's doing exactly what you told it to, remember, the top/left corner is 0x0, meaning coordinates increase in size as the move right/down
Polygon poly = new Polygon();
poly.addPoint(100, 200);
poly.addPoint(200, 100);
poly.addPoint(300, 200);
Last thing what about adding a tree do I make a bunch of arcs to get the "bush curviness" of the tree?
You could just use a series of over lapping ovals, using Graphics#fillOval or Graphics#drawArc
I would strongly recommend that you have a look at 2D Graphics for techniques and ideas when using Graphics.
I'd also encourage you to have a look at Painting in AWT and Swing and Performing Custom Painting to understand how painting actually works in AWT/Swing

Categories