I am having trouble getting if-else statement to draw correct colors for my program. I'm under the impression that the if-statements are not organized correctly with the else statement and the "setColor," I am stumped on how to make the black render as yellow. The best way to describe it is to show it.
I'd appreciate any help!
My output (wrong):
Goal output (right):
My code:
import java.awt.*;
public class IfGridEx3 {
public static void main(String[] args) {
DrawingPanel panel = new DrawingPanel(400, 400);
panel.setBackground(Color.blue);
Graphics g = panel.getGraphics();
int sizeX = 40;
int sizeY = 40;
for (int x = 0; x < 10; x++) {
for (int y = 0; y < 10; y++) {
int cornerX = x*sizeX;
int cornerY = y*sizeY;
if (x > 1)
if (x < 8)
if (y > 1)
if (y < 8)
g.setColor(Color.green);
else
g.setColor(Color.yellow);
g.fillRect(cornerX+1, cornerY+1, sizeX-2, sizeY-2);
g.setColor(Color.black);
g.drawString("x="+x, cornerX+10, cornerY+15); // text is positioned at its baseline
g.drawString("y="+y, cornerX+10, cornerY+33); // offsets from the corner do centering
}
}
}
}
Your else is based only on result of last if, so g.setColor(Color.yellow); will be invoked only if all conditions
if (x > 1)
if (x < 8)
if (y > 1)
will be true (otherwise condition in last if will not even be tested),
and result evaluation of condition from last if
if (y < 8)
will be false. It means, that else will not be invoked if previous 3 conditions are false, which is why you are seeing some areas unset.
To solve this problem you can create single condition for center area
if (x > 1 && x < 8 && y > 1 && y < 8){
g.setColor(Color.green);
} else {
g.setColor(Color.yellow);
}
Try this :
if((x>=2 && x<=7) && (y>=2 &&y<=7))
//fill color green
else
//fill yello color
Related
I have created the function of a game that a bullet goes to the way of the crosshair with a constant speed. But I have a question: how can I make the bullet go the opposite way to the way it has been shot?
Let me explain what I am trying to do. When the bullet touches a specific material, it goes the opposite way. Like this image:
As you can see, the bullet is "bouncing" to the opposite way.
Here is my function where I am setting the linear velocity from the bullet if you need it:
public void direccion(float xx, float yy) {
float mousex = Gdx.input.getX();
float mousey = 0;
if (shoot.getAngle() > 6.1 && shoot.getAngle() < 9.6) {
mousey = Gdx.input.getY() - 5;
} else {
mousey = Gdx.input.getY();
}
Vector3 mousePos = new Vector3(mousex, mousey, 0);
jugador.camera.unproject(mousePos);
float speed = 60f;
float velx = mousePos.x - xx;
float vely = mousePos.y - yy;
float length = (float) Math.sqrt(velx * velx + vely * vely);
if (length != 0) {
velx = velx / length;
vely = vely / length;
}
shoot.setLinearVelocity(velx * speed, vely * speed);
Hope you could understand my idea. Can anyone help me with this?
After thinking about how can i do this, I had an idea.
According to vector mathematics, the bullet can take these values after it touches the material in question for the rebound ...
As you can see in the picture:
After this analysis, i have adapted to a simple code.
vectorPart = shoot.getLinearVelocity();
if ((vectorPart.x > 0 && vectorPart.y < 0) || (vectorPart.x > 0 && vectorPart.y > 0)
|| (vectorPart.x < 0 && vectorPart.y < 0) || (vectorPart.x < 0 && vectorPart.y > 0)) {
vectorPart = new Vector2(vectorPart.x, vectorPart.y * -1);
} else {
vectorPart = new Vector2(vectorPart.x * -1, vectorPart.y * -1);
}
shoot.setLinearVelocity(vectorPart.x, vectorPart.y);
I evaluated the linearVelocity vector and then i modified the signs of it.
With this code and anylisis everything works fine!.
I'm really new to Java and am working on a class project - I need to draw some pixels in a panel. I was given the jar code for the panel, and now I need to make different trails - specifically, I need to create a trail of pixels that will go around the perimeter of the panel, and I need to create some circles.
Regarding the boxes - I've gotten part of it to work. My pixels starts in the upper left corner and run to the upper right corner, go down the right side of the panel, and then it goes a little crazy - I'm not sure if it stops at the bottom right corner or goes below the bounds of the panel itself, but it doesn't complete its trip around the perimeter. My code is:
import cs251.lab1.Display;
public class Visualizer {
private static final int PIXEL_SIZE = 50;
public static void main(String[] args) {
Display panel = new Display(10, PIXEL_SIZE);
drawWrappingDots(panel);}
public static void drawWrappingDots(Display panel) {
int x = 1;
int y = 1;
while (x > 0 && y > 0){
if (x < panel.getWidth()){
panel.drawNextPixel(x, y);
x++;
}
if (x == panel.getWidth()){
panel.drawNextPixel(x, y);
y++;
}
if (x > 0 && y == panel.getHeight()){
panel.drawNextPixel(x, y);
x--;
}
if (x == 0 && y == panel.getHeight()){
panel.drawNextPixel(x, y);
y--;
}
What am I doing wrong?
Second, how do I draw a circle? I know it needs to use the math library, but I'm not sure how to go about this. Any help on this is much appreciated. Thank you.
As for the first question, you could use multiple if-statements:
int x = 1; //x starts a little to the right of 0
int y = 0; //y starts at 0
while (x > 0 && y > 0){
if (x < panel.getWidth() && y == 0){
panel.drawNextPixel(x, y);
x++;
}
else if (x == panel.getWidth() && y != panel.getHeight()){
panel.drawNextPixel(x, y);
y++;
}
else if (x > 0 && y == panel.getHeight()){
panel.drawNextPixel(x, y);
x--;
}
else {
panel.drawNextPixel(x, y);
y--;
}
}
This way, you check both the x and y coordinates when deciding which way you want to draw the pixels. It starts with x=1 and y=0, then moves to the right until x hits the border, then moves downward until y hits the border, then moves left until x hits 0, and finally moves upwards until y hits 0 and the while condition becomes false.
As for the circle, you need to use trigonometry. Designate a point in the middle of the panel to draw the circle. Then designate a radius you want for the circle.
int middle = 50;
int radius = 20;
Then, you use trigonometry:
int deg = 0;
while ( deg <= 360 ) {
x = middle + (int)(Math.cos(deg)*radius);
y = middle + (int)(Math.sin(deg)*radius);
panel.drawNextPixel(x, y);
deg++;
}
That should do it.
Change while cycle to:
while (x > 0 && y > 0){
if (x < panel.getWidth()){
panel.drawNextPixel(x, y);
x++;
}
if (x == panel.getWidth() && y != panel.getHeight()){
panel.drawNextPixel(x, y);
y++;
}
if (x > 1 && y == panel.getHeight()){
panel.drawNextPixel(x, y);
x--;
}
if (x == 1 && y > 0){
panel.drawNextPixel(x, y);
y--;
}
Maybe, this is not perfect solution.
Im writing a small painting programm in java, and im stucked on the pen:
Therory: When im dragging the mouse i have to fill the circles between P(draggedX|draggedY) and P2(mouseX|mouseY) with circles. So i have to create a line / a path (?..) and calculate all points that are on it.
What ive tried:
double m = 0;
int width = draggedX - mouseX;
int height = draggedY - mouseY;
if(draggedX - mouseX != 0){
m = (draggedY - mouseY) / (draggedX - mouseX);
}
if(width > 0){
for(int i = 0; i < width; i++) {
double x = mouseX + i;
double y = mouseY + (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else if(width < 0){
for(int i = -width; i > 0; i--) {
double x = mouseX + i;
double y = mouseY + (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else{
if(height > 0){
for(int i = 0; i < height; i++){
g.fillOval(mouseX, (int) i + mouseY, 5, 5);
}
}
else if(height < 0){
for(int i = -height; i > 0; i--){
g.fillOval(mouseX, (int) i + mouseY, 5, 5);
}
}
}
It didnt work correct. sometimes curious lines splashed up and circles werent painted, like this:
Any other ideas, how to solve it?
Thank you!
Java will not generate events for all intermediate points - you can test this by drawing a point at each place where you actually receive an event. If the mouse moves too quickly, you will miss points. This happens in all drawing programs.
Bresenham's line-drawing algorithm is the traditional way to find integer pixels between two pixels coordinates. But you are programming in Java, and you have something much better: you can trace arbitrary paths, defined through coordinates. Two flavors are available,
The old Graphics version (g is a Graphics, possibly from your paintComponent() method):
// uses current g.setColor(color)
g.drawPolyline(xPoints, yPoints, int nPoints); // xPoints and yPoints are integer arrays
And the new Shape-based version (g2d is a Graphics2D; your Graphics in Swing can be cast to Graphics2D without problems):
// uses current stroke
g2d.draw(p); // p is a Path2D, build with successive moveTo(point) and lineTo(point)
I recommend the second version, since the stroke offers a lot more flexibility (line width, dashes, ...) than just simple colors
The division between two integers discards the fractional part: for example 2/3 returns 0. You can use floating point types for computation to keep the fractional parts.
double m;
m = (double) (draggedY - mouseY) / (draggedX - mouseX);
In addition to what the other answer said, you also need to do your drawing differently if the absolute value of m is greater than 1 or not. If it's 1 or less, then you'll want to iterate along the x direction and calculate the y from the slope. Otherwise, you'll need to iterate along the y direction and calculate the m from the (inverse) slope. You have the right idea in the code, but it's not quite implemented correctly. It should be something more like this:
if (abs(m) <= 1)
{
for (int i = startX; i < endX; i++)
{
float y = startY + (float)i * m;
float x = i;
g.fillOval(x, y, 5, 5);
}
}
else
{
for (int i = startY; i < endY; i++)
{
float x = startX + (float)i / m;
float y = i;
g.fillOval(x, y, 5, 5);
}
}
im programing a small drawing program.
But i have a bug with painting. left, right, does work correct, but top, bottom creates curious images. why? ANyone a idea? Im programming in java.
The Bug: (left normal, right bug) And no it ISNT because mouseevent isnt getting all points. Im drawing all circles between to points i actually get. see the code.
The code for painting:
double m = 0;
int width = draggedX - mouseX;
int height = draggedY - mouseY;
if(draggedX - mouseX != 0){
m = (double) (draggedY - mouseY) / (double) (draggedX - mouseX);
}
if(width > 0){
for(int i = 0; i < width; i++) {
double x = mouseX + i;
double y = mouseY + (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else if(width < 0){
for(int i = -width; i > 0; i--) {
double x = mouseX - i;
double y = mouseY - (m * i);
g.fillOval((int) x, (int) y, 5, 5);
}
}
else{
if(height > 0){
for(int i = 0; i < height; i++){
g.fillOval(mouseX, (int) i + mouseY, 5, 5);
}
}
else if(height < 0){
for(int i = -height; i > 0; i--){
g.fillOval(mouseX, (int) i - mouseY, 5, 5);
}
}
else{
g.fillOval(mouseX, mouseY, 5, 5);
}
}
Mouse events are tricky, they don't always follow a linear progression. Instead of using oval, I would simple paint lines between each distinct event point. If you need to make the lines thicker, the take a look at Stroke (or BasicStroke in particular)
For example Resize the panel without revalidation
I also have a very bad feeling your a painting directly to the graphics context by using getGraphics instead of using paintComponent
Suppose you draw a nearly vertical line with width = 10 and height = 200. With the given loop you will draw exactly 10 points, which is not enough to cover the entire line.
To fix this you need to check if height > width and in that case plot the points "vertically," iterating along the y-axis.
// when height > width
for(int i = 0; i < height; i++) {
double x = mouseX + i/m;
double y = mouseY + i;
g.fillOval((int) x, (int) y, 5, 5);
}
As you can see the algorithm to plot a single line becomes quite complex. That's why Bresenham's algorithm is such a big deal.
I'm using the following piece of code to iterate over all pixels in an image and draw a red 1x1 square over the pixels that are within a certain RGB-tolerance. I guess there is a more efficient way to do this? Any ideas appreciated. (bi is a BufferedImage and g2 is a Graphics2D with its color set to Color.RED).
Color targetColor = new Color(selectedRGB);
for (int x = 0; x < bi.getWidth(); x++) {
for (int y = 0; y < bi.getHeight(); y++) {
Color pixelColor = new Color(bi.getRGB(x, y));
if (withinTolerance(pixelColor, targetColor)) {
g2.drawRect(x, y, 1, 1);
}
}
}
private boolean withinTolerance(Color pixelColor, Color targetColor) {
int pixelRed = pixelColor.getRed();
int pixelGreen = pixelColor.getGreen();
int pixelBlue = pixelColor.getBlue();
int targetRed = targetColor.getRed();
int targetGreen = targetColor.getGreen();
int targetBlue = targetColor.getBlue();
return (((pixelRed >= targetRed - tolRed) && (pixelRed <= targetRed + tolRed)) &&
((pixelGreen >= targetGreen - tolGreen) && (pixelGreen <= targetGreen + tolGreen)) &&
((pixelBlue >= targetBlue - tolBlue) && (pixelBlue <= targetBlue + tolBlue)));
}
if (withinTolerance(pixelColor, targetColor)) {
bi.setRGB( x, y, 0xFFFF0000 )
}
BufferedImage's setRGB method's third parameter, as explained in the Javadoc, takes a pixel of the TYPE_INT_ARGB form.
8 bits for the alpha (FF here, fully opaque)
8 bits for the red component (FF here, fully flashy red)
8 bits for the green component (0, no green)
8 bits for the blue component.