Ball Collision Issues, only half of the ball is colliding - java

I don't understand why after i get over the first half of a ball that when the ball I control hits the right half of a moving ball that it doesn't activate the collision code to kill the program.
I have it set to measure the distance between the ball that you control then the ball that is passing by. I am still confused why I can land on the second half of the ball without the program closing itself out.
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import java.awt.event.ActionListener;
import java.awt.event.KeyListener;
import javax.swing.ImageIcon;
public class JumpingSprite extends JPanel implements KeyListener {
//public int yPos;
public static void main(String[] args) {
new JumpingSprite();
}
public JumpingSprite() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Mr.Baird");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
TestPane testPane = new TestPane();
frame.add(testPane);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
int getyPos(){
return yPos;
}
protected static final int SPRITE_HEIGHT = 60;
protected static final int SPRITE_WIDTH = 60;
private float vDelta;
private float rbDelta;
private float rbDegDelta;
public int yPos;
private float gDelta; // Gravity
private Timer engine;
private boolean bounce = false;
int ballx = 1000;
int bally = 500;
int ballw = 100;
int ballh = 100;
int ball2x = 1500;
int ball2y = 480;
int ball2w = 120;
int ball2h = 120;
int ball3x = 2500;
int ball3y = 0;
int ball3w = 600;
int ball3h = 600;
public TestPane() {
yPos = getPreferredSize().height - SPRITE_HEIGHT;
vDelta = 0;
gDelta = 3f;
rbDegDelta = 30f; //affects how many bounces mang
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "jump");
am.put("jump", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if (yPos + SPRITE_HEIGHT == getHeight()) {
vDelta = -40 ;
rbDelta = vDelta;
bounce = true;
}
}
});
engine = new Timer(15, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int height = getHeight();
if (height > 0) {
if (bounce) {
yPos += vDelta;
vDelta += gDelta;
// If the sprite is not on the ground
if (yPos + SPRITE_HEIGHT >= height) {
// put on le ground
yPos = height - SPRITE_HEIGHT;
if (rbDelta >= 0) {
// Stop bouncin
bounce = false;
} else {
// Add the re-bound degregation delta to the re-bound delta
rbDelta += rbDegDelta;
// Set the vDelta...
vDelta = rbDelta;
}
}
}
}
if (Math.sqrt((Math.pow((500 - (ballx)), 2)) + Math.pow((yPos - bally), 2)) <= (50)) {
System.exit(0);
}
if (Math.sqrt((Math.pow((500 - (ball2x)), 2)) + Math.pow((yPos - ball2y), 2)) <= (60)) {
System.exit(0);
}
if (Math.sqrt((Math.pow((500 - (ball3x)), 2)) + Math.pow((yPos - ball3y), 2)) <= (350)) {
System.exit(0);
}
ballx = ballx-8;
ball2x = ball2x-8;
ball3x = ball3x-8;
repaint();
}
});
engine.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(1000, 600);
}
#Override
protected void paintComponent(Graphics g) {
//addin all them pretty colors to le object
super.paintComponent(g);
//Graphics2D g2d = (Graphics2D) g.create();
g.setColor(Color.black);
g.fillRect(0,0,1000,1000);
int width = getWidth() - 1;
int xPos = (width - SPRITE_WIDTH) / 2;
g.setColor(Color.blue);
g.fillOval(xPos, yPos, SPRITE_WIDTH, SPRITE_HEIGHT);
//g.dispose();
g.setColor(Color.red);
g.fillOval(ballx, bally, ballw, ballh);
g.setColor(Color.green);
g.fillOval(ball2x, ball2y, ball2w, ball2h);
g.setColor(Color.pink);
g.fillOval(ball3x, ball3y, ball3w, ball3h);
}
}
#Override
public void keyPressed(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
}

The general solution to this problem is to calculate the (Euclidean) distance between the centers of both balls/circles, and determine if that length is less than their combined radii. The other way you could do this is to create java.awt.Areas from your Shapes, and use Area.intersect(Area) != null;

Related

Collision between rectangle and pointed line spinning in swing

