I have a KeyListener that works, but when I try to call a method such as getdx(), I'm not seeing any change. goal is to make a map move with arrows.
I've searched google and stackoverflow in various places, chopped my code all up and it's now pretty messy. what am I doing wrong?
public class GuiPanel extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;
private Timer timer;
private DrawMap drawmap = new DrawMap();
private DrawChar drawchar = new DrawChar();
KeyBoard keyboard = new KeyBoard();
boolean change = false;
public GuiPanel()
{
KeyListener listener = new KeyBoard();
addKeyListener(listener);
initGuiPanel();
}
private void initGuiPanel()
{
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
timer = new Timer(1000, this);
timer.start();
new GameLogic ("gamelogic").start();
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
draw(g);
Toolkit.getDefaultToolkit().sync();
}
private void draw(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
drawmap.drawmap(g2d);
drawchar.drawchar(g2d);
}
#Override
public void actionPerformed(ActionEvent e)
{
keyboard.getdx();
keyboard.getdy();
drawmap.move(keyboard.getdx(),keyboard.getdy());
repaint();
}
}
public class KeyBoard extends KeyAdapter
{
private int dx;
private int dy;
private int angle=1;
private boolean change = false;
KeyBoardLogic keyboardlogic = new KeyBoardLogic();
public int getdx()//does not return proper value
{
return keyboardlogic.getdx();
}
public void keyPressed(KeyEvent e)
{
keyboardlogic.keypressed(e);
}
public void keyReleased(KeyEvent e)
{
keyboardlogic.keyreleased(e);
}
}
public class KeyBoardLogic
{
private int dx=0;
public int getdx()
{
return dx;
}
public void keypressed(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
{
dx = -1;//does not update when getdx() is called
System.out.println("left");//works
}
}
public void keyreleased(KeyEvent e)
{
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT)
{
dx = -1;//just to know that something happened...
}
}
}
Initialize dx in the constructor of KeyBoardLogic like this:
public class KeyBoardLogic
{
private int dx;
public keyBoardLogic()
{
this.dx = 0;
}
//Remaining methods....
}
Got it. after a week of troubleshooting. dx and dy needed to be static. also a number of other coding errors masked the main problem.
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();
}
}
public class Board extends JPanel implements ActionListener {
private Player player;
private Timer timer;
public ArrayList<Enemy> enemyList;
public ArrayList<Bullet> bulletList;
private Random randomNumber;
public int WIDTH;
public int HEIGHT;
public Image plane;
public Image enemyimage;
private int x,y;
private final int DELAY = 25;
private final int B_WIDTH = 300;
private final int B_HEIGHT = 300;
private final int ICRAFT_X = 40;
private final int ICRAFT_Y = 60;
public Board(){
initBoard();
}
public void initBoard(){
addKeyListener(new TAdapter());
setBackground(Color.BLACK);
setFocusable(true);
setPreferredSize(new Dimension(B_WIDTH, B_HEIGHT));
player = new Player();
loadImage();
timer = new Timer(DELAY, this);
timer.start();
}
public void loadImage(){
ImageIcon ii = new ImageIcon("src/resources/planeimage.png");
plane = ii.getImage();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
doDrawing(g);
}
public void doDrawing(Graphics g){
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(player.getImage(),player.getX(),player.getY(),this);
ArrayList<Bullet> bulletList = player.getBullets();
for (Bullet bullet : bulletList){
g2d.drawImage(bullet.getImage(),bullet.getX(),bullet.getY(),this);
}
}
#Override
public void actionPerformed(ActionEvent e){
updateBullets();
updatePlayer();
repaint();
}
public void updateBullets() {
for (int i = 0; i < bulletList.size(); i++) {
Bullet bullet = bulletList.get(i);
if (bullet.isVisible()) {
bullet.move();
} else {
bulletList.remove(i);
}
}
}
public void updatePlayer(){
player.move();
}
private class TAdapter extends KeyAdapter {
#Override
public void keyReleased(KeyEvent e) {
player.keyReleased(e);
}
#Override
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
}
}
This is the player class which extends a vehicle class. Player constructor is being called in the board class and i guess, the problem lies their.
public class Player extends Vehicle{
public ArrayList<Bullet> bulletList;
public Player(){
super();
initPlayer();
}
public void initPlayer(){
bulletList = new ArrayList<>();
loadImage("src/resources/planeimage.png");
getImageDimensions();
}
#Override
public void move(){
x += dx;
y += dy;
}
public ArrayList<Bullet> getBullets(){
return bulletList;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_SPACE) {
fire();
}
if (key == KeyEvent.VK_LEFT) {
dx = -1;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 1;
}
if (key == KeyEvent.VK_UP) {
dy = -1;
}
if (key == KeyEvent.VK_DOWN) {
dy = 1;
}
}
#Override
public void fire() {
bulletList.add(new Bullet(x + w, y + h / 2));
}
public void keyReleased(KeyEvent e){
int key = e.getKeyCode();
if (key == KeyEvent.VK_LEFT) {
dx = 0;
}
if (key == KeyEvent.VK_RIGHT) {
dx = 0;
}
if (key == KeyEvent.VK_UP) {
dy = 0;
}
if (key == KeyEvent.VK_DOWN) {
dy = 0;
}
}
}
public class Application extends JFrame {
public Application() {
initUI();
}
private void initUI() {
add(new Board());
setSize(1024, 768);
setTitle("Application");
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> {
Application ex = new Application();
ex.setVisible(true);
});
}
}
Application class is the main class. Board class has all the code. When i run the program, only the black background is being shown, not the images. Why is that so, what am i doing wrong. Thank you.
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 have a problem with a simple Java game I am creating right now. I want a dot (a car) to be movable across the game screen, but instead of this all I can see on the screen is the long "snake" created by the dot moved by me:
Other problem is that activity manager on my Mac shows that the game uses huge amount of CPU power - my laptop gets very hot very fast. I suspect that there is something wrong with my game loop, but since now I haven't found any solution:
BoardPanel.java:
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import javax.swing.*;
#SuppressWarnings("serial")
public class BoardPanel extends JPanel implements KeyListener, Runnable {
public static final int WIDTH = 600;
public static final int HEIGHT = 600;
private Thread thread;
private boolean running;
private BufferedImage image;
private Graphics2D g;
private int FPS = 30;
private int targetTime = 1000/FPS;
private Map map;
private Car car;
public BoardPanel() {
super();
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
}
public void addNotify() {
super.addNotify();
if(thread == null) {
thread = new Thread(this);
thread.start();
}
addKeyListener(this);
}
public void run() {
init();
long startTime;
long reTime;
long waitTime;
while (running) {
startTime = System.nanoTime();
update();
render();
draw();
reTime = System.nanoTime() - startTime;
waitTime = targetTime - reTime;
try {
Thread.sleep(waitTime);
}
catch(Exception e) {
}
}
}
private void init() {
running = true;
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
g = (Graphics2D) image.getGraphics();
map = new Map();
car = new Car(map);
car.setxpos(50);
car.setypos(50);
}
private void update() {
map.update();
car.update();
}
private void render() {
map.draw(g);
car.draw(g);
}
private void draw() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
}
public void keyTyped(KeyEvent key) {
}
public void keyPressed(KeyEvent key) {
int code = key.getKeyCode();
if(code == KeyEvent.VK_LEFT) {
car.setLeft(true);
}
if(code == KeyEvent.VK_RIGHT) {
car.setRight(true);
}
if(code == KeyEvent.VK_UP) {
car.setUp(true);
}
if(code == KeyEvent.VK_DOWN) {
car.setDown(true);
}
}
public void keyReleased(KeyEvent key) {
int code = key.getKeyCode();
if(code == KeyEvent.VK_LEFT) {
car.setLeft(false);
}
if(code == KeyEvent.VK_RIGHT) {
car.setRight(false);
}
if(code == KeyEvent.VK_UP) {
car.setUp(false);
}
if(code == KeyEvent.VK_DOWN) {
car.setDown(false);
}
}
}
Car.java
import java.awt.*;
public class Car {
private double xpos;
private double ypos;
//private int xsize;
//private int ysize;
private boolean left;
private boolean right;
private boolean up;
private boolean down;
private Map map;
public Car(Map m) {
map = m;
}
public void setxpos(int i) {
xpos = i;
}
public void setypos(int i) {
ypos = i;
}
public void setLeft (boolean b) {
left = b;
}
public void setRight (boolean b) {
right = b;
}
public void setUp (boolean b) {
up = b;
}
public void setDown (boolean b) {
down = b;
}
public void update() {
if(left) {
xpos--;
}
if(right) {
xpos++;
}
if(up) {
ypos--;
}
if(down) {
ypos++;
}
}
public void draw(Graphics2D g) {
int mx = map.getx();
int my = map.gety();
g.setColor(Color.BLUE);
g.fillOval((int)(mx+xpos-20/2), (int)(my+ypos-20/2), 20, 20);
}
}
Map.java (I haven't created map yet, right now only want the dot to move properly)
import java.awt.*;
public class Map {
public int x;
public int y;
public int getx() {
return x;
}
public int gety() {
return y;
}
public void setx(int i) {
x = i;
}
public void sety(int i ) {
y = i;
}
public void update() {
}
public void draw(Graphics2D g) {
}
}
RacerMain.java
import javax.swing.JFrame;
public class RacerMain {
public static void main (String[]args) {
//MainFrame mf = new MainFrame();
JFrame mf = new JFrame("Racer");
mf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mf.setContentPane(new BoardPanel());;
mf.pack();
mf.setVisible(true);
}
}
Many thanks for your help!!!
In addition to what camickr said: Be careful with your usage of the Graphics. A rule of thumb:
Never call getGraphics on a Component!
Additionally, you are never disposing the Graphics that you are fetching from the BufferedImage. You are instead disposing the Graphics that you obtained from the Component, which may be even worse than fetching it in the first place!
I wonder why you are overriding the addNotify method. You should not implement any functionality based on averriding this method....
So you should change the respecive parts of your BoardPanel class roughly as follows:
public class BoardPanel extends JPanel implements KeyListener, Runnable {
...
// private Graphics2D g; // Don't store this here
public BoardPanel() {
...
// Create the thread here instead of in the "addNotify" method!
if(thread == null) {
thread = new Thread(this);
thread.start();
}
addKeyListener(this);
}
public void run() {
...
while (running) {
...
//draw(); // Don't call this method
repaint(); // Trigger a repaint instead!
}
}
private void render() {
Graphics2D g = image.createGraphics();
// Clear the background (see camickrs answer)
g.setColor(Color.BLACK);
g.fillRect(0,0,image.getWidth(),image.getHeight());
try
{
map.draw(g);
car.draw(g);
}
finally
{
g.dispose(); // Dispose the Graphics after it has been used
}
}
/** Don't call "getGraphics" on a component!
private void draw() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, null);
g2.dispose();
}
*/
// Override the paintComponent method instead:
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image,0,0,null);
}
In your draw() method you need to clear the BufferedImages background before your invoke the fillOval method. Something like:
g.setColor( Color.BLACK );
g.fillRect(...);
g.setColor( Color.BLUE );
g.fillOval(...);
Print out your "waitTime" to make sure you are waiting a reasonable time.
How can I obtain the coordinates of the cursor on a JPanel? I've tried using this:
MouseInfo.getPointerInfo().getLocation();
But this returns the location on the screen. I tried using the mouseMoved(MouseEvent m) method and then get the coordinates from m.getX() and m.getY(), but that method isn't being called. (I am using MouseListener).
Here's my Panel class:
public class Panel extends JPanel implements Runnable, KeyListener, MouseListener {
// serial
private static final long serialVersionUID = -2066956445832373537L;
// dimensions
public static final int WIDTH = 800;
public static final int HEIGHT = 600;
// game loop
private Thread thread;
private boolean running;
private final int FPS = 30;
private final int TARGET_TIME = 1000 / FPS;
// drawing
private BufferedImage image;
private Graphics2D g;
// status handler
private StatusHandler statusHandler;
// constructor
public Panel() {
setPreferredSize(new Dimension(WIDTH, HEIGHT));
setFocusable(true);
requestFocus();
}
public void addNotify() {
super.addNotify();
if(thread == null) {
addKeyListener(this);
addMouseListener(this);
thread = new Thread(this);
thread.start();
}
}
public void run() {
init();
long start;
long elapsed;
long wait;
// game loop
while(running) {
start = System.nanoTime();
update();
render();
renderToScreen();
elapsed = System.nanoTime() - start;
wait = TARGET_TIME - elapsed / 1000000;
if(wait < 0) wait = TARGET_TIME;
try {
Thread.sleep(wait);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
private void init() {
running = true;
image = new BufferedImage(WIDTH, HEIGHT, 1);
g = (Graphics2D) image.getGraphics();
statusHandler = new StatusHandler();
}
private void update() {
statusHandler.update();
}
private void render() {
statusHandler.render(g);
}
private void renderToScreen() {
Graphics g2 = getGraphics();
g2.drawImage(image, 0, 0, WIDTH, HEIGHT, null);
}
public void keyTyped(KeyEvent key) {}
public void keyPressed(KeyEvent key) {
KeyInput.setKey(key.getKeyCode(), true);
}
public void keyReleased(KeyEvent key) {
KeyInput.setKey(key.getKeyCode(), false);
}
public void mouseClicked(MouseEvent m) {}
public void mouseReleased(MouseEvent m) {
MouseInput.setButton(m.getButton(), false);
MouseInput.setMouseEvent(m);
}
public void mouseEntered(MouseEvent m) {}
public void mouseExited(MouseEvent m) {}
public void mousePressed(MouseEvent m) {
MouseInput.setButton(m.getButton(), true);
MouseInput.setMouseEvent(m);
}
}
The mouseMoved event is handled by a MouseMotionListener.