Need help adding a class and animations to a simple pet drawing? - java

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.

Related

How to display text inside a moving object in java/processing

I'm using the Processing IDE and I found out how to display static text but not one that displays inside and moves with the moving disk. Any help?
int xdirection = 1; // Left or Right
int ydirection = 1; // Top to Bottom
int value = 0;
Disk disk1;
Disk disk2;
Disk disk3;
Disk disk4;
void setup() {
size(400, 400);
cursor(CROSS);
noStroke();
disk1 = new Disk(color(255, 0, 0), 10, 100, 2, 6);
disk2 = new Disk(color(0, 0, 255), 10, 100, 1, 5);
disk3 = new Disk(color(0, 255, 0), 10, 100, 3, 4);
disk4 = new Disk(color(0, 255, 255), 10, 100, 4, 7);
frameRate(60);
}
void mousePressed() {
if (disk1.isOver() == true) {
value += 25;
}
if (disk2.isOver() == true) {
value += 50;
}
if (disk3.isOver() == true) {
value += 75;
}
if (disk4.isOver() == true) {
value += 100;
}
}
void draw() {
background(130, 140, 255);
stroke(175);
fill(0);
textAlign(CENTER);
text("Score: " + value, width/2, 60);
disk1.bounce();
disk1.display();
disk2.bounce();
disk2.display();
disk3.bounce();
disk3.display();
disk4.bounce();
disk4.display();
}
class Disk {
color c;
float xpos;
float ypos;
float xspeed;
float yspeed;
Disk(color tempC, float tempXpos, float tempYpos, float tempXspeed, float tempYspeed) {
c = tempC;
xspeed = tempXspeed;
yspeed = tempYspeed;
if (xpos > width-200 || xpos < 0) {
xdirection *= -1;
}
if (ypos > height-200 || ypos < 0) {
ydirection *= -1;
}
}
void display() {
stroke(0);
fill(c);
ellipseMode(CENTER);
ellipse(xpos, ypos, 20, 20);
}
boolean isOver() {
// Is mouse position over the circle i.e. dist < radius
if (dist(xpos, ypos, mouseX, mouseY) < 10)
return true;
else
return false;
}
void bounce() {
xpos = xpos + xspeed;
xpos = xpos + ( xspeed * xdirection );
ypos = ypos + ( yspeed * ydirection );
if (xpos > width - 20) {
xspeed = xspeed * -1;
}
if (xpos < 0) {
xspeed = xspeed * -1;
}
if (ypos > height - 20) {
yspeed = yspeed * -1;
}
if (ypos < 0) {
yspeed = yspeed * -1;
}
}
}
Edit: Updated post to show code. I'm also trying to figure out how to make the disks larger using scale() but haven't been able to find out how to do so. This is also my first time posting on stack overflow so if there is anything I can do better, please let me know. Thanks
The Disk class encapsulates the state of a single Disk instance. It contains code for checking mouse clicks and for bouncing. It also contains code for drawing a disk.
That code happens in the display() function. Read through that function to understand what it's doing, and try changing it to see what happens.
Specifically, this line of code draws a circle at the disk's location:
ellipse(xpos, ypos, 20, 20);
Try changing that do draw a rectangle at the disk's location. Then try changing it to draw some text at the disk's location.
Good luck!

Circle to Circle collision in Java