Just a small program I quickly made to see if I could perform collisions with a rectangle object and a rotating rectangle object.
Problem arises when rotating rectangle object, the collision box doesn't rotate, only the image rotates.
In this code I tried to use shape object but and performed transformations to it, but was unsuccessful.
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.MouseListener;
import java.awt.event.MouseEvent;
import java.util.*;
import java.io.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.imageio.*;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
public class test extends JFrame implements Runnable,KeyListener
{
MyDrawPanel playPanel = new MyDrawPanel();
Thread th= new Thread(this);
int w=500, h=539;
Rectangle s1;
Rectangle r1;
int x=50,y=50;
int spx=0;
int spy=0;
int b=0;
int spin=0,spin2=0;
Shape p1;
AffineTransform tx,ax;
public static void main (String [] args)
{
new test();
}
public test()
{
s1= new Rectangle(200,200,106,16);
p1= new Rectangle(200,200,106,16);
r1= new Rectangle(x,y,50,50);
this.setSize(w,h);
this.setVisible(true);
this.setResizable(true);
this.addKeyListener(this);
this.add(playPanel);
playPanel.setDoubleBuffered(true);
th.start();
}
public void keyPressed(KeyEvent e)
{
int key =e.getKeyCode();
if (key == KeyEvent.VK_DOWN)
{
spy=2;
}
if (key == KeyEvent.VK_UP)
{
spy=-2;
}
if (key == KeyEvent.VK_RIGHT)
{
spx=2;
}
if (key == KeyEvent.VK_LEFT)
{
spx=-2;
}
}
public void keyReleased(KeyEvent e)
{
spx=0;
spy=0;
}
public void keyTyped(KeyEvent e)
{}
public void coll()
{
if (r1.getBounds().intersects(p1.getBounds()))
{
b=1;
}
else{b=0;}
}
public void rot()
{
AffineTransform px= new AffineTransform();
px.rotate(Math.toRadians(spin),w/2,h/2);
p1=px.createTransformedShape(s1);
}
///DO TOP HEAD INTERSECT CHECKINGGGGGGGGGGGGGGGGG!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
public void run ()
{
while (true)
{
rot();
r1.x+=spx;
r1.y+=spy;
spin+=2;
coll();
repaint();
try
{
Thread.sleep (30);
}
catch (InterruptedException ex)
{
}
}
}
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g)
{
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if (b==1)
{
g2.setColor(Color.RED);
}
AffineTransform old= g2.getTransform();
//g2.rotate(Math.toRadians(spin),
//p1.getBounds().x+8,p1.getBounds().y+8);
g2.fillRect(p1.getBounds().x,p1.getBounds().y,106,16);
g2.setTransform(old);
g2.fillRect(r1.x,r1.y,r1.width,r1.height);
}
}
}
//15.31
/* ADD YOUR CODE HERE */
Used Bresenham's algorithm to find all pixels on a Line2D to detect collision between Rectangle and Line through class LineIterator.
Try like below said source, by increased value of spx and spy with difference value of 4 for moving the square faster:
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import java.util.Iterator;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
public class RotateRectangleRound extends JFrame implements KeyListener {
private static final long serialVersionUID = 9085168127541601308L;
private Rectangle stableRect;
private int cw = 400, ch = 400;
private boolean collision;
private int spx = 0, spy = 0;
private double radius = 120;
private double angleX = 0, angleY = 0;
private int rotatingVal = 0;
private Line2D line;
private LineIterator iterator;
private Point currentPoint;
private Point2D tp;
private static BasicStroke spinningStroke = new BasicStroke(8);
private static BasicStroke basicStroke = new BasicStroke(1);
private MyPanel panel;
private static boolean startWorker;
private SwingWorker<Void, Void> swingWorker;
public RotateRectangleRound() {
init();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new RotateRectangleRound();
}
});
}
private void init() {
this.setTitle("Rotate Rectangle - Paused");
this.getContentPane().setLayout(new GridLayout(1, 1));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setBounds(400, 200, 400, 400);
this.setLayout(new GridLayout(1, 1));
this.addKeyListener(this);
this.setVisible(true);
// getting the window width & height insets explicitly
cw = this.getContentPane().getWidth();
ch = this.getContentPane().getHeight();
// setting the stableRect and movableRect to between of screen except insets
stableRect = new Rectangle(20, 20, 40, 40);
angleX = 192;
angleY = 300;
this.panel = new MyPanel();
this.add(panel);
}
#Override
public void keyTyped(KeyEvent evt) {}
public void keyPressed(KeyEvent evt) {
int key = evt.getKeyCode();
if (key == KeyEvent.VK_DOWN) {
spy = 4;
moveStableRectangle();
} else if (key == KeyEvent.VK_UP) {
spy = -4;
moveStableRectangle();
} else if (key == KeyEvent.VK_RIGHT) {
spx = 4;
moveStableRectangle();
} else if (key == KeyEvent.VK_LEFT) {
spx = -4;
moveStableRectangle();
}
if (key == KeyEvent.VK_SPACE) {
startWorker = (!startWorker);
if (startWorker) {
this.setTitle("Rotate Rectangle");
collision = false;
startRotatingFromPoint();
}else {
this.setTitle("Rotate Rectangle - Paused");
}
}
}
private void moveStableRectangle() {
stableRect.x += spx;
stableRect.y += spy;
repaint();
}
public void keyReleased(KeyEvent evt) {
spx = 0;
spy = 0;
}
private void startRotatingFromPoint() {
swingWorker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
while (startWorker) {
try {
if (rotatingVal == 360)
rotatingVal = 0;
// first getting the angle x, y value for radius 100,
// second adding the half of width & height to rotate
// between screen accordingly with that w & h value
angleX = (Math.sin(Math.toRadians((double) rotatingVal)) * radius) + (cw / 2);
angleY = (Math.cos(Math.toRadians((double) rotatingVal++)) * radius) + (ch / 2);
// calculating collision
collision();
// requesting frame repainting
repaint();
Thread.sleep(10);
} catch (InterruptedException iex) {
iex.printStackTrace();
}
}
return null;
}
};
swingWorker.execute();
}
public void collision() {
if (detectCollision()) {
collision = true;
startWorker = false;
this.setTitle("Rotate Rectangle - Hitted");
} else {
collision = false;
}
}
private boolean detectCollision() {
boolean flag = false;
if(angleX < (cw/2))
line = new Line2D.Double(angleX, angleY, cw / 2, ch / 2);
else
line = new Line2D.Double(cw / 2, ch / 2, angleX, angleY);
//creating a iterator by use of Bresenham's algorithm
iterator = new LineIterator(line);
looperFor:
for (Iterator<Point2D> it = iterator; it.hasNext();) {
//getting Point2D Object of Point Iterator
tp = it.next();
currentPoint = new Point((int) tp.getX(), (int) tp.getY());
if (stableRect.contains(currentPoint)) {
flag = true;
break looperFor;
}
}
//returning the detected collision flag true or false
return flag;
}
class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
#Override
public void paintComponent(Graphics gr) {
Graphics2D g = (Graphics2D) gr;
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setStroke(basicStroke);
if (collision)
g.setColor(Color.RED);
g.fillRect(stableRect.x, stableRect.y, stableRect.width, stableRect.height);
g.setStroke(spinningStroke);
g.drawLine(cw / 2, ch / 2, (int) angleX, (int) angleY);
}
}
}
Hope this would help you.

