How to Make an Image Move While Listening to a Keypress in Java

How to make an image move while listening to a keypress in Java.

But basically I just want to know how to make the image move left to right while the window is listening to a keypress

You can use a Swing Timer to animate an image:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class TimerAnimation extends JLabel implements ActionListener
{
int deltaX = 2;
int deltaY = 3;
int directionX = 1;
int directionY = 1;

public TimerAnimation(
int startX, int startY,
int deltaX, int deltaY,
int directionX, int directionY,
int delay)
{
this.deltaX = deltaX;
this.deltaY = deltaY;
this.directionX = directionX;
this.directionY = directionY;

setIcon( new ImageIcon("dukewavered.gif") );
// setIcon( new ImageIcon("copy16.gif") );
setSize( getPreferredSize() );
setLocation(startX, startY);
new javax.swing.Timer(delay, this).start();
}

public void actionPerformed(ActionEvent e)
{
Container parent = getParent();

// Determine next X position

int nextX = getLocation().x + (deltaX * directionX);

if (nextX < 0)
{
nextX = 0;
directionX *= -1;
}

if ( nextX + getSize().width > parent.getSize().width)
{
nextX = parent.getSize().width - getSize().width;
directionX *= -1;
}

// Determine next Y position

int nextY = getLocation().y + (deltaY * directionY);

if (nextY < 0)
{
nextY = 0;
directionY *= -1;
}

if ( nextY + getSize().height > parent.getSize().height)
{
nextY = parent.getSize().height - getSize().height;
directionY *= -1;
}

// Move the label

setLocation(nextX, nextY);
}

public static void main(String[] args)
{
JPanel panel = new JPanel();
JFrame frame = new JFrame();

frame.setContentPane(panel);
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.getContentPane().setLayout(null);
// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );
frame.getContentPane().add( new TimerAnimation(300, 100, 3, 2, -1, 1, 20) );
// frame.getContentPane().add( new TimerAnimation(0, 000, 5, 0, 1, 1, 20) );
frame.getContentPane().add( new TimerAnimation(0, 200, 5, 0, 1, 1, 80) );
frame.setSize(400, 400);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
// frame.getContentPane().add( new TimerAnimation(10, 10, 2, 3, 1, 1, 10) );
// frame.getContentPane().add( new TimerAnimation(10, 10, 3, 0, 1, 1, 10) );
}
}

You can add a KeyListener to the panel and it will operate independently of the image animation.

Using Key Bindings to move Images

Two things with this code:

  • I do not see anything about the action map. The input map maps a key to an action identifier, and the action map is the link between the identifier and the actual action. So you normally have code like

    InputMap inputMap = component.getInputMap( );
    ActionMap actionMap = component.getActionMap();
    Action actionToTrigger = ...;
    actionMap.put( "myAction", actionToTrigger );
    inputMap.put( key, "myAction" );
  • If putting your action in the action map with the correct identifier and it still does not work, you might have been using the wrong input map. There are 3 different input maps as explained in the Swing keybindings guide. Try with the others

Perhaps you should consult the Swing keybindings tutorial again as it explains all this in more detail + contains code examples

How do I move a graphic across the screen with arrow keys?

Two big problems here:

public void paintComponent(Graphics g){
super.paintComponent(g);
ImageIcon i = new ImageIcon("C:\\Users\\Bryan\\Pictures\\ship.gif");
i.paintIcon(this, g, 0, 0);
}
  1. You're reading from a file from within paintComponent(...). Never do this as this will slow your drawing unnecessarily. Read the image once, perhaps in a constructor, and then use the stored image variable in drawing. The paintComponent method should be for painting only, and it should be lean, mean and fast.
  2. You're drawing at 0, 0 always. If you want to move something, draw at a variable position, and then change the values held by the variable and repaint.

Also: You should use Key Bindings to accept key strokes in a Swing application as this will help solve focus issues.

For example, please have a look at my code in this answer.

Image object is not moving(Spaceship Game) - Java Swing

The answer:

Simply i needed to create a thread and add it to the list of threds(projectiles) with the x,y values I wanted each time i press the space bar. Then in the paintComponent() method i moved with foreach loop on the threads list and draw them. Also i added Thread.sleep(10) in the while loop that moves the projectile so it will not move too fast.