So I am doing circle to circle collision in java. I am aware that there are many similiar questions like mine on this website but my problem is unique from all of them. When I run my code, the circle's collide with each other once every 4 times. Meaning: 3 times they will go through without colliding with one another but one time they will collide. Any help is greatly appreciated.
public class Ball {
float x, y; // coordinates of ball rectangle
float xo, yo;
float vx = 2, vy = 2; // coordinates of velocity vector
Color colour; // ball colour
float d; // diameter of the ball or sizes of ball rectangle
Ellipse2D.Float circle;
// overloaded constructor
Ball(int x, int y, int vx, int vy, int d, Color colour) {
this.x = x;
this.y = y;
this.d = d;
xo = x;
yo = y;
this.setColour(colour);
this.setVelocity(vx, vy);
circle = new Ellipse2D.Float(x, y, d, d);
}
public void setColour(Color colour) {
this.colour = colour;
}
public void setVelocity(int vx, int vy) {
this.vx = vx;
this.vy = vy;
}
public void show(Graphics g) {
((Graphics2D) g).setPaint(colour);
circle.setFrame(x, y, d, d);
((Graphics2D) g).fill(circle);
xo = x;
yo = y;
}
public void hide(Graphics g) {
Color c = ((Graphics2D) g).getBackground();
((Graphics2D) g).setPaint(c);
circle.setFrame(xo, yo, d, d);
((Graphics2D) g).fill(circle);
}
public void setPosition(float x, float y) {
this.x = x;
this.y = y;
}
public void move(int a, int b, int xh, int yh) {
if (vy > 0) {
if (y + d + vy - yh - b > 0) {
y = yh + b - d;
vy = -vy;
} else
y += vy;
} else {
if (y + vy <= b) {
y = b;
vy = -vy;
} else
y += vy;
}
if (vx > 0) {
if (x + d + vx - xh - a > 0) {
x = xh + a - d;
vx = -vx;
} else
x += vx;
} else {
if (x + vx <= a) {
x = a;
vx = -vx;
} else
x += vx;
}
}
The Collision Detector is in the class below
public class Game extends JFrame {
int ah, bh, xh, yh; // parameters of the rectangle frame
Color[] ColorAr = { Color.red, Color.blue, Color.pink, Color.green,
Color.yellow, Color.magenta, Color.black, Color.orange, Color.gray,
Color.cyan };
Ball b[];
int quantity = 4;
public void paint(Graphics g) {
int i;
((Graphics2D) g).setPaint(Color.black);
((Graphics2D) g).drawRect(ah, bh, xh, yh);
for (i = quantity - 1; i >= 0; i--) {
b[i].hide(g);
}
for (i = 0; i < quantity; i++) {
b[i].show(g);
}
}
public void prepare() {
int i;
ah = 20;
bh = 40;
xh = 400;
yh = 400;
b = new Ball[quantity];
for (i = 0; i < quantity; i++) {
b[i] = new Ball((int) (Math.random() * (300 - 1 + 1)) + 1, 100, 1,
1, 26, ColorAr[(int) (Math.random() * 9)]);
}
}
public void collision() {
int radius = 13;
int distance = 2 * radius;
if (b[1].x + distance == b[0].x && b[1].y == b[0].y
|| b[1].x - distance == b[0].x && b[1].y == b[0].y) {
b[1].vx = -b[1].vx;
b[0].vx = -b[0].vx;
}
}
public void run() {
int i;
while (true) {
for (i = 0; i < quantity; i++)
b[i].move(ah, bh, xh, yh);// move balls
collision();
for (int j = 0; j < 10000000; j++)
; // delay;
// collision();
repaint();
}
}
public static void main(String args[]) {
Game frame = new Game();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// frame.setBackground(Color.white);
frame.setSize(450, 470);
frame.prepare();
frame.setVisible(true);
frame.run();
}
}
For two circles:
First calculate the sum of lengths: radius_1 + radius_2 (the first and the second circle).
Collision of two circles can be detected if you calculate the length of (imaginary) line between centers. If THAT length <= radius_1 + radius_2, two circles are colliding.

Java: difficulties making fade out animation run without being refreshed by processing

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);
}

Java: How to detect a collision between a rectangle and falling circles of varying radius and speed?

