I have obtained from somewhere else a Java Swing code for a bouncing Ball. The code uses a class "Ball" which extends a JPanel.
Can Anyone help me converting this code to extends JFrame instead.
I want to do that so I could be able to call it from another frame class.
Here is the code:
public class Ball extends JPanel{
int x=0, y=0;
int angleX = 1, angleY = 1;
public void move(){
if (x + angleX <0) {
angleX =1;
} else if (x + angleX >getWidth()-50){
angleX =-1;
} else if (y + angleY <0) {
angleY =1;
} else if (y + angleY >getHeight()-50){
angleY =-1;
}
x = x + angleX;
y = y + angleY;
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 50, 50);
}
public static void main(String[] args){
JFrame jfrm= new JFrame("BounceBall");
jfrm.setSize(400,400);
jfrm.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jfrm.setVisible(true);
Ball bl = new Ball();
Component add = jfrm.add(bl);
while (true){
bl.move();
bl.repaint();
try{
Thread.sleep(10);
}catch(InterruptedException e){
}
}
}
}
Just extend JFrame and make some constructor for Ball class.
You can make an instance from Ball class from any other JFrame classes.
Ball bl = new Ball();/*then call methods*/
Or just call Balls main method in two ways:
Ball.main(null);
String args[]={/*some arguments*/}; Ball.main(args);
Here is your Ball class which now extends JFrame
import java.awt.Graphics;
import javax.swing.JFrame;
public class Ball extends JFrame {
public Ball() {
setSize(400, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
}
int x = 0, y = 0;
int angleX = 1, angleY = 1;
public void move() {
if (x + angleX < 0) {
angleX = 1;
} else if (x + angleX > getWidth() - 50) {
angleX = -1;
} else if (y + angleY < 0) {
angleY = 1;
} else if (y + angleY > getHeight() - 50) {
angleY = -1;
}
x = x + angleX;
y = y + angleY;
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 50, 50);
}
public static void main(String[] args) {
Ball bl = new Ball();
while (true) {
bl.move();
bl.repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
}
}
}
}
Related
I am working in java with swing. I've created a ball which moves on the sides of the screen. What I want is to pause the animaion when I click on the frame. I am implementin MouseListener but to no avail.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Ball extends JFrame implements MouseListener
{
int x = 20;
int y = 20;
int rad = 20;
boolean temp1 = true;
boolean temp2 = true;
boolean temp3 = true;
Ball()
{
setSize(500, 500);
setVisible(true);
}
public void mouseClicked(MouseEvent me)
{
System.out.println("Hee");
temp3 = false;
}
public void mouseEntered(MouseEvent me){
temp3 = false;
}
public void mouseExited(MouseEvent me){
System.out.println("");
}
public void mouseReleased(MouseEvent me){
System.out.println("");
}
public void mousePressed(MouseEvent me){
System.out.println("");
}
void move()
{
if(x == rad && y == rad)
{
temp1 = temp2 = true;
}
if(x < (getWidth() - rad) && temp1 )
{
x = x + 1;
}
if( x == (getWidth() - rad) && y < getHeight() -rad)
{
x = getWidth() - rad;
y = y + 1;
}
if( y == getHeight() - rad && temp2 )
{
temp1 = false;
y = getHeight() - rad;
x = x - 1;
}
if( x == rad )
{
temp2 = false;
x = rad;
y = y -1;
}
try{
Thread.sleep(1);
}catch(Exception e)
{
}
}
public void paint(Graphics g)
{
super.paint(g);
g.fillOval(x, y, rad, rad);
}
public static void main(String[] args)
{
Ball b = new Ball();
while(b.temp3)
{
b.move();
b.repaint();
}
}
}
There are two fundamental problems with the code:
The loop in the main(..) method is blocking the Event Dispatch Thread.
The MouseListener is never added to the frame.
The code still has ways it should be changed, but here are both those problems fixed:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
class Ball extends JFrame implements MouseListener {
int x = 20;
int y = 20;
int rad = 20;
boolean temp1 = true;
boolean temp2 = true;
boolean temp3 = true;
Ball() {
setSize(500, 500);
setVisible(true);
// the correct way to animate a Swing GUI
ActionListener animationListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (temp3) {
move();
repaint();
}
}
};
Timer timer = new Timer(20, animationListener);
timer.start();
// add the listener to the frame!
this.addMouseListener(this);
}
public void mouseClicked(MouseEvent me) {
System.out.println("Hee");
temp3 = false;
}
public void mouseEntered(MouseEvent me) {
temp3 = false;
}
public void mouseExited(MouseEvent me) {
System.out.println("");
}
public void mouseReleased(MouseEvent me) {
System.out.println("");
}
public void mousePressed(MouseEvent me) {
System.out.println("");
}
void move() {
if (x == rad && y == rad) {
temp1 = temp2 = true;
}
if (x < (getWidth() - rad) && temp1) {
x = x + 1;
}
if (x == (getWidth() - rad) && y < getHeight() - rad) {
x = getWidth() - rad;
y = y + 1;
}
if (y == getHeight() - rad && temp2) {
temp1 = false;
y = getHeight() - rad;
x = x - 1;
}
if (x == rad) {
temp2 = false;
x = rad;
y = y - 1;
}
try {
Thread.sleep(1);
} catch (Exception e) {
}
}
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, rad, rad);
}
public static void main(String[] args) {
Ball b = new Ball();
}
}
Good day, I'm new to StackOverflow and Java programming. I currently have a school project that needs multi threading and I just need your advice on how to fix my code. I have spent too much time looking for answers on how to create a moving multiple images using a thread. I knew I'm almost near to find the solution but I'm running out of time as the submission is fast approaching. I believed I'll be more efficient if I seek help from somehow who knows better in Java.
Many thanks in advance.
Below is my current code, and it seems that image is flickering while moving.
// Bounce.java
import javax.swing.JFrame;
public class Bounce {
public static void main(String args[]) {
myBall s = new myBall(10, 20, 2, 2);
myBall s1 = new myBall(100, 10, 2, 2);
myBall s2 = new myBall(40, 10, 2, 2);
JFrame f = new JFrame();
f.add(s);
f.add(s1);
f.add(s2);
f.setVisible(true);
f.setSize(600, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Moving Ball");
}
}
The next code is in separate file.
// myBall.java
import java.awt.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
public class myBall extends JPanel implements Runnable {
private Thread animator;
int x = 0, y = 0, velX = 2, velY = 2;
Timer t;
public myBall(int x, int y, int velX, int velY) {
JFrame jf = new JFrame();
jf.setSize(600,400);
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.add(this);
jf.setVisible(true);
this.x = (int )(Math.random() * 560);
this.y = (int )(Math.random() * 360);
this.velX = velX;
this.velY = velY;
}
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
g2.fill(ellipse);
}
public void cycle() {
if(x < 0 || x > 560) {
velX = -velX;
}
if(y < 0 || y > 360) {
velY = -velY;
}
x += velX;
y += velY;
System.out.println(x);
}
#Override
public void run() {
while(true) {
for (int i = 0; i < 600; i++) {
cycle();
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
}
}
Here you go. I normally don't do this, but you asked nicely and your code was pretty clean, so I assumed you been working a lot on it.
public class Start {
public static void main(String args[]) {
JFrame f = new JFrame();
Gui gui = new Gui();
gui.addBalls();
f.add(gui);
f.setSize(600, 400);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setTitle("Moving Ball");
f.setVisible(true);
}
}
Class GUI:
public class Gui extends JPanel implements Runnable {
private Thread animator;
int x = 0, y = 0, velX = 2, velY = 2;
Timer t;
ArrayList<myBall> myBalls = new ArrayList<>();
#Override
public void addNotify() {
super.addNotify();
animator = new Thread(this);
animator.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
for (myBall ball: myBalls) {
int x = ball.getX();
int y = ball.getY();
Ellipse2D ellipse = new Ellipse2D.Double(x, y, 40, 40);
g2.fill(ellipse);
}
}
public void cycle() {
for (myBall ball: myBalls) {
int x = ball.getX();
int y = ball.getY();
if(x < 0 || x > 560) {
ball.reverseX();
}
if(y < 0 || y > 360) {
ball.reverseY();
}
ball.move();
System.out.println(x);
}
}
#Override
public void run() {
while(true) {
for (int i = 0; i < 600; i++) {
cycle();
repaint();
try {
Thread.sleep(10);
} catch (InterruptedException e) {
System.out.println("interrupted");
}
}
}
}
public void addBalls() {
for (int i = 0; i < 4; i++) {
int x = (int )(Math.random() * 560);
int y = (int )(Math.random() * 360);
int velX = -5;
int velY = 5;
myBalls.add(new myBall(x, y, velX, velY));
}
}
}
Class Ball:
public class myBall {
int x;
int y;
int velX;
int velY;
public myBall(int x, int y, int velX, int velY) {
this.x = (int )(Math.random() * 560);
this.y = (int )(Math.random() * 360);
this.velX = velX;
this.velY = velY;
}
public void move() {
x+=velX;
y+=velY;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void reverseX() {
velX = -velX;
}
public void reverseY() {
velY = -velY;
}
}
I am new to Java and I'm creating a basic 'mini tennis game' I would like for the score to increase by one point each time the ball makes contact with the racket. I already have the score displayed on the screen at 0 but I don't know how to make it increase. I would greatly appreciate any help you could give me. Here is the code I have so far:
Game class
private int score = 0;
Ball ball = new Ball(this);
SecondBall ball2 = new SecondBall(this);
Racquet racquet = new Racquet(this);
public Game() {
addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
racquet.keyPressed(e);
}
#Override
public void keyReleased(KeyEvent e) {
racquet.keyReleased(e);
}
});
setFocusable(true);
}
private void move() {
ball.move();
ball2.move();
racquet.move();
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
ball2.paint(g2d);
racquet.paint(g2d);
**//Show score on screen
String s = Integer.toString(score);
String sc = "Your score: ";
g.drawString(sc, getWidth()-150, 50);
g.drawString(s, getWidth()-50, 50);**
}
public void gameOver() {
JOptionPane.showMessageDialog(this, "You Suck!!", "Game Over", JOptionPane.YES_NO_OPTION);
System.exit(ABORT);
}
public static void main(String[] args) throws InterruptedException {
JFrame frame = new JFrame("Mini Tennis");
Game game = new Game();
frame.add(game);
frame.setSize(300, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
while (true) {
game.move();
game.repaint();
Thread.sleep(10);
}
}
}
Ball Class
private static final int DIAMETER = 30;
int x = 0;
int y = 0;
int xa = 1;
int ya = 1;
private Game game;
private int score = 0;
private String yourScoreName;
public Ball(Game game) {
this.game = game;
}
public void move() {
if (x + xa < 0)
xa = 1;
if (x + xa > game.getWidth() - DIAMETER)
xa = -1;
if (y + ya < 0)
ya = 1;
if (y + ya > game.getHeight() - DIAMETER)
game.gameOver();
if (collision()) {
ya = -1;
y = game.racquet.getTopY() - DIAMETER;
}
x = x + xa;
y = y + ya;
}
private boolean collision() {
return game.racquet.getBounds().intersects(getBounds());
}
public void paint(Graphics2D g) {
g.fillOval(x, y, 30, 30);
}
public Rectangle getBounds() {
return new Rectangle(x, y, DIAMETER, DIAMETER);
}
}
You already have a collision method which returns true if the ball collides with your racquet. So you can easily increment your score:
if (collision()) {
ya = -1;
y = game.racquet.getTopY() - DIAMETER;
score++; //// like this
}
Just an advice, by copy pasting a tutorial you wont learn it. Start at the beggining.
Well when I am pressing any of the key arrows, the red box moves, yes it moves 10px and then stops for 1 second & continues moving, instead of move right away without stopping.
example of the occurring issue:
(source: gyazo.com)
Can you see how it stopped for 1 or 0.5 secs and continued?
How can I fix it?
I am using KeyEventDispatcher
My key detecting:
Whole src:
public class Game extends Frame {
private class Keyboard implements KeyEventDispatcher {
private Game game;
public Keyboard(Game game) {
this.game = game;
}
#Override
public boolean dispatchKeyEvent(KeyEvent e) {
if (e.getID() == KeyEvent.KEY_PRESSED) {
this.movement(e);
} else if (e.getID() == KeyEvent.KEY_RELEASED) {
} else if (e.getID() == KeyEvent.KEY_TYPED) {
}
return false;
}
public void movement(KeyEvent e) {
int keyCode = e.getKeyCode();
switch( keyCode ) {
case KeyEvent.VK_UP:
game.movePlayer(0, -10);
break;
case KeyEvent.VK_DOWN:
game.movePlayer(0, 10);
break;
case KeyEvent.VK_LEFT:
game.movePlayer(-10, 0);
break;
case KeyEvent.VK_RIGHT :
game.movePlayer(10, 0);
break;
}
}
}
private static final long serialVersionUID = 1L;
private int coordinateX = 1;
private int coordinateY = 1;
public int width = 300;
public int height = width / 16 * 9;
public int scale = 3;
public int mouseY = MouseInfo.getPointerInfo().getLocation().y;
public int mouseX = MouseInfo.getPointerInfo().getLocation().x;
private Player player = new Player(0, 0);
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
frame.setSize(width, height);
frame.setResizable(false);
frame.setTitle("First game");
JPanel j = new JPanel();
j.setVisible(true);
JLabel text = new JLabel("coords");
j.add(text);
frame.add(this);
frame.pack();
frame.add(j);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
KeyboardFocusManager manager = KeyboardFocusManager.getCurrentKeyboardFocusManager();
manager.addKeyEventDispatcher(new Keyboard(this));
}
private void movePlayer(int x, int y) {
/**
* Main region area
*/
int pX = 0, pY = 0;
if (y == 0) { // x
if (player.getX() + x + 100 > frame.getContentPane().getWidth() || player.getX() + x < 0) {
if (player.getX() + x < 0) {
player.setX(0);
return;
}
if (player.getX() + x > 0) {
player.setX(frame.getContentPane().getWidth() - 100);
return;
}
return;
}
pX = x;
}
else if (x == 0) { // y
if (player.getY() + y + 100 > frame.getContentPane().getHeight() || player.getY() + y < 0) {
if (player.getY() + y < 0) {
player.setY(0);
return;
}
if (player.getY() + y > 0) {
player.setY(frame.getContentPane().getHeight() - 100);
return;
}
return;
}
pY = y;
}
player.updatePosition(pX, pY);
}
public void update() {
}
public void render() {
bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
g = bs.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.RED);
g.fillRect(player.getX(), player.getY(), 100, 100);
g.dispose();
bs.show();
}
}
Frame.java:
public class Frame extends Canvas {
public static final long serialVersionUID = 8L;
public static JFrame frame = new JFrame();
public static Threads thread;
public static Game game;
public Graphics g;
public BufferStrategy bs;
/**
* #param args
*/
public static void main(String[] args) {
thread = new Threads(new Game());
thread.start();
}
}
The problem is the repeat rate for KeyStrokes. This is controlled by the OS.
The solution is to use a Swing Timer to schedule the animation as soon as the key is pressed.
See Motion Using the Keyboard for more information and a complete working example.
Also, you should NOT be using a KeyListener but intead should be using KeyBindings.
I am having a problem getting my application to draw a Ball when i click on the frame.
I thought my code was correct, and I don't get any errors, but it still doesn't work.
I feel the problem is with the MouseListener implementation and that the application is not handling the MouseEvent properly.
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class BouncingBallApp extends JFrame
{
public static void main(String[] args)
{
Container container;
BouncingBallApp bouncingBalls = new BouncingBallApp();
bouncingBalls.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
container = new Container();
BouncingBallPanel BBP = new BouncingBallPanel();
container.add(BBP);
bouncingBalls.addMouseListener(BBP);
//addMouseListener;
bouncingBalls.setBackground( Color.WHITE );
bouncingBalls.setSize(400,300);
bouncingBalls.setVisible( true );
}//end of main method
}//end of BouncingBallApp
class BouncingBallPanel extends JPanel implements MouseListener, Runnable
{
private Ball[] ballArray = new Ball[20];
private int ballCount = 0;
public void run()
{
for(int i = 0; i<ballArray.length; i++){
if(ballArray[i] != null){
ballArray[i].move();}}
repaint();
//delay(1);
}
public void mouseClicked(MouseEvent e)
{
ballArray[ballCount] = new Ball();
ballCount++;
if(ballCount == 1)
(new Thread(new BouncingBallPanel())).start();
}
//empty interface methods
public void mouseExited(MouseEvent e){}
public void mouseReleased(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mousePressed(MouseEvent e){}
public void paintComponent(Graphics g)
{
super.paintComponent( g );
Graphics2D g2d = (Graphics2D) g;
for(int i = 0; i<ballArray.length; i++)
{
if(ballArray[i] != null){
g2d.setColor(ballArray[i].getColor());
g2d.fill(new Ellipse2D.Double(ballArray[i].getX(),ballArray[i].getY(),ballArray
[i].getDiameter(),ballArray[i].getDiameter()));}
}//end of for loop
}
}//end of BouncingBallPanel
class Ball
{
private double x;
private double y;
private double deltaX;
private double deltaY;
private double diameter;
private Color color;
Random random = new Random();
public Ball()
{
x = random.nextInt(400);
y = random.nextInt(300);
deltaX = 2;
deltaY = 2;
diameter = 10;
color = new Color(random.nextInt(256),random.nextInt(256),random.nextInt(256));
}//end of constructor
public double getX(){
return x;}
public double getY(){
return y;}
public double getDiameter(){
return diameter;}
public Color getColor(){
return color;}
public void move()
{
x += deltaX;
y += deltaY;
if (x < 0) {
x = 0;
deltaX = -deltaX;}
else if (x > 400) {
x = 400;
deltaX = -deltaX;}
if (y < 0) {
y = 0;
deltaY = -deltaY;}
else if (y > 300) {
y = 300;
deltaY = -deltaY;}
}//end of method move
}//end of ball
3 Things
No size for container
You are not adding container
No loop to update graphics
The code below is working
import java.awt.*;
import java.awt.geom.*;
import javax.swing.*;
import java.awt.event.*;
import java.util.*;
public class BouncingBallApp extends JFrame {
public static void main(String[] args) {
// Container container;
BouncingBallApp bouncingBalls = new BouncingBallApp();
bouncingBalls.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// container = new Container();
BouncingBallPanel BBP = new BouncingBallPanel();
// container.add(BBP);
bouncingBalls.addMouseListener(BBP);
// addMouseListener;
bouncingBalls.setBackground(Color.WHITE);
bouncingBalls.setSize(400, 300);
BBP.setSize(400, 300);
BBP.setLayout(null);
bouncingBalls.setContentPane(BBP);
/*
* JTextField jtf = new JTextField(); BBP.add(jtf); jtf.setSize(100,
* 20);
*/
bouncingBalls.setVisible(true);
}// end of main method
}// end of BouncingBallApp
class BouncingBallPanel extends JPanel implements MouseListener {
private Ball[] ballArray = new Ball[20];
private int ballCount = 0;
public void mouseClicked(MouseEvent e) {
ballArray[ballCount] = new Ball();
ballCount++;
if (ballCount == 1) {
final Runnable updateGraphics = new Runnable() {
public void run() {
for (int i = 0; i < ballArray.length; i++) {
if (ballArray[i] != null) {
ballArray[i].move();
}
}
repaint();
}
};
Runnable animation = new Runnable() {
public void run() {
while (true) {
try {
EventQueue.invokeLater(updateGraphics);
Thread.sleep(100);
} catch (InterruptedException e) {
return;
}
}
}
};
new Thread(animation).start();
}
}
// empty interface methods
public void mouseExited(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void paintComponent(Graphics g) {
// super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (int i = 0; i < ballArray.length; i++) { if (ballArray[i] !=
null) { System.out.println(" ball " + i + " , " +
ballArray[i].getColor() + " , " + ballArray[i].getX() + " , " +
ballArray[i].getY() + " , " + ballArray[i].getDiameter());
g2d.setColor(ballArray[i].getColor());
g2d.fillRect((int)ballArray[i].getX(), (int)ballArray[i].getY(),
(int)ballArray[i].getDiameter(), (int)ballArray[i].getDiameter()); }
}// end of for loop
}
}// end of BouncingBallPanel
class Ball {
private double x;
private double y;
private double deltaX;
private double deltaY;
private double diameter;
private Color color;
Random random = new Random();
public Ball() {
x = random.nextInt(400);
y = random.nextInt(300);
deltaX = 2;
deltaY = 2;
diameter = 10;
color = new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256));
}// end of constructor
public double getX() {
return x;
}
public double getY() {
return y;
}
public double getDiameter() {
return diameter;
}
public Color getColor() {
return color;
}
public void move() {
x += deltaX;
y += deltaY;
if (x < 0) {
x = 0;
deltaX = -deltaX;
}
else if (x > 400) {
x = 400;
deltaX = -deltaX;
}
if (y < 0) {
y = 0;
deltaY = -deltaY;
}
else if (y > 300) {
y = 300;
deltaY = -deltaY;
}
}// end of method move
}// end of ball