I have an issue where I'm unable to see Color Picker.
I'm trying to generate a lot of lines to make patterns to make me feel accomplished. It's a side project.
I'm not the best at coding so I need help. Also you have to minimize the window and open it back up to make it work when you are running it by the way.
*update I've figured out that the color picker is there but just behind all of my lines that I've drawn.
Here is my code.
import controlP5.ColorPicker;
import controlP5.ControlEvent;
import controlP5.ControlP5;
import processing.core.PApplet;
public class main extends PApplet {
ControlP5 cp5;
ColorPicker cp;
boolean guiState;
int col;
public static void main(String[] args) {
PApplet.main("main");
}
void drawLines() {
float lineLength = sqrt(height * height + width * width);
float nsHueStart = random((float) 10);
float nsSatStart = random((float) 10);
float nsRotStart = random((float) 10);
float nsHStart = random((float) 10);
float nsWStart = random((float) 10);
int lineWidthMax = 50;
for (int lineWidth = 1; lineWidth <= lineWidthMax; ++lineWidth) {
strokeWeight((5 * pow(lineWidth, 2)));
nsHueStart += 001;
float nsHue = nsHueStart;
float nsSat = nsSatStart;
float nsH = nsHStart;
float divH;
float divW;
for (float idxH = 0; idxH < height; idxH += divH) {
divH = map(noise(nsH), 0, 1, 80, 200);
float nsRot = nsRotStart;
float nsW = nsWStart;
for (float idxW = 0; idxW < width; idxW += divW) {
divW = map(noise(nsW), 0, 1, 0, 5); // do not use 2D noise
float brushHue = map(noise(nsHue), 0, 1, 0, 720) % 360; // various colors
float brushSat = map(noise(nsSat), 0, 1, 20, 70) / map(lineWidth, 1, lineWidthMax, 1, (float) 1.8);
float brushBri = map(noise(nsSat), 0, 1, 8, 15) / map(lineWidth, 1, lineWidthMax, 1, (float) (lineWidthMax * 2.8));
float brushAlp = 100;
float brushSiz = lineLength;
float brushRot = map(noise(nsRot), 0, 1, -60, 60);
pushMatrix();
translate(idxW, idxH);
canvasRotation(brushRot);
stroke(brushHue, brushSat, brushBri, brushAlp);
line(-brushSiz, 0, brushSiz, 0);
popMatrix();
nsHue += 002;
nsRot += 005;
nsW += 01 + noise(nsH) / 10; // not to be same shape
}
nsSat += 5;
nsH += 8;
}
}
}
public void settings() {
size(2560, 1395);
smooth(8);
}
public void setup() {
noStroke();
cp5 = new ControlP5(this);
cp = cp5.addColorPicker("picker")
.setPosition(60, 100)
.setColorValue(color(0, 128, 255, 128))
;
colorMode(HSB, 360, 100, 100, 100);
blendMode(SCREEN);
cp5.show();
frameRate(60);
}
public void draw() {
background(cp.getColorValue());
fill(0, 80);
rect(50, 90, 275, 80);
translate(0, 0);
drawLines();
}
public void controlEvent(ControlEvent c) {
if (c.isFrom(cp)) {
float r = (c.getArrayValue(0));
float g = (c.getArrayValue(1));
float b = (c.getArrayValue(2));
float a = (c.getArrayValue(3));
col = color(r, g, b, a);
println("event\talpha:"+a+"\tred:"+r+"\tgreen:"+g+"\tblue:"+b+"\tcol"+col);
}
}
void canvasRotation(float degrees) {
rotate(radians(degrees));
}
public void toggleGUI(boolean state) {
if (state) {
cp5.show();
} else {
cp5.hide();
background(200);
}
guiState = state;
}
public void keyPressed() {
if (keyCode == LEFT) toggleGUI(guiState);
switch (key) {
case ('1'):
cp.setArrayValue(new float[]{120, 0, 120, 255});
break;
case ('2'):
cp.setColorValue(color(255, 0, 0, 255));
break;
}
}
}
Related
Attatched are 2 methods from code that prints out a gird of 25 boxes in jframe and when you click the space bar the boxes fill up one by one with random colors. I need to modify the code so the first 13 boxes show up in shades of red and the next 12 show up only in shades of blue. Also, I need to change the background color to a random color. Thanks.
public void setColor()
{
int r = (int) (Math.random()*256);
int g = (int) (Math.random()*256);
int b = (int) (Math.random()*256);
myColors[clicked] = new Color(r,g,b);
}
public void paint(Graphics g)
{
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.black);
counter = 0;
for (int x = 0; x < myFloor.length; x++)
{
for (int y = 0; y < myFloor[0].length; y++)
{
if (myColors[counter] != null)
{
for (int i = 0; i < counter+1; i++)
{
setColor();
g2.setColor(myColors[i]);
g2.fill(myFloor[x][y]);
}
}
else
{
g2.setColor(Color.BLACK);
g2.draw(myFloor[x][y]);
}
counter++;
}
}
}
I need to modify the code so the first 13 boxes show up in shades of red and the next 12 show up only in shades of blue. Also, I need to change the background color to a random color. Thanks.
You could...
Use a "color blending" algorithm, which could blend a range of colors together.
The following example basically constructs a color range of dark to light red, light blue to dark blue, split over a normalised range of 0-51% and 52-100%
This has a neat side effect of filling the first 13 squares with shades of red and the last 12 with shades of blue.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.text.NumberFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int cols = 5;
private int rows = 5;
private int cellSize = 50;
private ColorGradient colorGradient;
public TestPane() {
colorGradient = new ColorGradient(
new float[]{0f, 0.51f, 0.52f, 1f},
new Color[]{Color.RED.darker(), Color.RED.brighter(), Color.BLUE.brighter(), Color.BLUE.darker()}
);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(cols * cellSize, rows * cellSize);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Color borderColor = new Color(0, 0, 0, 64);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
float progress = ((row * rows) + col) / (float)(rows * cols);
g2d.setColor(colorGradient.colorAt(progress));
g2d.fillRect(col * cellSize, row * cellSize, cellSize, cellSize);
g2d.setColor(borderColor);
g2d.drawRect(col * cellSize, row * cellSize, cellSize, cellSize);
}
}
g2d.dispose();
}
}
public class ColorGradient {
private float[] fractions;
private Color[] colors;
public ColorGradient(float[] fractions, Color[] colors) {
this.fractions = fractions;
this.colors = colors;
}
public Color colorAt(float progress) {
Color color = null;
if (fractions != null) {
if (colors != null) {
if (fractions.length == colors.length) {
int[] indicies = getFractionIndicies(progress);
float[] range = new float[]{fractions[indicies[0]], fractions[indicies[1]]};
Color[] colorRange = new Color[]{colors[indicies[0]], colors[indicies[1]]};
float max = range[1] - range[0];
float value = progress - range[0];
float weight = value / max;
color = blend(colorRange[0], colorRange[1], 1f - weight);
} else {
throw new IllegalArgumentException("Fractions and colours must have equal number of elements");
}
} else {
throw new IllegalArgumentException("Colours can't be null");
}
} else {
throw new IllegalArgumentException("Fractions can't be null");
}
return color;
}
protected int[] getFractionIndicies(float progress) {
int[] range = new int[2];
int startPoint = 0;
while (startPoint < fractions.length && fractions[startPoint] <= progress) {
startPoint++;
}
if (startPoint >= fractions.length) {
startPoint = fractions.length - 1;
}
range[0] = startPoint - 1;
range[1] = startPoint;
return range;
}
protected Color blend(Color color1, Color color2, double ratio) {
float r = (float) ratio;
float ir = (float) 1.0 - r;
float rgb1[] = new float[3];
float rgb2[] = new float[3];
color1.getColorComponents(rgb1);
color2.getColorComponents(rgb2);
float red = rgb1[0] * r + rgb2[0] * ir;
float green = rgb1[1] * r + rgb2[1] * ir;
float blue = rgb1[2] * r + rgb2[2] * ir;
if (red < 0) {
red = 0;
} else if (red > 255) {
red = 255;
}
if (green < 0) {
green = 0;
} else if (green > 255) {
green = 255;
}
if (blue < 0) {
blue = 0;
} else if (blue > 255) {
blue = 255;
}
Color color = null;
try {
color = new Color(red, green, blue);
} catch (IllegalArgumentException exp) {
NumberFormat nf = NumberFormat.getNumberInstance();
System.out.println(nf.format(red) + "; " + nf.format(green) + "; " + nf.format(blue));
exp.printStackTrace();
}
return color;
}
}
}
Oh, and if you want to generate a random color, you could simply use something like...
Random rnd = new Random();
Color color = new Color(rnd.nextInt(255), rnd.nextInt(255), rnd.nextInt(255));
You could...
Define the red and blue color bands separately, and then, based on the cell index, decide which band you're going to use.
This provides more "absolute" control over the decision making process. For example, the following index allows the cells between 0-12 inclusively to draw colors from the red band and 13-24 from blue band.
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.text.NumberFormat;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class Range {
private int lower;
private int upper;
public Range(int lower, int upper) {
this.lower = lower;
this.upper = upper;
}
public int getLower() {
return lower;
}
public int getUpper() {
return upper;
}
public boolean contains(int value) {
return value >= getLower() && value <= getUpper();
}
public int getDistance() {
return getUpper() - getLower();
}
public float normalised(int value) {
return (value - getLower()) / (float)getDistance();
}
}
public class TestPane extends JPanel {
private int cols = 5;
private int rows = 5;
private int cellSize = 50;
private ColorBand redColorBand;
private ColorBand blueColorBand;
private Range redRange = new Range(0, 12);
private Range blueRange = new Range(13, 24);
public TestPane() {
redColorBand = new ColorBand(
new float[]{0f, 1f},
new Color[]{Color.RED.darker(), Color.RED.brighter()}
);
blueColorBand = new ColorBand(
new float[]{0f, 1f},
new Color[]{Color.BLUE.brighter(), Color.BLUE.darker()}
);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(cols * cellSize, rows * cellSize);
}
protected Color colorForSqaure(int index) {
if (redRange.contains(index)) {
return redColorBand.colorAt(redRange.normalised(index));
} else if (blueRange.contains(index)) {
return blueColorBand.colorAt(blueRange.normalised(index));
}
return Color.BLACK;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Color borderColor = new Color(0, 0, 0, 64);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
g2d.setColor(colorForSqaure(((row * rows) + col)));
g2d.fillRect(col * cellSize, row * cellSize, cellSize, cellSize);
g2d.setColor(borderColor);
g2d.drawRect(col * cellSize, row * cellSize, cellSize, cellSize);
}
}
g2d.dispose();
}
}
public class ColorBand {
private float[] fractions;
private Color[] colors;
public ColorBand(float[] fractions, Color[] colors) {
this.fractions = fractions;
this.colors = colors;
}
public Color colorAt(float progress) {
Color color = null;
if (fractions != null) {
if (colors != null) {
if (fractions.length == colors.length) {
int[] indicies = getFractionIndicies(progress);
float[] range = new float[]{fractions[indicies[0]], fractions[indicies[1]]};
Color[] colorRange = new Color[]{colors[indicies[0]], colors[indicies[1]]};
float max = range[1] - range[0];
float value = progress - range[0];
float weight = value / max;
color = blend(colorRange[0], colorRange[1], 1f - weight);
} else {
throw new IllegalArgumentException("Fractions and colours must have equal number of elements");
}
} else {
throw new IllegalArgumentException("Colours can't be null");
}
} else {
throw new IllegalArgumentException("Fractions can't be null");
}
return color;
}
protected int[] getFractionIndicies(float progress) {
int[] range = new int[2];
int startPoint = 0;
while (startPoint < fractions.length && fractions[startPoint] <= progress) {
startPoint++;
}
if (startPoint >= fractions.length) {
startPoint = fractions.length - 1;
}
range[0] = startPoint - 1;
range[1] = startPoint;
return range;
}
protected Color blend(Color color1, Color color2, double ratio) {
float r = (float) ratio;
float ir = (float) 1.0 - r;
float rgb1[] = new float[3];
float rgb2[] = new float[3];
color1.getColorComponents(rgb1);
color2.getColorComponents(rgb2);
float red = rgb1[0] * r + rgb2[0] * ir;
float green = rgb1[1] * r + rgb2[1] * ir;
float blue = rgb1[2] * r + rgb2[2] * ir;
if (red < 0) {
red = 0;
} else if (red > 255) {
red = 255;
}
if (green < 0) {
green = 0;
} else if (green > 255) {
green = 255;
}
if (blue < 0) {
blue = 0;
} else if (blue > 255) {
blue = 255;
}
Color color = null;
try {
color = new Color(red, green, blue);
} catch (IllegalArgumentException exp) {
NumberFormat nf = NumberFormat.getNumberInstance();
System.out.println(nf.format(red) + "; " + nf.format(green) + "; " + nf.format(blue));
exp.printStackTrace();
}
return color;
}
}
}
You could...
Predefine the colors up-front
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int cols = 5;
private int rows = 5;
private int cellSize = 50;
private Color[] colors = new Color [] {
new Color(64, 0, 0),
new Color(79, 0, 0),
new Color(94, 0, 0),
new Color(109, 0, 0),
new Color(124, 0, 0),
new Color(139, 0, 0),
new Color(154, 0, 0),
new Color(169, 0, 0),
new Color(184, 0, 0),
new Color(199, 0, 0),
new Color(214, 0, 0),
new Color(229, 0, 0),
new Color(244, 0, 0),
new Color(0, 0, 64),
new Color(0, 0, 80),
new Color(0, 0, 96),
new Color(0, 0, 112),
new Color(0, 0, 128),
new Color(0, 0, 144),
new Color(0, 0, 160),
new Color(0, 0, 176),
new Color(0, 0, 192),
new Color(0, 0, 208),
new Color(0, 0, 224),
new Color(0, 0, 240),
};
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(cols * cellSize, rows * cellSize);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
Color borderColor = new Color(0, 0, 0, 64);
for (int row = 0; row < rows; row++) {
for (int col = 0; col < cols; col++) {
g2d.setColor(colors[((row * rows) + col)]);
g2d.fillRect(col * cellSize, row * cellSize, cellSize, cellSize);
g2d.setColor(borderColor);
g2d.drawRect(col * cellSize, row * cellSize, cellSize, cellSize);
}
}
g2d.dispose();
}
}
}
float x = 100;
float y = 100;
float p = 150;
float l = 10;
float a = 100;
float b = 100;
float n =20;
int value = 255;
int r = 150;
int t = 100;
int s = 100;
int w = 60;
int h = 60;
int z = 11;
int eyeSize = 10;
int pigNose = 30;
int pigBody = 30;
int pigEars = 35;
int pigTail = 20;
int otherpigTail = 200;
int speed = 1;
void setup () {
size (600, 600);
a = width/2.5;
b = height/2;
}
void draw() {
background(184, 233, 249);
//Draw legs
stroke(0);
fill(249, 137, 244);
rect(x+(2*w), y+h/3.5, z, 2*z);
rect(x+(w), y+h/3, z, 2*z);
rect(x+(1.5*w), y+h/3, z, 2*z);
rect(x+(2.5*w), y+h/3.5, z, 2*z);
////draw body
stroke(0);
fill(249, 137, 244);
ellipse(110+x,y-pigBody, p, p-20);
//draw tail
fill(0);
line(185+x, y-pigTail, x+otherpigTail, y-(2*pigTail));
// Draw payer's head
fill(249, 137, 244);
ellipse(x,y-pigNose,t,t);
// Draw player's eyes
fill(0);
ellipse(x-w/3+1,y-h/2,eyeSize,eyeSize);
ellipse(x+w/3-1,y-h/2,eyeSize,eyeSize);
//Draw nose
stroke(0);
fill(198, 105, 194);
ellipse(x, y, pigNose, pigNose);
//draw ears
stroke(0);
fill(198, 105, 194);
ellipse(x-(w/2),y-h, pigEars, pigEars);
ellipse(x+(w/2),y-h, pigEars, pigEars);
//draw obstacles
fill(value);
ellipse(a, b, s, s);
ellipse(300+a, 200+b, s, s);
ellipse(300-a, 400+b, s, s);
ellipse(300-a, 600+b, s, s);
ellipse(300-a, b, s, s);
ellipse(300+a, 800+b, s, s);
}
I need help turning this code into something similar to this:
/*
This is a very rudimentary virtual pet. It can sit,
lie down, and wag it's tail.
*/
class Pet {
int x, y;
int pose;
int WAG = 1, SLEEP = 2, SIT = 3;
float tailWag, wagSpeed;
Pet(int x, int y) {
this.x = x;
this.y = y;
pose = SIT;
}
// adjust pose and stop tail wagging
void sit() {
pose = SIT;
wagSpeed = 0;
tailWag = 0;
}
// adjust pose and start tail wagging
void wag() {
pose = WAG;
wagSpeed = .1;
}
// adjust pose and stop tail wagging
void sleep() {
pose = SLEEP;
wagSpeed = 0;
tailWag = 0;
}
// draw in selected pose
void draw() {
pushMatrix();
translate(x, y);
if (pose == SIT) {
drawSitting();
}
else if (pose == WAG) {
wagTail();
drawSitting();
}
else {
drawLaying();
}
popMatrix();
}
void drawLaying() {
// needs work :-)
ellipse(0, 0, 150, 60);
}
void wagTail() {
float maxTailWag = .5; // controls how much the tail wags back and forth
tailWag = tailWag + wagSpeed;
// reverse wag direction if the wag limit is reached
if (tailWag > maxTailWag || tailWag < -maxTailWag) {
wagSpeed = -wagSpeed;
}
}
// not pretty but gets the idea across
// origin is the center of the torso
void drawSitting() {
// torso
pushMatrix();
rotate(radians(-30));
ellipse(0, 0, 80, 120);
popMatrix();
ellipse(-20, -70, 60, 60); // head
// nose
pushMatrix();
translate(-55, -55);
rotate(radians(-15));
arc(0, 0, 40, 30, radians(20), radians(310), OPEN);
popMatrix();
// eyes
ellipse(-40, -85, 15, 15); // left eye
ellipse(-25, -80, 15, 15); // right eye
//ear
pushMatrix();
translate(15, -50);
rotate(radians(-20));
ellipse(0, 0, 20, 40);
popMatrix();
//tail
pushMatrix();
translate(40, 30);
rotate(radians(45)+tailWag);
arc(0, -35, 30, 60, radians(-220)-tailWag, radians(80), OPEN);
popMatrix();
// back leg
ellipse(0, 60, 50, 20);
// front leg
pushMatrix();
translate(-50, 30);
rotate(radians(15));
ellipse(0, 0, 30, 60);
popMatrix();
}
}
with classes and whatnot so that I can start working on adding in my own animations for the pet. I'm just not sure where to put everything/how to organize it like that using my drawing.
If I were you, I would start with something simpler. For example, here's a program that uses 4 variables to show a ball bouncing around:
float circleX = 50;
float circleY = 50;
float xSpeed = 1;
float ySpeed = 2;
void draw() {
background(200);
circleX += xSpeed;
if (circleX < 0 || circleX > width) {
xSpeed *= -1;
}
circleY += ySpeed;
if (circleY < 0 || circleY > height) {
ySpeed *= -1;
}
ellipse(circleX, circleY, 20, 20);
}
(source: happycoding.io)
From here, we can encapsulate those 4 variables into a class:
class Circle{
float x;
float y;
float xSpeed;
float ySpeed;
Circle(float x, float y, float xSpeed, float ySpeed){
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
}
}
Now that we have a class, we can use an instance of that class to control our ball.
Circle circle = new Circle(50, 50, 1, 2);
void draw() {
background(200);
circle.x += circle.xSpeed;
if (circle.x < 0 || circle.x > width) {
circle.xSpeed *= -1;
}
circle.y += circle.ySpeed;
if (circle.y < 0 || circle.y > height) {
circle.ySpeed *= -1;
}
ellipse(circle.x, circle.y, 20, 20);
}
class Circle{
float x;
float y;
float xSpeed;
float ySpeed;
Circle(float x, float y, float xSpeed, float ySpeed){
this.x = x;
this.y = y;
this.xSpeed = xSpeed;
this.ySpeed = ySpeed;
}
}
Your code would follow a similar pattern: create a class, encapsulate your data by moving your variables inside the class, and then create an instance of that class and call its methods to draw your figure. Start with something simpler, and just create a class that draws a single circle. Get that working first, and then add variables to that class to draw two circles (a head and a body), and keep working in small steps like that until you're drawing your whole figure.
I really suggest trying something out and posting an MCVE if you get stuck. Good luck.
Shameless self-promotion: I've written a tutorial on creating classes in Processing available here.
In my code i am trying to make one button change the background color from black to white to black to white. Here is my code. I included all of the code so you can see. This is not for school or anything just for fun.
int circleX, circleY; // Position of circle button
int circleSize = 93; // Diameter of circle
color circleColor, baseColor;
color circleHighlight;
color currentColor;
boolean circleOver = false;
int start;
int m = 0;
void setup() {
start = millis();
size(640, 360);
circleColor = color(255);
circleHighlight = color(204);
baseColor = color(102);
currentColor = baseColor;
circleX = width/2+circleSize/2+10;
circleY = height/2;
ellipseMode(CENTER);
}
void draw() {
update(mouseX, mouseY);
background(currentColor);
if (circleOver) {
fill(circleHighlight);
} else {
fill(circleColor);
}
stroke(0);
ellipse(circleX, circleY, circleSize, circleSize);
int timer = millis()-start;
fill(0, 102, 153);
textSize(40);
text(timer, 40, 40);
textSize(20);
text("milliseconds", 200,40);
fill(0,102,153);
textSize(40);
text(m,400,40);
textSize(20);
text("hits", 450,40);
}
void update(int x, int y) {
if ( overCircle(circleX, circleY, circleSize) ) {
circleOver = true;
} else {
circleOver = false;
}
}
void mousePressed() {
if (circleOver) {
currentColor = circleColor;
m = m + 1;
}
}
boolean overCircle(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
return true;
} else {
return false;
}
}
Use a boolean in draw() as a flag, and change it in mousePressed you can say booleanX = !booleanX; this will toogle the value of the boolean.
here:
int circleX, circleY;
// Position of circle button
int circleSize = 93;
// Diameter of circle
color circleColor, baseColor;
color circleHighlight;
color currentColor;
boolean color1 = false;
int start;int m = 0;
void setup() {
start = millis();
size(640, 360);
circleColor = color(255);
circleHighlight = color(204);
baseColor = color(102);
currentColor = baseColor;
circleX = width/2+circleSize/2+10;
circleY = height/2;
ellipseMode(CENTER);
}
void draw() {
if (color1){
currentColor = color(255);
}else{
currentColor = color(85);
}
background(currentColor);
if (overCircle(circleX, circleY, circleSize)) {
fill(circleHighlight);} else {
fill(circleColor);}
stroke(0);
ellipse(circleX, circleY, circleSize, circleSize);
int timer = millis()-start;
fill(0, 102, 153);
textSize(40);
text(timer, 40, 40);
textSize(20);
text("milliseconds", 200,40);
fill(0,102,153);
textSize(40);
text(m,400,40);
textSize(20);
text("hits", 450,40);
}
void mousePressed() {
if (overCircle(circleX, circleY, circleSize)) {
color1 = !color1;
m = m + 1;
}
}
boolean overCircle(int x, int y, int diameter) {
float disX = x - mouseX;
float disY = y - mouseY;
if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
return true;
} else {
return false;
}
}
I have a simple animation play of a circle scale outwards and fade out whenever the applications detects that the hammer object has reached a certain angle. However, as it is currently implemented the animation will only play once. I have attempted using for loops to allow the animation to complete, but this causes the entire application to pause while the code is looped, and other attempts I have made have not worked, so any help at all would be appreciated.
import oscP5.*;
import netP5.*;
OscP5 oscP5;
NetAddress myRemoteLocation;
float bx;
float by;
int boxSizeX = 160;
int boxSizeY = 30;
boolean overBox = true;
boolean locked = false;
float xOffset = 0.0;
float yOffset = 0.0;
float angle = 4.70;
float cooldown;
int alphaVal = 255;
int colorchange = 0;
//for sound effect
float a = 0.0;
float s = 0.0;
BeatBall b1 = new BeatBall(210,425,60, 1);
BeatBall b2 = new BeatBall(570,395,60, 2);
Hammer h = new Hammer(135, -67, boxSizeY+25, boxSizeX-25, 1);
void setup()
{
ellipseMode(CENTER);
size(800, 600);
smooth();
frameRate(120);
bx = width/2.0;
by = height/2.0;
oscP5 = new OscP5(this,12001);
/* myRemoteLocation is a NetAddress. a NetAddress takes 2 parameters,
* an ip address and a port number. myRemoteLocation is used as parameter in
* oscP5.send() when sending osc packets to another computer, device,
* application. usage see below. for testing purposes the listening port
* and the port of the remote location address are the same, hence you will
* send messages back to this sketch.
*/
myRemoteLocation = new NetAddress("127.0.0.1",12000);
}
void draw()
{
background(0);
ellipseMode(CENTER);
float mx = constrain(angle, -2.6075916, -0.5207284);
///////////////////////////
//THIS IS THE ANIMATION //
//////////////////////////
if(locked)
{
a = a + 0.02;
s = cos(a)*10;
pushMatrix();
translate(210,425);
scale(s);
fill(colorchange, 30, 150, alphaVal);
ellipse(0, 0, 50, 50);
alphaVal = alphaVal - 3;
colorchange = colorchange + 3;
popMatrix();
}
pushMatrix();
translate(400, 425);
rotate(mx);
fill(222,223,255);
h.displayHammer();
rect(-25, -15, boxSizeX, boxSizeY);
popMatrix();
pushMatrix();
translate(595, 390);
rotate(radians(58));
fill(122,78,163);
rect(0, 0, 50, 50);
popMatrix();
b1.displayBall();
//b2.displaySquare();
cooldown = cooldown + 0.01;
println(cooldown);
if(mx == -2.6075916)
{
if(cooldown > 0.5)
{
locked = true;
soundEffect();
b1.collide();
cooldown = 0;
}
}
else if(mx == -0.5207284)
{
if(cooldown > 0.5)
{
b1.collide();
cooldown = 0;
}
}
}
void soundEffect()
{
}
void mousePressed()
{
xOffset = mouseX-bx;
yOffset = mouseY-by;
}
void mouseDragged()
{
angle = atan2(mouseY - 400, mouseX - 400);
println(angle);
}
I have custom arrow class, which extends BasicArrowButton. It is constructed and displayed the way I need, but then, when it is repainted (mouse over, other tab clicked, etc) arrow disappeares. How can I fix it?
public class CustomArrow extends BasicArrowButton {
private transient Color shadow = new Color(241, 241, 241);
private transient Color dark = new Color(150, 150, 150);
private static int defaultSize = 10;
/** The Polygon that points up. */
private static Polygon upIcon = new Polygon(new int[] { 0, 5, 9 },
new int[] { 7, 2, 7 }, 3);
/** The Polygon that points down. */
private static Polygon downIcon = new Polygon(new int[] { 1, 8, 19 },
new int[] { 3, 13, 3 }, 3);
/** The Polygon that points left. */
private static Polygon leftIcon = new Polygon(new int[] { 7, 3, 7 },
new int[] { 1, 5, 9 }, 3);
/** The Polygon that points right. */
private static Polygon rightIcon = new Polygon(new int[] { 3, 7, 3 },
new int[] { 1, 5, 9 }, 3);
private transient Border buttonBorder = new Border()
{
public Insets getBorderInsets(Component c)
{
return new Insets(2, 2, 2, 2);
}
public boolean isBorderOpaque()
{
return true;
}
public void paintBorder(Component c, Graphics g, int x, int y, int w, int h)
{
Color saved = g.getColor();
g.setColor(shadow);
g.drawLine(x + 1, y, x + w - 1, y);
g.setColor(dark);
g.drawLine(x, y, x, y + h + 2);
g.setColor(shadow);
g.drawLine(x + w - 1, y + 1, x + w - 1, y + h - 1);
g.setColor(shadow);
g.drawLine(x + 1, y + h - 1, x + w, y + h - 1);
g.setColor(saved);
}
};
#Override
public synchronized void addKeyListener(KeyListener l) {
super.addKeyListener(l);
}
#Override
public void addActionListener(ActionListener l) {
super.addActionListener(l);
}
public CustomArrow(int direction)
{
super(direction);
setBorder(buttonBorder);
setDirection(direction);
this.setRolloverEnabled(false);
}
public CustomArrow(int direction, Color background, Color shadow, Color darkShadow, Color highlight)
{
this(direction);
setBackground(background);
}
#Override
public void paintTriangle(Graphics g, int x, int y, int size, int direction, boolean isEnabled)
{
Polygon arrow = null;
switch (direction)
{
case NORTH:
arrow = upIcon;
break;
case SOUTH:
arrow = downIcon;
break;
case EAST:
case RIGHT:
arrow = rightIcon;
break;
case WEST:
case LEFT:
arrow = leftIcon;
break;
}
int[] xPoints = arrow.xpoints;
int[] yPoints = arrow.ypoints;
int x1;
int y1;
int x2;
int y2;
x1 = y1 = x2 = y2 = 0;
x = x - 1;
if (size != defaultSize)
{
float scale = size * 1f / defaultSize;
for (int i = 0; i < 3; i++)
{
xPoints[i] *= scale;
yPoints[i] *= scale;
}
}
g.translate(x, y);
switch (direction)
{
case NORTH:
x1 = xPoints[0] + 2;
y1 = yPoints[0];
y2 = y1;
x2 = xPoints[2] - 1;
break;
case SOUTH:
x1 = xPoints[1];
y1 = yPoints[1] + 1;
x2 = xPoints[2] - 1;
y2 = yPoints[2];
break;
case LEFT:
case WEST:
x1 = xPoints[0] + 1;
y1 = yPoints[0] + 1;
x2 = x1;
y2 = yPoints[2] + 1;
break;
case RIGHT:
case EAST:
x1 = xPoints[2];
y1 = yPoints[2] + 1;
x2 = xPoints[1] - 1;
y2 = yPoints[1] + 1;
break;
}
Color saved = g.getColor();
g.setColor(dark);
if (arrow != null) {
g.fillPolygon(xPoints, yPoints, 3);
}
g.setColor(saved);
g.translate(-x, -y);
}
public static void main(String[] args) {
// Resize the frame to reproduce
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new CustomArrow(SwingConstants.NORTH));
frame.setSize(400, 400);
frame.setVisible(true);
}
}
Array variables hold references to the array, not the array itself (just like Object variables). When you do something like
int[] xPoints = arrow.xpoints;
int[] yPoints = arrow.ypoints;
you are copying the reference, not the data, meaning that xPoints and arrow.xpoints still point at the same data and modifying either will affect the other. When you later scale these points, you're changing how the arrow will look every future time it is drawn.
If you want to copy the array data to avoid this, you can use System.arraycopy:
int[] xPoints = new int[3]; //arrow.xpoints;
int[] yPoints = new int[3]; //arrow.ypoints;
System.arraycopy(arrow.xpoints, 0, xPoints, 0, 3);
System.arraycopy(arrow.ypoints, 0, yPoints, 0, 3);
However, you can simply scale the graphics object instead of scaling your reference points:
Graphics2D g2 = (Graphics2D) g;
float scale = size * 1f / defaultSize;
g2.scale(scale, scale);