以下是我正在研究的Simon Says计划。现在它只显示一个灰色框。我在keyListener中添加了以查看是否可以使弧点亮。我想显示一个flash动画序列。有人可以解释为什么这不起作用吗?
public class SimonShape extends JFrame implements KeyListener, ActionListener {
private JFrame f;
private JPanel p;
public static void main(String[] args) {
new SimonShape();
}
public SimonShape() {
f = new JFrame("Simon Says");
f.setSize(500, 500);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawStuff draw = new DrawStuff();
p = new JPanel();
p.setBackground(Color.GRAY);
p.setLayout(new BorderLayout());
draw.playSequence();
p.add(draw, BorderLayout.CENTER);
// initiates the sequence
f.add(p);
f.addKeyListener(this);
f.setLocationRelativeTo(null); // positions the frame in the middle of
// the screen
f.setVisible(true);
}
public class DrawStuff extends JComponent {
Color COLOR1;
Color COLOR2;
Color COLOR3;
Color COLOR4;
public void playSequence() {
ArrayList<Integer> Computer = new ArrayList<Integer>();
ArrayList<Integer> Player = new ArrayList<Integer>();
int compPick, compPick2, compPick3, compPick4;
Random gen = new Random();
compPick = gen.nextInt(4);
compPick2 = gen.nextInt(4);
compPick3 = gen.nextInt(4);
compPick4 = gen.nextInt(4);
Computer.add(compPick);
Computer.add(compPick4);
Computer.add(compPick2);
Computer.add(compPick3);
for (int i = 0; i < Computer.size(); i++) {
if (Computer.get(i) == 0) {
COLOR1 = Color.GREEN.brighter();
repaint();
} else if (Computer.get(i) == 1) {
COLOR2 = Color.BLUE.darker();
repaint();
} else if (Computer.get(i) == 2) {
COLOR3 = Color.RED.darker();
repaint();
} else if (Computer.get(i) == 3) {
COLOR4 = Color.YELLOW.brighter();
repaint();
}
}
}
}
public int flash = 0;
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
Graphics2D g3 = (Graphics2D) g;
Graphics2D g4 = (Graphics2D) g;
Graphics2D g5 = (Graphics2D) g;
// assume d == 145 && e == 90
if (flash == 1) {
g2.setPaint(Color.GREEN);
} else {
g2.setPaint(Color.GREEN.darker());
}
g2.fill(new Arc2D.Double(150, 150, 200, 200, 145, 90, Arc2D.PIE));
if (flash == 2) {
g3.setPaint(Color.BLUE);
} else {
g3.setPaint(Color.BLUE.darker());
}
g3.fill(new Arc2D.Double(150, 150, 200, 200, 235, 90, Arc2D.PIE));
if (flash == 3) {
g4.setPaint(Color.RED);
} else {
g4.setPaint(Color.RED.darker());
}
g4.fill(new Arc2D.Double(150, 150, 200, 200, 325, 90, Arc2D.PIE));
if (flash == 4) {
g5.setPaint(Color.YELLOW);
} else {
g4.setPaint(Color.YELLOW.darker());
}
g5.fill(new Arc2D.Double(150, 150, 200, 200, 55, 90, Arc2D.PIE));
}
public void keyPressed(KeyEvent e) {
int event = e.getKeyCode();
if (event == KeyEvent.VK_RIGHT) {
flash = 1;
}
if (event == KeyEvent.VK_DOWN) {
flash = 2;
}
if (event == KeyEvent.VK_LEFT) {
flash = 3;
}
if (event == KeyEvent.VK_UP) {
flash = 4;
}
}
@Override
public void keyTyped(KeyEvent e) {//not used
}
@Override
public void keyReleased(KeyEvent e) {//not used
}
@Override
public void actionPerformed(ActionEvent e) {//not used
}
}
答案 0 :(得分:0)
创建任何Swing GUI时,应始终使用model / view / controller pattern。此模式允许您将您的关注点分开,并一次关注GUI的一部分。
分而治之。
这是我创建的GUI。
我做的第一件事是为游戏创建一个模型。 GameModel类是一个普通的Java对象,它保存计算机序列和播放器序列。
public class GameModel {
private List<Integer> computerSequence;
private List<Integer> playerSequence;
private Random random;
public GameModel() {
this.computerSequence = new ArrayList<Integer>();
this.playerSequence = new ArrayList<Integer>();
this.random = new Random();
}
public void addToComputerSequence() {
computerSequence.add(Integer.valueOf(random.nextInt(4)));
}
public void clearComputerSequence() {
computerSequence.clear();
}
public List<Integer> getComputerSequence() {
return computerSequence;
}
public void clearPlayerSequence() {
playerSequence.clear();
}
public void addToPlayerSequence(int number) {
playerSequence.add(Integer.valueOf(number));
}
public boolean doSequencesMatch() {
if (computerSequence.size() == playerSequence.size()) {
for (int i = 0; i < computerSequence.size(); i++) {
int computer = computerSequence.get(i);
int player = playerSequence.get(i);
if (computer != player) {
return false;
}
}
return true;
}
return false;
}
}
模型类允许我们添加到计算机序列,添加到播放器序列,并确定计算机和播放器序列是否匹配。
接下来,我们需要一个模型类来保存圆的4个切片。 ArcModel类是另一个包含切片的普通Java对象。
public class ArcModel {
private final int closureType;
private final double startingAngle;
private final double extent;
private Color color;
private final Color originalColor;
private final Rectangle rectangle;
public ArcModel(Color color, Rectangle rectangle, double startingAngle,
double extent, int closureType) {
this.color = color;
this.originalColor = color;
this.rectangle = rectangle;
this.startingAngle = startingAngle;
this.extent = extent;
this.closureType = closureType;
}
public int getClosureType() {
return closureType;
}
public double getStartingAngle() {
return startingAngle;
}
public double getExtent() {
return extent;
}
public Rectangle getRectangle() {
return rectangle;
}
public Color getColor() {
return color;
}
public void brighterColor() {
this.color = Color.WHITE;
}
public void darkerColor() {
this.color = originalColor;
}
}
除了getter和setter之外,我们还有一种提亮颜色的方法和一种使颜色变暗的方法。我将亮色设置为白色,使其更容易看清。
现在我们已经创建了模型类,让我们看一下视图类。第一个视图类是DrawingPanel类。
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 70146219705119575L;
private List<ArcModel> segments;
public DrawingPanel() {
this.segments = new ArrayList<ArcModel>();
int margin = 50;
int diameter = 300;
Rectangle r = new Rectangle(margin, margin, diameter, diameter);
segments.add(new ArcModel(Color.GREEN, r, 180, 90, Arc2D.PIE));
segments.add(new ArcModel(Color.BLUE, r, 270, 90, Arc2D.PIE));
segments.add(new ArcModel(Color.RED, r, 360, 90, Arc2D.PIE));
segments.add(new ArcModel(Color.YELLOW, r, 90, 90, Arc2D.PIE));
int width = diameter + margin + margin;
this.setPreferredSize(new Dimension(width, width));
}
public void brighterArcModelColor(int index) {
segments.get(index).brighterColor();
repaint();
}
public void darkerArcModelColor(int index) {
segments.get(index).darkerColor();
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
for (ArcModel arcModel : segments) {
g2d.setPaint(arcModel.getColor());
Rectangle r = arcModel.getRectangle();
g2d.fill(new Arc2D.Double(r.getX(), r.getY(), r.getWidth(), r
.getHeight(), arcModel.getStartingAngle(), arcModel
.getExtent(), arcModel.getClosureType()));
}
}
}
在这里,我们创建一个ArcModel段列表。我们根据要用段创建的圆的边距和直径来设置绘图面板的大小。
我们有两种方法,一种用于增亮一段颜色,另一种用于使一段颜色变暗。
我们在paintComponent方法中进行绘制。由于我们创建了ArcModel类,因此实际绘图非常简单。 paintComponent方法除了绘制圆的饼图片外什么都不做。
接下来,我们来看看SimonShape的主要课程。该类创建游戏模型并创建GUI。
public class SimonShape implements Runnable {
private GameModel gameModel;
private JFrame frame;
public static void main(String[] args) {
SwingUtilities.invokeLater(new SimonShape());
}
public SimonShape() {
this.gameModel = new GameModel();
}
@Override
public void run() {
frame = new JFrame("Simon Says");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
DrawingPanel drawingPanel = new DrawingPanel();
frame.add(drawingPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
GameRunnable runnable = new GameRunnable(drawingPanel, gameModel);
new Thread(runnable).start();
}
}
run方法的最后两行创建动画。
控制器类是GameRunnable类。我编写了足够的代码让计算机选择10个随机段,并显示段的序列。我将剩下的游戏代码留给你了。它将进入GameRunnable类。
public class GameRunnable implements Runnable {
private volatile boolean running;
private DrawingPanel drawingPanel;
private GameModel gameModel;
public GameRunnable(DrawingPanel drawingPanel, GameModel gameModel) {
this.drawingPanel = drawingPanel;
this.gameModel = gameModel;
}
@Override
public void run() {
running = true;
while (running && gameModel.getComputerSequence().size() < 10) {
generateComputerSequence();
sleep(1800L);
}
}
private void generateComputerSequence() {
gameModel.addToComputerSequence();
for (Integer index : gameModel.getComputerSequence()) {
drawingPanel.brighterArcModelColor(index);
sleep(1000L);
drawingPanel.darkerArcModelColor(index);
sleep(200L);
}
}
private void sleep(long duration) {
try {
Thread.sleep(duration);
} catch (InterruptedException e) {
}
}
public synchronized void setRunning(boolean running) {
this.running = running;
}
}
记住,分而治之。祝其他代码好运。