I haven't looked at the code for this little game I made a while ago, and now all of the sudden the image won't move up when I click it?
I know the clicks are being called because the counter goes up. But the image won't move up. Any help is appreciated.
Batman class below
package Clicky;
import java.awt.Image;
import javax.swing.ImageIcon;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class Batman
{
private String batz = "batbomb.png";
private int x;
private int y;
private Image image;
private boolean visible;
public Batman()
{
ImageIcon ii = new ImageIcon(this.getClass().getResource(batz));
image = ii.getImage();
visible = true;
x = 145;
y = 620;
}
public int getX() { return x; }
public int getY() { return y; }
public Image getImage() { return image; }
public boolean isVisible()
{
return visible;
}
public void setVisible(boolean visible)
{
this.visible = visible;
}
public void mouseClicked(MouseEvent e)
{
int button = MouseEvent.BUTTON1;
if (button == MouseEvent.MOUSE_CLICKED)
{
y -= 1;
}
}
}
Where everything is drawn here
package Clicky;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Image;
import javax.swing.ImageIcon;
public class Clicky extends JPanel implements ActionListener
{
private Batman bat;
private Timer timer;
private int clicks = 0;
private boolean visible;
public Clicky() {
addMouseListener(new TAdapter());
setFocusable(true);
setBackground(Color.BLACK);
setDoubleBuffered(true);
timer = new Timer(5, this);
timer.start();
bat = new Batman();
}
public int getClickCount()
{
return clicks;
}
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g.setColor(Color.WHITE);
g2d.drawString("Clicks: " + getClickCount(), 10, 50);
g2d.drawRect(150, 70, 200, 600);
g2d.drawImage(bat.getImage(), bat.getX(), bat.getY(), this);
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e) {
repaint();
}
private class TAdapter extends MouseAdapter
{
public void mouseClicked(MouseEvent e)
{
e.getClickCount();
clicks = clicks + 1;
}
}
}
Your Batman mouseClicked(MouseEvent e) method never gets called (if I'm wrong, please show me where). But even if it did, your MOUSE_CLICKED == BUTTON1 boolean check would always be false, since BUTTON1 and MOUSE_CLICKED are both constants and equal to different things, 1 and 500 respectively, and this will make sure that the if block never worked.
Related
I've added keybinding on one of my JPanels. The problem is this keybinding didn't do its "actionPerformed". Even though I put a sysout in the actionPerformed, nothing was outputted on the console. Can someone help me with this problem? I've already tried to disable my buttons, but still my keybinding doesn't work.
package project.fin;
import java.awt.*;
import java.io.*;
import java.util.List;
import java.awt.event.*;
import javax.swing.*;
//Panel for my game
public class GamePlayPanel extends JPanel{
private Image current;
private Baby bayi;
public GamePlayPanel(String img) {
Dimension size = new Dimension(1200, 500);
this.setPreferredSize(size);
this.setMaximumSize(size);
this.setMinimumSize(size);
this.setSize(size);
this.setLayout(null);
//An baby object
bayi = new Baby(100, 410, 5);
//this is where my keyBinding initialized
bayi.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT,0), "moveRight");
bayi.getActionMap().put("moveRight", new Move_it(1));
}
//this is the action class that i want to put in my keybinding
private class Move_it extends AbstractAction{
int code;
public Move_it(int code) {
this.code=code;
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("test\n");
if (this.code==1) {
bayi.MoveRight();
}
repaint();
}
}
//To draw my baby
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
bayi.draw(g);
}
}
This is my baby class:
package project.fin;
import java.awt.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import java.awt.event.*;
public class Baby extends JComponent{
float x, y;
float speed;
Image current;
private List <Image> ImgPool;
private int Current;
public Baby(float x, float y, float speed) {
// TODO Auto-generated constructor stub
this.x = x;
this.y = y;
this.speed = speed;
ImgPool = new ArrayList<Image>();
//These are just some images that i use to build my moving baby
ImgPool.add(new ImageIcon("baby1_50.png").getImage());
ImgPool.add(new ImageIcon("baby2_50.png").getImage());
ImgPool.add(new ImageIcon("baby1_50.png").getImage());
ImgPool.add(new ImageIcon("baby3_50.png").getImage());
this.current = ImgPool.get(0);
this.Current = 0;
}
//The action that i want my baby to do when a key is pressed
public void MoveRight() {
if (x>600) return;
this.x+=speed;
if (this.Current==3)this.Current=0;
else
this.Current++;
this.current = this.ImgPool.get(Current);
}
public void draw(Graphics g) {
g.drawImage(this.current, (int)this.x, (int)this.y, null);
}
}
Baby isn't attached to the component hierarchy and therefore won't receive any key events. In fact, the design doesn't make sense. There's no need for Bady to extend from JPanel at all.
Instead, make use of the GamePlayPanel directly
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.*;
import javax.swing.AbstractAction;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new GamePlayPanel());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class GamePlayPanel extends JPanel {
private Baby bayi;
public GamePlayPanel() {
//An baby object
bayi = new Baby(100, 410, 5);
//this is where my keyBinding initialized
getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "moveRight");
getActionMap().put("moveRight", new Move_it(1));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(1200, 500);
}
//this is the action class that i want to put in my keybinding
private class Move_it extends AbstractAction {
int code;
public Move_it(int code) {
this.code = code;
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
System.out.println("test\n");
if (this.code == 1) {
bayi.moveRight();
}
repaint();
}
}
//To draw my baby
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
bayi.draw(g);
}
}
public class Baby {
float x, y;
float speed;
Image current;
private List<Image> ImgPool;
private int Current;
public Baby(float x, float y, float speed) {
// TODO Auto-generated constructor stub
this.x = x;
this.y = y;
this.speed = speed;
ImgPool = new ArrayList<Image>();
//These are just some images that i use to build my moving baby
ImgPool.add(new ImageIcon("baby1_50.png").getImage());
ImgPool.add(new ImageIcon("baby2_50.png").getImage());
ImgPool.add(new ImageIcon("baby1_50.png").getImage());
ImgPool.add(new ImageIcon("baby3_50.png").getImage());
this.current = ImgPool.get(0);
this.Current = 0;
}
//The action that i want my baby to do when a key is pressed
public void moveRight() {
if (x > 600) {
return;
}
this.x += speed;
if (this.Current == 3) {
this.Current = 0;
} else {
this.Current++;
}
this.current = this.ImgPool.get(Current);
}
public void draw(Graphics g) {
g.drawImage(this.current, (int) this.x, (int) this.y, null);
}
}
}
So, I am using ImageIcon and Image to animate a character. So far my code makes it look like the character is running however for a reason that I can't figure out KeyListener is not working. I have been at this for a while and I am wondering what I am doing wrong. This is my code:
*Right now I took out moving up and down because I couldn't get side to side to work. velyY was going to be the change in y.
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.MediaTracker;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.*;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Image;
public class Main extends JPanel implements ActionListener,KeyListener{
ImageIcon images[];
int x = 100;
int y = 5;
int velX;
int velY;
int totalImages =3, currentImage = 0, animationDelay = 160;
Timer animationTimer;
public Main() {
images = new ImageIcon[totalImages];
images[0] = new ImageIcon("standing.png");
images[1] = new ImageIcon("ready.png");
images[2] = new ImageIcon("running.png");
startAnimation();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics g2 = (Graphics) g;
if (images[currentImage].getImageLoadStatus() == MediaTracker.COMPLETE){
Image img = images[currentImage].getImage();
g2.drawImage(img, x, 407, null);
currentImage = (currentImage + 1) % totalImages;
}
}
public void actionPerformed(ActionEvent e) {
repaint();
x+=velX;
}
public void right(){
velX = 8;
}
public void left(){
velX = -8;
}
public void keyPressed(KeyEvent arg0) {
int code = arg0.getKeyCode();
if (code == KeyEvent.VK_A){
left();
}
if(code == KeyEvent.VK_D){
right();
}
}
public void keyTyped(KeyEvent e){}
public void keyReleased(KeyEvent e){
velX = 0;
velY = 0;
}
public void startAnimation() {
if (animationTimer == null) {
currentImage = 0;
animationTimer = new Timer(animationDelay, this);
animationTimer.start();
} else if (!animationTimer.isRunning())
animationTimer.restart();
}
public void stopAnimation() {
animationTimer.stop();
}
}//end class
You have to register your KeyListener to your panel, if you want it to manage key events.
The second thing is that a JPanel is not focusable by default, so you have to make it focusable to receive key events.
In your Main constructor, just add :
setFocusable(true); // make your panel focusable
addKeyListener(this); // register the key listener
Ok I'm doing a project and the image is supposed to move around randomly and when the user clicks on the image it's supposed to count how many times the click on it. From there on it keeps moving until they x out. However, I made the mistake of making the image move AFTER they click on it, so when the program starts the image isn't already moving. I need it to move from the beginning of the program.
Attached here because for whatever reason, stack overflow keeps saying I formatted wrong.
import java.awt.Graphics;
import java.awt.Image;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
// Zombie class
public class Zombie {
//declare variables
private int x;
private int y;
private int size;
private Image image;
//constructor
public Zombie(int xIn, int yIn, String imagePath) {
x = xIn;
y = yIn;
size = Settings.DEFAULT_SIZE;
setImage(imagePath);
}
//getter for x
public int getX() {
return x;
}
//getter for y
public int getY() {
return y;
}
//setter for x
public void setX(int x) {
this.x = x;
}
//setter for y
public void setY(int y) {
this.y = y;
}
//drawImage method
public void update(Graphics g) {
g.drawImage(image, x, y, size, size, null);
}
//try catch exception, if image isn't found
public void setImage(String imagePath) {
try {
image = ImageIO.read(new File(imagePath));
} catch (IOException ioe) {
System.out.println("Unable to load image file.");
}
}
}
public class Settings {
//adjusts the width and height of the creature
public static final int WIDTH = 500;
public static final int HEIGHT = 300;
public static final int DEFAULT_SIZE = 50;
//image name
public static final String ZOMBIE_IMAGE = "zombie.png";
}
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Graphics;
import java.awt.Image;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.util.Random;
class Controller implements MouseListener {
//declares variables
Zombie zombie;
View view;
private int count = 0;
Controller() {
//System.out.println ("Controller()");
}
public void addZombie(Zombie z){
//System.out.println("Controller: adding zombie");
this.zombie = z;
}
public void addView(View v){
//System.out.println("Controller: adding view");
this.view = v;
}
public void mousePressed(MouseEvent e) {
//System.out.println("Controller sees mouse pressed: acting on Model");
int prevX = e.getX();
int prevY = e.getY();
prevX -= zombie.getX();
prevY -= zombie.getY();
if((prevX > 0 && prevX < Settings.DEFAULT_SIZE) &&
(prevY > 0 && prevY < Settings.DEFAULT_SIZE)) {
//System.out.println("Got Zombie.");
Random r = new Random();
zombie.setX(r.nextInt(view.getWidth() - Settings.DEFAULT_SIZE));
zombie.setY(r.nextInt(view.getHeight() - Settings.DEFAULT_SIZE));
++count;
}
}
public int getCount() {
return count;
}
//mouse events
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void update(Graphics g) {
zombie.update(g);
}
}
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.awt.Component;
import java.awt.Graphics;
import java.awt.Image;
import javax.imageio.ImageIO;
import java.io.File;
import java.io.IOException;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.util.Random;
public class View implements ActionListener {
private JFrame frame;
Controller controller;
public static void main(String[] args) {
Zombie zombie = new Zombie(Settings.WIDTH/2, Settings.HEIGHT/2, Settings.ZOMBIE_IMAGE);
View view = new View();
Controller myController = new Controller();
myController.addZombie(zombie);
myController.addView(view);
view.addController(myController);
new Timer(500, view).start();
}
private class MyPanel extends JPanel {
private static final long serialVersionUID = 1L;
public void paintComponent(Graphics g) {
controller.update(g);
revalidate();
}
}
private MyPanel panel;
View() {
//System.out.println("View()");
frame = new JFrame("Catch The Zombie");
// Create a panel to contain a label, a text box, and a button
panel = new MyPanel();
frame.add(panel);
frame.setSize(Settings.WIDTH, Settings.HEIGHT);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.addWindowListener(new WindowAdapter()
{
#Override
public void windowClosing(WindowEvent e)
{
// TODO Auto-generated method stub
System.out.println("Zombie was caught " + controller.getCount() + "times");
}
});
}
public void revalidate() {
}
public void addController(Controller controller){
//System.out.println("View : adding controller");
this.controller = controller;
frame.getContentPane().addMouseListener((MouseListener) controller);
}
public int getWidth() {
return frame.getWidth();
}
public int getHeight() {
return frame.getHeight();
}
public void actionPerformed(ActionEvent e) {
frame.repaint();
}
}
I can not figure out why the game is only drawing only on half the window I make.
I add in actionPerformed to always implement to y position and it goes only on half the window , then the images stopes.
Main
import java.awt.EventQueue;
import javax.swing.JFrame;
public class Main extends JFrame{
public static void main(String[]args){
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame ex = new Main();
ex.setVisible(true);
}
});
}
public Main(){
setTitle("Maze");
add(new Game());
pack();
setResizable(false);
setLocationRelativeTo(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Game
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Game extends JPanel implements ActionListener {
private final int GWIDTH = 400;
private final int GHEIGHT = 400;
private int GAME_DELAY = 10;
private Timer timer;
private Image player;
/*Player*/
private final int spawnPosition = 0;
int playerX = 0;
int playerY = spawnPosition;
/*Mouse*/
private Mouse m;
public Game(){
setFocusable(true);
setPreferredSize(new Dimension(GWIDTH, GHEIGHT));
addMouseListener(new Mouse());
initTime();
//Importam poza
loadPlayer();
//Mouse
m = new Mouse();
}
private void initTime(){
timer = new Timer(GAME_DELAY, this);
timer.start();
}
private void loadPlayer(){
ImageIcon img = new ImageIcon("smiley.png");
player = img.getImage();
}
public int getX(){ return playerX; }
public int getY() { return playerY; }
private void drawPlayer(Graphics2D g2d){
g2d.drawImage(player,getX(),getY(),null);
Toolkit.getDefaultToolkit().sync();
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
drawPlayer(g2d);
g2d.dispose();
}
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
playerY += 1;
repaint();
}
}
Image
Im having trouble getting the key pressed event to work, it doesn't recognize key input, can someone please help?
I have three classes player, exe, and board
Here is the board class
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyListener;
import java.awt.event.KeyEvent;
import javax.swing.JPanel;
import javax.swing.Timer;
import java.applet.*;
import java.awt.*;
import java.awt.event.*;
public class Board extends JPanel implements ActionListener{
private Timer timer;
private Player player;
//private Floor
public Board() {
addKeyListener( new TAdapter() );
setFocusable(true);
setBackground(Color.WHITE);
setDoubleBuffered(true);
player = new Player();
//floor = new Floor();
timer = new Timer(5, this);
timer.start();
}
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2d = (Graphics2D)g;
g2d.drawImage(player.getImage(), player.getX(), player.getY(), this);
// g2d.drawImage(floor.getImage(), floor.getX(), floor.getY(), this);
//System.out.println(player.getX() + ", " + player.getY());
Toolkit.getDefaultToolkit().sync();
g.dispose();
}
public void actionPerformed(ActionEvent e) {
// checkPlayerOnGround();
player.move();
repaint();
}
private class TAdapter extends KeyAdapter implements KeyListener{
public void keyTyped(KeyEvent e) {
player.keyReleased(e);
System.out.println("Released");
}
public void keyPressed(KeyEvent e) {
player.keyPressed(e);
System.out.println("Pressed");
}
}
}
here is the player class
import java.awt.Image;
import java.awt.event.KeyEvent;
import javax.swing.ImageIcon;
import javax.swing.Timer;
import java.util.TimerTask;
public class Player{
private String player = "player.jpg";
private int moveX;
private int moveY;
private int x;
private int y;
private Image image;
private boolean canFall = false;
//private Timer jumpTimer = new Timer();
boolean canJump = true;
public Player() {
ImageIcon playeriImage = new ImageIcon(this.getClass().getResource(player));
image = playeriImage.getImage();
x = 40;
y = 60;
}
public void checkFall() {
if(canFall) {
moveY = -4;
}
}
public void move() {
//checkFall();
x = moveX + x;
y = moveY + y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public Image getImage() {
return image;
}
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
moveX = -4;
}
if (key == KeyEvent.VK_D) {
moveX = 4;
}
if (key == KeyEvent.VK_W) {
if(canJump)
this.jump();
}
}
public void keyReleased(KeyEvent e) {
int key = e.getKeyCode();
if (key == KeyEvent.VK_A) {
moveX = 0;
}
if (key == KeyEvent.VK_D) {
moveX = 0;
}
}
here is the exe class
import javax.swing.JFrame;
public class Exe extends JFrame {
public Exe() {
add(new Board());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(500, 500);
setLocationRelativeTo(null);
setTitle("TSA Video Game");
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new Exe();
}
}
thanks in advance
KeyListener will only respond to key events IF the component is focusable AND has focus.
It would be better to use the Key Bindings API which will allow you to overcome this limitation (if you want to)
I would also recommend that you override paintComponent instead of paint. You should also not be calling Graphics#dispose, as you did not create the Graphics context, this could actually prevent anything from being painted on some systems
I would also suggest that a delay of 5 milliseconds (on your Timer) might be a little excessive (5 milliseconds = 200fps!).
A value of 16 (60fps) or 40 (25fps) may be more suitable and reduce the overhead on the system...IMHO