Java俄罗斯方块-无法设置将密钥设置保存到配置文件中



我无法完成最近添加到俄罗斯方块游戏中的一个功能。基本上,我正在处理关键设置,允许用户将控件更改为WASD,而不是箭头等。我想我已经设置好了一切,但一旦我关闭游戏并重新打开它,我的配置就不会保存设置。每次我打开游戏时,配置文件都会将自己重置为默认值。

如果你发现可能导致这个问题的原因,请你伸出援手,仔细检查代码?

提前非常感谢!

主要类别:

package mypackage;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Collections;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
public class RiskTetris extends JPanel {
/**
*
*/
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
final JFrame f = new JFrame("Tetrisoid");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//f.setLocationRelativeTo(null);                
// setting up frame in the middle
//for Keys configuration.
KeyGetter.LoadKeys();
try {
Config.loadConfig();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//menubar from here
JMenuBar mb= new JMenuBar();
JMenu file = new JMenu("Menu");
mb.add(file);
JMenuItem NewGame=new JMenuItem("New Game");
//file.add(NewGame);
NewGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Starting New Game...");
}
});
JMenuItem HighScore=new JMenuItem("High Score");
//file.add(HighScore);
HighScore.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//System.out.println("High Score...");
long score=0;   //replace with high score code later
final JFrame alert=new JFrame("High Score");
alert.setSize(300, 200);
alert.setLayout(null);
alert.setLocationRelativeTo(null);
//alert.setAlwaysOnTop(true); 
JLabel highscore=new JLabel("The highscore is: " + score);
highscore.setBounds(85,0, 200,50);
alert.setResizable(false);
alert.setVisible(true);
JButton okayButton=new JButton ("Okay");
alert.add(highscore);
alert.add(okayButton);
okayButton.setBounds(90, 120, 100, 30);
alert.setLocationRelativeTo(null);
okayButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//alert.add(okayButton);
alert.dispose();
}
});
}
});
JMenuItem options = new JMenuItem("Options");
//file.add(options);
options.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Options...");
Config.openConfig(f);
}
});
JMenuItem exit = new JMenuItem ("Exit");
//file.add(exit);
exit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.out.println("Exit...");
System.exit(0);
}
});
f.setJMenuBar(mb);
f.setSize(12*26+10, 26*23+25);
f.setVisible(true);
f.setSize(12*26+11, 26*24+26);      //Corrected so that the frame shows from the beginening, not only with sizing.
f.setVisible(true);
final RiskTetris game = new RiskTetris();
file.add(NewGame);
file.add(HighScore);
file.add(options);
file.add(exit);
game.init();
f.add(game);
f.addKeyListener(new KeyListener() {
public void keyTyped(KeyEvent e) {
}
public void keyPressed(KeyEvent e) {
switch (e.getKeyCode()) {
case KeyEvent.VK_UP:
game.rotate(-1);
break;
case KeyEvent.VK_DOWN:
game.rotate(+1);
break;
case KeyEvent.VK_LEFT:
game.move(-1);
break;
case KeyEvent.VK_RIGHT:
game.move(+1);
break;
case KeyEvent.VK_SPACE:
game.dropDown();
//game.score += 1;
break;
}
}
public void keyReleased(KeyEvent e) {
}
});
new Thread() {
@Override public void run() {
while (true) {
try {
Thread.sleep(1000);
game.dropDown();
} catch ( InterruptedException e ) {}
}
}
}.start();
}
private final Point[][][] MyShapes = {
// I-Piece
{
{ new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(3, 1) },
{ new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(1, 3) },
{ new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(3, 1) },
{ new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(1, 3) }
},
// J-Piece
{
{ new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(2, 0) },
{ new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(2, 2) },
{ new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(0, 2) },
{ new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(0, 0) }
},
// L-Piece
{
{ new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(2, 2) },
{ new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(0, 2) },
{ new Point(0, 1), new Point(1, 1), new Point(2, 1), new Point(0, 0) },
{ new Point(1, 0), new Point(1, 1), new Point(1, 2), new Point(2, 0) }
},
// O-Piece
{
{ new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) },
{ new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) },
{ new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) },
{ new Point(0, 0), new Point(0, 1), new Point(1, 0), new Point(1, 1) }
}
};
private final Color[] MyColors = {
Color.cyan, Color.MAGENTA, Color.orange, Color.yellow, Color.black, Color.pink,
Color.red };
private Point pt;
private int currentPiece;
private int rotation;
private ArrayList<Integer> nextPieces = new ArrayList<Integer>();
public long score;
private Color[][] well;
private void init() {
well = new Color[12][24];
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 23; j++) {
if (i == 0 || i == 11 || j == 22) {
well[i][j] = Color.darkGray;
} else {
well[i][j] = Color.black;
}
}
}
newPiece();
}
public void newPiece() {
pt = new Point(5, 2);
rotation = 0;
if (nextPieces.isEmpty()) {
Collections.addAll(nextPieces, 0, 1, 2, 3);
Collections.shuffle(nextPieces);
}
currentPiece = nextPieces.get(0);
nextPieces.remove(0);
}
private boolean collidesAt(int x, int y, int rotation) {
for (Point p : MyShapes[currentPiece][rotation]) {
if (well[p.x + x][p.y + y] != Color.black) {
return true;
}
}
return false;
}
public void rotate(int i) {
int newRotation = (rotation + i) % 4;
if (newRotation < 0) {
newRotation = 3;
}
if (!collidesAt(pt.x, pt.y, newRotation)) {
rotation = newRotation;
}
repaint();
}
public void move(int i) {
if (!collidesAt(pt.x + i, pt.y, rotation)) {
pt.x += i;
}
repaint();
}
public void dropDown() {
if (!collidesAt(pt.x, pt.y + 1, rotation)) {
pt.y += 1;
} else {
fixToWell();
}
repaint();
}
public void fixToWell() {
for (Point p : MyShapes[currentPiece][rotation]) {
well[pt.x + p.x][pt.y + p.y] = MyColors[currentPiece];
}
clearRows();
newPiece();
}
public void deleteRow(int row) {
for (int j = row-1; j > 0; j--) {
for (int i = 1; i < 11; i++) {
well[i][j+1] = well[i][j];
}
}
}
public void clearRows() {
boolean gap;
int numClears = 0;
for (int j = 21; j > 0; j--) {
gap = false;
for (int i = 1; i < 11; i++) {
if (well[i][j] == Color.black) {
gap = true;
break;
}
}
if (!gap) {
deleteRow(j);
j += 1;
numClears += 1;
}
}
switch (numClears) {
case 1: score += 100;break;
case 2: score += 300;break;
case 3: score += 500;break;
case 4: score += 800;break;
}
}
private void drawPiece(Graphics g) {
g.setColor(MyColors[currentPiece]);
for (Point p : MyShapes[currentPiece][rotation]) {
g.fillRect((p.x + pt.x) * 26,
(p.y + pt.y) * 26,
25, 25);
}
}
@Override
public void paintComponent(Graphics g)
{
g.fillRect(0, 0, 26*12, 26*23);
for (int i = 0; i < 12; i++) {
for (int j = 0; j < 23; j++) {
g.setColor(well[i][j]);
g.fillRect(26*i, 26*j, 25, 25);
}
}
g.setColor(Color.GREEN);
g.drawString("Score : " + score, 19*12, 25);
drawPiece(g);
}
}

