我刚刚写了一些代码让我的玩家在我的小迷宫游戏中移动,但没有任何反应。我的迷宫也没有像矩阵输入那样被绘制得正确。我不明白为什么这个代码错了...任何帮助都很好。 谢谢!
INSERT INTO Results (eventID,Result1,Result2,Result3,Result4,Result5)
SELECT eventID, [1] as Result1, [2] as Result2, [3] as Result3, [4] as Result4, [5] as Result5
FROM
(SELECT [inputTable].eventID,[inputTable].eQualType,[inputTable].Value1
FROM eventQData
WHERE eQualType IN (1, 2, 3, 4, 5) AND (Value2 > 0)
) AS inputTable
PIVOT
(MAX(Value1)
FOR [eQualType] IN ([1],[2],[3],[4],[5])
应该看起来像:
答案 0 :(得分:-1)
问题/建议:
paintComponent
方法,因为这会给你带来几个好处,包括默认使用动画的双缓冲。public int getX()
和public int getY()
方法,因为这些方法会覆盖将组件放在其容器中的关键方法。由于Main类甚至不应该扩展JPanel,因此对于您的代码来说这最终会成为一个问题,但将来它会破坏您的程序。修改
出于某种原因,这个问题引起了我的兴趣,所以我决定尽可能尝试使用M-V-C或模型 - 视图 - 控制器,看看我能想出什么。所以这里有一堆类的工作,从保存数据的文本文件开始。
GUI看起来像:
它必须与类文件位于同一位置,因为它是作为资源获取的,并且必须具有文件名"input.txt"
1111111111111111111111111111111111111111111
1000000010001000001000000010000000100000001
1010111010101010101111101011111010111111101
1010001010100010100000001010000010000010001
1011101010111110101111111010111111111010111
1000101010100000101000001000100010000010001
1011101011101011111011101111111010111110101
1010001000001010000010100000001010000010101
1010111111111010111110111111101011111011101
1010100000100010100000000000101000000000101
1110101111101110111110111011101011111110101
1000100000000010000010100010001000100010001
1011111111111111111011101010111111101011101
1000000000000000100010001010000000001010001
1011111111111011101110111011111111111010111
1000100010001000001010001000100000001010101
1110101011101111111010101110111110111010101
1000101010001000100000101000100000100010001
1011101010111010101111101011101110101111111
1000001010000010000000101000001000100010001
1111111011111110111111101111111011111010101
1000001010000010100010001000000010000010101
1011111010111011101010111011111110101110101
1010000010001010001010001000100000101010101
1010111111101010111011101111101111101011101
1000100000001010101010001000100010101000101
1011111011111010101010111010111010101011101
1010000010001000101010000010001010001000001
1010101110101111101011101111101011111010101
1010101000101000001000101000001000000010101
1011101011111010111110111011101111111110111
1000001000000010000000000010000000000010021
1111111111111111111111111111111111111111111
接下来,主程序,创建模型,视图和控制器的程序,将它们挂钩在一起,然后显示GUI:
import java.awt.BorderLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
/**
* link: http://stackoverflow.com/a/41418250/522444
*
* @author Pete
*
*/
@SuppressWarnings("serial")
public class Main2 extends JPanel {
private View mainPanel;
public Main2(MatrixModel matrixModel) {
mainPanel = new View(matrixModel);
new Controller(matrixModel, mainPanel);
setLayout(new BorderLayout());
add(mainPanel, BorderLayout.CENTER);
}
private static void createAndShowGui(MatrixModel model) {
Main2 mainPanel = new Main2(model);
JFrame frame = new JFrame("Main2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
final MatrixModel model = MatrixUtil.getInput(MatrixUtil.PATH_TO_RSC);
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui(model);
}
});
}
}
接下来是一个带有静态方法的实用程序类,用于将文本文件作为资源读取并将其转换为Model对象:
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;
public class MatrixUtil {
// again this text file must be in the jar file or the code base
// at the same location as the class / java files
public static final String PATH_TO_RSC = "input.txt";
public static MatrixModel getInput(String resourcePath) {
InputStream is = MatrixUtil.class.getResourceAsStream(resourcePath);
if (is == null) {
String text = "resourcePath is not found and not loading text: " + resourcePath;
throw new IllegalArgumentException(text);
}
return getInput(is);
}
public static MatrixModel getInput(InputStream is) {
MatrixModel model = null;
try (Scanner scan = new Scanner(is)) {
List<List<MatrixPosition>> listOfLists = new ArrayList<>();
while (scan.hasNextLine()) {
String line = scan.nextLine();
if (line.trim().isEmpty()) {
continue;
}
List<MatrixPosition> list = new ArrayList<>();
for (char c : line.toCharArray()) {
list.add(MatrixPosition.getMatrixPosition(String.valueOf(c)));
}
listOfLists.add(list);
}
MatrixPosition[][] grid = new MatrixPosition[listOfLists.size()][];
for (int i = 0; i < grid.length; i++) {
List<MatrixPosition> list = listOfLists.get(i);
grid[i] = list.toArray(new MatrixPosition[] {});
}
model = new MatrixModel(grid, new SpritePosition(1, 1));
}
return model;
}
}
表示方向的基本枚举:
public enum Direction {
UP, DOWN, LEFT, RIGHT
}
另一个用于表示网格中位置点的枚举,以及它是墙,coridor还是结尾以及从数字转换为MatrixPosition的静态方法:
public enum MatrixPosition {
WALL(1), CORRIDOR(0), END(2);
private int value;
private MatrixPosition(int value) {
this.value = value;
}
public int getValue() {
return value;
}
public static MatrixPosition getMatrixPosition(int value) {
for (MatrixPosition position : MatrixPosition.values()) {
if (value == position.getValue()) {
return position;
}
}
String text = "value of " + value;
throw new IllegalArgumentException(text);
}
public static MatrixPosition getMatrixPosition(String strValue) {
int value = -1;
try {
value = Integer.parseInt(strValue);
} catch (NumberFormatException e) {
String text = "NumberFormatException for strValue " + strValue;
throw new IllegalAccessError(text);
}
return getMatrixPosition(value);
}
}
用于表示精灵位置的类,类似于java.awt.Point
类但使用行和列字段而不是x和y:
public class SpritePosition {
int row;
int column;
public SpritePosition(int row, int column) {
this.row = row;
this.column = column;
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getColumn() {
return column;
}
public void setColumn(int column) {
this.column = column;
}
public void setRowColumn(int row, int column) {
this.row = row;
this.column = column;
}
}
该模型具有属性更改支持代码,因此它可以通知任何听取其状态更改的类。控制器将是听模型的类
import java.beans.PropertyChangeListener;
import javax.swing.event.SwingPropertyChangeSupport;
public class MatrixModel {
public static final String SPRITE_POINT = "sprite point";
private SwingPropertyChangeSupport pcSupport = new SwingPropertyChangeSupport(this);
private MatrixPosition[][] grid;
private SpritePosition spritePosition;
public MatrixModel(MatrixPosition[][] grid, SpritePosition spritePosition) {
this.grid = grid;
this.spritePosition = spritePosition;
}
public int getRows() {
return grid.length;
}
public int getColumns() {
return grid[0].length;
}
public MatrixPosition getPosition(SpritePosition p) {
return getPosition(p.row, p.column);
}
public MatrixPosition getPosition(int row, int col) {
return grid[row][col];
}
public void setSpritePoint(SpritePosition spritePosition) {
SpritePosition oldValue = this.spritePosition;
SpritePosition newValue = spritePosition;
this.spritePosition = spritePosition;
pcSupport.firePropertyChange(SPRITE_POINT, oldValue, newValue);
}
public boolean isPointValid(SpritePosition p) {
if (p.column < 0 || p.row < 0) {
return false;
}
if (p.column >= grid[0].length || p.row >= grid.length) {
return false;
}
return grid[p.row][p.column] == MatrixPosition.CORRIDOR;
}
public boolean isMoveValid(Direction direction) {
int row = spritePosition.row;
int column = spritePosition.column;
switch (direction) {
case UP:
return isPointValid(new SpritePosition(row - 1, column));
case DOWN:
return isPointValid(new SpritePosition(row + 1, column));
case LEFT:
return isPointValid(new SpritePosition(row, column - 1));
case RIGHT:
return isPointValid(new SpritePosition(row, column + 1));
default:
return false;
}
}
public void move(Direction direction) {
if (!isMoveValid(direction)) {
String text = "For move to " + direction + "spritePosition: " + spritePosition;
throw new IllegalArgumentException(text);
}
int row = spritePosition.row;
int column = spritePosition.column;
switch (direction) {
case UP:
setSpritePoint(new SpritePosition(row - 1, column));
break;
case DOWN:
setSpritePoint(new SpritePosition(row + 1, column));
break;
case LEFT:
setSpritePoint(new SpritePosition(row, column - 1));
break;
case RIGHT:
setSpritePoint(new SpritePosition(row, column + 1));
break;
default:
break;
}
}
public SpritePosition getSpritePosition() {
return spritePosition;
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(listener);
}
public void addPropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.addPropertyChangeListener(name, listener);
}
public void removePropertyChangeListener(String name, PropertyChangeListener listener) {
pcSupport.removePropertyChangeListener(name, listener);
}
}
控制器类,它在视图上设置键绑定,以便它可以监听按键,检查它们是否代表有效移动,如果是,则告诉模型进行移动。它还为模型添加了一个监听器,这样当状态发生变化时,它会告诉视图移动精灵
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.util.EnumMap;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.KeyStroke;
public class Controller {
private MatrixModel model;
private View view;
private Map<Direction, KeyStroke> dirKeyMap = new EnumMap<>(Direction.class);
public Controller(MatrixModel model, View view) {
this.model = model;
this.view = view;
dirKeyMap.put(Direction.DOWN, KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0));
dirKeyMap.put(Direction.UP, KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0));
dirKeyMap.put(Direction.LEFT, KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0));
dirKeyMap.put(Direction.RIGHT, KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0));
model.addPropertyChangeListener(new ModelListener());
setUpKeyBindings(view);
}
private void setUpKeyBindings(View view) {
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = view.getInputMap(condition);
ActionMap actionMap = view.getActionMap();
for (Direction dir : Direction.values()) {
KeyStroke keyStroke = dirKeyMap.get(dir);
hookUp(inputMap, actionMap, dir, keyStroke);
}
}
private void hookUp(InputMap inputMap, ActionMap actionMap, Direction dir, KeyStroke key) {
inputMap.put(key, key.toString());
actionMap.put(key.toString(), new MoveAction(dir, model));
}
public MatrixModel getModel() {
return model;
}
public View getView() {
return view;
}
class ModelListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (MatrixModel.SPRITE_POINT.equals(evt.getPropertyName())) {
SpritePosition p = model.getSpritePosition();
view.setSpritePoint(p);
}
}
}
}
@SuppressWarnings("serial")
class MoveAction extends AbstractAction {
private Direction dir;
private MatrixModel model;
public MoveAction(Direction dir, MatrixModel model) {
super(dir.toString());
this.dir = dir;
this.model = model;
}
public void actionPerformed(ActionEvent e) {
if (model.isMoveValid(dir)) {
model.move(dir);
}
}
}
最后,扩展JPanel的View类显示了迷宫和精灵:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
@SuppressWarnings("serial")
public class View extends JPanel {
private static final int CELL_WIDTH = 20;
private static final Color CORRIDOR_COLOR = Color.LIGHT_GRAY;
private static final Color WALL_COLOR = Color.DARK_GRAY;
private static final Color END_COLOR = Color.ORANGE;
private static final Color SPRITE_COLOR = Color.RED;
private static final int GAP = 1;
private BufferedImage gridImg = null;
private SpritePosition spritePosition;
private JPanel mainPanel = new JPanel();
public View(MatrixModel matrixModel) {
gridImg = createImg(matrixModel);
spritePosition = matrixModel.getSpritePosition();
}
public JPanel getMainPanel() {
return mainPanel;
}
@Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet() || gridImg == null) {
return super.getPreferredSize();
}
int prefW = gridImg.getWidth();
int prefH = gridImg.getHeight();
return new Dimension(prefW, prefH);
}
public void setSpritePoint(SpritePosition spritePosition) {
this.spritePosition = spritePosition;
repaint();
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (gridImg != null) {
g.drawImage(gridImg, 0, 0, this);
}
g.setColor(SPRITE_COLOR);
int y = spritePosition.row * CELL_WIDTH + GAP;
int x = spritePosition.column * CELL_WIDTH + GAP;
g.fillRect(x, y, CELL_WIDTH - 2 * GAP, CELL_WIDTH - 2 * GAP);
}
private BufferedImage createImg(MatrixModel matrixModel) {
BufferedImage img = null;
if (matrixModel != null && matrixModel.getRows() > 0) {
int w = matrixModel.getColumns() * CELL_WIDTH;
int h = matrixModel.getRows() * CELL_WIDTH;
img = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2 = img.createGraphics();
for (int row = 0; row < matrixModel.getRows(); row++) {
for (int col = 0; col < matrixModel.getColumns(); col++) {
MatrixPosition position = matrixModel.getPosition(row, col);
Color c = null;
switch (position) {
case CORRIDOR:
c = CORRIDOR_COLOR;
break;
case WALL:
c = WALL_COLOR;
break;
case END:
c = END_COLOR;
break;
}
g2.setColor(c);
int x = col * CELL_WIDTH;
int y = row * CELL_WIDTH;
g2.fillRect(x, y, CELL_WIDTH, CELL_WIDTH);
}
}
g2.dispose();
}
return img;
}
}