Image circling the window using JApplet

So here's where I am stuck... I got it to go to the end of the window horizontally, then go down, but I don't know how to make it go left after it reaches the bottom of the window and then go up when it reaches the left side of the screen.
Thanks,
import javax.swing.*;
import java.awt.*;
public class AnimatedImageApplet extends JApplet implements Runnable {
private static final long serialVersionUID = 1L;
private Thread t = null;
private Image image;
private int x = 0;
private int y = 0;
private static final int vx = 1;
private static final int vy= 1;
private boolean horizontal = true;
private boolean vertical = true;
public void init() {
image = getImage(getDocumentBase(), "face.png");
}
public void start() {
if (t == null) {
t = new Thread(this);
t.start();
}
}
public void paint(Graphics canvas) {
canvas.fillRect(0,0,getWidth(),getHeight());
synchronized (this) {
canvas.drawImage(image, x, y, this);
}
}
#Override
public void run() {
int direction = 1;
while (true) {
synchronized (this) {
x += vx * direction;
y += vy * (horizontal ? 0 : 1);
if (x + image.getWidth(this) == getWidth()) {
horizontal = false;
direction = 0;
}
}
repaint();
try {
Thread.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
Conceptually, the idea is simple enough. When you reach one of your edges, you need to change the direction of your movement.
if x + image.width > width then go down
else if x < 0 then go up
else if y + image.height > height then go left
else if y < 0 then go right
for clock wise motion.
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class MoveTest {
public static void main(String[] args) {
new MoveTest();
}
public MoveTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private BufferedImage img;
private int xDelta = 2;
private int yDelta = 0;
private int x, y = 0;
public TestPane() {
try {
img = ImageIO.read(...);
} catch (IOException ex) {
ex.printStackTrace();
}
Timer timer = new Timer(15, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
x += xDelta;
y += yDelta;
if (x + img.getWidth() > getWidth()) {
x = getWidth() - img.getWidth();
xDelta = 0;
yDelta = 2;
} else if (x < 0) {
x = 0;
xDelta = 0;
yDelta = -2;
}
if (y + img.getHeight() > getHeight()) {
y = getHeight() - img.getHeight();
xDelta = -2;
yDelta = 0;
} else if (y < 0) {
y = 0;
xDelta = 2;
yDelta = 0;
}
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.drawImage(img, x, y, this);
g2d.dispose();
}
}
}
You should be careful of threads in Swing as Swing is not thread save. Have a look at Concurrency in Swing and How to use Swing Timers for more details

java GUI to assign array value

There is one Paraview user interface as follow attracted me.
I think this interface can be used to assign value into array. It works like this :
I want to implement this into a Java program but I found no Java API can support my idea. The closest design from me would be adding multiple JSlider like this :
But what if it is a 100 size array, I wouldn't want to add 100 JSliders. Do you have better solution for this ?
Okay, so this is a pretty basic example. It needs a lot more work and optimisation, but should get you moving in the right direction
Have a look at Painting in AWT and Swing, Performing Custom Painting, 2D Graphics and How to Write a Mouse Listener for more details
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Shape;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestGraph {
public static void main(String[] args) {
new TestGraph();
}
public TestGraph() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new GraphPane(0, 100, new int[100]));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class GraphPane extends JPanel {
protected static final int COLUMN_WIDTH = 10;
protected static final int VERTICAL_INSETS = 10;
private int[] data;
private int minValue, maxValue;
private Path2D.Double graph;
private List<Shape> buttons;
private Point mousePoint;
public GraphPane(int minValue, int maxValue, int[] data) {
this.data = data;
this.minValue = minValue;
this.maxValue = maxValue;
buttons = new ArrayList<>(data == null ? 25 : data.length);
updateView();
MouseAdapter ma = new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
updateData(e);
}
#Override
public void mouseDragged(MouseEvent e) {
updateData(e);
}
};
addMouseListener(ma);
addMouseMotionListener(ma);
}
protected void updateData(MouseEvent e) {
// Which "column" was clicked on
int column = (int) Math.round(((double) e.getX() / (double) COLUMN_WIDTH)) - 1;
// Get the "height" of the clickable area
int clickRange = getHeight() - (VERTICAL_INSETS * 2);
// Adjust the y click point for the margins...
int yPos = e.getY() - VERTICAL_INSETS;
// Calculate the vertical position that was clicked
// this ensures that the range is between 0 and clickRange
// You could choose to ignore values out side of this range
int row = Math.min(Math.max(clickRange - yPos, 0), clickRange);
// Normalise the value between 0-1
double clickNormalised = row / (double) clickRange;
// Calculate the actual row value...
row = minValue + (int) (Math.round(clickNormalised * maxValue));
// Update the data
data[column] = row;
mousePoint = new Point(
COLUMN_WIDTH + (column * COLUMN_WIDTH),
getHeight() - (VERTICAL_INSETS + (int) Math.round((data[column] / 100d) * clickRange)));
updateView();
repaint();
}
#Override
public void invalidate() {
super.invalidate();
updateView();
}
protected Shape createButton(int xPos, int yPos) {
return new Ellipse2D.Double(xPos - COLUMN_WIDTH / 2, yPos - COLUMN_WIDTH / 2, COLUMN_WIDTH, COLUMN_WIDTH);
}
protected void updateView() {
graph = new Path2D.Double();
buttons.clear();
if (data != null && data.length > 0) {
int verticalRange = getHeight() - (VERTICAL_INSETS * 2);
int xPos = COLUMN_WIDTH;
int yPos = getHeight() - (VERTICAL_INSETS + (int) Math.round((data[0] / 100d) * verticalRange));
graph.moveTo(xPos, yPos);
if (data[0] > 0) {
buttons.add(createButton(xPos, yPos));
}
for (int index = 1; index < data.length; index++) {
xPos = (index * COLUMN_WIDTH) + COLUMN_WIDTH;
yPos = getHeight() - (VERTICAL_INSETS + (int) Math.round((data[index] / 100d) * verticalRange));
graph.lineTo(xPos, yPos);
if (data[index] > 0) {
buttons.add(createButton(xPos, yPos));
}
}
}
}
#Override
public Dimension getPreferredSize() {
return new Dimension(data == null ? 0 : (data.length + 1) * COLUMN_WIDTH, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (data != null) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(new Color(64, 64, 64, 32));
for (int index = 0; index < data.length; index++) {
int xPos = (index * COLUMN_WIDTH) + COLUMN_WIDTH;
g2d.drawLine(xPos, VERTICAL_INSETS, xPos, getHeight() - VERTICAL_INSETS);
}
g2d.setColor(Color.BLACK);
g2d.draw(graph);
for (Shape button : buttons) {
g2d.fill(button);
}
if (mousePoint != null) {
g2d.setColor(new Color(255, 192, 203));
Ellipse2D dot = new Ellipse2D.Double((mousePoint.x - COLUMN_WIDTH / 2) - 2, (mousePoint.y - COLUMN_WIDTH / 2) - 2, COLUMN_WIDTH + 4, COLUMN_WIDTH + 4);
g2d.draw(dot);
g2d.setColor(new Color(255, 192, 203, 128));
g2d.fill(dot);
}
g2d.dispose();
}
}
}
}
Before anyone says I didn't put the "fill" in, I deliberately used a Path2D to make it much simpler to achieve ;)
here is a small example how to create this using polygon class .i sorted x coordinate and use polygon class to make this.
GraphPane.class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JPanel;
public class GraphPane extends JPanel {
ArrayList<XYpoints> poinList = new ArrayList();
private int px;
private int py;
private XYpoints last;
private boolean drag;
private static Color graphColor=new Color(32, 178, 170);
public GraphPane() {
initComponents();
poinList.add(new XYpoints(50, 400));
poinList.add(new XYpoints(450, 50));
poinList.add(new XYpoints(600, 400));
}
private void initComponents() {
setBackground(new java.awt.Color(255, 255, 255));
addMouseMotionListener(new java.awt.event.MouseMotionAdapter() {
public void mouseDragged(java.awt.event.MouseEvent evt) {
System.out.println("drag");
if (drag) {
last.setY(evt.getY());
GraphPane.this.repaint();
}
}
});
addMouseListener(new java.awt.event.MouseAdapter() {
public void mousePressed(java.awt.event.MouseEvent evt) {
int x = evt.getX();
int y = evt.getY();
for (XYpoints poinList1 : poinList) {
px = poinList1.getpX();
py = poinList1.getpY();
if (x < px + 5 && x > px - 5 && y < py + 5 && y > py - 5) {
System.out.println("inter");
poinList1.setIntersect(true);
last = poinList1;
drag = true;
GraphPane.this.repaint();
return;
}
}
poinList.add(new XYpoints(x, y));
Collections.sort(poinList, new XComp());
GraphPane.this.repaint();
}
public void mouseReleased(java.awt.event.MouseEvent evt) {
if (drag) {
drag = false;
last.setIntersect(false);
GraphPane.this.repaint();
}
}
});
}
#Override
protected void paintComponent(Graphics gr) {
super.paintComponent(gr);
Graphics2D g = (Graphics2D) gr.create();
Polygon p = new Polygon();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for (XYpoints poinList1 : poinList) {
px = poinList1.getpX();
py = poinList1.getpY();
p.addPoint(px, py);
}
g.setColor(graphColor);
g.fillPolygon(p);
for (XYpoints poinList1 : poinList) {
px = poinList1.getpX();
py = poinList1.getpY();
g.setColor(Color.red);
if (poinList1.isIntersect()) {
g.setColor(Color.blue);
}
g.fillOval(px - 5, py - 5, 10, 10);
}
g.dispose();
}
}
XYpoints.class
import java.awt.Polygon;
import java.util.Comparator;
public class XYpoints extends Polygon {
private int x;
private int y;
private boolean inter;
public XYpoints(int x, int y) {
this.x = x;
this.y = y;
}
public void setIntersect(boolean state) {
inter = state;
}
public void setY(int y){
this.y=y;
}
public boolean isIntersect() {
return inter;
}
public int getpX() {
//System.out.println("send " + this.x);
return this.x;
}
public int getpY() {
return this.y;
}
}
XComp .class
class XComp implements Comparator<XYpoints> {
#Override
public int compare(XYpoints t, XYpoints t1) {
if (t.getpX() < t1.getpX()) {
return -1;
} else {
return 1;
}
}
}
myframe.class
import javax.swing.JFrame;
public class myframe extends JFrame {
public myframe() {
GraphPane pane = new GraphPane();
setContentPane(pane);
setSize(650, 500);
setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new myframe();
}
});
}
}