public class MyJPanel extends JPanel implements ActionListener
{
private static final long serialVersionUID = 1L;

private Timer timer;
private Image backgroundImage;
private Image player;
private int playerX, playerY;
private int projectileX,projectileY;
private Image projectileImage;
private ArrayList<ProjectileThread> projectiles = new ArrayList<ProjectileThread>();

static boolean gameLoop = true;

public MyJPanel(Image backgroundImage, Image player,Image projectileImage)
{
this.backgroundImage = backgroundImage;
this.player = player;
this.projectileImage = projectileImage;
this.setLayout(null);

timer = new Timer(50, this);
timer.start();

this.addKeyListener(new KeyAdapter() // Listens for a keyboard event
{
public void keyPressed(KeyEvent e)
{
if (e.getKeyCode() == KeyEvent.VK_SPACE) // If pressing space - shoot
{
ProjectileThread projectileThread = new ProjectileThread(playerX,playerY);
projectileThread.start(); // Create a Thread and call run() method
projectiles.add(projectileThread);
repaint();
}
}
});

// Mouse listener
this.addMouseMotionListener(new MouseMotionListener()
{
@Override
public void mouseMoved(MouseEvent e)
{
playerX = e.getX();
playerY = e.getY();
}

@Override
public void mouseDragged(MouseEvent e)
{

}
});
hideMouseCursor();

this.setFocusable(true);
this.setVisible(true);
} // End of JPanel constructor

public int getX()
{
return this.projectileX;
}

public int getY()
{
return this.projectileX;
}

public void paintComponent(Graphics graphics)
{
super.paintComponent(graphics);

graphics.drawImage(backgroundImage,0,0,this.getWidth(),this.getHeight(),null); // Draw the background
graphics.drawImage(player,playerX,playerY,null); // Draw the player
for (ProjectileThread projectileThread : projectiles)
{
graphics.drawImage(projectileImage,projectileThread.getX(),projectileThread.getY(),null);
}
}

public void hideMouseCursor() // Hides the mouse cursor
{
//Transparent 16 x 16 pixel cursor image.
BufferedImage cursorbackgroundImgage = new BufferedImage(16, 16, BufferedImage.TYPE_INT_ARGB);

// Create a new blank cursor.
Cursor blankCursor = Toolkit.getDefaultToolkit().createCustomCursor(
cursorbackgroundImgage, new Point(0, 0), "Blank Cursor");

// Set the blank cursor to the JPanel.
this.setCursor(blankCursor);
}

@Override
public void actionPerformed(ActionEvent actionEvent) // Without the method and the repaint() the mouse listener will not work
{
repaint();
}

public class ProjectileThread extends Thread
{
private int projectileX;
private int projectileY;

public ProjectileThread(int playerX,int playerY)
{
this.projectileX = playerX + player.getWidth(null);
this.projectileY = playerY + player.getHeight(null) / 2 - 28;
}
@Override
public void run()
{
try
{
while (projectileX < backgroundImage.getWidth(null) - projectileImage.getWidth(null))
{
projectileX += 2;
Thread.sleep(10);
repaint(); // Goes to paintComponent() method
}
projectiles.remove(this); // Remove the thread from the list
}
catch (InterruptedException e)
{
e.printStackTrace();
}
catch (Exception e)
{
e.printStackTrace();
}
}

public int getX()
{
return this.projectileX;
}

public int getY()
{
return this.projectileY;
}
}

public static void main(String[] args)
{
JFrame frame = new JFrame("A Game by me");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setExtendedState(JFrame.MAXIMIZED_BOTH); // Making the frame take a full screen

ImageIcon backgroundImageIcon = new ImageIcon("space_background_2.jpg");
Image backgroundImgage = backgroundImageIcon.getImage();
ImageIcon playerImageIcon = new ImageIcon("spaceship_1.png");
Image playerImage = playerImageIcon.getImage();
ImageIcon projectileIcon = new ImageIcon("spaceship_projectile_1.png");
Image projectileImage = projectileIcon.getImage();

frame.add(new MyJPanel(backgroundImgage,playerImage,projectileImage));
frame.setVisible(true);

while (gameLoop)
{

}
}
} // End of MyJPanel


Related Topics



Leave a reply



Submit