我正在为课堂制作一个游戏,我制作了一个面板来显示某些分数,但是,当使用类的更新方法(即 setext("" newscore) )对其进行更新时,它将框架重置为默认位置的开头,在用方法移动它们之前。如果我只是将 jlabel 添加到 mainpanel 并尝试使用按钮输入更新它,也会发生这种情况。我想知道为什么会发生这种情况,因为即使您按下正确的按钮,它似乎仍处于循环状态。 主要代码
package ddr.view;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import ddr.ScreenObserver;
import ddr.gameObserver;
import ddr.model.Game;
public class GameplayGUI implements KeyListener, gameObserver { //UI during gameplay
JFrame frame2;
ImagePanel mainPanel;
JPanel arrowsPanel;
JPanel space1;
JPanel space2;
JPanel space3;
JPanel space4;
JLabel right;
ImageIcon rights;
JLabel left;
ImageIcon lefts;
JLabel up;
ImageIcon ups;
JLabel down;
ImageIcon downs;
JLabel back;
ImageIcon backs;
JPanel gridArrows;
JPanel spawnpoint;
ImageIcon leftIcon;
ImageIcon downIcon;
ImageIcon upIcon;
ImageIcon rightIcon;
JLabel leftMove;
JLabel downMove;
JLabel upMove;
JLabel rightMove;
int bottom_row = 450;
scores_panel score;
Game gamerGame;
ScreenObserver controller;
int scorex;
int scorey;
private Timer leftTimer, downTimer, upTimer, rightTimer;
public GameplayGUI(ScreenObserver screen, Game game)
{ //javaswing constructor
frame2 = new JFrame("Gameplay");
frame2.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
backs = new ImageIcon(getClass().getClassLoader().getResource("game_background.png"));
mainPanel = new ImagePanel(backs);
mainPanel.setLayout(new FlowLayout(FlowLayout.CENTER,30,0));
mainPanel.setPreferredSize(new Dimension(700,500));
frame2.addKeyListener(this);
spawnpoint = new JPanel(new FlowLayout(FlowLayout.CENTER,30,0));
spawnpoint.setOpaque(false);
int stepSize =2;
//creating moving arrows and adding them to main panel
leftIcon = new ImageIcon(getClass().getClassLoader().getResource("left.gif"));
leftMove = new JLabel(leftIcon);
downIcon = new ImageIcon(getClass().getClassLoader().getResource("down.gif"));
downMove = new JLabel(downIcon);
upIcon = new ImageIcon(getClass().getClassLoader().getResource("up.gif"));
upMove = new JLabel(upIcon);
rightIcon = new ImageIcon(getClass().getClassLoader().getResource("right.gif"));
rightMove = new JLabel(rightIcon);
mainPanel.add(leftMove);
mainPanel.add(downMove);
mainPanel.add(upMove);
mainPanel.add(rightMove);
score = new scores_panel();
mainPanel.add(score);
//making the arrow receptors panel and adding it to a grid
arrowsPanel = new JPanel(new FlowLayout(FlowLayout.CENTER,30,0));
arrowsPanel.setPreferredSize(new Dimension(700,100));
arrowsPanel.setBackground(Color.gray);
arrowsPanel.setOpaque(false);
space1 = new JPanel();
space2 = new JPanel();
space3 = new JPanel();
space4 = new JPanel();
space1.setPreferredSize(new Dimension(233,135));
space2.setPreferredSize(new Dimension(233,135));
space1.setOpaque(false);
space2.setOpaque(false);
gridArrows = new JPanel(new GridLayout(5, 1));
gridArrows.setOpaque(false);
gridArrows.add(space1);
gridArrows.add(space2);
gridArrows.add(arrowsPanel);
mainPanel.add(gridArrows);
frame2.add(mainPanel);
lefts = new ImageIcon(getClass().getClassLoader().getResource("leftarrow.png"));
left = new JLabel(lefts);
arrowsPanel.add(left);
downs = new ImageIcon(getClass().getClassLoader().getResource("downarrow.png"));
down = new JLabel(downs);
arrowsPanel.add(down);
ups = new ImageIcon(getClass().getClassLoader().getResource("uparrow.png"));
up = new JLabel(ups);
arrowsPanel.add(up);
rights = new ImageIcon(getClass().getClassLoader().getResource("rightarrow.png"));
right = new JLabel(rights);
arrowsPanel.add(right);
frame2.pack();
frame2.setVisible(true);
frame2.setResizable(false);
leftTimer = new Timer(20, new ActionListener() {
public void actionPerformed(ActionEvent e) {
leftMove.setLocation(leftMove.getX(), leftMove.getY() + stepSize);
if (leftMove.getY() > 460){
System.out.println("booo");
}
}
});
downTimer = new Timer(40, new ActionListener() {
public void actionPerformed(ActionEvent e) {
downMove.setLocation(downMove.getX(), downMove.getY() + stepSize);
}
});
upTimer = new Timer(60, new ActionListener() {
public void actionPerformed(ActionEvent e) {
upMove.setLocation(upMove.getX(), upMove.getY() + stepSize);
}
});
rightTimer = new Timer(80, new ActionListener() {
public void actionPerformed(ActionEvent e) {
rightMove.setLocation(rightMove.getX(), rightMove.getY() + stepSize);
}});
rightTimer.start();
leftTimer.start();
upTimer.start();
downTimer.start();
gamerGame = game;
controller = screen;
}
public void disable()
{
frame2.setVisible(false);
frame2.setEnabled(false);
leftTimer.stop();
downTimer.stop();
upTimer.stop();
rightTimer.stop();
}
public void enable()
{
frame2.setVisible(true);
frame2.setEnabled(true);
rightTimer.start();
leftTimer.start();
upTimer.start();
downTimer.start();
}
public void keyPressed(KeyEvent e)
{ // +420 immediatly goes to bottom arrows
int stepSize = 10;
//System.out.println("here");
if(e.getKeyCode()== KeyEvent.VK_RIGHT)
{
//System.out.println("right");
rightMove.setLocation(rightMove.getX(), rightMove.getY() + stepSize);
}
else if(e.getKeyCode()== KeyEvent.VK_LEFT)
{
//System.out.println("left");
leftMove.setLocation(leftMove.getX(), leftMove.getY() + stepSize);
if (leftMove.getY() > 400 && leftMove.getY() < 450) {
System.out.println("aahhhhh");
controller.press(1);
}
}
else if(e.getKeyCode()== KeyEvent.VK_UP)
{
//System.out.println("up");
upMove.setLocation(upMove.getX(), upMove.getY() + stepSize);
}
else if(e.getKeyCode()== KeyEvent.VK_DOWN)
{
//System.out.println("down");
downMove.setLocation(downMove.getX(), downMove.getY() + stepSize);
}
}
public void keyReleased(KeyEvent e) {
}
public void keyTyped(KeyEvent e) {
}
public void set_start(){
leftMove.setLocation(left.getX(),-50);
rightMove.setLocation(right.getX(),-50);
upMove.setLocation(up.getX(),-50);
downMove.setLocation(down.getX(),-50);
score.setLocation(downMove.getX()+50,200);
scorex = score.getX();
scorey = score.getY();
}
@Override
public void update(){
score.score_update(gamerGame.getScore());
score.combo_update(gamerGame.getCurrentCombo());
score.setLocation(scorex, scorey);
score.setLocation(scorex, scorey);
}
}
分数_面板
package ddr.view;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
public class scores_panel extends JPanel {
JLabel comboJLabel;
JLabel scoreLabel;
JLabel missJLabel;
int score;
int combo;
public scores_panel() {
setLayout(new GridLayout(2, 1,0,5));
setPreferredSize(new Dimension(200, 150));
score = 0;
combo = 0;
scoreLabel = new JLabel(score +" score");
comboJLabel = new JLabel(combo + " combo");
Font scoreFont = new Font("Arial", Font.PLAIN, 20);
scoreLabel.setFont(scoreFont);
Font comboFont = new Font("Arial", Font.PLAIN, 50);
comboJLabel.setFont(comboFont);
add(scoreLabel);
add(comboJLabel);
setOpaque(false);
scoreLabel.setForeground(Color.WHITE);
scoreLabel.setOpaque(false);
comboJLabel.setForeground(Color.WHITE);
comboJLabel.setOpaque(false);
}
public void score_update(int num){
score = num;
scoreLabel.setText(score + " score");
this.revalidate();
this.repaint();
}
public void combo_update(int num){
combo = num;
comboJLabel.setText(combo + " combo");
this.revalidate();
this.repaint();
}
}
我尝试使用按钮来查看它是否只是标签,事实并非如此,我还为分数面板制作了一个新面板,只是为了检查它是否只是重置主面板中的内容
我想我得到了你想要做的事情。很久以前我在框架和面板中也遇到过这种情况。这可以通过 MVC 方法轻松完成。 由于您在父框架或面板中使用默认值实例化了所有内容,因此无论您在子框架中做什么,如果您从内部调用它,都不会更新。您需要使用 revalidate 和 repaint 方法更新父框架,而不是子框架。这就是它在框架和面板中的完成方式:在单独的测试场景中尝试。
parent.add(child); parent.setViewportView(child); parent.revalidate(); parent.repaint();