Java 4-Way Pong, Stuck With Checking for Collisions

I am working on a 4 Way Pong Program. I have it to the point where my paddles will move with mouse movement, and the ball will bounce around the screen.
I am stuck when it comes to figuring out how to check for collisions between the ball and the paddles (which will increase the score) and between the ball and the edges of the JPanel (which will end the game).
Any guidance is greatly appreciated...
Game Class
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.RandomAccessFile;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Game extends JPanel {
JFrame window = new JFrame();
Timer timer = new Timer(30, new ActionHandler());
ArrayList<Ball> balls = new ArrayList<Ball>();
ArrayList<Paddle> horizPaddles = new ArrayList<Paddle>();
ArrayList<Paddle> vertPaddles = new ArrayList<Paddle>();
Paddle pTop;
Paddle pBottom;
Paddle pRight;
Paddle pLeft;
Ball b;
int score = 0;
JLabel scoreLabel;
//==========================================================
public Game() {
window.setBounds(100,100,900,500);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setTitle("4 Way Pong");
window.setResizable(false);
JPanel scorePanel = new JPanel(true);
scoreLabel = new JLabel("Current Score: " + Integer.toString(score));
scoreLabel.setFont(new Font("sansserif", Font.PLAIN, 20));
scoreLabel.setForeground(Color.RED);
scorePanel.add(scoreLabel);
JPanel buttons = new JPanel(true);
Container con = window.getContentPane();
con.setLayout(new BorderLayout());
con.add(this, BorderLayout.CENTER);
con.add(buttons, BorderLayout.SOUTH);
con.add(scorePanel, BorderLayout.NORTH);
this.setBackground(Color.BLACK);
this.addMouseMotionListener(new MouseMoved());
ButtonCatch bc = new ButtonCatch();
JButton btn;
btn = new JButton("New Game");
btn.addActionListener(bc);
buttons.add(btn);
btn = new JButton("Swap Colors");
btn.addActionListener(bc);
buttons.add(btn);
btn = new JButton("High Scores");
btn.addActionListener(bc);
buttons.add(btn);
btn = new JButton("Save Score");
btn.addActionListener(bc);
buttons.add(btn);
btn = new JButton("Quit");
btn.addActionListener(bc);
buttons.add(btn);
timer.start();
window.setVisible(true);
}
//==========================================================
public static void main(String[] args) {
new Game();
}
//==========================================================
public void update() {
for(Ball b : balls) {
b.move(getWidth() + 30, getHeight() + 25);
}
//checkSideCollision();
//checkHorizPaddleCollision();
//checkVertPaddleCollision();
repaint();
}
//==========================================================
public void checkSideCollision() {
if(b.getyPos() > getHeight()) {
JOptionPane.showMessageDialog(null, "Game Over. You Scored " + score + ".", "GAME OVER", JOptionPane.INFORMATION_MESSAGE);
System.exit(0);
}
}
//==========================================================
public void checkHorizPaddleCollision() {
if(b.getxPos() == pBottom.getX() && b.getyPos() == pBottom.getY()) {
//b.yPos = b.yPos - 5;
score++;
}
}
//==========================================================
public void checkVertPaddleCollision() {
}
//==========================================================
public class ButtonCatch implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
switch(e.getActionCommand()) {
case "Quit": JOptionPane.showMessageDialog(null, "You Quit... No Score Recorded", "Game Over", JOptionPane.INFORMATION_MESSAGE); System.exit(0);
case "New Game": newGame(); break;
case "Swap Colors": swapColors(); break;
case "High Scores": try { displayScores(); } catch (Exception e1) { System.out.println(e1.getMessage()); } break;
case "Save Score": try { saveScore(); } catch (Exception e2) { System.out.println(e2.getMessage()); } break;
}
}
}
//==========================================================
public void paint(Graphics g) {
super.paint(g);
for(Ball b : balls) {
b.draw(g);
}
for(Paddle p : horizPaddles) {
p.draw((Graphics2D) g);
}
for(Paddle p : vertPaddles) {
p.draw((Graphics2D) g);
}
}
//==========================================================
//FIX FOR DISPLAYING SCORES
private void displayScores() throws Exception {
}
//==========================================================
//FIX -- Store Score in a File
private void saveScore() throws Exception {
int userScore = score;
String name = JOptionPane.showInputDialog("Enter Your Name: ");
JOptionPane.showMessageDialog(null, "Saved!\n" + name + " scored " + userScore, "Score Recorded", JOptionPane.INFORMATION_MESSAGE);
}
//==========================================================
private void swapColors() {
for(Ball b : balls) {
if(b.color.equals(Color.red)) {
b.setColor(Color.yellow);
} else if (b.color.equals(Color.yellow)) {
b.setColor(Color.blue);
} else {
b.setColor(Color.red);
}
}
}
//==========================================================
private void newGame() {
//CREATE BALL
balls.clear();
b = new Ball();
b.color = Color.red;
b.dx = (int)(Math.random() * 4) + 1;
b.dy = (int)(Math.random() * 4) + 1;
b.xPos = (int)(Math.random() * 4) + 1;
b.yPos = (int)(Math.random() * 4) + 1;
balls.add(b);
//CREATE PADDLES
horizPaddles.clear();
vertPaddles.clear();
// bottom
pBottom = new Paddle();
pBottom.x = getWidth() / 2;
pBottom.y = getHeight();
pBottom.setX(pBottom.getX()-20);
pBottom.setY(pBottom.getY()-20);
pBottom.setWidth(100);
pBottom.setHeight(20);
horizPaddles.add(pBottom);
//top
pTop = new Paddle();
pTop.x = getWidth() / 2;
pTop.y = getHeight();
pTop.setX(0 + pTop.getX());
pTop.setY(0);
pTop.setWidth(100);
pTop.setHeight(20);
horizPaddles.add(pTop);
//left
pLeft = new Paddle();
pLeft.x = getWidth() / 2;
pLeft.y = getHeight();
pLeft.setX(0);
pLeft.setY(pLeft.getY() / 2);
pLeft.setWidth(20);
pLeft.setHeight(100);
vertPaddles.add(pLeft);
//right
pRight = new Paddle();
pRight.x = getWidth() / 2;
pRight.y = getHeight();
pRight.setX(875);
pRight.setY(pRight.getY() / 2);
pRight.setWidth(20);
pRight.setHeight(100);
vertPaddles.add(pRight);
timer.start();
}
//==========================================================
public class ActionHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent arg0) {
update();
}
}
//==========================================================
public class MouseMoved implements MouseMotionListener {
#Override
public void mouseMoved(MouseEvent e) {
for(Paddle p : horizPaddles) {
p.x = e.getX();
}
for(Paddle p : vertPaddles) {
p.y = e.getY();
}
}
#Override public void mouseDragged(MouseEvent e) {}
}
}
Paddle Class
import java.awt.Color;
import java.awt.Graphics2D;
public class Paddle implements Drawable{
public int x, y, width, height;
public Paddle() {
super();
}
public Paddle(int x, int y, int width, int height) {
super();
setX(x);
setY(y);
setWidth(width);
setHeight(height);
}
#Override
public void draw(Graphics2D g) {
g.setColor(Color.green);
g.fillRect(x, y, width, height);
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
}
Ball Class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.io.IOException;
import java.io.RandomAccessFile;
import javax.swing.JPanel;
public class Ball implements Comparable<Ball>, Cloneable{
private static int count = 0;
public static final int NAME_LENGTH = 20;
public String name = "";
public int xPos=0, yPos=0, dx = 3, dy = 2;
public Color color = Color.red;
public static void resetCounter() { count = 0; }
public Ball() {name = "Rock: " + ++count;}
public Ball(RandomAccessFile file) {
load(file);
}
public void load(RandomAccessFile file) {
try {
xPos = file.readInt();
yPos = file.readInt();
dx = file.readInt();
dy = file.readInt();
color = new Color( file.readInt() );
byte[] n = new byte[NAME_LENGTH];
file.readFully(n);
name = new String(n).trim();
System.out.println(name);
} catch (IOException e) {
e.printStackTrace();
}
}
public void save(RandomAccessFile file) {
try {
file.writeInt(xPos);
file.writeInt(yPos);
file.writeInt(dx);
file.writeInt(dy);
file.writeInt(color.getRGB());
file.writeBytes( getStringBlock(name, NAME_LENGTH) );
} catch (IOException e) {
e.printStackTrace();
}
}
private String getStringBlock(String string, int len) {
StringBuilder sb = new StringBuilder(name);
sb.setLength(len);
return sb.toString();
}
public void draw(Graphics g) {
g.setColor(color);
g.fillOval(xPos, yPos, 25, 25);
g.setColor(Color.black);
g.drawOval(xPos, yPos, 25, 25);
}
public void setColor(Color c) {
color = c;
}
public void move(int width, int height) {
xPos+=dx;
yPos+=dy;
if(xPos + 50 > width) {
xPos = width - 50;
dx = -dx;
}
if(yPos + 50 > height) {
yPos = height - 50;
dy = -dy;
}
if(xPos < 0) {
xPos = 0;
dx = -dx;
}
if(yPos < 0) {
yPos = 0;
dy = -dy;
}
}
#Override
public int compareTo(Ball arg0) {
return 0;
}
public int getxPos() {
return xPos;
}
public int getyPos() {
return yPos;
}
}
Thanks again...
For the Paddle-Ball collisions, I think calling this method on a timer might suffice:
public void checkPaddleCollisions(){
Rectangle a = new Rectangle(pTop.getX(), pTop.getY(), pTop.getWidth(), pTop.getHeight());
Rectangle b = ... //Do this for all the paddles.
Rectangle ball = new Rectangle(ball.getX(), ball.getY(), ball.getWidth(), ball.getHeight());
if(a.intersects(ball) || b.intersects(ball) || c.intersects(ball) || d.intersects(ball)){
//Increment score and bounce ball.
}
}
As for collisions with the edge, I think you could do something similar, just create 4 rectangles representing the edges of the screen.

draw method animation to another class

A little rough with java but can someone tell me how I take a draw method from a list of objects, say there's more than 1 box, and put it in the actionPerform so I could modify the getter of X and Y to repaint() them and make them move?
From Box Class:
public void draw(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect((int) (getX() - (width/2)), (int) (getY() - (height/2)), getWidth(), getHeight());
}
actionPerform method: (This is in another class)
public void actionPerformed(ActionEvent e){
timer.start();
}
The basic idea is...
When actionPerformed is called...
Iterate through the list of objects and update them in some meaningful way
Call repaint...
Then within your components paintComponent method, iterate the list and paint them
The following is a very basic concept...
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FlyingBoxes {
public static void main(String[] args) {
new FlyingBoxes();
}
public interface Drawable {
public void update(JComponent comp);
public void draw(Graphics g);
}
public class Box implements Drawable {
private int x;
private int y;
private int width = 10;
private int height = 10;
private int xDelta;
private int yDelta;
public Box(int x, int y) {
this.x = x;
this.y = y;
xDelta = random();
yDelta = random();
}
#Override
public void update(JComponent comp) {
x += xDelta;
y += yDelta;
if (x < 0) {
x = 0;
xDelta *= -1;
} else if (x + width > comp.getWidth()) {
x = comp.getWidth() - width;
xDelta *= -1;
}
if (y < 0) {
y = 0;
yDelta *= -1;
} else if (y + height > comp.getHeight()) {
y = comp.getHeight() - height;
yDelta *= -1;
}
}
#Override
public void draw(Graphics g) {
g.setColor(Color.BLUE);
g.fillRect(x, y, width, height);
}
protected int random() {
int value = 0;
do {
value = -2 + (int)(Math.random() * 4);
} while (value == 0);
return value;
}
}
public FlyingBoxes() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private List<Drawable> drawables;
public TestPane() {
drawables = new ArrayList<>(25);
for (int index = 0; index < 25; index++) {
int x = (int) (Math.random() * 190);
int y = (int) (Math.random() * 190);
drawables.add(new Box(x, y));
}
Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
for (Drawable d : drawables) {
d.update(TestPane.this);
}
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Drawable d : drawables) {
d.draw(g);
}
}
}
}

Categories

Resources