to start off, I'm making a simple game in Java that involves a blue rectangle that can be moved with arrow keys and seven falling circles of varying color, radius, and falling speed. Essentially, whenever the rectangle comes in contact with one of these circles, the rectangle will "lose" a life, which will be indicated by 3 rectangles on the top right of a JFrame that I haven't drawn yet. Every time the rectangle is hit by one of these circles, one of the rectangles will disappear, and when the blue rectangle is hit once more, a red "Game Over" text will appear in the middle of the frame.
Now then, although I'm having trouble getting the colors and speed to randomize each time the circles hit the bottom, I'll leave those for a future question. My main concern is the hit detection between the circles and the blue rectangle. I know that I need to define a certain method, but I'm unsure on how to go about doing it, and how to test it for each of the seven circles over and over while they're falling and having their Y value constantly change.
How could I go about doing this? Anyway, here's my main and circles classes for this project. I'm aware that there's a lot of junk code that isn't being used in the main class as well. I'll clean it up after I just figure this out.
**Main class (Keyexample)
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.Random;
public class Keyexample extends JPanel implements ActionListener, KeyListener{
Timer t = new Timer(5, this);
private Circle[] Circles = new Circle[7];
private javax.swing.Timer t2;
private Circle newc, c1, c2, c3, c4, c5, c6, c7;
double x = 100, y = 100;
double changeX = 0, changeY = 0;
private int cx = 10, cy = 0;
private int newcx = 0, newcy = 0;
private Random rand = new Random();
private Random colorc = new Random();
private int n = rand.nextInt(8);
public keyExample() {
t.start();
addKeyListener(this);
setFocusable(true);
setFocusTraversalKeysEnabled(false);
Random colorc = new Random();
Random radiusc = new Random();
int r1 = radiusc.nextInt(12);
int r2 = radiusc.nextInt(12);
int r3 = radiusc.nextInt(12);
int r4 = radiusc.nextInt(12);
int r5 = radiusc.nextInt(12);
int r6 = radiusc.nextInt(12);
int r7 = radiusc.nextInt(12);
Color cc1 = new Color(colorc.nextInt(255), colorc.nextInt(255),
colorc.nextInt(255));
Color cc2 = new Color(colorc.nextInt(255), colorc.nextInt(255),
colorc.nextInt(255));
Color cc3 = new Color(colorc.nextInt(255), colorc.nextInt(255),
colorc.nextInt(255));
Color cc4 = new Color(colorc.nextInt(255), colorc.nextInt(255),
colorc.nextInt(255));
Color cc5 = new Color(colorc.nextInt(255), colorc.nextInt(255),
colorc.nextInt(255));
Color cc6 = new Color(colorc.nextInt(255), colorc.nextInt(255),
colorc.nextInt(255));
Color cc7 = new Color(colorc.nextInt(255), colorc.nextInt(255),
colorc.nextInt(255));
//creating the 7 circles and spacing them out
c1 = new Circle(cx, cy, r1, cc1);
c2 = new Circle(cx + 50, cy, r2, cc2);
c3 = new Circle(cx + 100, cy, r3, cc3);
c4 = new Circle(cx + 150, cy, r4, cc4);
c5 = new Circle(cx + 200, cy, r5, cc5);
c6 = new Circle(cx + 300, cy, r6, cc6);
c7 = new Circle(cx + 400, cy, r7, cc7);
Circles[0] = c1;
Circles[1] = c2;
Circles[2] = c3;
Circles[3] = c4;
Circles[4] = c5;
Circles[5] = c6;
Circles[6] = c7;
t2 = new javax.swing.Timer(33, new CircleListener());
t2.start();
}
//painting rectangle and circles
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.BLUE);
g2.fill(new Rectangle2D.Double(x, y, 40, 40));
for (int i = 0; i < Circles.length; i++){
Color circlecolor = new Color(rand.nextInt(255), rand.nextInt(255),
rand.nextInt(255));
//circle color starts spazzing out here. constantly changing while falling
g2.setColor(circlecolor);
Circles[i].fill(g);
}
}
public void createCircle(){
}
public void actionPerformed(ActionEvent e) {
repaint();
x += changeX;
y += changeY;
changeX = 0;
changeY = 0;
}
private class CircleListener implements ActionListener {
public void actionPerformed(ActionEvent e) {
Random rand = new Random();
int move = 2 + rand.nextInt(10);
int move2 =2 + rand.nextInt(10);
int move3 =2 + rand.nextInt(10);
int move4 =2 + rand.nextInt(10);
int move5 =2 + rand.nextInt(10);
int move6 =2 + rand.nextInt(10);
c1.move(0, n);
position(c1);
c2.move(0, move);
position(c2);
c3.move(0, move2);
position(c3);
c4.move(0, move3);
position(c4);
c5.move(0, move4);
position(c5);
c6.move(0, move5);
position(c6);
c7.move(0, move6);
position(c7);
repaint();
}
public void position(Circle cp) {
int height = getHeight();
int loc = cp.centerX;
int speed = 3 + rand.nextInt(10);
int radiuss = cp.radius;
Rectangle bound = cp.Bounds();
if (bound.topY + bound.width > height){
cp.centerY = 0;
//moving circle back to the top
cp.move(0, speed);
//randomizing speed of circle after moving to top, not working
cp.radius = 5 + rand.nextInt(20);
//randomizing radius of circle after moving to top, does work
}
}
}
public void up() {
if (y != 0){
changeY = -3.5;
changeX = 0;
}
}
public void down() {
if (y <= 350) {
changeY = 3.5;
changeX = 0;
}
}
public void left() {
if (x >=0) {
changeX = -3.5;
changeY = 0;
}
}
public void right() {
if (x <= 550) {
changeX = 3.5;
changeY = 0;
}
}
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
up();
}
if (code == KeyEvent.VK_DOWN) {
down();
}
if (code == KeyEvent.VK_RIGHT) {
right();
}
if (code == KeyEvent.VK_LEFT) {
left();
}
}
public void keyTyped(KeyEvent e) {
}
public void keyReleased(KeyEvent e) {
}
}
**Circle class
import java.awt.*;
import java.util.Random;
public class Circle{
public int centerX, centerY, radius;
public Color color;
public Circle (int x, int y, int r, Color c){
centerX = x;
centerY = y;
radius = r;
Random random = new Random();
}
public void draw(Graphics g){
Color oldColor = g.getColor();
g.setColor(color);
g.drawOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
g.setColor(oldColor);
}
public void fill(Graphics g){
Color oldColor = g.getColor();
g.setColor(color);
g.fillOval(centerX - radius, centerY - radius, radius * 2, radius * 2);
g.setColor(oldColor);
}
public boolean containsPoint(int x, int y){
int xSquared = (x - centerX) * (x - centerX);
int ySquared = (y - centerY) * (y - centerY);
int radiusSquared = radius * radius;
return xSquared + ySquared - radiusSquared <=0;
}
public void move(int xAmount, int yAmount){
centerX = centerX + xAmount;
centerY = centerY + yAmount;
}
public Rectangle Bounds(){
int x = centerX - radius;
int y = centerY - radius;
return new Rectangle(x, y, radius * 2, radius * 2, Color.red);
}
}
You want to break the problem into two parts: the first - see if there is "definitely no collision". This happens when the center of the circle is more than a radius away from the edges. It's a very fast test, and will be true most of the time:
if(left > x + radius ||
right < x - radius ||
etc.) { // no collision }
The second - if you fail this test, you may still not hit. That depends on whether both x and y are sufficient for overlap. Within this, there are two situations:
A corner of the rectangle is inside the circle: easy to compute (distance from one corner to center of circle < r)
An edge is inside the circle. This means that in one direction (say X) the center lies between the edges; and in the other direction an edge is less than radius away.
This is general, without actual code. I assume you can write the code from here.
You can detect collisions by simple if else conditions on the circle's and rectangle's co ordinates on screen.
distance(circle, Rectangle) <= circle.radius + Rectangle.radius
You can implement distance helper function using the simple distance formula between two points.
link

How to make star shape in Java?

I'm trying to make some shapes with Java. I created two rectangles with two different colors but I want to create a star shape and I can't find useful source to help me doing this.
Here is my code:
import java.awt.*;
import javax.swing.*;
public class shapes extends JPanel{
#Override
public void paintComponent(Graphics GPHCS){
super.paintComponent(GPHCS);
GPHCS.setColor(Color.BLUE);
GPHCS.fillRect(25,25,100,30);
GPHCS.setColor(Color.GRAY);
GPHCS.fillRect(25,65,100,30);
GPHCS.setColor(new Color(190,81,215));
GPHCS.drawString("This is my text", 25, 120);
}
}
You could try using a polygon and some basic math:
int midX = 500;
int midY = 340;
int radius[] = {118,40,90,40};
int nPoints = 16;
int[] X = new int[nPoints];
int[] Y = new int[nPoints];
for (double current=0.0; current<nPoints; current++)
{
int i = (int) current;
double x = Math.cos(current*((2*Math.PI)/max))*radius[i % 4];
double y = Math.sin(current*((2*Math.PI)/max))*radius[i % 4];
X[i] = (int) x+midX;
Y[i] = (int) y+midY;
}
g.setColor(Color.WHITE);
g.fillPolygon(X, Y, nPoints);
You can also use existing classes e.g. http://java-sl.com/shapes.html for regular polygons and stars.
The Polygon class can be considered as a legacy class that has been there since Java 1.0, but should hardly be used any more in new code. The odd way of specifying the x/y coordinates in separate arrays, and, more importantly, the fact that it only supports int[] arrays limits its application areas. Although it implements the Shape interface, there are more modern implementations of this interface that can be used to represent polygons. In most cases, describing the polygon as a Path2D is easier and more flexible. One can create a Path2D p = new Path2D.Double(); and then do a sequence of moveTo and lineTo calls to geneate the desired shape.
The following program shows how the Path2D class may be used to generate star shapes. The most important method is the createStar method. It is very generic. It receives
the center coordinates for the star
the inner and outer radius of the star
the number of rays that the star should have
the angle where the first ray should be (i.e. the rotation angle of the star)
If desired, a simpler method may be wrapped around this one - as with the createDefaultStar example in the code below.
The program shows different stars, painted as lines and filled with different colors and radial gradient paints, as examples:
The complete program as a MCVE:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RadialGradientPaint;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class DrawStarShape
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new DrawStarShapePanel());
f.setSize(600, 600);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class DrawStarShapePanel extends JPanel
{
#Override
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(Color.BLACK);
g.draw(createDefaultStar(50, 200, 200));
g.setPaint(Color.RED);
g.fill(createStar(400, 400, 40, 60, 10, 0));
g.setPaint(new RadialGradientPaint(
new Point(400, 200), 60, new float[] { 0, 1 },
new Color[] { Color.RED, Color.YELLOW }));
g.fill(createStar(400, 200, 20, 60, 8, 0));
g.setPaint(new RadialGradientPaint(
new Point(200, 400), 50, new float[] { 0, 0.3f, 1 },
new Color[] { Color.RED, Color.YELLOW, Color.ORANGE }));
g.fill(createStar(200, 400, 40, 50, 20, 0));
}
private static Shape createDefaultStar(double radius, double centerX,
double centerY)
{
return createStar(centerX, centerY, radius, radius * 2.63, 5,
Math.toRadians(-18));
}
private static Shape createStar(double centerX, double centerY,
double innerRadius, double outerRadius, int numRays,
double startAngleRad)
{
Path2D path = new Path2D.Double();
double deltaAngleRad = Math.PI / numRays;
for (int i = 0; i < numRays * 2; i++)
{
double angleRad = startAngleRad + i * deltaAngleRad;
double ca = Math.cos(angleRad);
double sa = Math.sin(angleRad);
double relX = ca;
double relY = sa;
if ((i & 1) == 0)
{
relX *= outerRadius;
relY *= outerRadius;
}
else
{
relX *= innerRadius;
relY *= innerRadius;
}
if (i == 0)
{
path.moveTo(centerX + relX, centerY + relY);
}
else
{
path.lineTo(centerX + relX, centerY + relY);
}
}
path.closePath();
return path;
}
}
I have 2 method.
1)
public static Bitmap drawStar(int W, int H, int color, boolean andRing)
{
Path path = new Path();
Bitmap output = Bitmap.createBitmap(W, H, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(color);
float midW ,min ,fat ,half ,radius;
if(andRing)
{
midW = W / 2;
min = Math.min(W, H);
half = min / 2;
midW = midW - half;
fat = min / 17;
radius = half - fat;
paint.setStrokeWidth(fat);
paint.setStyle(Paint.Style.STROKE);
canvas.drawCircle(midW + half, half, radius, paint);
path.reset();
paint.setStyle(Paint.Style.FILL);
path.moveTo( half * 0.5f, half * 0.84f);
path.lineTo( half * 1.5f, half * 0.84f);
path.lineTo( half * 0.68f, half * 1.45f);
path.lineTo( half * 1.0f, half * 0.5f);
path.lineTo( half * 1.32f, half * 1.45f);
path.lineTo( half * 0.5f, half * 0.84f);
}
else
{
min = Math.min(W, H);
half = min/2;
path.reset();
paint.setStyle(Paint.Style.FILL);
path.moveTo( half * 0.1f , half * 0.65f);
path.lineTo( half * 1.9f , half * 0.65f);
path.lineTo( half * 0.40f , half * 1.65f);
path.lineTo( half , 0 );
path.lineTo( half * 1.60f, half * 1.65f);
path.lineTo( half * 0.1f, half * 0.65f);
}
canvas.drawPath(path, paint);
return output;
}
2)
public static Bitmap drawStar(int W,int H,int spikes,int innerRadius,int outerRadius, int backColor,boolean border, int borderColor)
{
if(W < 10)
W = 10;
if(H < 10)
H = 10;
if(spikes < 5)
spikes = 5;
int smallL = W;
if(H < W)
smallL = H;
if(outerRadius > smallL/2)
outerRadius = smallL/2;
if(innerRadius < 5)
innerRadius = 5;
if(border)
{
outerRadius -=2;
innerRadius -=2;
}
Path path = new Path();
Bitmap output = Bitmap.createBitmap(W, H, Config.ARGB_8888);
Canvas canvas = new Canvas(output);
final Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
paint.setColor(backColor);
int cx = W/2;
int cy = H/2;
double rot = Math.PI / 2 * 3;
float x,y;
double step = Math.PI / spikes;
path.moveTo(cx, cy - outerRadius);
for (int i = 0; i < spikes; i++)
{
x = (float) (cx + Math.cos(rot) * outerRadius);
y = (float) (cy + Math.sin(rot) * outerRadius);
path.lineTo(x, y);
rot += step;
x = (float) (cx + Math.cos(rot) * innerRadius);
y = (float) (cy + Math.sin(rot) * innerRadius);
path.lineTo(x, y);
rot += step;
}
path.lineTo(cx, cy - outerRadius);
path.close();
canvas.drawPath(path, paint);
if(border)
{
paint.setStyle(Style.STROKE);
paint.setStrokeWidth(2);
paint.setColor(borderColor);
canvas.drawPath(path, paint);
}
return output;
}

Categories