Related
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();
}
}
}
Hi I'm creating a program where the user needs to give certain inputs to gain points and there is a timer, but the timer is I created is making the cursor in the jtextfield to blink too fast for the program to take inputs at times. In my timer class I imported TimerTask and used timer.scheduleAtFixedRate() to count time. This isn't all my code but this is the main class.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
class Interface extends JPanel implements ActionListener {
private JTextField textField;
private int fontSize;
private Font font;
private GridBagConstraints c = new GridBagConstraints();
private int x, y;
private collection userInputData;
private boolean initialized = false;
private String[] answers;
private String[] questions;
private int points = 0;
private timer timer;
private boolean timerStarted = false;
Interface() {
super(new GridBagLayout());
x = 0;
y = 0;
userInputData = new collection();
setBackground(Color.BLACK);
timer = new timer(60);
questions = new String[] {"a", "b", "c", "d"};
answers = new String[] {"a","b","c","d","e","f","g" };
/*questions = new String[] {"云", "人", "口", "一"};
answers = new String[] {"去","十","二","大","运","中","丁" };*/
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
fontSize = getWidth() / 25;
Font font = new Font(g.getFont().getFontName(), Font.BOLD, fontSize);
g.setFont(font);
g.setColor(Color.WHITE);
if(initialized){
updateUserDataFrame();
updateFrame();
textField.requestFocus();
}
if (!timer.timeUp()) {
questions(g);
fontSize = getWidth() / 50;
Font n = new Font(g.getFont().getFontName(), Font.BOLD, fontSize);
g.setFont(n);
displayTimer(g);
points(g);
displayUserInput(g);
}
if (timer.timeUp()) {
displayScoreboard(g);
remove(textField);
}
}
private void displayTimer(Graphics g) {
if (!timerStarted) {
timer.start();
timerStarted = true;
}
//fontSize = getWidth() / 35;
timer.setColor(Color.RED);
timer.setPosition(getWidth() - (int) (getWidth() ), fontSize );
timer.displayTimer(g);
repaint();
}
private void displayScoreboard(Graphics g) {
int x = getWidth() / 50;
int y = getHeight() / 5;
g.drawString("Your Answers:", x, y);
/* String correctWrongNumber = "Correct: " + correctAnswers + " "
+ "Wrong: " + (question.length - correctAnswers);
x = getWidth() - g.getFontMetrics().stringWidth(correctWrongNumber) - getWidth() / 25;
g.drawString(correctWrongNumber, x, y);
x = getWidth() / 50;
y += getHeight() / 15 + fontSize;
for (int i = 0; i < studentAnswers.length; i++) {
g.drawString(i + 1 + ". " + studentAnswers[i], x, y);
x += getWidth() / 10.5;
}*/
}
private void points(Graphics g) {
int x = getWidth() / 4;
int y = getHeight() / 4;
g.setColor(Color.white);
g.drawString("Points: " + points, x, y);
}
private void questions( Graphics g) {
int x = getWidth() / 4;
int y = getHeight() / 8;
int borderY = getHeight() /60;
fontSize = getWidth() / 15;
Font font = new Font(g.getFont().getFontName(), Font.BOLD, fontSize);
g.setFont(font);
for(int i = 0; i < questions.length; i++) {
g.setColor(Color.red.brighter());
g.fillRect(x + 1, borderY, fontSize, fontSize);
g.setColor(Color.orange.brighter());
g.drawRect(x, borderY, fontSize, fontSize);
g.setColor(Color.white);
g.drawString(questions[i],x,y);
x += getWidth() / 6;
}
}
private void updateFrame() {
fontSize = getWidth() / 20;
font = new Font("SansSerif", Font.BOLD, fontSize);
textField.setFont(font);
c.insets = new Insets(0, 0, getHeight() / 2, 0);
remove(textField);
add(textField, c);
}
private void updateUserDataFrame(){
int x = getWidth()/60;
int y = getHeight()/3 + getHeight()/20;
int width = getWidth()/16;
int height = getWidth()/16;
int fontSize = getWidth()/20;
Font font = new Font("SansSerif", Font.BOLD, fontSize);
userInputData.reset();
while(userInputData.hasNext()){
structure temp = (structure)userInputData.next();
x += getWidth()/16;
temp.updateData(font, x, y, width, height);
}
}
private void displayUserInput(Graphics g) {
userInputData.paint(g);
}
void init(){
x = getWidth()/60;
y = getHeight()/3 + getHeight()/20;
fontSize = getWidth()/20;
font = new Font("SansSerif", Font.BOLD, fontSize);
textField = new JTextField(3);
textField.setFont(font);
textField.addActionListener(this);
//Add Components to this panel.
c.insets = new Insets(0, 0, getHeight()/2, 0);
c.gridx = 0;
c.gridy = 0;
add(textField, c);
updateUI();
initialized = true;
repaint();
}
#Override
public void actionPerformed(ActionEvent e) {
int buttonWidth = getWidth()/16;
int buttonHeight = getWidth()/16;
x += getWidth()/16;
String userInput = textField.getText();
for(int i = 0; i < answers.length; i++) {
if(answers[i].equals(textField.getText()))
points++;
}
userInputData.add(new structure(userInput, Color.WHITE, font,x,y,buttonWidth,buttonHeight));
textField.setText("");
repaint();
}
}
Edited: Timer class
import java.awt.*;
import java.util.Timer;
import java.util.TimerTask;
class timer {
private Timer timer = new Timer();
private int timeLimit;
private int x, y;
private Color color;
private TimerTask task = new TimerTask() {
public void run() {
timeLimit--;
if(timeLimit == 0){
timer.cancel();
}
}
};
timer() {
timeLimit = 120;
}
timer(int limit) {
timeLimit = limit;
}
void start() {
timer.scheduleAtFixedRate(task, 1000, 1000);
}
void displayTimer(Graphics g) {
int minute = timeLimit / 60;
int second = timeLimit % 60;
g.setColor(color);
if (minute < 10) {
if (second < 10)
g.drawString("0" + minute + ":0" + second, x, y);
else
g.drawString("0" + minute + ":" + second, x, y);
} else {
if (second < 10)
g.drawString(minute + ":0" + second, x, y);
else
g.drawString(minute + ":" + second, x, y);
}
}
void setColor(Color color) {
this.color = color;
}
void setPosition(int x, int y) {
this.x = x;
this.y = y;
}
int getTime() {
return timeLimit;
}
void setTime(int time) {
timeLimit = time;
}
boolean timeUp() {
return timeLimit == 0;
}
}
I don't understand where this timer is coming from ? You can use this code Timer timer = new Timer(1000,this); instead of timer timer = new timer(60);
Making 1000 enable to you use real timer.
I hope this make life your easier a bit.
I have been working on this java application.
So far it has no meaning, just a randomly colored ball bouncing around.
But now, when i wanted to add another ball to the bouncing app, the balls followed each other.
This is my code so far.
import java.awt.*;
import javax.swing.*;
public class MainFrame extends JPanel implements Runnable {
Color color = Color.red;
int dia = 60;
Diameter of the objects.
long delay = 20;
Delay time.
private int x = (int)Math.floor(Math.random() * 580);
private int y = (int)Math.floor(Math.random() * 900);
private int xx = (int)Math.floor(Math.random() * 580);
private int yy = (int)Math.floor(Math.random() * 900);
Above is the objects position.
private int dx = (int)Math.floor(Math.random() * 7);
private int dy = (int)Math.floor(Math.random() * 7);
private int dxx = (int)Math.floor(Math.random() * 7);
private int dyy = (int)Math.floor(Math.random() * 7);
Above is object speed.
protected void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g.setColor(color);
g.fillOval(x,y,60,60);
g.setColor(color);
g.fillOval(xx,yy,60,60);
}
The graphics.
And below is just calculations, thread.sleep and the JFrame.
public void run() {
while(isVisible()) {
try {
Thread.sleep(delay);
} catch(InterruptedException e) {
System.out.println("interrupted");
}
move();
repaint();
}
}
public void move() {
if(x + dx < 0 || x + dia + dx > getWidth()) {
dx *= -1;
color = getColor();
}
if(y + dy < 0 || y + dia + dy > getHeight()) {
dy *= -1;
color = getColor();
}
if(xx + dxx < 0 || xx + dia + dxx > getWidth()) {
dxx *= -1;
color = getColor();
}
if(yy + dyy < 0 || yy + dia + dyy > getHeight()) {
dyy *= -1;
color = getColor();
}
x += dx;
y += dy;
xx += dx;
yy += dy;
}
private Color getColor() {
int rval = (int)Math.floor(Math.random() * 256);
int gval = (int)Math.floor(Math.random() * 256);
int bval = (int)Math.floor(Math.random() * 256);
return new Color(rval, gval, bval);
}
private void start() {
while(!isVisible()) {
try {
Thread.sleep(25);
} catch(InterruptedException e) {
System.exit(1);
}
}
Thread thread = new Thread(this);
thread.setPriority(Thread.NORM_PRIORITY);
thread.start();
}
public static void main(String[] args) {
MainFrame test = new MainFrame();
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(test);
f.setSize(640, 960);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
f.setLocation(dim.width/2-f.getSize().width/2, dim.height/2-f.getSize().height/2);
f.setVisible(true);
test.start();
}
}
I just can not figure it out.
I know the answer is going to be simple.
You should define a single class Ball and create two instances of it rather than repeating the variables and have an x,y co-ordinate and velocity dx and dy inside that class.
The two follow each other ebcause you add the same velocity to both balls all the time:
x += dx;
y += dy;
xx += dx;
yy += dy;
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;
}}
I have an assignment that requires us to paint a tree of Pythagoras using recursion. The tree is started with the square ABCD and the points A and B are defined by mouse clicks. Everything seems to work until I get to the recursion where I can get either the left or right part of the tree to paint, but not both. I placed a comment where I believe I am running into problems.
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
public class PythagorasTree extends JFrame
{
public static void main(String[] args)
{
new PythagorasTree();
}
PythagorasTree()
{
super("Pythagoras Tree");
setSize(800,800);
add("Center", new DrawingPanel());
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
class DrawingPanel extends JPanel
{
Random random = new Random();
int centerX;
int centerY;
int clickCount = 0;
float pixelSize;
float rWidth = 10.0F;
float rHeight = 7.5F;
float red, green, blue;
Point a = new Point();
Point b = new Point();
Point c = new Point();
Point d = new Point();
Point e = new Point();
Point u = new Point();
DrawingPanel()
{
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent click)
{
clickCount++;
if (clickCount == 1)
{
a.x = fx(click.getX());
a.y = fy(click.getY());
repaint();
}
if (clickCount == 2)
{
b.x = fx(click.getX());
b.y = fy(click.getY());
repaint();
}
}
});
}
void initgr()
{
Dimension d = getSize();
int maxX = d.width - 1;
int maxY = d.height - 1;
pixelSize = Math.max(rWidth/maxX, rHeight/maxY);
centerX = maxX/2;
centerY = maxY/2;
}
int iX(float x){return Math.round(centerX + x/pixelSize);}
int iY(float y){return Math.round(centerY - y/pixelSize);}
float fx(int x){return (x - centerX) * pixelSize;}
float fy(int y){return (centerY - y) * pixelSize;}
public void paintComponent(Graphics g)
{
initgr();
super.paintComponent(g);
setBackground(Color.white);
g.setColor(Color.red);
if (clickCount == 1)
g.drawLine(iX(a.x), iY(a.y), iX(a.x), iY(a.y));
if (clickCount > 1)
drawTree(g,a,b);
}
public void drawTree(Graphics g, Point first, Point second)
{
float xSquared = (float) Math.pow((second.x-first.x),2);
float ySquared = (float) Math.pow((second.y-first.y),2);
float length = (float) Math.sqrt(xSquared + ySquared);
if ( length > .001)
{
u.x = second.x - first.x;
u.y = second.y - first.y;
a.x = first.x;
a.y = first.y;
b.x = second.x;
b.y = second.y;
d.x = first.x + (u.y * -1);
d.y = first.y + u.x;
c.x = d.x + u.x;
c.y = d.y + u.y;
e.x = d.x + .5F * (u.x + (u.y*-1));
e.y = d.y + .5F * (u.y + u.x);
Polygon square = new Polygon();
Polygon triangle = new Polygon();
square.addPoint(iX(a.x), iY(a.y));
square.addPoint(iX(b.x), iY(b.y));
square.addPoint(iX(c.x), iY(c.y));
square.addPoint(iX(d.x), iY(d.y));
red = random.nextFloat();
green = random.nextFloat();
blue = random.nextFloat();
g.setColor(new Color(red, green, blue));
g.fillPolygon(square);
triangle.addPoint(iX(c.x), iY(c.y));
triangle.addPoint(iX(d.x), iY(d.y));
triangle.addPoint(iX(e.x), iY(e.y));
red = random.nextFloat();
green = random.nextFloat();
blue = random.nextFloat();
g.setColor(new Color(red, green, blue));
g.fillPolygon(triangle);
/* Problem code is here, tree will draw Left or Right depending on which recursive call
* is first in the code, but will never reach the 2nd call.
*/
drawTree(g,d,e); //Draw tree left
drawTree(g,e,c); //Draw tree right
}
}
}
class Point
{
public float x;
public float y;
public Point()
{
}
}
It's time this question had an answer. The problem is with these member variable declarations:
Point c = new Point();
Point e = new Point();
And this code in drawTree():
drawTree(g,d,e); //Draw tree left
drawTree(g,e,c); //Draw tree right
Since c and e are a member variables, not local, they get modified by the first recursive call to drawTree(g, d, e) so by the time we make the second call to drawTree(g, e, c), it's no longer the same c and e we thought we had. The following rework of the code makes these local (clearly not as efficient GC-wise, but also not as buggy) as well as several other small modifications:
import java.awt.*;
import java.awt.event.*;
import java.util.Random;
import javax.swing.*;
class Point
{
public float x;
public float y;
public Point(float x, float y) {
this.x = x;
this.y = y;
}
public Point() {
}
}
class DrawingPanel extends JPanel
{
Random random = new Random();
int clickCount = 0;
float pixelSize;
float rWidth = 10.0F;
float rHeight = 7.5F;
float red, green, blue;
Point a = new Point();
Point b = new Point();
Point center = new Point();
DrawingPanel()
{
addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent click)
{
clickCount++;
if (clickCount == 1)
{
a.x = fx(click.getX());
a.y = fy(click.getY());
repaint();
}
else if (clickCount == 2)
{
b.x = fx(click.getX());
b.y = fy(click.getY());
repaint();
}
}
});
}
void initgr()
{
Dimension d = getSize();
int maxX = d.width - 1;
int maxY = d.height - 1;
pixelSize = Math.max(rWidth / maxX, rHeight / maxY);
center.x = maxX / 2;
center.y = maxY / 2;
}
int iX(float x){ return Math.round(center.x + x / pixelSize); }
int iY(float y){ return Math.round(center.y - y / pixelSize); }
float fx(int x){ return (x - center.x) * pixelSize; }
float fy(int y){ return (center.y - y) * pixelSize; }
public void paintComponent(Graphics g)
{
super.paintComponent(g);
initgr();
setBackground(Color.white);
if (clickCount == 1)
{
g.setColor(Color.red);
g.drawLine(iX(a.x), iY(a.y), iX(a.x), iY(a.y));
}
else if (clickCount > 1) {
drawTree(g, a, b);
}
}
public void drawTree(Graphics g, Point first, Point second)
{
double xSquared = Math.pow(second.x - first.x, 2);
double ySquared = Math.pow(second.y - first.y, 2);
if (Math.sqrt(xSquared + ySquared) < 0.01) {
return;
}
Point u = new Point(second.x - first.x, second.y - first.y);
Point d = new Point(first.x - u.y, first.y + u.x);
Point c = new Point(d.x + u.x, d.y + u.y);
Point e = new Point(d.x + 0.5F * (u.x - u.y), d.y + 0.5F * (u.y + u.x));
Polygon square = new Polygon();
square.addPoint(iX(first.x), iY(first.y));
square.addPoint(iX(second.x), iY(second.y));
square.addPoint(iX(c.x), iY(c.y));
square.addPoint(iX(d.x), iY(d.y));
red = random.nextFloat();
green = random.nextFloat();
blue = random.nextFloat();
g.setColor(new Color(red, green, blue));
g.fillPolygon(square);
Polygon triangle = new Polygon();
triangle.addPoint(iX(c.x), iY(c.y));
triangle.addPoint(iX(d.x), iY(d.y));
triangle.addPoint(iX(e.x), iY(e.y));
red = random.nextFloat();
green = random.nextFloat();
blue = random.nextFloat();
g.setColor(new Color(red, green, blue));
g.fillPolygon(triangle);
drawTree(g, d, e); // Draw tree left
drawTree(g, e, c); // Draw tree right
}
}
public class PythagorasTree extends JFrame
{
PythagorasTree()
{
super("Pythagoras Tree");
setSize(800, 800);
add("Center", new DrawingPanel());
setVisible(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args)
{
new PythagorasTree();
}
}
OUTPUT