问题
I'm quite new to java. I need to animate two images on a java game. It's meant to be a spaceship game allowing two users to control the objects, using a keyboard. I've partially implemented this, however I cannot understand how to allow for two keyboard controls, and also the one object that is moving via keyboard input is flickering a lot.
public class MainFrame extends JFrame implements KeyListener {
MainPanel mPanel;
MainPanel secondss;
MainPanel thirdss;
int speed = 5;
//ss facing north
int direction = 0;
MainFrame() {
setTitle("spaceship Game");
mPanel = new MainPanel("C:/img");
secondss = new MainPanel("C:/img");
setSize(1024, 768);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(mPanel); // add MainPanel JPanel to JFrame
setVisible(true); // show class
add(secondSs);
add(thirdSs);
seconds.currentSs.setX(400);
secondSS.currentSs.setY(100);
}
public void actionPerformed( ActionEvent e )
{
if( e.getSource() == mPanel)
{
}
}
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == e.VK_LEFT) {
int x = mPanel.currentSs.getX() - speed;
mPanel.currentSs.setX(x);
}
if (e.getKeyCode() == e.VK_RIGHT) {
int x = mPanel.currentSs.getX() + speed;
mPanel.currentSs.setX(x);
}
if (e.getKeyCode() == e.VK_DOWN) {
int y = mPanel.currentSs.getY() + speed;
mPanel.currentSs.setY(y);
}
if (e.getKeyCode() == e.VK_UP) {
int y = mPanel.currentSs.getY() - speed;
mPanel.currentSs.setY(y);
}
//change image direction
mPanel.frame = direction;
}
public static void main(String[] args) {
MainFrame mainFrame = new MainFrame();
mainFrame.addKeyListener(mainFrame);
}
If someone could provide help or if not point me in the right direction I would be grateful.
回答1:
JFrame isn't focusable for KeyEvents, then by default never to react to KeyEvents
setVisible(true); should be last code line, after all JComponents are added to JFrame,
for why reason is there public void actionPerformed( ActionEvent e ), must generating excpetion form compilier
create a JFrame as local variable
put JPanel into JFrame
override getPreferredSize for JPanel, instesad of setSize for JFrame
then call pack() and setVisble(true)
put images to the Java package
put Images to JLabel
set NullLayout to JPanel (otherwise animations isn't possible)
add KeyBindings to JPanel, override desired/required KeyEvents
- there is another way by using Custom painting, by override paintComponent for JPanel, for KeyEvents stays here KeyBindings as better listener in compare with KeyListener
回答2:
It's meant to be a spaceship game allowing two users to control the objects, using a keyboard
Don't use a KeyListener. Swing was designed to be used with Key Bindings.
See Motion Using the Keyboard for more information and examples.
The KeyboardAnimation example demonstrates how two users can control individual images.
回答3:
Well, there's a lot you should change here:
- Graphics in games is seldom done using components. Remember that components carry a lot of weight with them (e.g. UI delegate, listeners, peer, etc.). What you should do is to create a single custom component which will act as a game board. This component's paint methods will paint to images of spaceships. This will also get rid of the flickering (invoke
setDoubleBuffered(true)on that component) - The location of the ships should be changed independently of the painting, i.e. the location should be calculated and kept in member variables, and the painting should happen according to swing's painting manager's will. However, you can still enforce more rigorous painting by using
paintImmediately(...)to paint the images of the ships whenever they move - There's no way (at least not that I'm aware of) to handle two keyboards or anything of the kind. If you want 2 users playing at once, they should use the same keyboard, and you should have 2 separate (and hopefully distant) sets of keys, one for each player. Just like in the old days :-)
回答4:
From how I understand the question, the players need to interact with the game using different sets of keys depending on you are player 1 or player 2. If that's the case, implement the KeyListener and override the following methods just like what the following codes does:
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W)
playerOne_up = true;
if (e.getKeyCode() == KeyEvent.VK_S)
playerOne_down = true;
if (e.getKeyCode() == KeyEvent.VK_UP)
playerTwo_up = true;
if (e.getKeyCode() == KeyEvent.VK_DOWN)
playerTwo_down = true;
}
@Override
public void keyReleased(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_W)
playerOne_up = false;
if (e.getKeyCode() == KeyEvent.VK_S)
playerOne_down = false;
if (e.getKeyCode() == KeyEvent.VK_UP)
playerTwo_up = false;
if (e.getKeyCode() == KeyEvent.VK_DOWN)
playerTwo_down = false;
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
if (!isStarted()) {
doInitializations();
setStarted(true);
}
}
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
if (isStarted()) {
setStarted(false);
} else {
frame.dispose();
}
}
}
However, in my example, only movements up and down are allowed (pingpong game). Player one uses W for up and S for down while Player two uses UP arrow key and DOWN arrow key. The booleans playerOne_up, playerOne_down, etc are the switches for other methods to see if the object needs to be moved on which direction.
来源:https://stackoverflow.com/questions/22595306/animating-two-images-in-java