How to make the ball bounce off the circle Graphic2D? - Java - java

I'm working on Air Hockey game. Until now, I've moved both handles and bounce the ball in my Air Hockey table actually ball can bounce off the walls, but my problem is I can't hit the ball with my handles and I don't have any idea for that. I searched in the net but I couldn't find any thing. I'll appreciate if you help me as soon as you can!!
This is all my code that you need:
public class StartGamePanel extends JPanel implements ActionListener, KeyListener, Runnable {
private static final long serialVersionUID = 1L;
double xCircle1=200;
double yCircle1 =100 ;
double xCircle2=200;
double yCircle2 =700 ;
double xBall=200;
double yBall=400;
double rBall=20;
double ballSpeedX=-3;
double ballSpeedY=0;
private Ball m_ball = new Ball(0, 0, 7, 7);
private int m_interval = 35;
private Timer m_timer;
double dx = 0, dy = 0, dx2=0, dy2=0;
private Graphics2D circle1;
private Graphics2D circle2;
private Graphics2D circle3;
public static void main(String[] args) {
JFrame f=new JFrame();
f.setSize(new Dimension(512,837));
StartGamePanel p=new StartGamePanel();
f.add(p);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
public StartGamePanel(){
m_timer = new Timer(m_interval, new TimerAction());
m_timer.start(); // start animation by starting the timer.
Timer t = new Timer(5, this);
t.start();
addKeyListener(this);
setFocusable(true);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
addKeyListener(this);
ContainerTable table=new ContainerTable(2, 0, 493, 800, new Color(51,153,255), Color.WHITE);
table.draw(g);
circle1 = (Graphics2D) g;
circle1.setColor(new Color(255,51,51));
Shape theCircle = new Ellipse2D.Double(xCircle1 - 40, yCircle1 - 40, 2.0 * 40, 2.0 * 40);
circle1.fill(theCircle);
circle2 = (Graphics2D) g;
circle2.setColor(new Color(255,102,102));
Shape theCircle2 = new Ellipse2D.Double(xCircle1 - 35, yCircle1 - 35, 2.0 * 35, 2.0 * 35);
circle2.fill(theCircle2);
circle3 = (Graphics2D) g;
circle3.setColor(new Color(255,51,51));
Shape theCircle3 = new Ellipse2D.Double(xCircle1 - 20, yCircle1 - 20, 2.0 * 20, 2.0 * 20);
circle3.fill(theCircle3);
Graphics2D circleprim = (Graphics2D) g;
circleprim.setColor(new Color(0,51,102));
Shape theCircleprim = new Ellipse2D.Double(xCircle2 - 40, yCircle2 - 40, 2.0 * 40, 2.0 * 40);
circleprim.fill(theCircleprim);
Graphics2D circle2prim = (Graphics2D) g;
circle2prim.setColor(new Color(0,102,204));
Shape theCircle2prim = new Ellipse2D.Double(xCircle2 - 35, yCircle2 - 35, 2.0 * 35, 2.0 * 35);
circle2prim.fill(theCircle2prim);
Graphics2D circle3prim = (Graphics2D) g;
circle3prim.setColor(new Color(0,51,102));
Shape theCircle3prim = new Ellipse2D.Double(xCircle2 - 20, yCircle2 - 20, 2.0 * 20, 2.0 * 20);
circle3prim.fill(theCircle3prim);
g.setColor(Color.gray);
m_ball.draw(g);
Graphics2D goal = (Graphics2D) g;
goal.setColor(Color.BLACK);
goal.fill3DRect(100, 0, 300, 10, true);
Graphics2D goal2 = (Graphics2D) g;
goal2.setColor(Color.BLACK);
goal2.fill3DRect(100, 790, 300, 10, true);
}
class TimerAction implements ActionListener {
public void actionPerformed(ActionEvent e) {
m_ball.setBounds(getWidth(), getHeight());
m_ball.move();
repaint();
}
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
xCircle1 += dx;
yCircle1 += dy;
yCircle2 += dy2;
xCircle2+= dx2;
}
#Override
public void keyPressed(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
if(yCircle1>40){
dy = -2;
dx = 0;
}else{
yCircle1=40;
dy *= -1;
dx=0;
}
}
if (code == KeyEvent.VK_DOWN) {
if(yCircle1<360){
dy = 2;
dx = 0;
}else{
yCircle1=360;
dx =0;
dy *= -1;
}
}
if (code == KeyEvent.VK_LEFT) {
if (xCircle1 < 30) {
xCircle1=30;
dy = 0;
dx *= -1;
}else {
dy = 0;
dx = -2;
}
}
if (code == KeyEvent.VK_RIGHT) {
if (xCircle1 > 460) {
xCircle1= 460;
dx *= -1;
dy = 0;
}else{
dy = 0;
dx = 2;
}
}
if (code == KeyEvent.VK_F) {
if (xCircle2 > 460) {
xCircle2= 460;
dy2 = 0;
dx2 *= -1;
}else{
dy2 = 0;
dx2 = 2;
}
}
if (code == KeyEvent.VK_S) {
if (xCircle2 < 30) {
xCircle2=30;
dy2 = 0;
dx2 *= -1;
}else {
dy2 = 0;
dx2 = -2;
}
}
if (code == KeyEvent.VK_E) {
if(yCircle2>430){
dy2 = -2;
dx2 = 0;
}else{
yCircle2=430;
dy*= -1;
dx=0;
}}
if (code == KeyEvent.VK_D) {
if(yCircle2>750){
yCircle2=750;
dy2 *= -1;
dx2=0;
}else{
dy2 = 2;
dx2 = 0;
}}
}
#Override
public void keyReleased(KeyEvent e) {
int code = e.getKeyCode();
if (code == KeyEvent.VK_UP) {
dy = 0;
dx = 0;
}
if (code == KeyEvent.VK_DOWN) {
dy = 0;
dx = 0;
}
if (code == KeyEvent.VK_LEFT) {
dy = 0;
dx = 0;
}
if (code == KeyEvent.VK_RIGHT) {
dy = 0;
dx = 0;
}
if (code == KeyEvent.VK_E) {
dy2 = 0;
dx2 = 0;
}
if (code == KeyEvent.VK_D) {
dy2 = 0;
dx2 = 0;
}
if (code == KeyEvent.VK_S) {
dy2 = 0;
dx2 = 0;
}
if (code == KeyEvent.VK_F) {
dy2 = 0;
dx2 = 0;
}
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void run() {
Thread.currentThread().setPriority(Thread.MIN_PRIORITY);
while (true)
{
xBall += ballSpeedX;
yBall += ballSpeedX;
repaint();
if (xBall < 30) {
ballSpeedX = -ballSpeedX;
xBall = 30;
}
if (xBall > 470) {
ballSpeedX = -ballSpeedX;
xBall = 470;
}
try { Thread.sleep (20); }
catch (InterruptedException ex) {}
Thread.currentThread().setPriority(Thread.MAX_PRIORITY); }}}
class Ball {
final static int DIAMETER = 50;
private int m_x;
private int m_y;
private int m_velocityX;
private int m_velocityY;
private int m_rightBound;
private int m_bottomBound;
public Ball(int x, int y, int velocityX, int velocityY) {
m_x = x;
m_y = y;
m_velocityX = velocityX;
m_velocityY = velocityY;
}
public void setBounds(int width, int height) {
m_rightBound = width - DIAMETER;
m_bottomBound = height - DIAMETER;
}
public void move() {
m_x += m_velocityX;
m_y += m_velocityY;
if (m_x < 0) {
m_x = 0;
m_velocityX = -m_velocityX;
} else if (m_x > m_rightBound) {
m_x = m_rightBound;
m_velocityX = -m_velocityX;
}
if (m_y < 0) {
m_y = 0;
m_velocityY = -m_velocityY;
} else if (m_y > m_bottomBound) {
m_y = m_bottomBound;
m_velocityY = -m_velocityY;
}
}
public void draw(Graphics g) {
g.fillOval(m_x, m_y, DIAMETER, DIAMETER);
}
public int getDiameter() { return DIAMETER;}
public int getX() { return m_x;}
public int getY() { return m_y;}
public void setPosition(int x, int y) {
m_x = x;
m_y = y;
}
}
class ContainerTable {
public int minX;
public int maxX;
public int minY;
public int maxY;
private Color colorFilled;
private Color colorBorder;
public ContainerTable(int x, int y, int width, int height, Color colorFilled, Color colorBorder) {
minX = x;
minY = y;
maxX = x + width - 1;
maxY = y + height - 1;
this.colorFilled = colorFilled;
this.colorBorder = colorBorder;
}
public void set(int x, int y, int width, int height) {
minX = x;
minY = y;
maxX = x + width - 1;
maxY = y + height - 1;
}
public void draw(Graphics g) {
g.setColor(colorFilled);
g.fillRect(minX, minY, maxX - minX - 1, maxY - minY - 1);
g.setColor(colorBorder);
g.drawRect(minX, minY, maxX - minX - 1, maxY - minY - 1);
Graphics2D southArc = ( Graphics2D ) g;
southArc.setColor ( Color.WHITE );
southArc.setStroke(new BasicStroke(3));
southArc.drawArc ( 98, 640 , 300, 300 , 0, 180 );
Graphics2D northArc = ( Graphics2D ) g;
northArc.setColor ( Color.WHITE );
northArc.setStroke(new BasicStroke(3));
northArc.drawArc ( 98, -143 , 300, 300 , 180, 180 );
Graphics2D line = ( Graphics2D ) g;
line.setStroke(new BasicStroke(3));
line.setColor(Color.white);
line.drawLine(4, 395, 491, 395);
Graphics2D dot=(Graphics2D) g;
dot.setColor(Color.black);
for(int j=10;j<800;j+=20){
for(int i=6;i<502;i+=20){
dot.drawLine(i, j, i, j);
}
}
}
public int getMinX() {
return minX;
}
public void setMinX(int minX) {
this.minX = minX;
}
public int getMaxX() {
return maxX;
}
public void setMaxX(int maxX) {
this.maxX = maxX;
}
public int getMinY() {
return minY;
}
public void setMinY(int minY) {
this.minY = minY;
}
public int getMaxY() {
return maxY;
}
public void setMaxY(int maxY) {
this.maxY = maxY;
}}

Related

Processing - How to resize shapes

Using the mouse, I would like to change the size of the shapes that I have in my code (which is circle and rectangle) by clicking on the corners and dragging it to change the shape's width and height.
Here's my main code:
circleShape [] objs;
int numObjs = 1;
int pickedItem = -1;
rectShape [] objss;
int numObjss = 1;
int itemPicked = -1;
void setup() {
size(600, 600);
objs = new circleShape[numObjs];
for (int i = 0; i < numObjs; i++) {
int radius = (int)(random(20, 70));
color c = (int)(random(0, 255));
objs[i] = new circleShape(radius, c);
}
objss = new rectShape[numObjss];
for (int i = 0; i < numObjss; i++) {
int Radius = (int)(random(20, 70));
color C = (int)(random(0, 255));
objss[i] = new rectShape(Radius, C);
}
}
void draw() {
background(255);
for (int i = 0; i < numObjs; i++) {
objs[i].drawShape();
}
for (int i =0; i < numObjss; i++) {
objss[i].shapeDraw();
}
}
// return the index number of the picked item from the array
// return -1 otherwise
int getPickedObj(int x, int y) {
for (int i = 0; i < numObjs; i++) {
if (objs[i].isOnShape(x, y)) {
return i;
}
}
return -1;
}
int pickedObj(int X, int Y) {
for (int i = 0; i < numObjss; i++) {
if (objss[i].onShape(X, Y)) {
return i;
}
}
return -1;
}
void mousePressed() {
pickedItem = getPickedObj(mouseX, mouseY);
itemPicked = pickedObj(mouseX, mouseY);
}
void mouseDragged() {
if (pickedItem >= 0) {
objs[pickedItem].move(mouseX, mouseY);
objs[pickedItem].drawShape();
}
if (itemPicked >= 0) {
objss[itemPicked].move(mouseX, mouseY);
objss[itemPicked].shapeDraw();
}
}
And here's my shape code:
// a shape is simply as a circle
class circleShape {
int posX, posY, radius;
color c;
circleShape(int radius, color c) {
this.radius = radius;
this.c = c;
posX = (int)random(0, 200);
posY = (int)random(0, 200);
}
// return true if the position x, y is on the shape
boolean isOnShape(int x, int y) {
float d = (posX - x)*(posX - x) + (posY - y)*(posY - y);
d = sqrt(d);
if (d < radius) return true;
else return false;
}
void move (int newPosX, int newPosY) {
this.posX = newPosX;
this.posY = newPosY;
}
void drawShape() {
noStroke();
fill(c);
ellipse(posX, posY, 2*radius, 2*radius);
}
}
//Rectangle Shape
class rectShape {
int xPos, yPos, Radius;
color C;
rectShape(int Radius, color C) {
this.Radius = Radius;
this.C = C;
xPos = (int)random(0, 200);
yPos = (int)random(0, 200);
}
boolean onShape(int X, int Y) {
float D = (xPos - X)*(xPos - X) + (yPos - Y)*(yPos - Y);
D = sqrt(D);
if (D < Radius) return true;
else return false;
}
void move (int posXnew, int posYnew) {
this.xPos = posXnew;
this.yPos = posYnew;
}
void shapeDraw() {
noStroke();
fill(C);
rect(xPos, yPos, 2*Radius+60, 2*Radius);
}
}
My code allows the mouse to move the shapes from one place to another. It just needs to be able to change the size of them.
I'll give you an example for a rectangular shape.
A rectangle is defined by a position, the width and the height. Change the attributes and the constructor of the rectangle:
class rectShape {
int xPos, yPos, Width, Height;
color C;
rectShape(int X, int Y, int Width, int Height, color C) {
this.xPos = X;
this.yPos = Y;
this.Width = Width;
this.Height = Height;
this.C = C;
}
// [...]
void shapeDraw() {
noStroke();
fill(C);
rect(xPos, yPos, this.Width, this.Height);
}
}
Create a random rectangle:
void setup() {
size(600, 600);
// [...]
objss = new rectShape[numObjss];
for (int i = 0; i < numObjss; i++) {
int xPos = (int)random(0, 200);
int yPos = (int)random(0, 200);
int Width = (int)(random(20, 70));
int Height = (int)(random(20, 70));
color C = (int)(random(0, 255));
objss[i] = new rectShape(xPos, yPos, Width, Height, C);
}
}
Create a method in the class rectShape, which determines if the mouse is on the rectangle and if it is on the left, right, top, bottom or center:
String onShape(int X, int Y) {
String where = "";
Boolean isOn = X > xPos && X < xPos + Width && Y > yPos && Y < yPos + Height;
if (isOn) {
int left = abs(X - xPos);
int right = abs(X - (xPos + Width));
int top = abs(Y - yPos);
int bottom = abs(Y - (yPos + Height));
if (min (left, right) < min (top, bottom)) {
if (left < 10)
where = "left";
else if (right < 10)
where = "right";
else
where = "center";
}
else {
if (top < 10)
where = "top";
else if (bottom < 10)
where = "bottom";
else
where = "center";
}
}
return where;
}
Create a method which can change the rectangle dependent on an action command:
void update(String what, int posXnew, int posYnew) {
if (what == "left") {
if (posXnew < this.xPos + this.Width) {
this.Width = this.xPos + this.Width - posXnew;
this.xPos = posXnew;
}
}
else if (what == "right") {
if (posXnew > this.xPos) {
this.Width = posXnew - this.xPos;
}
}
else if (what == "top") {
if (posYnew < this.yPos + this.Height) {
this.Height = this.yPos + this.Height - posYnew;
this.yPos = posYnew;
}
}
else if (what == "bottom") {
if (posYnew > this.yPos) {
this.Height = posYnew - this.yPos;
}
}
else {
this.xPos = posXnew - this.Width / 2;
this.yPos = posYnew - this.Height / 2;
}
}
Determine the action when the rectangle is clicked on:
String itemAction = "";
int pickedObj(int X, int Y) {
for (int i = 0; i < numObjss; i++) {
itemAction = objss[i].onShape(X, Y);
if (itemAction != "") {
return i;
}
}
return -1;
}
void mousePressed() {
// [...]
itemPicked = pickedObj(mouseX, mouseY);
}
Pass the action to the update method when the mouse is dragged:
void mouseDragged() {
if (itemPicked >= 0) {
objss[itemPicked].update(itemAction, mouseX, mouseY);
}
}
Complete class rectShape:
//Rectangle Shape
class rectShape {
int xPos, yPos, Width, Height;
color C;
rectShape(int X, int Y, int Width, int Height, color C) {
this.xPos = X;
this.yPos = Y;
this.Width = Width;
this.Height = Height;
this.C = C;
}
String onShape(int X, int Y) {
String where = "";
Boolean isOn = X > xPos && X < xPos + Width && Y > yPos && Y < yPos + Height;
if (isOn) {
int left = abs(X - xPos);
int right = abs(X - (xPos + Width));
int top = abs(Y - yPos);
int bottom = abs(Y - (yPos + Height));
if (min (left, right) < min (top, bottom)) {
if (left < 10)
where = "left";
else if (right < 10)
where = "right";
else
where = "center";
}
else {
if (top < 10)
where = "top";
else if (bottom < 10)
where = "bottom";
else
where = "center";
}
}
return where;
}
void update(String what, int posXnew, int posYnew) {
if (what == "left") {
if (posXnew < this.xPos + this.Width) {
this.Width = this.xPos + this.Width - posXnew;
this.xPos = posXnew;
}
}
else if (what == "right") {
if (posXnew > this.xPos) {
this.Width = posXnew - this.xPos;
}
}
else if (what == "top") {
if (posYnew < this.yPos + this.Height) {
this.Height = this.yPos + this.Height - posYnew;
this.yPos = posYnew;
}
}
else if (what == "bottom") {
if (posYnew > this.yPos) {
this.Height = posYnew - this.yPos;
}
}
else {
this.xPos = posXnew - this.Width / 2;
this.yPos = posYnew - this.Height / 2;
}
}
void shapeDraw() {
noStroke();
fill(C);
rect(xPos, yPos, this.Width, this.Height);
}
}

Processing: Where would I initialize a counter if it is changed in draw?

Table t1;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
int stickColR=0;
int stickColG=0;
int stickColB=0;
int counter=0;
//--------------
void setup(){
size(1000,600);
smooth();
t1 = new Table(1000,600);
t1.startGame();
//sound player setup
minim= new Minim(this);
player=minim.loadFile("ballsound.mp3");
}
//--------------
void draw(){
strokeWeight(10);
stroke(255,0,0);
fill(26, 218, 35);
rect(0, 0, 1000, 600);
fill(0);
noStroke();
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
t1.updatePos(); //calling the function to update the position of the balls
t1.visualize(); // Function responsible for drawing the balls
}
//--------------
void mousePressed(){
t1.mousePressed(mouseX-t1.x,mouseY-t1.y);
}
//--------------
void mouseReleased(){
t1.mouseReleased(mouseX-t1.x,mouseY-t1.y);
}
//=============================
class Table{
boolean GameIsOver=false;
float drag = 0.99;
float bounce = 0.4;
float wallBounce = 0.3;
float pushFactor = 0.4;
float maxPush = 20;
color[] ballColors = new color[]{color (255), color (216,7,17),color(17,242,225), color ( #45B4CE) , color ( #6A6347) , color (#E80909) ,color (#CEA9A9)};
Ball[] balls;
Ball selectedBall;
int x,y,width,height;
//--------------
Table(int w, int h){
width = w;
height = h;
}
//--------------
void startGame(){
buildBalls(5);
}
//--------------
void buildBalls(int count){
balls = new Ball[2*count+1];
int x_coor_red=600;
int y_coor_red=300;
int x_coor_green=626;
int y_coor_green=313;
for(int i=0;i<count;i++)
{
balls[i] = new Ball(x_coor_red, y_coor_red,i+1, this);
x_coor_red+=26;
y_coor_red-=13;
if(i>=3)
{
x_coor_red-=26;
y_coor_red+=26;
}
}
for(int i=0;i<count;i++)
{
balls[count+i] = new Ball( x_coor_green, y_coor_green,i+2, this);
x_coor_green+=26;
y_coor_green+=13;
if(i==1)
{
x_coor_green-=26;
y_coor_green-=20;
}
if(i==2)
{
y_coor_green-=20;
}
if(i==3)
{
x_coor_green-=45;
}
}
balls[2*count] = new Ball( 0.5*(width), 0.5*(height),0, this);
}
//--------------
void updatePos(){
//simulation
for(int i=0;i<balls.length;i++)
balls[i].update();
//collision detection
for(int i=0;i<balls.length;i++)
for(int j=i+1;j<balls.length;j++)
balls[i].collisionDetect(balls[j]);
}
//--------------
void visualize(){
translate(x,y);
noStroke();
//draw stick
if(mousePressed && selectedBall!= null && (mouseX<=26+selectedBall.x || mouseX>26-selectedBall.x) && selectedBall.ballColor==color(255)){
stickColR+=2;
stickColB+=2;
strokeWeight(4);
stroke(stickColR, stickColG, stickColB);
line ( mouseX , mouseY , mouseX + cos (atan2 ( mouseY -selectedBall.y , mouseX - selectedBall.x) )*300 , mouseY + sin( atan2 ( mouseY - selectedBall.y , mouseX -selectedBall.x ))*300);
}
//drawing
for(int i=0;i<balls.length;i++){
balls[i].visualize();
//Balls"disappearing" in corners
if(balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550)){
player.rewind();
player.play();
if(balls[i].ballColor==color(255))
{
textSize(25);
text("Cue Ball Sunk. GAME OVER",350,560);
}
fill(0);
ellipse(0,0,100,100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
balls[i].x=1200;
balls[i].y=0;
counter++;
if (balls[i].ballColor != 255 && counter>=3)
{
textSize(25);
text("YOU WIN", 350,560);
}
}
}
}
//--------------
float kineticEnergy(){
float energy=0;
for(int i=0;i<balls.length;i++)
energy += mag( balls[i].vx, balls[i].vy );
return energy;
}
//--------------
void mousePressed(int mx, int my){
for(int i=0;i<balls.length;i++)
if( dist(balls[i].x,balls[i].y,mx,my) < balls[i].radius) {
selectedBall = balls[i];
break;
}
}
//--------------
void mouseReleased(int mx, int my){
if(selectedBall != null){
float px = (selectedBall.x-mx) * pushFactor;
float py = (selectedBall.y-my) * pushFactor;
float push = mag(px,py);
stickColR=0;
stickColB=0;
if( push > maxPush ){
px = maxPush*px/push;
py = maxPush*py/push;
}
selectedBall.push(px,py);
}
selectedBall = null;
}
}
class Ball{
float x,y,vx,vy,radius,diameter;
int type;
Table table;
color ballColor;
//--------------
Ball(float x, float y, int type, Table t){
this.x = x;
this.y = y;
this.type = type;
diameter = 26;
radius = diameter/2;
table = t;
ballColor = table.ballColors[type];
}
//--------------
void update(){
vx *= table.drag;
vy *= table.drag;
x += vx;
y += vy;
wallBounce();
}
//--------------
void wallBounce(){
if(x<=radius){
vx = -table.wallBounce*vx;
x = radius;
player.rewind();
player.play();
}
if(x>=t1.width-radius){
vx = -table.wallBounce*vx;
x = table.width-radius;
player.rewind();
player.play();
}
if(y<=radius){
vy = -table.wallBounce*vy;
y = radius;
player.rewind();
player.play();
}
if(y>=t1.height-radius){
vy = -table.wallBounce*vy;
y = table.height-radius;
player.rewind();
player.play();
}
}
//--------------
void visualize(){
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x,y,diameter,diameter);
}
//--------------
void push(float dx, float dy){
vx += dx;
vy += dy;
}
//--------------
void collisionDetect(Ball b){
float distance = dist(x,y,b.x,b.y);
if( distance < diameter && (b.x>50 && (b.y>50 || b.y<550) || b.x<950 &&(b.y>50 || b.y<550))){
float vxSum = 0.5*(vx + b.vx);
float vySum = 0.5*(vy + b.vy);
float forceMagnitude = ((b.x-x)*(vx-vxSum) + (b.y-y)*(vy-vySum));
float xForce = 0.25*(x-b.x)*forceMagnitude/distance;
float yForce = 0.25*(y-b.y)*forceMagnitude/distance;
vx = vx + table.bounce * xForce;
vy = vy + table.bounce * yForce;
b.vx = b.vx - table.bounce * xForce;
b.vy = b.vy - table.bounce * yForce;
b.x = x + (diameter+1)*(b.x-x)/distance;
b.y = y + (diameter+1)*(b.y-y)/distance;
player.rewind();
player.play();
}
}
}
Im making a pool game in processing and I'm almost done but I'm stuck here. I want to add a counter that counts when a ball has been in the corner, then once the counter equals ten, the number of balls, it will display the winning message. I think something is going wrong in that the counter is being reset each time since it's in draw? But I'm not sure where else to initialize it. Btw, right now I just have it >= 3 so that I can quickly see if it's working. Thanks all
due to my low reputation, I have to show you my solution even though I think I haven't fixed all the bugs in your code.
I think your bug stated in the question has little relationship with the counter variable. I ran your code and found that you tried to hide the "disappeared" ball by changing coordinates. It means that "disappeared" balls can still be qualified to the if statement below, and as the result, value of counter will keep increasing.
//Balls"disappearing" in corners
if(balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550))
So you can add a boolean field to the Ball class
class Ball{
float x,y,vx,vy,radius,diameter;
int type;
Table table;
color ballColor;
// add this variable.
boolean disappeared = false;
// your constructor, wallBounce(), push(), collisionDetect()
void visualize(){
// only draw the ball when it hasn't disappeared.
if(!this.disappeared) {
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x,y,diameter,diameter);
}
}
}
and then use it to avoid double counting.
// other code in visualize()
if(!balls[i].disappeared) {
counter++;
balls[i].disappeared = true;
}
// other code
Table t1;
import ddf.minim.*;
AudioPlayer player;
Minim minim;
int stickColR=0;
int stickColG=0;
int stickColB=0;
float counter;
boolean isAllIn = false;
//--------------
void setup() {
counter=0;
size(1000, 600);
smooth();
t1 = new Table(1000, 600);
t1.startGame();
//sound player setup
minim= new Minim(this);
player=minim.loadFile("ballsound.mp3");
}
//--------------
void draw() {
strokeWeight(10);
stroke(255, 0, 0);
fill(26, 218, 35);
rect(0, 0, 1000, 600);
fill(0);
noStroke();
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
t1.updatePos(); //calling the function to update the position of the balls
t1.visualize(); // Function responsible for drawing the balls
}
//--------------
void mousePressed() {
t1.mousePressed(mouseX-t1.x, mouseY-t1.y);
}
//--------------
void mouseReleased() {
t1.mouseReleased(mouseX-t1.x, mouseY-t1.y);
}
//=============================
class Table {
float drag = 0.99;
float bounce = 0.4;
float wallBounce = 0.3;
float pushFactor = 0.4;
float maxPush = 20;
color[] ballColors = new color[]{color (255), color (216, 7, 17), color(17, 242, 225), color ( #45B4CE), color ( #6A6347), color (#E80909), color (#CEA9A9)};
Ball[] balls;
Ball selectedBall;
int x, y, width, height;
//--------------
Table(int w, int h) {
width = w;
height = h;
}
//--------------
void startGame() {
buildBalls(5);
}
void restart() {
t1 = new Table(1000, 600);
t1.startGame();
}
//--------------
void buildBalls(int count) {
balls = new Ball[2*count+1];
int x_coor_red=600;
int y_coor_red=300;
int x_coor_green=626;
int y_coor_green=313;
for (int i=0; i<count; i++)
{
balls[i] = new Ball(x_coor_red, y_coor_red, i+1, this);
x_coor_red+=26;
y_coor_red-=13;
if (i>=3)
{
x_coor_red-=26;
y_coor_red+=26;
}
}
for (int i=0; i<count; i++)
{
balls[count+i] = new Ball( x_coor_green, y_coor_green, i+2, this);
x_coor_green+=26;
y_coor_green+=13;
if (i==1)
{
x_coor_green-=26;
y_coor_green-=20;
}
if (i==2)
{
y_coor_green-=20;
}
if (i==3)
{
x_coor_green-=45;
}
}
balls[2*count] = new Ball( 0.5*(width), 0.5*(height), 0, this);
}
//--------------
void updatePos() {
//simulation
for (int i=0; i<balls.length; i++)
balls[i].update();
//collision detection
for (int i=0; i<balls.length; i++)
for (int j=i+1; j<balls.length; j++)
balls[i].collisionDetect(balls[j]);
}
//--------------
void visualize() {
translate(x, y);
noStroke();
//draw stick
if (mousePressed && selectedBall!= null && (mouseX<=26+selectedBall.x || mouseX>26-selectedBall.x) && selectedBall.ballColor==color(255)) {
stickColR+=2;
stickColB+=2;
strokeWeight(4);
stroke(stickColR, stickColG, stickColB);
line ( mouseX, mouseY, mouseX + cos (atan2 ( mouseY -selectedBall.y, mouseX - selectedBall.x) )*300, mouseY + sin( atan2 ( mouseY - selectedBall.y, mouseX -selectedBall.x ))*300);
}
//drawing
for (int i=0; i<balls.length; i++) {
balls[i].visualize();
//Balls"disappearing" in corners
if (balls[i].x<50 && (balls[i].y<50 || balls[i].y>550) || balls[i].x>950 &&(balls[i].y<50 || balls[i].y>550)) {
player.rewind();
player.play();
if (balls[i].ballColor==color(255))
{
textSize(25);
text("Cue Ball Sunk. GAME OVER. Press any key to restart.", 170, 560);
if (keyPressed == true) {
t1.restart();
}
}
/*
fill(0);
ellipse(0, 0, 100, 100);
ellipse(1000, 0, 100, 100);
ellipse(0, 600, 100, 100);
ellipse(1000, 600, 100, 100);
balls[i].x=1200;
balls[i].y=0;
*/
if (!balls[i].disappeared) {
counter++;
balls[i].disappeared=true;
}
if ( counter>=3) {
textSize(25);
text("YOU WIN. Press any key to restart.", 300, 560);
if (keyPressed == true) {
t1.restart();
}
}
}
}
}
//--------------
float kineticEnergy() {
float energy=0;
for (int i=0; i<balls.length; i++)
energy += mag( balls[i].vx, balls[i].vy );
return energy;
}
//--------------
void mousePressed(int mx, int my) {
for (int i=0; i<balls.length; i++)
if ( dist(balls[i].x, balls[i].y, mx, my) < balls[i].radius) {
selectedBall = balls[i];
break;
}
}
//--------------
void mouseReleased(int mx, int my) {
if (selectedBall != null) {
float px = (selectedBall.x-mx) * pushFactor;
float py = (selectedBall.y-my) * pushFactor;
float push = mag(px, py);
stickColR=0;
stickColB=0;
if ( push > maxPush ) {
px = maxPush*px/push;
py = maxPush*py/push;
}
selectedBall.push(px, py);
}
selectedBall = null;
}
}
class Ball {
boolean disappeared = false;
float x, y, vx, vy, radius, diameter;
int type;
Table table;
color ballColor;
//--------------
Ball(float x, float y, int type, Table t) {
this.x = x;
this.y = y;
this.type = type;
diameter = 26;
radius = diameter/2;
table = t;
ballColor = table.ballColors[type];
}
//--------------
void update() {
vx *= table.drag;
vy *= table.drag;
x += vx;
y += vy;
wallBounce();
}
//--------------
void wallBounce() {
if (x<=radius) {
vx = -table.wallBounce*vx;
x = radius;
player.rewind();
player.play();
}
if (x>=t1.width-radius) {
vx = -table.wallBounce*vx;
x = table.width-radius;
player.rewind();
player.play();
}
if (y<=radius) {
vy = -table.wallBounce*vy;
y = radius;
player.rewind();
player.play();
}
if (y>=t1.height-radius) {
vy = -table.wallBounce*vy;
y = table.height-radius;
player.rewind();
player.play();
}
}
//--------------
void visualize() {
if (!this.disappeared) {
fill(ballColor);
stroke(0);
strokeWeight(2);
stroke(0);
ellipse(x, y, diameter, diameter);
}
}
//--------------
void push(float dx, float dy) {
vx += dx;
vy += dy;
}
//--------------
void collisionDetect(Ball b) {
float distance = dist(x, y, b.x, b.y);
if ( distance < diameter && (b.x>50 && (b.y>50 || b.y<550) || b.x<950 &&(b.y>50 || b.y<550))) {
float vxSum = 0.5*(vx + b.vx);
float vySum = 0.5*(vy + b.vy);
float forceMagnitude = ((b.x-x)*(vx-vxSum) + (b.y-y)*(vy-vySum));
float xForce = 0.25*(x-b.x)*forceMagnitude/distance;
float yForce = 0.25*(y-b.y)*forceMagnitude/distance;
vx = vx + table.bounce * xForce;
vy = vy + table.bounce * yForce;
b.vx = b.vx - table.bounce * xForce;
b.vy = b.vy - table.bounce * yForce;
b.x = x + (diameter+1)*(b.x-x)/distance;
b.y = y + (diameter+1)*(b.y-y)/distance;
player.rewind();
player.play();
}
}
}

Java paint program double buffering

So I'm working on a paint program in school and now I have to double buffer it. After a week of searching and using tutorials online I am still unable to double buffer my program properly... I have written a double buffer function but then you can't paint anything... When i disable the double buffer you can paint fine but the screen flickers. Please help
(Yes I am aware that some of my code is deprecated and I should fix that)
Code:
import java.applet.*;
import java.awt.*;
public class PaintRun extends Applet
{
static int posx = 0;
static int posy = 0;
static int posxOld = 0;
static int posyOld = 0;
static int size = 20;
static int toolNum = 0;
static boolean ready = false;
static Color col = new Color(120,120,120);
static Button clear = new Button(0,0,20,'C');
static Button sizeInc = new Button(20,0,20,'+');
static Button sizeDec = new Button(40,0,20,'-');
static Tools tool = new Tools(posx,posy);
public void paint(Graphics g)
{
drawButtons(g);
detectButtons(g);
}
private static void detectButtons(Graphics g)
{
if (clear.detect(posx,posy) == true)
{
g.setColor(Color.WHITE);
g.fillRect(0, 0, 800000, 800000);
drawButtons(g);
}
else if (sizeInc.detect(posx, posy))
{
size+=2;
drawButtons(g);
}
else if (sizeDec.detect(posx, posy))
{
size-=2;
if (size <= 2)
size = 2;
drawButtons(g);
}
else
{
if (ready == true)
{
g.setColor(Color.BLACK);
g.drawLine(posxOld, posyOld, posx, posy);
drawButtons(g);
}
}
}
private static void drawButtons(Graphics g)
{
clear.setColor(col, Color.BLACK);
sizeInc.setColor(col, Color.BLACK);
sizeDec.setColor(col, Color.BLACK);
clear.drawButton(g);
sizeInc.drawButton(g);
sizeDec.drawButton(g);
}
public boolean mouseDown(Event e, int x, int y)
{
posx = x;
posy = y;
posxOld = x;
posyOld = y;
ready = true;
repaint();
return true;
}
public boolean mouseDrag(Event e, int x, int y)
{
posxOld = posx;
posyOld = posy;
posx = x;
posy = y;
repaint();
return true;
}
// Normal Update function
public void update(Graphics g)
{
paint(g);
}
// Double buffered Update function
/*public void update(Graphics g)
{
Graphics offgc;
Image offscreen = null;
Dimension d = size();
offscreen = createImage(d.width, d.height);
offgc = offscreen.getGraphics();
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
paint(offgc);
g.drawImage(offscreen, 0, 0, this);
}
*/
}
class Button extends Applet
{
int minX; // X coord where the button is drawn
int minY; // Y coord where the button is drawn
int maxX; // X size
int maxY; // Y size
char letter;
Color back;
Color line;
// Constructor block
public Button(char desc)
{
minX = 0;
minY = 0;
maxX = 40;
maxY = 40;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
public Button(int x, int y, char desc)
{
minX = x;
minY = y;
maxX = 40;
maxY = 40;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
public Button(int x, int y, int size, char desc)
{
minX = x;
minY = y;
maxX = size;
maxY = size;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
public Button(int x, int y, int sizeX, int sizeY, char desc)
{
minX = x;
minY = y;
maxX = sizeX;
maxY = sizeY;
back = new Color(255,255,255);
line = new Color(0,0,0);
letter = desc;
}
// Draws the button
public void drawButton(Graphics g)
{
g.setColor(back);
g.fillRect(minX, minY, maxX, maxY);
g.setColor(line);
g.drawRect(minX, minY, maxX, maxY);
g.drawString(Character.toString(letter), (minX+maxX/2)-4, (minY+maxY/2)+4);
}
// Sets the button colors
public void setColor(Color b, Color l)
{
back = b;
line = l;
}
// Detects if those coordinates are in the button location or not
public boolean detect(int x, int y)
{
boolean flag = false;
if (x > minX && x < (minX + maxX) && y > minY && y < (minY + maxY))
flag = true;
else
flag = false;
return flag;
}
}

Timer is not starting in JPanel

I am trying to move an image in JPanel and the static variable x and y are the coordinates of red color changed in an other class using opencv. Here the timer is not starting. Please tell me where I am mistaken.
class ImageFollowingPanel extends JPanel
{
private final BufferedImage image;
private Point imagePosition = new Point(150, 150);
private Point redPoint;
private double imageAngleRad = 0;
public static int x, y;
public ImageFollowingPanel()
{
BufferedImage i = null;
try
{
i = ImageIO.read(new File("forward.png"));
}
catch (IOException e)
{
e.printStackTrace();
}
image = i;
ActionListener taskPerformer = new ActionListener()
{
public void actionPerformed(ActionEvent evt)
{
if (redPoint != null)
{
int centerX = imagePosition.x + (image.getWidth() / 2);
int centerY = imagePosition.y + (image.getHeight() / 2);
if (redPoint.x != centerX)
{
imagePosition.x += redPoint.x < centerX ? -1 : 1;
}
if (redPoint.y != centerY)
{
imagePosition.y += redPoint.y < centerY ? -1 : 1;
}
System.out.println("mouse::: x : " + x + "y :" + y);
redPoint.x = x;
redPoint.y = y;
double dx = x - imagePosition.getX();
double dy = y - imagePosition.getY();
imageAngleRad = Math.atan2(dy, dx);
repaint();
}
}
};
Timer timer = new Timer(1000, taskPerformer);
timer.start();
}
protected void paintComponent(Graphics gr)
{
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr;
g.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
int cx = image.getWidth() / 2;
int cy = image.getHeight() / 2;
AffineTransform oldAT = g.getTransform();
g.translate(cx + imagePosition.x, cy + imagePosition.y);
g.rotate(imageAngleRad);
g.translate(-cx, -cy);
g.drawImage(image, 0, 0, null);
g.setTransform(oldAT);
}
}
Everytime the timer fires the action event, you check if redPoint is not null, if it's null you just do nothing. But in your code redPoint is always null, that's why nothing happens.

stop applet flickering with double buffering Java Applet

sorry to keep asking questions about my program but i think i'm nearly there and i'm teaching myself java so please bear with me. I'm creating an applet that moves sheep object across the screen in a random direction when a dog object moves close to the sheep. Getting the sheep to move in a random direction took some work and with the help of you guys on here it now works (sort of) but what I'm trying to do now is stop it from flickering when i drag objects across the screen. I've read about double buffering, I can get it to work for items drawn in the paint method of a main class but cant get it to work for my sheep and dog objects which are defined as separate objects in separate classes. Any help will be much appreciated. Here is my code:
package mandAndDog;
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
public class SheepDog extends Applet implements ActionListener, MouseListener, MouseMotionListener
{
/**
*
*/
private static final long serialVersionUID = 1L;
/**
*
*/
Dog dog;
Sheep sheep;
int[] directionNumbersLeft = {0, 1, 3};
int[] directionNumbersUp = {0, 1, 2};
int x;
int selection;
int xposR;
int yposR;
int sheepx;
int sheepy;
int sheepBoundsx;
int sheepBoundsy;
int MAX_DISTANCE = 50;
int direction;
int distance;
Boolean sheepisclosetodog;
public void init()
{
addMouseListener(this);
addMouseMotionListener(this);
dog = new Dog(10, 10);
sheepx = 175;
sheepy = 75;
sheep = new Sheep(sheepx, sheepy);
sheepBoundsx = 30;
sheepBoundsy = 30;
direction = (int)(Math.random()*4);
distance = (int) (Math.random() * MAX_DISTANCE) % MAX_DISTANCE;
sheepisclosetodog = false;
Random rand = new Random();
x = rand.nextInt(3);
selection = directionNumbersLeft[x];
}
public void paint(Graphics g)
{
dog.display(g);
sheep.display(g);
g.drawString(Integer.toString(distance), 85, 100);
g.drawString(Integer.toString(direction), 85, 125);
g.drawString(Integer.toString(selection), 85, 140);
}
public void actionPerformed(ActionEvent ev)
{}
public void mousePressed(MouseEvent e)
{}
public void mouseReleased(MouseEvent e)
{}
public void mouseEntered(MouseEvent e)
{}
public void mouseExited(MouseEvent e)
{}
public void mouseMoved(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{}
public void mouseDragged(MouseEvent e)
{
dog.setLocation(xposR, yposR);
sheep.setLocation(sheepx, sheepy);
if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
&& yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 0){
sheepx = sheepx + 50;
direction = (int)(Math.random()*4);
}
if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
&& yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 1){
sheepy = sheepy + 50;
direction = (int)(Math.random()*4);
}
if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
&& yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 2){
sheepx = sheepx - 50;
direction = (int)(Math.random()*4);
}
if (sheepx <= 5){
direction = directionNumbersLeft[x];
}
if (xposR > (sheepx - 20)&& xposR < (sheepx - 20)+(sheepBoundsx - 20) && yposR > (sheepy - 20)
&& yposR < (sheepy - 20)+(sheepBoundsy - 20) && direction == 3){
sheepy = sheepy - 50;
direction = (int)(Math.random()*4);
}
if (sheepy <=5){
direction = directionNumbersUp[x];
}
xposR = e.getX();
yposR = e.getY();
repaint();
}
}
class Dog
{
int xpos;
int ypos;
int circleWidth = 30;
int circleHeight = 30;
public Dog(int x, int y)
{
xpos = x;
ypos = y;
}
public void setLocation(int lx, int ly)
{
xpos = lx;
ypos = ly;
}
public void display(Graphics g)
{
g.setColor(Color.blue);
g.fillOval(xpos, ypos, circleWidth, circleHeight);
}
}
class Sheep
{
int xpos;
int ypos;
int circleWidth = 10;
int circleHeight = 10;
public Sheep(int x, int y)
{
xpos = x;
ypos = y;
}
public void setLocation(int lx, int ly)
{
xpos = lx;
ypos = ly;
}
public void display(Graphics g)
{
g.setColor(Color.green);
g.fillOval(xpos , ypos, circleWidth, circleHeight);
g.drawOval(xpos - 20, ypos - 20, 50, 50);
}
}
First of all, I dont exactly understand why you have a display method inside your Sheep and Dog class. Instead of doing that, I suggest you display the sheep and dog inside your SheepDog class.
Also instead of using Graphics, you should use Graphics2D. In order to use this simply do
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
}
This is possible because Graphics2D is a subclass of Graphics. Once you do that, what I would do is override the update() method and do this
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
graphics = image.getGraphics();
}
graphics.setColor(getBackground());
graphics.fillRect(0, 0, this.getWidth(), this.getHeight());
graphics.setColor(getForeground());
paint(graphics);
g.drawImage(image, 0, 0, this);
}
When you call repaint(), it actually first calls the update() method, which in turn calls the paint() method. Towards the top of the class, you should declare
Image image;
Graphics graphics;

Categories

Resources