这是我正在做的同一个游戏,我遇到了一个我无法理解的问题。我正在使用Key Bindings移动我的精灵,它的工作效果很好!但由于它是一个蛇游戏,我需要精灵在不停止的情况下继续前进并改变方向并在玩家键入一个键后继续移动。我知道KeyListener可以实现,但我真的不想完全改变我的程序。我只需要知道需要更改哪些代码。
最重要的是,我还在为蛇体的x和y坐标制作两个阵列,这样正方形将跟在头后面,但我无法让它画出来。以及如何显示分数的整数。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
import java.util.ArrayList;
public class Snake2 extends JFrame {
/* Sprite: snake head co-ordinates */
int x = 400;
int y = 450;
int width = 10;
int height = 10;
/* Sprite: snake body */
int length = 0;
ArrayList <Integer> bodyX = new ArrayList <Integer>();
ArrayList <Integer> bodyY = new ArrayList <Integer>();
/* Score */
int point = 0;
/* Sprite: mouse co-ordinates */
Random rand = new Random();
int addx = (rand.nextInt(10))*10;
int addy = (rand.nextInt(10))*10;
int mx = ((rand.nextInt(5)+1)*100) + addx;
int my = ((rand.nextInt(6)+2)*100) + addy;
DrawPanel drawPanel = new DrawPanel();
public Snake2() {
addMouseListener(new MouseListener());
System.out.print(mx + " " + my);
/* move snake up */
Action upAction = new AbstractAction(){
public void actionPerformed(ActionEvent e) {
y -=10;
if (y >= my && y <= my+9 && x >= mx && x <= mx+9)
{
addx = (rand.nextInt(10))*10;
addy = (rand.nextInt(10))*10;
mx = ((rand.nextInt(5)+1)*100) + addx;
my = ((rand.nextInt(6)+1)*100) + addy;
point += 100;
length++;
bodyY.add(0, y);
}
if (y <99)
{
new GameOver();
dispose();
}
drawPanel.repaint();
}
};
/* move snake down */
Action downAction = new AbstractAction(){
public void actionPerformed(ActionEvent e) {
y +=10;
if (y >= my && y <= my+9 && x >= mx && x <= mx+9)
{
addx = (rand.nextInt(10))*10;
addy = (rand.nextInt(10))*10;
mx = ((rand.nextInt(5)+1)*100) + addx;
my = ((rand.nextInt(6)+1)*100) + addy;
point += 100;
length++;
bodyY.add(0, y);
}
if (y > 799)
{
new GameOver();
dispose();
}
drawPanel.repaint();
}
};
/* move snake left */
Action leftAction = new AbstractAction(){
public void actionPerformed(ActionEvent e) {
x -=10;
if (x >= mx && x <= mx+9 && y >= my && y <= my+9)
{
addx = (rand.nextInt(10))*10;
addy = (rand.nextInt(10))*10;
mx = ((rand.nextInt(5)+1)*100) + addx;
my = ((rand.nextInt(6)+1)*100) + addy;
point += 100;
length++;
bodyX.add(0, x);
}
if (x <99)
{
new GameOver();
dispose();
}
drawPanel.repaint();
}
};
/* move snake right */
Action rightAction = new AbstractAction(){
public void actionPerformed(ActionEvent e) {
x +=10;
if (x >= mx && x <= mx+9 && y >= my && y <= my+9)
{
addx = (rand.nextInt(10))*10;
addy = (rand.nextInt(10))*10;
mx = ((rand.nextInt(5)+1)*100) + addx;
my = ((rand.nextInt(6)+1)*100) + addy;
point += 100;
length++;
bodyX.add(0, x);
}
if (x > 699)
{
new GameOver();
dispose();
}
drawPanel.repaint();
}
};
InputMap inputMap = drawPanel.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = drawPanel.getActionMap();
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
actionMap.put("rightAction", rightAction);
inputMap.put(KeyStroke.getKeyStroke("LEFT"), "leftAction");
actionMap.put("leftAction", leftAction);
inputMap.put(KeyStroke.getKeyStroke("DOWN"), "downAction");
actionMap.put("downAction", downAction);
inputMap.put(KeyStroke.getKeyStroke("UP"), "upAction");
actionMap.put("upAction", upAction);
add(drawPanel);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}//Snake2()
private class GameOver extends JFrame implements ActionListener{
JLabel answer = new JLabel("");
JPanel pane = new JPanel(); // create pane object
JButton pressme = new JButton("Quit");
JButton replay = new JButton("Replay?");
GameOver() // the constructor
{
super("Game Over"); setBounds(100,100,300,200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane(); // inherit main frame
con.add(pane); pressme.setMnemonic('Q'); // associate hotkey
pressme.addActionListener(this); // register button listener
replay.addActionListener(this);
pane.add(answer); pane.add(pressme); pane.add(replay); pressme.requestFocus();
answer.setText("You Lose");
setVisible(true); // make frame visible
}//GameOver()
// here is the basic event handler
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();
if (source == pressme)
System.exit(0);
if (source == replay)
{
dispose();
EventQueue.invokeLater(new Runnable(){
public void run(){
new Snake2();
}
});
}
}//actionPreformed
}//GameOver
private class DrawPanel extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Font ith = new Font("Ithornît", Font.BOLD, 78);
/* Background: Snake */
g.setColor(Color.darkGray);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.gray);
g.fillRect(100,100,600,700);
g.setColor(Color.white);
g.drawRect(99,99,601,701);
g.drawString("Quit",102,86);
g.drawRect(100,70,30,20);
g.drawString("Score: ", 602, 86);
g.setFont(ith);
g.drawString("SNAKE",350,60);
/* Sprite: Mouse */
g.setColor(Color.black);
g.fillRect(mx, my, width, height);
//System.out.print(mx + " " + my);
/* Sprite: Snake Body */
if (length != 0){
for(int i = 0; i >= length; i++)
{
g.setColor(Color.darkGray);
g.fillRect(bodyX.get(i), bodyY.get(i), width, height);
}
}
/* Sprite: Snake head */
g.setColor(Color.white);
g.fillRect(x, y, width, height);
}//Paint Component
public Dimension getPreferredSize() {
return new Dimension(800, 850);
}//Dimension
}//DrawPanel
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable(){
public void run(){
new Snake2();
}
});
}// main
}//Snake Class
/* Tracks where mouse is clicked */
class MouseListener extends MouseAdapter {
public void mouseReleased(MouseEvent me) {
if (me.getX() >= 101 && me.getX() <= 131 && me.getY() >= 94 && me.getY() <= 115){
System.exit(0);
}
String str="Mouse Released at "+me.getX()+","+me.getY();
System.out.println(str);
}
}//MouseAdapter
答案 0 :(得分:0)
“但是因为它是一个蛇游戏我需要精灵继续前进而不停止”
您需要使用javax.swing.Timer
。基本构造函数就像这样
Timer(int delay, ActionListener listener) // delay is in milliseconds
基本实现将是这样的
Timer timer = new Timer(100, new ActionListener(){
public void actionPerformed(ActionEvent e) {
// do something
}
});
timer.start();
基本上,定时器的作用是每隔几毫秒触发ActionEvent
。这就是你用swing做动画的方法。因此,如果没有按任何键,精灵将自动移动。它的工作方式与按钮非常相似。按下按钮时会触发事件。但是在计时器的情况下,计时器是触发事件的计时器。您可以指定所需的任何delay
。您甚至想要在达到某个级别时动态更改持续时间。 timer.setDelay(someInt)
更新
我对您当前的代码进行了很少的更改。我做了几乎我在下面评论中所说的内容
好的,所以我想到了,我会做这样的事情:有一个方向变量。对于动作,您应该做的就是改变方向。在计时器actionPerformed中,你应该去的所有逻辑。检查方向。如果if等于“left”,则继续向左移动,就像按下按键一样。等等
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.util.Random;
import java.util.ArrayList;
public class Snake2 extends JFrame {
String direction = "right";
//String duration =
/* Sprite: snake head co-ordinates */
int x = 400;
int y = 450;
int width = 10;
int height = 10;
/* Sprite: snake body */
int length = 0;
ArrayList<Integer> bodyX = new ArrayList<Integer>();
ArrayList<Integer> bodyY = new ArrayList<Integer>();
/* Score */
int point = 0;
/* Sprite: mouse co-ordinates */
Random rand = new Random();
int addx = (rand.nextInt(10)) * 10;
int addy = (rand.nextInt(10)) * 10;
int mx = ((rand.nextInt(5) + 1) * 100) + addx;
int my = ((rand.nextInt(6) + 2) * 100) + addy;
DrawPanel drawPanel = new DrawPanel();
Timer timer;
public Snake2() {
addMouseListener(new MouseListener());
timer = new Timer(50, new TimerListener()); ////////////// <<<<<<<<<<<<<<<<<< TIMER
timer.start();
System.out.print(mx + " " + my);
/* move snake up */
Action upAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
direction = "up"; ////////////// <<<<<<<<<<<<<<<<<< direction only change
}
};
/* move snake down */
Action downAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
direction = "down";
}
};
/* move snake left */
Action leftAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
direction = "left";
}
};
/* move snake right */
Action rightAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
direction = "right";
}
};
InputMap inputMap = drawPanel
.getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = drawPanel.getActionMap();
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
actionMap.put("rightAction", rightAction);
inputMap.put(KeyStroke.getKeyStroke("LEFT"), "leftAction");
actionMap.put("leftAction", leftAction);
inputMap.put(KeyStroke.getKeyStroke("DOWN"), "downAction");
actionMap.put("downAction", downAction);
inputMap.put(KeyStroke.getKeyStroke("UP"), "upAction");
actionMap.put("upAction", upAction);
add(drawPanel);
pack();
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}// Snake2()
private class TimerListener implements ActionListener {
public void actionPerformed(ActionEvent e) { /////////////////// <<<<<<<<<<<<<< All logic here
if ("right".equals(direction)) {
x += 10;
if (x >= mx && x <= mx + 9 && y >= my && y <= my + 9) {
addx = (rand.nextInt(10)) * 10;
addy = (rand.nextInt(10)) * 10;
mx = ((rand.nextInt(5) + 1) * 100) + addx;
my = ((rand.nextInt(6) + 1) * 100) + addy;
point += 100;
length++;
bodyX.add(0, x);
}
if (x > 699) {
new GameOver();
dispose();
}
} else if ("left".equals(direction)) {
x -= 10;
if (x >= mx && x <= mx + 9 && y >= my && y <= my + 9) {
addx = (rand.nextInt(10)) * 10;
addy = (rand.nextInt(10)) * 10;
mx = ((rand.nextInt(5) + 1) * 100) + addx;
my = ((rand.nextInt(6) + 1) * 100) + addy;
point += 100;
length++;
bodyX.add(0, x);
}
if (x < 99) {
new GameOver();
dispose();
}
} else if ("up".equals(direction)) {
y -= 10;
if (y >= my && y <= my + 9 && x >= mx && x <= mx + 9) {
addx = (rand.nextInt(10)) * 10;
addy = (rand.nextInt(10)) * 10;
mx = ((rand.nextInt(5) + 1) * 100) + addx;
my = ((rand.nextInt(6) + 1) * 100) + addy;
point += 100;
length++;
bodyY.add(0, y);
}
if (y < 99) {
new GameOver();
dispose();
}
} else if ("down".equals(direction)) {
y += 10;
if (y >= my && y <= my + 9 && x >= mx && x <= mx + 9) {
addx = (rand.nextInt(10)) * 10;
addy = (rand.nextInt(10)) * 10;
mx = ((rand.nextInt(5) + 1) * 100) + addx;
my = ((rand.nextInt(6) + 1) * 100) + addy;
point += 100;
length++;
bodyY.add(0, y);
}
if (y > 799) {
new GameOver();
dispose();
}
}
drawPanel.repaint();
}
}
private class GameOver extends JFrame implements ActionListener {
JLabel answer = new JLabel("");
JPanel pane = new JPanel(); // create pane object
JButton pressme = new JButton("Quit");
JButton replay = new JButton("Replay?");
GameOver() // the constructor
{
super("Game Over");
timer.stop(); ////////////////////// <<<<<<<<<< Stop TIMER
setBounds(100, 100, 300, 200);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container con = this.getContentPane(); // inherit main frame
con.add(pane);
pressme.setMnemonic('Q'); // associate hotkey
pressme.addActionListener(this); // register button listener
replay.addActionListener(this);
pane.add(answer);
pane.add(pressme);
pane.add(replay);
pressme.requestFocus();
answer.setText("You Lose");
setVisible(true); // make frame visible
}// GameOver()
// here is the basic event handler
public void actionPerformed(ActionEvent event) {
Object source = event.getSource();
if (source == pressme)
System.exit(0);
if (source == replay) {
dispose();
EventQueue.invokeLater(new Runnable() {
public void run() {
new Snake2();
}
});
}
}// actionPreformed
}// GameOver
private class DrawPanel extends JPanel {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Font ith = new Font("Ithornît", Font.BOLD, 78);
/* Background: Snake */
g.setColor(Color.darkGray);
g.fillRect(0, 0, getWidth(), getHeight());
g.setColor(Color.gray);
g.fillRect(100, 100, 600, 700);
g.setColor(Color.white);
g.drawRect(99, 99, 601, 701);
g.drawString("Quit", 102, 86);
g.drawRect(100, 70, 30, 20);
g.drawString("Score: ", 602, 86);
g.setFont(ith);
g.drawString("SNAKE", 350, 60);
/* Sprite: Mouse */
g.setColor(Color.black);
g.fillRect(mx, my, width, height);
// System.out.print(mx + " " + my);
/* Sprite: Snake Body */
if (length != 0) {
for (int i = 0; i >= length; i++) {
g.setColor(Color.darkGray);
g.fillRect(bodyX.get(i), bodyY.get(i), width, height);
}
}
/* Sprite: Snake head */
g.setColor(Color.white);
g.fillRect(x, y, width, height);
}// Paint Component
public Dimension getPreferredSize() {
return new Dimension(800, 850);
}// Dimension
}// DrawPanel
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
new Snake2();
}
});
}// main
}// Snake Class
/* Tracks where mouse is clicked */
class MouseListener extends MouseAdapter {
public void mouseReleased(MouseEvent me) {
if (me.getX() >= 101 && me.getX() <= 131 && me.getY() >= 94
&& me.getY() <= 115) {
System.exit(0);
}
String str = "Mouse Released at " + me.getX() + "," + me.getY();
System.out.println(str);
}
}// MouseAdapter