I am trying to make a chess game in java, by having a class of pieces and a subclass for each piece. However, When I try to draw the pieces, The position doesn't seem to register.
Here is my Piece class:
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.geom.AffineTransform;
import java.net.URL;
public class Piece {
public int Id;
public int color;
public int state;
public Image Sprite;
public AffineTransform tx;
public boolean dragged;
public int x;
public int y;
public Piece(int Id, int color, int position){
dragged = false;
this.Id = Id;
this.color = color;
int x = 100*(position % 8);
int y = 100*(position / 8);
System.out.println(x);
tx = AffineTransform.getTranslateInstance(x, y);
init(x, y);
}
private void init (double a, double b) {
tx.setToTranslation(a, b);
tx.scale(0.1, 0.1);
}
private void update(){
tx.setToTranslation(x*1000, y*1000);
tx.scale(0.1, 0.1);
}
protected Image getImage(String path) {
Image tempImage = null;
try {
URL imageURL = Piece.class.getResource(path);
tempImage = Toolkit.getDefaultToolkit().getImage(imageURL);
} catch (Exception e) {e.printStackTrace();}
return tempImage;
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
update();
g2.drawImage(Sprite, tx, null);
}
}
my pawn class:
public class Pawn extends Piece {
public Pawn(int Id, int color, int position) {
super(Id, color, position);
this.state = 0;
String path = "/imgs/Pieces/";
if(color == 0){
path += "W";
} else{
path += "B";
}
path += "_Pawn.png";
Sprite = getImage(path);
}
}
my Board class:
Piece[][] board;
public Board(){
board = new Piece[8][8];
for(int i = 0; i < 8; i++){
board[1][i] = new Pawn(i, 1, 8+i);
}
for(int i = 0; i < 8; i++){
board[6][i] = new Pawn(i, 0, 8+i);
}
}
}
and my main class:
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Main extends JPanel implements ActionListener, MouseListener, KeyListener{
Color GREEN = new Color( 41, 176, 59);
Color WHITE = new Color(254, 255, 228);
Board board = new Board();
public static void main(String[] args) {
new Main();
}
public void paint(Graphics g){
super.paintComponent(g);
boolean flag = true;
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
if(flag){
g.setColor(WHITE);
} else{
g.setColor(GREEN);
}
g.fillRect((j*100), (i*100), ((j+1)*100), ((i+1)*100));
flag = !flag;
}
flag = !flag;
}
for(int i = 0; i < 8; i++){
for(int j = 0; j < 8; j++){
if(board.board[i][j] != null){
board.board[i][j].paint(g);
}
}
}
}
public Main() {
JFrame f = new JFrame("Chess");
f.setSize(new Dimension(800, 800));
f.setBackground(Color.blue);
f.add(this);
f.setResizable(false);
f.setLayout(new GridLayout(1,2));
f.addMouseListener(this);
f.addKeyListener(this);
Timer t = new Timer(16, this);
t.start();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
}
}
I had previously written a game that implemented this techqnique, so I'm not sure what could have gone wrong with this one
It's really important to read the documentation, especially for something that is (to my simple brain), complicated.
If you have a read of the documentation for AffineTransform#scale
Concatenates this transform with a scaling transformation
(emphis added by me)
This is important, as it seems to apply that each time you call it, it will apply ANOTHER scaling operation.
Based on your avaliable code, this means that when the Piece is created, a scale is applied and the each time it's painted, a new scale is applied, until you're basically scaled out of existence.
Sooo. I took out your init (applied the scale within the constructor directly instead) and update methods and was able to get a basic result
Scaling from 1.0, 0.75, 0.5, 0.25and0.1` (it's there but I had to reduce the size of the output)
Runnable example...
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
JFrame frame = new JFrame();
frame.add(new Main());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class Main extends JPanel implements ActionListener, MouseListener, KeyListener {
Color GREEN = new Color(41, 176, 59);
Color WHITE = new Color(254, 255, 228);
Board board;
public Main() throws IOException {
board = new Board();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(800, 800);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
super.paintComponent(g);
boolean flag = true;
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (flag) {
g.setColor(WHITE);
} else {
g.setColor(GREEN);
}
g.fillRect((j * 100), (i * 100), ((j + 1) * 100), ((i + 1) * 100));
flag = !flag;
}
flag = !flag;
}
for (int i = 0; i < 8; i++) {
for (int j = 0; j < 8; j++) {
if (board.board[i][j] != null) {
board.board[i][j].paint(g);
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void keyTyped(KeyEvent e) {
}
#Override
public void keyPressed(KeyEvent e) {
}
#Override
public void keyReleased(KeyEvent e) {
}
}
public class Board {
Piece[][] board;
public Board() throws IOException {
board = new Piece[8][8];
for (int i = 0; i < 8; i++) {
board[1][i] = new Pawn(i, 1, 8 + i);
}
for (int i = 0; i < 8; i++) {
board[6][i] = new Pawn(i, 0, 16 + i);
}
}
}
public class Pawn extends Piece {
public Pawn(int Id, int color, int position) throws IOException {
super(Id, color, position);
this.state = 0;
String path = "/imgs/Pieces/";
if (color == 0) {
path += "W";
} else {
path += "B";
}
path += "_Pawn.png";
Sprite = getImage(path);
}
}
public class Piece {
public int Id;
public int color;
public int state;
public Image Sprite;
public AffineTransform tx;
public boolean dragged;
public int x;
public int y;
public Piece(int Id, int color, int position) {
dragged = false;
this.Id = Id;
this.color = color;
x = 100 * (position % 8);
y = 100 * (position / 8);
System.out.println(x + "x" + y);
tx = AffineTransform.getTranslateInstance(x, y);
tx.scale(0.1, 0.1);
}
protected Image getImage(String path) throws IOException {
BufferedImage img = new BufferedImage(100, 100, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setFont(new JLabel().getFont().deriveFont(Font.PLAIN, 16));
g2d.setColor(Color.BLACK);
FontMetrics fm = g2d.getFontMetrics();
int cellX = x;
int cellY = y;
String text = x + "x" + y;
int x = (100 - fm.stringWidth(text)) / 2;
int y = ((100 - fm.getHeight()) / 2) + fm.getAscent();
g2d.drawString(text, x, y);
g2d.setStroke(new BasicStroke(16));
g2d.drawRect(0, 0, 99, 99);
g2d.dispose();
return img;
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(Sprite, tx, null);
}
}
}
Related
I am developing a space invaders application for a college assignment and I've come into a problem where the aliens change direction one by one as they hit a wall rather than the whole array of objects switching direction when any alien touches the boundary. I hae a feeling it is an issue in my for loop where my move method containing reverseDirection() method acts on each element individually but I do not know how to fix this and any help would be greatly appreciated. Here is my code for you;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.*;
public class InvadersApplication extends JFrame implements Runnable {//, KeyListener {
private static final Dimension WindowSize = new Dimension(800, 600);
private static final int NUMALIENS = 16;
private Alien AliensArray[] = new Alien[NUMALIENS];
private Image alienImage;
private Image playerImage;
private String workingDirectory = "C:\\Users\\brads\\IdeaProjects\\Assignment3\\src\\workingDirectory\\";
private Player playerShip;
private BufferStrategy strategy;
public InvadersApplication() {
System.out.println(System.getProperty("user.dir"));
setDefaultCloseOperation(EXIT_ON_CLOSE);
Dimension screenSize = java.awt.Toolkit.getDefaultToolkit().getScreenSize();
int x = screenSize.width / 2 - WindowSize.width / 2;
int y = screenSize.height / 2 - WindowSize.height / 2;
setBounds(x, y, WindowSize.width, WindowSize.height);
this.setTitle("Alien Invaders App");
ImageIcon playerIcon = new ImageIcon(workingDirectory + "player_ship.png");
playerImage = playerIcon.getImage();
ImageIcon alienIcon = new ImageIcon(workingDirectory + "alien_ship_1.png");
alienImage = alienIcon.getImage();
playerShip = new Player(playerImage);
// addKeyListener(this);
setVisible(true);
createBufferStrategy(2);
strategy = getBufferStrategy();
for (int i = 0; i < NUMALIENS; i++) {
AliensArray[i] = new Alien(alienImage);
AliensArray[i].setPosition(70 * (i%4), 70 * (i/4));
AliensArray[i].setXspeed(1);
}
Thread thread1 = new Thread(this);
thread1.start();
repaint();
}
#Override
public void run(){
while(true){
try{
for(int i = 0; i < NUMALIENS; i++) {
AliensArray[i].move();
}
repaint();
Thread.sleep(5);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/* public void keyPressed(KeyEvent e) {
int KeyCode = e.getKeyCode();
if (KeyCode == KeyEvent.VK_LEFT) {
playerShip.movePlayer(-8);
} else if (KeyCode == KeyEvent.VK_RIGHT) {
playerShip.movePlayer(8);
}
}
*/
public void keyReleased(KeyEvent e){
}
public void keyTyped(KeyEvent e){}
public void paint(Graphics g){
g = strategy.getDrawGraphics();
g.setColor(Color.BLACK);
g.fillRect(0,0,800,600);
for(int i=0; i < NUMALIENS; i++){
AliensArray[i].paint(g);
}
// playerShip.paint(g);
//playerShip.paintPlayer(g);
strategy.show();
this.repaint();
}
public static void main(String[] args){
InvadersApplication x = new InvadersApplication();
}
}
Sprite2D class;
public class Sprite2D{
protected int x = 0,y = 30;
protected Image myImage;
public Sprite2D(Image myImage){
this.x = x;
this.y = y;
this.myImage = myImage;
}
public void setPosition(int xx, int yy){
x = xx;
y = yy;
}
public void paint(Graphics g){
g.drawImage(myImage, x,y, null);
}
}
Alien subclass of sprite2D;
import java.awt.*;
import java.util.Random;
import javax.swing.*;
public class Alien extends Sprite2D {
private int xi;
private int xj;
public Alien(Image myImage) {
super(myImage);
this.myImage = myImage;
this.x = x;
this.y = y;
this.xi = xi;
this.xj = xj;
}
// #Override
// public void setPosition(int xx, int yy){
// xx = x;
// yy = y;
//
// }
public void move() {
y+=xj;
x+= xi;
if(x >= 750) {
reverseDirection();
x = x + xi;
}
else if (x < 0)
{
reverseDirection();
x = x + xi;
}
}
public void setXspeed(int xi) {
this.xi = xi;
}
public void setYspeed(int xj) {
this.xj = xj;
}
public void reverseDirection() {
xi = -xi;
System.out.println("reverse");
}
// #Override
// public void paint(Graphics g) {
//
//
// g.drawImage(myImage, xx, yy, null);
// }
}
I'm having trouble with some custom Component I'm using in my project. It's drawing fine, but now I want to find coordinates of first pixel in certain color and have some troubles with it.
Here is my component code:
class DrawPad extends JComponent {
private LinkedList<Line> lines = new LinkedList<>();
DrawPad() {
setDoubleBuffered(true);
addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
lines.add(new Line());
lines.getLast().add(e.getPoint());
}
});
addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
lines.getLast().add(e.getPoint());
repaint();
}
});
}
void clear() {
lines.clear();
repaint();
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.BLACK);
if (!lines.isEmpty()) {
for (Line line : lines) {
// TODO
LinkedList<Point> points = line.getPoints();
Point previous = points.getFirst(), current = previous;
for (int i = 1; i < points.size(); i++) {
current = points.get(i);
g.drawLine(previous.x, previous.y, current.x, current.y);
previous = current;
}
}
}
}
}
I know it probably can be optimized, but it's not so important right now.
Can anyone help me to write a method that's searching for first pixel in certain color?
I recently find out that it has to do something with BufferedImage, but don't know how to implement it. Any help would be appreciated.
The example below paints an Icon into a BufferedImage and sets a RED pixel for find() to discover. Hover the mouse over other pixels to see the underlying color.
System.out.println(find(Color.RED));
…
private Point find(Color color) {
for (int r = 0; r < imgH; r++) {
for (int c = 0; c < imgW; c++) {
if (img.getRGB(c, r) == color.getRGB()) {
System.out.println(c + "," + r + ": "
+ String.format("%08X", img.getRGB(c, r)));
return new Point(c, r);
}
}
}
return new Point(-1 , -1);
}
Console:
32,32: FFFF0000
java.awt.Point[x=32,y=32]
Code:
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.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import javax.swing.Icon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
/**
* #see http://stackoverflow.com/a/37574791/230513
* #see http://stackoverflow.com/questions/2900801
*/
public class Grid extends JPanel {
private static final int SCALE = 8;
private final BufferedImage img;
private int imgW, imgH, paneW, paneH;
public Grid(String name) {
Icon icon = UIManager.getIcon(name);
imgW = icon.getIconWidth();
imgH = icon.getIconHeight();
img = new BufferedImage(imgW, imgH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = (Graphics2D) img.getGraphics();
icon.paintIcon(null, g2d, 0, 0);
g2d.dispose();
img.setRGB(imgW / 2, imgH / 2, Color.RED.getRGB());
this.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
Point p = e.getPoint();
int x = p.x * imgW / paneW;
int y = p.y * imgH / paneH;
int c = img.getRGB(x, y);
setToolTipText(x + "," + y + ": "
+ String.format("%08X", c));
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(imgW * SCALE, imgH * SCALE);
}
#Override
protected void paintComponent(Graphics g) {
paneW = this.getWidth();
paneH = this.getHeight();
g.drawImage(img, 0, 0, paneW, paneH, null);
System.out.println(find(Color.RED));
}
private Point find(Color color) {
for (int r = 0; r < imgH; r++) {
for (int c = 0; c < imgW; c++) {
if (img.getRGB(c, r) == color.getRGB()) {
System.out.println(r + "," + c + ": "
+ String.format("%08X", img.getRGB(c, r)));
return new Point(c, r);
}
}
}
return new Point(-1 , -1);
}
private static void create() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(new Grid("OptionPane.informationIcon"));
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
create();
}
});
}
}
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();
}
});
}
}
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.
newbie programmer here.
I'm making a program that renders user-inputted equations in a Cartesian coordinate system. At the moment I'm having some issues with letting the user move the view around freely in the coordinate. Currently with mouseDragged the user can drag the view around a bit, but once the user releases the mouse and tries to move the view again the origin snaps back to the current position of the mouse cursor. What is the best way to let the user move around freely? Thanks in advance!
Here's the code for the drawing area.
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.geom.Line2D;
import java.awt.geom.Point2D;
import javax.swing.JPanel;
public class DrawingArea extends JPanel implements MouseMotionListener {
private final int x_panel = 350; // width of the panel
private final int y_panel = 400; // height of the panel
private int div_x; // width of one square
private int div_y; // height of one square
private int real_y;
private int real_x;
private Point origin; // the origin of the coordinate
private Point temp; // temporary point
private static int y = 0;
private static int x = 0;
DrawingArea() {
setBackground(Color.WHITE);
real_x = x_panel;
real_y = y_panel;
setDivisionDefault();
setOrigin(new Point((real_x / 2), (real_y / 2)));
setSize(x_panel, y_panel);
addMouseMotionListener(this);
}
DrawingArea(Point origin, Point destination) {
this.origin = origin;
this.destination = destination;
panel = new JPanel();
panel.setSize(destination.x, destination.y);
panel.setLocation(origin);
this.panel.setBackground(Color.red);
panel.setLayout(null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D line = (Graphics2D) g;
temp = new Point(origin.x, origin.y);
line.setColor(Color.red);
drawHelpLines(line);
line.setColor(Color.blue);
drawOrigin(line);
line.setColor(Color.green);
for (int i = 0; i < 100; i++) { // This is a test line
//temp = this.suora();
temp.x++;
temp.y++;
line.drawLine(temp.x, temp.y, temp.x, temp.y);
}
}
public void setOrigin(Point p) {
origin = p;
}
public void drawOrigin(Graphics2D line) {
line.drawLine(origin.x, 0, origin.x, y_panel);
line.drawLine(0, origin.y, x_panel, origin.y);
}
public void drawHelpLines(Graphics2D line) {
int xhelp= origin.x;
int yhelp= origin.y;
for (int i = 0; i < 20; i++) {
xhelp+= div_x;
line.drawLine(xhelp, 0, xhelp, y_panel);
}
xhelp= origin.x;
for (int i = 0; i < 20; i++) {
xhelp-= div_x;
line.drawLine(xhelp, 0, xhelp, y_panel);
}
for (int i = 0; i < 20; i++) {
yhelp-= div_y;
line.drawLine(0, yhelp,x_panel, yhelp);
}
yhelp= origin.y;
for (int i = 0; i < 20; i++) {
yhelp+= div_y;
line.drawLine(0, yhelp, x_panel, yhelp);
}
}
public void setDivisionDefault() {
div_x = 20;
div_y = 20;
}
#Override
public void mouseDragged(MouseEvent e) {
//Point temp_point = new Point(mouse_x,mouse_y);
Point coords = new Point(e.getX(), e.getY());
setOrigin(coords);
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
Based on this example, the following program allows the user to drag the axes' intersection to an arbitrary point, origin, which starts at the center of the panel.
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* #see https://stackoverflow.com/a/15576413/230513
* #see https://stackoverflow.com/a/5312702/230513
*/
public class MouseDragTest extends JPanel {
private static final String TITLE = "Drag me!";
private static final int W = 640;
private static final int H = 480;
private Point origin = new Point(W / 2, H / 2);
private Point mousePt;
public MouseDragTest() {
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
this.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
mousePt = e.getPoint();
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
#Override
public void mouseDragged(MouseEvent e) {
int dx = e.getX() - mousePt.x;
int dy = e.getY() - mousePt.y;
origin.setLocation(origin.x + dx, origin.y + dy);
mousePt = e.getPoint();
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawLine(0, origin.y, getWidth(), origin.y);
g.drawLine(origin.x, 0, origin.x, getHeight());
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame(TITLE);
f.add(new MouseDragTest());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}