** Here i created only one moving object ,i want to create more objects which falls down and has random X coordinate .i know i should implement runnable and i should create squres then store them in a collection but its really hard for me to merge everything.i also might have done some mistakes btw . Could you help me some ? **
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.Random;
public class Project3 extends JFrame {
public Project3(){
super("Game");
setSize(600,600);
add(new Game(600,600));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Project3());
}
class Squares{
public int x;
public int y;
public Squares(int x, int y) {
this.x = x;
this.y = y;
}
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;
}
}
class Game extends JPanel implements ActionListener {
private int score;
private java.util.List<Squares> shapeList=new ArrayList<>();
private boolean play ;
private int X=50;
private int Y=0;
Timer timer=new Timer(10,this);
public Game(int w , int h){
Dimension d = new Dimension(w, h);
setBackground(Color.BLUE);
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.fillRect(X,Y,60,60);
timer.start();
}
#Override
public void actionPerformed(ActionEvent e) {
Y=Y+5;
repaint();
if(Y==600){
Random random=new Random();
Y=0;
X=random.nextInt(600-60);
}
}
}
}
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class Project3 extends JFrame {
public Project3() {
super("Game");
setSize(600, 600);
add(new Game(600,600));
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new Project3());
}
class Square {
public int squareX;
public int squareY;
int squareW = 25;
int squareH = 25;
public Square(int X, int Y) {
this.squareX = X;
this.squareY = Y;
}
public int getSquareX() {
return squareX;
}
public void setSquareX(int X) {
this.squareX = X;
}
public int getSquareY() {
return squareY;
}
public void setSquareY(int Y) {
this.squareY = Y;
}
}
class Game extends JPanel implements ActionListener ,Runnable,MouseListener {
public int score;
private java.util.List<Square> shapeList = new ArrayList<>();
Timer timer = new Timer(10, this);
private boolean play= true;
public Game(int w, int h) {
Dimension d = new Dimension(600, 600);
setBackground(Color.BLUE);
add(new Label("SCORE...."),BorderLayout.PAGE_END);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.YELLOW);
for (Square s:shapeList) {
g.fillRect(s.squareX,s.squareY,25,25);
}
}
#Override
public void actionPerformed(ActionEvent e) {
for (Square k : shapeList) {
k.setSquareY(k.getSquareY() + 5);
repaint();
}
}
public void stop() {
play = false;
}
#Override
public void run() {
while(play){
int randomNumber=(int)(Math.random()*600)+1;
shapeList.add(new Square(randomNumber,0));
for (Square k : shapeList) {
if (k.getSquareY()== 600) {
stop();
}try {
Thread.sleep(500);
} catch (InterruptedException ignored) {
}
}
}
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
int mouseX=e.getX();
int mouseY=e.getY();
for (Square s:shapeList){
if ((mouseX > s.squareX) && (mouseX < s.squareX + s.squareW) && (mouseY > s.squareY) && (mouseY < s.squareY + s.squareH)) {
shapeList.remove(s);
score++;
}
}
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
}
}
This code produces three layers of 'snow flakes' which drift towards the bottom of the screen.
Have a look over it, for tips:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import java.util.Random;
public class AnimatedSnowFall {
private JComponent ui = null;
AnimatedSnowFall() {
initUI();
}
public final void initUI() {
if (ui != null) {
return;
}
ui = new JPanel(new BorderLayout(4, 4));
ui.setBorder(new EmptyBorder(4, 4, 4, 4));
ui.add(new SnowFall());
}
public JComponent getUI() {
return ui;
}
public static void main(String[] args) {
Runnable r = () -> {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception useDefault) {
}
AnimatedSnowFall o = new AnimatedSnowFall();
JFrame f = new JFrame(o.getClass().getSimpleName());
f.setResizable(false);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(o.getUI());
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
};
SwingUtilities.invokeLater(r);
}
}
class SnowFall extends JPanel implements ActionListener {
Dimension prefSize = new Dimension(1600, 900);
SnowFlake[] farFlakes = new SnowFlake[200];
SnowFlake[] midFlakes = new SnowFlake[150];
SnowFlake[] closeFlakes = new SnowFlake[75];
Color farColor = new Color(100,100,255);
Color midColor = new Color(150,150,255);
Color closeColor = new Color(255,255,255);
SnowFall() {
setBackground(Color.BLACK);
for (int ii = 0; ii < farFlakes.length; ii++) {
farFlakes[ii] = new SnowFlake(prefSize.width, prefSize.height, 2, 4);
}
for (int ii = 0; ii < midFlakes.length; ii++) {
midFlakes[ii] = new SnowFlake(prefSize.width, prefSize.height, 3, 6);
}
for (int ii = 0; ii < closeFlakes.length; ii++) {
closeFlakes[ii] = new SnowFlake(prefSize.width, prefSize.height, 4, 8);
}
Timer timer = new Timer(50, this);
timer.start();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(farColor);
for (SnowFlake snowFlake : farFlakes) {
snowFlake.draw(g);
}
g.setColor(midColor);
for (SnowFlake snowFlake : midFlakes) {
snowFlake.draw(g);
}
g.setColor(closeColor);
for (SnowFlake snowFlake : closeFlakes) {
snowFlake.draw(g);
}
}
#Override
public Dimension getPreferredSize() {
return prefSize;
}
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}
class SnowFlake {
int w;
int h;
int x;
int y;
int size;
int speed;
static Random r = new Random();
SnowFlake(int w, int h, int size, int speed) {
this.w = w;
this.h = h;
x = r.nextInt(w);
y = r.nextInt(h);
this.size = size;
this.speed = speed;
}
public void draw(Graphics g) {
y += speed;
if (y > h) {
x = r.nextInt(w);
y = 0;
}
g.fillOval(x, y, size, size);
}
}
Related
I'm trying to make a game with ducks, the ducks are moving on the screen and I can't get a mouse click on them. I'm obviously doing something wrong because despite setting a MouseListener, its methods are not called. This is my code, I omitted getters and the DuckGame class, which is only generating ducks.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class DuckGameScreen extends JPanel {
private int initialDuckNum = 7;
private final int INTERVAL = 25;
private final int INTERVAL_BTWN_DUCKS = 1000;
private Timer duckTimer;
private int ducksStarted = 0;
private DuckGame duckGame;
public DuckGameScreen() {
setBackground(Color.cyan);
askAboutDifficulty();
startTimer();
startGame();
startDifficultyIncrease();
}
private void startGame() {
duckGame = new DuckGame(initialDuckNum);
startDucks();
addDuckListeners();
}
private void addDuckListeners() {
for (Duck duck : duckGame.getDucks()) {
duck.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("Duck clicked");}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
});
}
}
#Override
public void paint(Graphics g) {
super.paint(g);
drawDucks(g);
Toolkit.getDefaultToolkit().sync();
}
private void animateDuck(Duck duck) {
new Thread() {
#Override
public void run() {
super.run();
while (!duck.isDuckStopped()) {
try {
Thread.sleep(INTERVAL);
duck.move();
if (duck.getX() - duck.getWidth() >= Toolkit.getDefaultToolkit().getScreenSize().width) {
duck.resetPosition();
}
repaint();
} catch (InterruptedException e) {
e.printStackTrace();
duck.stop();
break;
}
}
}
}
.start();
}
private void drawDucks(Graphics g) {
for (Duck duck : duckGame.getDucks()) {
duck.paintComponent(g);
}
}
}
And my Duck class:
public class Duck extends JComponent {
private final static int INIT_X = -100;
private int x = INIT_X;
private int y = 100;
private int width = 0;
private int height = 0;
private Image image = null;
private boolean isDuckStopped = false;
private final int STEP = 5;
public Duck() {
initRandomPosition();
loadImage();
setVisible(true);
setBounds(x, y, width, height);
}
private void initRandomPosition() {
y = getRandomY();
}
public void move() {
x += STEP;
}
private void loadImage() {
ImageIcon imageIcon = new ImageIcon(getFilePath(Images.DUCK.getFileName()));
Dimension newDimension = Utils.getScaledDimension(100, 100, imageIcon.getIconWidth(), imageIcon.getIconHeight());
image = imageIcon.getImage().getScaledInstance(newDimension.width, newDimension.height, Image.SCALE_DEFAULT);
width = image.getWidth(null);
height = image.getHeight(null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
drawDuck(g);
Toolkit.getDefaultToolkit().sync();
}
private void drawDuck(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(image, x, y, this);
setBounds(x, y, width, height);
}
public void stop() {
isDuckStopped = true;
setVisible(false);
}
public void resetPosition() {
x = INIT_X;
y = getRandomY();
}
}
Good Morning, I was building when i find the problem that I don't know how to make my Player jump.
There are my classes:
GamePanel
package src;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class GamePanel extends JPanel implements Runnable{
public static final int WIDTH=300, HEIGHT=300, MIN_X_COORD=0, MIN_Y_COORD=0, MAX_X_COORD=19, MAX_Y_COORD=19;
private Thread thread;
private boolean playing, key=false;
private Random r;
int xCoord = 0, yCoord = 16, size = 15;
char direction;
private Player p;
private Victory v;
private ArrayList<Ground> grounds;
private ArrayList<Grass> grasses;
private ArrayList<Sky> sky;
Action jump=new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
yCoord--;
yCoord--;
yCoord++;
yCoord++;
}
};
Action right=new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(xCoord!=MAX_X_COORD)xCoord++;
direction='l';
}
};
Action left=new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
if(xCoord!=MIN_X_COORD)xCoord--;
direction='r';
}
};
public GamePanel() {
this.getInputMap().put(KeyStroke.getKeyStroke('d'),"right");
this.getInputMap().put(KeyStroke.getKeyStroke('a'),"left");
this.getInputMap().put(KeyStroke.getKeyStroke("SPACE"),"up");
this.getActionMap().put("right", right);
this.getActionMap().put("left", left);
this.getActionMap().put("up", jump);
setFocusable(true);
setPreferredSize(new Dimension(WIDTH, HEIGHT));
grounds = new ArrayList<Ground>();
grasses=new ArrayList<Grass>();
r=new Random();
v=new Victory(16,19, size);
p=new Player(xCoord, yCoord, size);
sky=new ArrayList<Sky>();
start();
}
public void start() {
playing=true;
thread=new Thread(this);
thread.start();
}
#Override
public void run() {
while (playing) {
tick();
repaint();
}
}
public void stop() {
playing = false;
// now we create the Game Over Screen
JFrame f=new JFrame("Game Over Screen");
JButton b=new JButton("Press this to play again!");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setPreferredSize(new Dimension(500,500));
JButton close = new JButton("Quit!");
b.setBounds(130,200,250, 40);
f.add(b);
f.add(close);
f.setLayout(new FlowLayout());
f.pack();
f.setVisible(true);
f.setLocationRelativeTo(null);
Main.returnFrame().dispatchEvent(new WindowEvent(Main.returnFrame(), WindowEvent.WINDOW_CLOSING));
Main.returnFrame().dispose();
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
f.dispatchEvent(new WindowEvent(f, WindowEvent.WINDOW_CLOSING));
Main.main(null);
}
});
close.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void tick() {
p=new Player(xCoord, yCoord, size);
if(grounds.size()==0) {
for(int y=MAX_Y_COORD;y>17;y--)
for(int x = 0;x<=MAX_X_COORD;x++)
grounds.add(new Ground(x,y,size));
}
if(grasses.size()==0)
for (int x=0;x<=MAX_X_COORD;x++)
grasses.add(new Grass(x, 17, size));
if (v.getxCoord()==p.getxCoord()&&v.getyCoord()==p.getyCoord()) {
win();
}
if (sky.size()==0)
for (int x=MIN_X_COORD;x<=MAX_X_COORD;x++)
for (int y=MIN_Y_COORD;y<17;y++)
sky.add(new Sky(x, y, size));
for(int i = 0;i< grounds.size();i++)
if(p.getxCoord() == grounds.get(i).getX_COORD() && p.getyCoord() ==grounds.get(i).getY_COORD())
back();
for(int i = 0;i< grasses.size();i++)
if(p.getxCoord() == grasses.get(i).getX_COORD() && p.getyCoord() ==grasses.get(i).getY_COORD())
back();
}
#Override
public void paint(Graphics g) {
g.clearRect(0, 0, WIDTH, HEIGHT);
g.setColor(Color.black);
g.fillRect(0, 0, WIDTH, HEIGHT);
for(int i = 0;i<WIDTH/10;i++) { // draws lines
g.drawLine(i*10, 0, i*10, HEIGHT);
}
for(int i = 0;i<HEIGHT/10;i++) {
g.drawLine(0, i*10, HEIGHT, i*10);
}
for(int i = 0;i<grounds.size();i++) {
grounds.get(i).draw(g);
}
for (Grass grass : grasses) {
grass.draw(g);
}
for (Sky s:sky)
s.draw(g);
v.draw(g);
p.draw(g);
}
public void win() {
JOptionPane.showMessageDialog(null, "Hai Vinto");
stop();
}
public void die() {
JOptionPane.showMessageDialog(null, "Sei morto");
stop();
}
public void back() {
switch (direction) {
case 'l': xCoord++;break;
case 'r': xCoord--;break;
}
}
}
Player
import java.awt.Color;
import java.awt.Graphics;
public class Player {
int xCoord, yCoord, width, height;
public Player(int xCoord, int yCoord, int size) {
this.xCoord=xCoord;
this.yCoord=yCoord;
width=size;
height=size;
}
public void draw(Graphics g) {
g.setColor(Color.RED);
g.fillRect(xCoord*width, yCoord*height, width, height);
}
public void setxCoord(int xCoord) {
this.xCoord = xCoord;
}
public int getxCoord() {
return xCoord;
}
public int getyCoord() {
return yCoord;
}
public void setyCoord(int yCoord) {
this.yCoord = yCoord;
}
}
I need that the action jump make the player character jump of two squares and return down.
I thought that i had to increase the yCoord and to repaint but it doesn't affect
I have a project that a circle goes with random x and y values and with selected colors but when the user pressed the space bar the color of the circle must be changed. My circle moves both x and y coordinate and I want to change the color of the circle when I press the space button. But it does not work when I pressed it. It goes with its original color. So how can I make this code right?
public class c {
private int x,y,r;
private Color co;
private int Re,G,B;
private Random ran;
public c() {
// TODO Auto-generated constructor stub
ran= new Random();
x=100;
y=50;
r= ran.nextInt(200)+50;
Re=ran.nextInt(255);
G=ran.nextInt(255);
B=ran.nextInt(255);
co= new Color(Re,G,B);
}
public int getRe() {
return Re;
}
public int getG() {
return G;
}
public int getB() {
return B;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getR() {
return r;
}
public void setCo(int Re,int G,int B) {
co= new Color(Re,G,B);
}
public Color getCo() {
return co;
}
public Random getRan() {
return ran;
}
public void setX(int x) {
this.x=x;
}
public void setY(int y) {
this.y=y;
}
}
public class Circle extends JFrame implements ActionListener,KeyListener{
private Timer timer;
private int x,y,a=5,b=5;
private Random rand;
c circ = new c();
public Circle() {
setLayout(new BorderLayout());
x=circ.getX();
y=circ.getY();
timer=new Timer(50,this);
timer.start();
addKeyListener(this);
setSize(550,550);
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x,y,100,100);
g.setColor(circ.getCo());
}
public static void main(String[]args) {
new Circle();
}
#Override
public void actionPerformed(ActionEvent e) {
moveWithTimer();
repaint();
}
public void moveWithTimer() {
x=x+b;
y=y+a;
if(x<0) {
b=5;
}
if(x+50>500) {
b=-5;
}
if(y<0){
a=5;
}
if(y+50>500) {
a=-5;
}
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(e.getKeyCode()==e.VK_SPACE) {
circ.setCo(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255));
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
But it does not work when I pressed it. It goes with its original color. So how can I make this code right?
KeyListener is fickle, better to use the Key Bindings API which overcomes the primary, focus related, issues of KeyListener
As a general rule of thumb, you shouldn't override paint of top level containers like JFrame, they are compound components and it's just a real mess.
Instead, start with a JPanel and override it's paintComponent method. It's generally more flexible. Have a look at Performing Custom Painting for more details.
Your movement code is wrong. You assign the x/y values of the circle class to some other variables, the problem here is, changing the values of these variables will have no affect on the variables in you circle class, instead, you need assign them back...
public void moveWithTimer() {
int x = circ.getX();
int y = circ.getY();
x = x + b;
y = y + a;
if (x < 0) {
b = 5;
}
if (x + 50 > 500) {
b = -5;
}
if (y < 0) {
a = 5;
}
if (y + 50 > 500) {
a = -5;
}
circ.setX(x);
circ.setY(y);
}
Your "circle" class could also use a couple of additional methods. One to randomise the color (it already has a Random object, might as well use it) and one to paint the object.
public class Circle {
//...
public void paint(Graphics2D g2d) {
g2d.setColor(co);
g2d.fillOval(x, y, r * 2, r * 2);
}
//...
public void randomColor() {
setCo(ran.nextInt(255), ran.nextInt(255), ran.nextInt(255));
}
//...
}
If it was me, I'd be tempted to add a move method as well, but that's me ;)
As a runnable example...
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.util.Random;
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;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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 Timer timer;
private int a = 5, b = 5;
private Random rand;
private Circle circ = new Circle();
public TestPane() {
timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
moveWithTimer();
repaint();
}
});
timer.start();
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaced");
am.put("spaced", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
circ.randomColor();
repaint();
}
});
}
public void moveWithTimer() {
int x = circ.getX();
int y = circ.getY();
x = x + b;
y = y + a;
if (x < 0) {
b = 5;
}
if (x + 50 > 500) {
b = -5;
}
if (y < 0) {
a = 5;
}
if (y + 50 > 500) {
a = -5;
}
circ.setX(x);
circ.setY(y);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
circ.paint(g2d);
g2d.dispose();
}
}
public class Circle {
private int x, y, r;
private Color co;
private int Re, G, B;
private Random ran;
public Circle() {
// TODO Auto-generated constructor stub
ran = new Random();
x = 100;
y = 50;
r = ran.nextInt(50) + 50;
Re = ran.nextInt(255);
G = ran.nextInt(255);
B = ran.nextInt(255);
co = new Color(Re, G, B);
}
public void paint(Graphics2D g2d) {
g2d.setColor(co);
g2d.fillOval(x, y, r * 2, r * 2);
}
public int getRe() {
return Re;
}
public int getG() {
return G;
}
public int getB() {
return B;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getR() {
return r;
}
public void randomColor() {
setCo(ran.nextInt(255), ran.nextInt(255), ran.nextInt(255));
}
public void setCo(int Re, int G, int B) {
co = new Color(Re, G, B);
}
public Color getCo() {
return co;
}
public Random getRan() {
return ran;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
}
I suggest you should set the color of the graphics object within paint(g) before painting the circle.
public void paint(Graphics g) {
super.paint(g);
g.setColor(circ.getCo());
g.fillOval(x,y,100,100);
}
In general, you should not override the paint() method of the JFrame. Instead, create a JPanel, add it to your frame and override the paintComponent() method of the panel.
I have a problem with repaint() method in my Java code. I want to call it in another class but I can't, something doesn't work at all. I've searched on forums, but nothing was able to help me out.
My Main class:
public class Main {
public static Main main;
public static JFrame f;
public Main(){
}
public static void main(String[] args) {
main = new Main();
f = new JFrame();
Ball b = new Ball();
f.getContentPane().setBackground(Color.GRAY);
f.add(b);
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setTitle("Test");
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.addMouseMotionListener(b);
f.addKeyListener(new Key());
}
}
Ball class where I created 2DGraphics for moving shapes:
public class Ball extends JLabel implements MouseMotionListener{
public Ball(){
}
public static double x = 10;
public static double y = 10;
public static double width = 40;
public static double height = 40;
String nick;
boolean isEllipse = true;
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if(isEllipse){
Ellipse2D e2d = new Ellipse2D.Double(x, y, width, height);
g2d.setColor(Color.RED);
g2d.fill(e2d);
}
else{
Rectangle2D r2d = new Rectangle2D.Double(x, y, width, height);
g2d.setColor(Color.GREEN);
g2d.fill(r2d);
}
}
#Override
public void mouseDragged(MouseEvent e) {
isEllipse = false;
x = e.getX() - 30;
y = e.getY() - 40;
this.repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
x = e.getX() - 30;
y = e.getY() - 40;
isEllipse = true;
this.repaint();
}
}
And Key class where I put KeyListener for move the shapes by key pressing:
public class Key extends Ball implements KeyListener {
public Key() {
}
#SuppressWarnings("static-access")
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
super.x += 10;
super.repaint();
System.out.println("x: " + super.x);
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
But something is wrong with this code: super method doesn't work for Key class. Everything in Ball class is working well. Where is the problem?
Super works fine, but your interpretation of what it does is wrong. Your problem is that you're trying to use inheritance to solve a problem that isn't solved with inheritance. You need to call repaint() on the actual visualized and used Ball instance, not on an instance of some completely different class, Key, that inappropriately extends from Ball. First off, make Key not extend Ball, pass in a true Ball reference into Key and the solution will fall from that.
Perhaps do something like this:
f.addKeyListener(new Key(b));
and
public class Key implements KeyListener {
private Ball ball;
public Key(Ball ball) {
this.ball = ball;
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
b.incrX(10); // give Ball a public method for this
b.repaint();
// System.out.println("x: " + super.x);
}
}
// .... etc...
Note, myself, I'd use Key Bindings for this, not a KeyListener, since then I wouldn't have to futz with keyboard focus.
For example:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.*;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class MoveBall {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private static void createAndShowGui() {
BallPanel ballPanel = new BallPanel(PREF_W, PREF_H);
MyMouse myMouse = new MyMouse(ballPanel);
ballPanel.addMouseListener(myMouse);
ballPanel.addMouseMotionListener(myMouse);
new CreateKeyBindings(ballPanel);
JFrame frame = new JFrame("MoveBall");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(ballPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
#SuppressWarnings("serial")
class BallPanel extends JPanel {
private static final Color ELLIPSE_COLOR = Color.RED;
private static final Color SQUARE_COLOR = Color.GREEN;
private static final int BALL_WIDTH = 40;
private int prefW;
private int prefH;
private boolean isEllipse = true;
private int ballX;
private int ballY;
public BallPanel(int prefW, int prefH) {
this.prefW = prefW;
this.prefH = prefH;
}
public boolean isEllipse() {
return isEllipse;
}
public void setEllipse(boolean isEllipse) {
this.isEllipse = isEllipse;
}
public int getBallX() {
return ballX;
}
public void setBallX(int ballX) {
this.ballX = ballX;
}
public void setXY(int x, int y) {
ballX = x;
ballY = y;
repaint();
}
public void setXYCenter(int x, int y) {
ballX = x - BALL_WIDTH / 2;
ballY = y - BALL_WIDTH / 2;
repaint();
}
public void setXYCenter(Point p) {
setXYCenter(p.x, p.y);
}
public int getBallY() {
return ballY;
}
public void setBallY(int ballY) {
this.ballY = ballY;
}
public void incrementBallX(int x) {
ballX += x;
repaint();
}
public void incrementBallY(int y) {
ballY += y;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (isEllipse) {
g2.setColor(ELLIPSE_COLOR);
g2.fillOval(ballX, ballY, BALL_WIDTH, BALL_WIDTH);
} else {
g2.setColor(SQUARE_COLOR);
g2.fillOval(ballX, ballY, BALL_WIDTH, BALL_WIDTH);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(prefW, prefH);
}
}
class MyMouse extends MouseAdapter {
private BallPanel ballPanel;
public MyMouse(BallPanel ballPanel) {
this.ballPanel = ballPanel;
}
#Override
public void mousePressed(MouseEvent e) {
ballPanel.setXYCenter(e.getPoint());
}
#Override
public void mouseDragged(MouseEvent e) {
ballPanel.setXYCenter(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
ballPanel.setXYCenter(e.getPoint());
}
}
enum Direction {
UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN), LEFT(KeyEvent.VK_LEFT), RIGHT(KeyEvent.VK_RIGHT);
private int key;
private Direction(int key) {
this.key = key;
}
public int getKey() {
return key;
}
}
// Actions for the key binding
#SuppressWarnings("serial")
class MyKeyAction extends AbstractAction {
private static final int STEP_DISTANCE = 5;
private BallPanel ballPanel;
private Direction direction;
public MyKeyAction(BallPanel ballPanel, Direction direction) {
this.ballPanel = ballPanel;
this.direction = direction;
}
#Override
public void actionPerformed(ActionEvent e) {
switch (direction) {
case UP:
ballPanel.incrementBallY(-STEP_DISTANCE);
break;
case DOWN:
ballPanel.incrementBallY(STEP_DISTANCE);
break;
case LEFT:
ballPanel.incrementBallX(-STEP_DISTANCE);
break;
case RIGHT:
ballPanel.incrementBallX(STEP_DISTANCE);
break;
default:
break;
}
}
}
class CreateKeyBindings {
private BallPanel ballPanel;
public CreateKeyBindings(BallPanel ballPanel) {
this.ballPanel = ballPanel;
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = ballPanel.getInputMap(condition);
ActionMap actionMap = ballPanel.getActionMap();
for (Direction direction : Direction.values()) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(direction.getKey(), 0);
String keyString = keyStroke.toString();
inputMap.put(keyStroke, keyString);
actionMap.put(keyString, new MyKeyAction(ballPanel, direction));
}
}
}
I am supposed to make a little game simulation. in this game there are three button . when user click start tank and car will close each other in 90 degrees when user click shut button tank will throw bullet to car.
i made and a simulation for this. tank throw bullet to car but when bullet crash car i couldn't this. i just need increase score of how many times tank hit car.
here is the source code
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Vehicle extends Thread {
private JPanel box;
private int XSIZE;
private int YSIZE;
private int time;
private int x;
private int y;
private int dx = 5;
private int dy = 5;
private int dim;
public Vehicle(JPanel b, int i) {
box = b;
this.dim = i;
if (i == 0) {
x = 0;
y = 100;
time = 1000;
XSIZE = 9;
YSIZE = 20;
} else {
time = 200;
y = box.getSize().height;
x = box.getSize().width / 2;
XSIZE = 6;
YSIZE = 10;
}
}
public void draw() {
Graphics g = box.getGraphics();
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void moveHorizontal() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setColor(Color.BLUE);
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
x += dx;
Dimension d = box.getSize();
if (x < 0) {
x = 0;
dx = -dx;
}
if (x + XSIZE >= d.width) {
x = d.width - XSIZE;
dx = -dx;
}
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public JPanel getBox() {
return box;
}
public void setBox(JPanel box) {
this.box = box;
}
public void moveVertical() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
y += dy;
Dimension d = box.getSize();
if (y < 0) {
y = 0;
dy = -dy;
}
if (y + YSIZE >= d.height) {
y = d.height - YSIZE;
dy = -dy;
}
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void move(int i) {
if (i == 0) {
moveHorizontal();
} else {
moveVertical();
}
}
public int getYSIZE() {
return YSIZE;
}
public void setYSIZE(int ySIZE) {
YSIZE = ySIZE;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public int getXSIZE() {
return XSIZE;
}
public void setXSIZE(int xSIZE) {
XSIZE = xSIZE;
}
public void setY(int y) {
this.y = y;
}
public void run() {
try {
draw();
for (;;) {
move(dim);
sleep(time);
}
} catch (InterruptedException e) {
}
}
}
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Bullet extends Thread {
private JPanel box;
private int XSIZE = 3;
public int getXSIZE() {
return XSIZE;
}
public void setXSIZE(int xSIZE) {
XSIZE = xSIZE;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
private int YSIZE = 1;
private int x;
private int y;
private int dx = 3;
public Bullet(JPanel b, Vehicle tank, Vehicle car) {
box = b;
x = tank.getX() + tank.getXSIZE();
if (x >= tank.getBox().getSize().width / 2)
dx = -dx;
y = tank.getY() + tank.getYSIZE() / 2;
;
}
public void draw() {
Graphics g = box.getGraphics();
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void move() {
if (!box.isVisible())
return;
Graphics g = box.getGraphics();
g.setColor(Color.RED);
g.setXORMode(box.getBackground());
g.fillOval(x, y, XSIZE, YSIZE);
x += dx;
Dimension d = box.getSize();
if (x < 0) {
x = 0;
}
if (x + XSIZE >= d.width) {
x = d.width - XSIZE;
}
g.fillOval(x, y, XSIZE, YSIZE);
g.dispose();
}
public void run() {
try {
draw();
for (;;) {
move();
sleep(20);
}
} catch (InterruptedException e) {
}
}
}
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
#SuppressWarnings("serial")
public class Tank_Shut_Car_ThreadFrame extends JFrame {
private JPanel canvas;
private boolean isOn = false;
private Vehicle tank;
private Vehicle car;
private JLabel score;
public static int sc = 0;
public Tank_Shut_Car_ThreadFrame() {
setResizable(false);
setSize(600, 400);
setTitle("Tank Shut Car");
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
Container contentPane = getContentPane();
canvas = new JPanel();
contentPane.add(canvas, "Center");
canvas.setLayout(null);
score = new JLabel("0");
score.setBounds(527, 11, 36, 14);
canvas.add(score);
JLabel lblScore = new JLabel("score");
lblScore.setBounds(481, 11, 36, 14);
canvas.add(lblScore);
JPanel p = new JPanel();
addButton(p, "Start", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (!isOn) {
tank = new Vehicle(canvas, 0);
tank.start();
car = new Vehicle(canvas, 1);
car.start();
isOn = true;
}
}
});
addButton(p, "Shut", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (isOn) {
Bullet bullet = new Bullet(canvas, tank, car);
bullet.start();
score.setText("" + sc);
}
}
});
addButton(p, "Close", new ActionListener() {
public void actionPerformed(ActionEvent evt) {
canvas.setVisible(false);
System.exit(0);
}
});
contentPane.add(p, "South");
}
public void addButton(Container c, String title, ActionListener a) {
JButton button = new JButton(title);
c.add(button);
button.addActionListener(a);
}
}
import javax.swing.JFrame;
public class Test {
public static void main(String[] args) {
JFrame frame = new Tank_Shut_Car_ThreadFrame();
frame.setVisible(true);
}
}
Okay, so I had a play around with this (just for fun)
Now, this is far from a "proper" or "complete" game engine, but it provides a basic idea of how it might be possible to mix a core thread engine with UI components.
Rather then pasting the entire code, I've uploaded the source it to Tank.zip
But the basic engine looks like this...
public class GameEngine extends Thread {
public static final Object ASSET_LOCK = new Object();
private List<GameAsset> lstAssets;
private GameScreen screen;
public GameEngine(GameScreen screen) {
// Let the thread die when the JVM closes
setDaemon(true);
// Want to be below the UI thread (personal preference)
setPriority(NORM_PRIORITY - 1);
// A list of game assests
lstAssets = new ArrayList<GameAsset>(25);
// A reference to the screen
this.screen = screen;
// Add global key listener, this is simpler to the trying to attach a key listener
// to the screen.
Toolkit.getDefaultToolkit().addAWTEventListener(new EventHandler(), AWTEvent.KEY_EVENT_MASK);
}
public GameAsset[] getAssets() {
synchronized (ASSET_LOCK) {
return lstAssets.toArray(new GameAsset[lstAssets.size()]);
}
}
/*
* Allows for assets to be added
*/
public void addAsset(GameAsset asset) {
synchronized (ASSET_LOCK) {
lstAssets.add(asset);
}
}
#Override
public void run() {
while (true) {
try {
sleep(40);
} catch (InterruptedException ex) {
}
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : assets) {
if (lstAssets.contains(asset)) {
asset.update(this, screen);
}
}
screen.repaint(new ArrayList<GameAsset>(lstAssets));
}
}
}
/**
* Allows the removal of an asset...
*/
public void removeAsset(GameAsset asset) {
synchronized (ASSET_LOCK) {
lstAssets.remove(asset);
}
}
/**
* Key event handling...
*/
protected class EventHandler implements AWTEventListener {
#Override
public void eventDispatched(AWTEvent event) {
KeyEvent keyEvent = (KeyEvent) event;
if (keyEvent.getID() == KeyEvent.KEY_PRESSED) {
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : assets) {
if (lstAssets.contains(asset)) {
asset.processKeyPressed(GameEngine.this, screen, keyEvent);
}
}
}
} else if (keyEvent.getID() == KeyEvent.KEY_RELEASED) {
synchronized (ASSET_LOCK) {
GameAsset[] assets = lstAssets.toArray(new GameAsset[lstAssets.size()]);
for (GameAsset asset : lstAssets) {
if (lstAssets.contains(asset)) {
asset.processKeyReleased(GameEngine.this, screen, keyEvent);
}
}
}
}
}
}
}
Swing is not thread safe. Events should be fired on the event-dispatching thread.
http://www.javamex.com/tutorials/threads/invokelater.shtml