KeyGetter类:

package mypackage;
import java.awt.event.KeyEvent;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.HashMap;
//import com.sun.java.util.jar.pack.Package.Class.Field;
//<>()*//\()}}}}}{    [ ]
public class KeyGetter {
public static HashMap<String, Integer> keys;
public static ArrayList<String> keyNames;
public static void LoadKeys() {
keys= new HashMap<String, Integer>();
keyNames=new ArrayList<String>();
java.lang.reflect.Field[] fields = KeyEvent.class.getFields();
for(java.lang.reflect.Field f: fields) {
if(Modifier.isStatic(f.getModifiers())) {
if(f.getName().startsWith("VK")) {
try {
int num=f.getInt(null);
String name= KeyEvent.getKeyText(num);
keys.put(name, num);
keyNames.add(name);
}
catch(Exception e) {
e.printStackTrace();
}
}
}
}
}
}

配置类别:

package mypackage;
import java.awt.Choice;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Scanner;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class Config {
public static String rotate = "Up", left = "Left", right = "Right", down = "Down", pause = "P";
private static ArrayList<Choice> choices;
//<>()*//\()}}}}}{    [ ]
public static void openConfig(JFrame frame) {
choices = new ArrayList<Choice>();
final JFrame options = new JFrame("Options");
options.setSize(400, 300);
options.setResizable(true);
options.setLocationRelativeTo(null); //???
options.setLayout(null);
Choice left = addChoice("Left", options, 30, 30);
left.select(Config.left);
Choice right = addChoice("Right", options, 150, 30);
right.select(Config.right);
Choice down = addChoice("Down", options, 30, 80);
down.select(Config.down);
Choice rotate = addChoice("Rotate", options, 150, 80);
rotate.select(Config.rotate);
Choice pause = addChoice("Pause", options, 30, 130);
pause.select(Config.pause);
JButton done = new JButton("Done");
done.setBounds(150, 220, 100, 30);
done.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
options.dispose();
saveChanges();
}
});
options.add(done);
options.setVisible(true);
}
public static void saveChanges() {
Choice left = choices.get(0);
Choice right = choices.get(1);
Choice down = choices.get(2);
Choice rotate = choices.get(3);
Choice pause = choices.get(4);
Config.left = left.getSelectedItem();
Config.right = right.getSelectedItem();
Config.down = down.getSelectedItem();
Config.rotate = rotate.getSelectedItem();
Config.pause = pause.getSelectedItem();
try {
saveConfig();
} catch (Exception e) {
e.printStackTrace();
}
}
public static Choice addChoice(String name, JFrame options, int x, int y) {
JLabel label = new JLabel(name);
label.setBounds(x, y - 20, 100, 20);
Choice key = new Choice();
for (String s : getKeyNames()) {
key.add(s);
}
key.setBounds(x, y, 100, 20);
options.add(key);
options.add(label);
choices.add(key);
return key;
}
public static ArrayList<String> getKeyNames() {
ArrayList<String> result = new ArrayList<String>();
for (String s : KeyGetter.keyNames) {
result.add(s);
if (s.equalsIgnoreCase("F24")) {
break;
}
}
return result;
}
public static void loadConfig() throws Exception {
File directory = new File(getDefaultDirectory(), "/Tetris");
if (!directory.exists()) {
directory.mkdirs();
}
File config = new File(directory, "/Tetris");
if (!config.exists()) {
config.createNewFile();
System.out.println("File not found, saving defaults");
saveConfig();
return;
}
//@SuppressWarnings("resource")
Scanner s = new Scanner(config);
HashMap<String, String> values = new HashMap<String, String>();
while (s.hasNextLine()) {
String[] entry = s.nextLine().split(":");         //BUde souviset s tim ze je to v configu napsane na PICU
if (entry.length >= 2) {
String key = entry[0];         // COrrect error here
String value = entry[1];
values.put(key, value);
s.close();   //pridano mnou
}
}
if (values.size() != 5) {
System.out.println("Config is unuasable, saving defaults.");
saveConfig();
return;
}
if (!values.containsKey("left") || !values.containsKey("right") || !values.containsKey("rotate") || !values.containsKey("down") || !values.containsKey("pause")) {
System.out.println("Invalid names in config, saving defauls");
saveConfig();
return;
}
String left = values.get("left");
String right = values.get("right");
String rotate = values.get("rotate");
String down = values.get("down");
String pause = values.get("pause");
if (!(getKeyNames().contains(left) && getKeyNames().contains(right) && getKeyNames().contains(rotate) && getKeyNames().contains(down) && getKeyNames().contains(pause))) {
System.out.println("Invalid key in config, saving defaults");
;
}
Config.left = left;
Config.right = right;
Config.rotate = rotate;
Config.down = down;
Config.pause = pause;
}
public static void saveConfig() throws Exception {
File directory = new File(getDefaultDirectory(), "/Tetris");
if (!directory.exists()) {
directory.mkdirs();
}
File config = new File(directory, "/config.text");
PrintWriter pw = new PrintWriter(config);
pw.println("right:" + right);
pw.println("left:" + left);
pw.println("rotate:" + rotate);
pw.println("down:" + down);
pw.println("pause:" + pause);
pw.close();
}
public static String getDefaultDirectory() {
String OS = System.getProperty("os.name").toUpperCase();
if (OS.contains("WIN")) {
return System.getenv("APPDATA");
}
if (OS.contains("MAC")) {
return System.getProperty("user.home") + "Library/Application Support";
}
return System.getProperty("user.home");
}
}

保存配置文件时使用路径"/Tetris/config.text",但读取配置文件时则使用路径"Tetris/Tetris"。它应该与保存配置文件的文件名相同,否则您将读取和写入不同的文件。

事实上,您应该将目录路径和配置文件名保存在静态字段中,如:

public static final String START_DIRECTORY = "Tetris";
public static final String CONFIG_FILENAME = "config.text";

并在代码中使用这些常量。这样,所有不同的地方(读取配置文件、保存配置文件…(都使用完全相同的名称,并且不会在同一个问题中运行两次,即不同位置的名称不同。代码将如下所示:

...
File config=new File(directory, CONFIG_FILENAME);
if(!config.exists()) {
...

最新更新