我正在为Java游戏构建基于swing的GUI。游戏本质上是一个由自定义data Term a
= Var a
| Star -- or alternatively, "Type", or "*"
| Lam (Type a) (Scope () Term a)
| Pi (Type a) (Scope () Term a)
| App (Type a) (Term a)
deriving (Show, Eq, Functor)
-- boilerplate omitted (Monad, Applicative, Eq1, Show1 instances)
-- reduce to normal form
rnf :: Term a -> Term a
rnf = ...
-- Note: IIRC "Simply easy" and Augustsson's post reduces to whnf
-- when type checking. I use here plain normal form, because it
-- simplifies the presentation a bit and it also works fine.
-- We rely on Bound's alpha equality here, and also on the fact
-- that we keep types in normal form, so there's no need for
-- additional reduction.
check :: Eq a => Cxt a -> Type a -> Term a -> TC ()
check cxt want t = do
have <- infer cxt t
when (want /= have) $ Left "type mismatch"
infer :: Eq a => Cxt a -> Term a -> TC (Type a)
infer cxt = \case
Var a -> cxt a
Star -> pure Star -- "Type : Type" system for simplicity
Lam ty t -> do
check cxt Star ty
let ty' = rnf ty
Pi ty' . toScope <$> infer (consCxt ty' cxt) (fromScope t)
Pi ty t -> do
check cxt Star ty
check (consCxt (rnf ty) cxt) Star (fromScope t)
pure Star
App f x ->
infer cxt f >>= \case
Pi ty t -> do
check cxt ty x
pure $ rnf (instantiate1 x t)
_ -> Left "can't apply non-function"
对象组成的4x4网格,实质上是一个自定义的JButton。以下代码
Cell
package gamePack;
import java.awt.Graphics;
import java.util.ArrayList;
import javax.swing.JButton;
public class Cell extends JButton {
int co_x = 0;
int co_y = 0;
ArrayList<Players> current = new ArrayList <Players>();
}
允许我存储不同ArrayList
的对象。所有Players
都继承自同一个类,因此我基本上重新绘制单元格并根据ArrayList中的对象类型添加图标。每个单元格都有一个ArrayList,因为每个单元格可以有多个Players
。
Players
单击“移动”按钮时游戏会发生变化。在这里,当我点击start时,我正在添加玩家的精灵,并且会调用重绘方法。下面的重绘方法:
GUI initialization:
package gamePack;
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.border.Border;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class StarFight {
public JFrame frame;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
StarFight window = new StarFight();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the application.
*/
public StarFight() {
initialize();
}
/**
* Initialize the contents of the frame.
*/
private void initialize() {
frame = new JFrame();
frame.setVisible(true);
frame.setBounds(100, 100, 487, 349);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
final JPanel gamePanel = new JPanel();
gamePanel.setBounds(0, 0, 365, 310);
frame.getContentPane().add(gamePanel);
int i = 4;
int j = 4;
final Cell[][] panelHolder = new Cell[i][j];
gamePanel.setLayout(new GridLayout(4, 4, 0, 0));
//91.25 x 77.5 rectangles
Border border = BorderFactory.createLineBorder(Color.white);
for(int m = 0; m < i; m++) {
for(int n = 0; n < j; n++) {
panelHolder[m][n] = new Cell();
panelHolder[m][n].co_x = m;
panelHolder[m][n].co_y= n;
panelHolder[m][n].setBackground(Color.black);
panelHolder[m][n].setEnabled(false);
panelHolder[m][n].setBorder(border);
gamePanel.add(panelHolder[m][n]);
}
}
JPanel controlPanel = new JPanel();
controlPanel.setBounds(375, 0, 86, 310);
frame.getContentPane().add(controlPanel);
controlPanel.setLayout(null);
final JButton Move = new JButton("Move");
Move.setEnabled(false);
Move.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
panelHolder[0][0].current.clear();
BattleCruiser q = new BattleCruiser();
panelHolder[3][2].current.add(q);
Redraw.draw(gamePanel, panelHolder);
}
});
Move.setBounds(1, 82, 84, 65);
controlPanel.add(Move);
final JButton Undo = new JButton("Undo");
Undo.setEnabled(false);
Undo.setBounds(1, 158, 84, 65);
controlPanel.add(Undo);
JButton Exit = new JButton("Exit");
Exit.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
System.exit(0);
}
});
Exit.setBounds(1, 234, 84, 65);
controlPanel.add(Exit);
final JButton btnStart = new JButton("Start");
btnStart.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent arg0) {
Move.setEnabled(true);
Undo.setEnabled(true);
btnStart.setEnabled(false);
PlayChar p = new PlayChar();
BattleCruiser q = new BattleCruiser();
BattleStar s = new BattleStar();
BattleShooter sh = new BattleShooter();
panelHolder[0][0].current.add(p);
Redraw.draw(gamePanel, panelHolder);
}
});
btnStart.setBounds(1, 6, 84, 65);
controlPanel.add(btnStart);
}
}
重绘方法检查每个单元格中的ArrayList,然后适当地添加一个图标。目前,当我单击Move时,它应该删除所有JButton,然后使用适当的sprite将它们添加回来。
问题在于,当我这样做时,即使在添加另一个精灵之前使用package gamePack;
import java.awt.Color;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.Border;
public class Redraw {
public static void draw(JPanel gamePanel, Cell[][] panelHolder ){
gamePanel.setBounds(0, 0, 365, 310);
int i = 4;
int j = 4;
gamePanel.setLayout(new GridLayout(4, 4, 0, 0));
//91.25 x 77.5 rectangles
Border border = BorderFactory.createLineBorder(Color.white);
for(int m = 0; m < i; m++) {
for(int n = 0; n < j; n++) {
panelHolder[m][n].setBackground(Color.black);
panelHolder[m][n].setEnabled(false);
panelHolder[m][n].setBorder(border);
panelHolder[m][n].setIcon(null);
for(Players p: panelHolder[m][n].current){
if(p instanceof PlayChar){
String arg = "Player.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
} else if (p instanceof BattleStar) {
String arg = "BattleStar.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
} else if (p instanceof BattleCruiser){
String arg = "BattleCruiser.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
} else if (p instanceof BattleShooter){
String arg = "BattleShooter.png";
ImageIcon icon = new ImageIcon(arg);
JLabel label = new JLabel();
label.setIcon(icon);
panelHolder[m][n].add(label);
}
}
}
}
gamePanel.revalidate();
gamePanel.repaint();
}
}
,仍会绘制0,0位置的精灵。单步执行代码显示current.clear()
对象的if语句未被调用,因此我必须假设它与重绘方法有关。我做错了什么吗?
编辑:基于反馈,我现在已经改变它,所以重绘功能不会取代JButton,而是改变它们的属性。我还添加了它,以便在设置任何图标之前将Icon设置为null,以确保将其删除。然而,同样的问题仍在发生
答案 0 :(得分:0)
发现问题!感谢@faljbour
你有没有理由使用JLabel并调用add来设置JButton上的图标而不是直接使用.setIcon(icon)?
这就是问题所在。该图像被设置为JLabel,然后被添加,因此删除Icon没有任何效果。
代码应为:
String arg = "Player.png";
ImageIcon icon = new ImageIcon(arg);
panelHolder[m][n].setIcon(icon);