到目前为止,我能够使用jlabels制作由瓷砖组成的电路板。游戏的下一步是红色和蓝色玩家轮流选择他们最初控制的行星(通过点击行星牌)。一旦玩家点击一颗行星,就应该将一个meeple计数器放在该行星的顶部。
行星的阵列数据也应该更新,以便知道行星的所有者。现在,我不知道如何将我的jlabel瓷砖与我的变量相关联。
如果你能指出我正确的方向,我将非常感激。谢谢。
package SpaceBattle;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.Random;
//import javax.smartcardio.Card;
import javax.swing.*;
public class spacebattle2 extends JFrame {
JLabel[] tilelabel = new JLabel[31];
JLabel[] hexlabel = new JLabel[31];
ImageIcon tileicon, hexicon;
int rownum, colnum;
int c, r, xloc, yloc, hexctr, tilectr;
int energy, ore, capacity;
String labelname;
String type;
int numtiles = 31;
int deckctr = 26;
String[] tiledeck = new String[numtiles];
int[] tilexloc = new int[numtiles];
int[] tileyloc = new int[numtiles];
int tileenergy[] = new int[numtiles];
int tileore[] = new int[numtiles];
int tilecapacity[] = new int[numtiles];
String tiletype[] = new String[numtiles];
String tilename[] = new String[numtiles];
int tilemeeple[] = new int[numtiles];
String[] hexnum = new String[numtiles];
int[] hexxloc = new int[numtiles];
int[] hexyloc = new int[numtiles];
String[] hexempty = new String[numtiles];
int hexenergy[] = new int[numtiles];
int hexore[] = new int[numtiles];
int hexcapacity[] = new int[numtiles];
String hextype[] = new String[numtiles];
String hexname[] = new String[numtiles];
String hexplayer[] = new String[numtiles];
String[] players = new String[6];
String playerturn;
int startingplanets = 2;
int bluemaxplanet = startingplanets;
int redmaxplanet = startingplanets;
int numplanets = 7;
int numspace = 24;
int nonplayertiles = numplanets + numspace;
String planetCode;
String planetselected = "none";
//selectPlanet
String player = "Red";
int i;
public spacebattle2() {
setLayout(null);
createDeck();
shuffleDeck();
drawBoard();
//selectPlanet();
}
private void selectPlanet() {
// TODO Auto-generated method stub
for(i = 0; i < numtiles; i++) {
tilelabel[i].addMouseListener(new MouseListener() {
public void mouseClicked(MouseEvent e) {
System.out.println(i);
}
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
}
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
});
}
}
private void shuffleDeck() {
// TODO Auto-generated method stub
System.out.println("shuffling deck...");
Random r = new Random();
int swapIndex;
String temp;
for(int startIndex = 0; startIndex < numtiles; startIndex++) {
System.out.println(startIndex + " startIndex " + tiledeck[startIndex]);
swapIndex = r.nextInt(numtiles);
System.out.println(swapIndex + " swapIndex " + tiledeck[swapIndex]);
if(swapIndex != startIndex) {
temp = tiledeck[swapIndex];
tiledeck[swapIndex] = tiledeck[startIndex];
System.out.println("Moving " + startIndex + " " + tiledeck[startIndex] + " startIndex to " + swapIndex + " swapIndex");
tiledeck[startIndex] = temp;
System.out.println("Moving " + temp + " temp to " + startIndex + " startIndex");
}
}
}
private void createDeck() {
// TODO Auto-generated method stub
int s, p, xloc = 667, yloc = 10;
/*******************************
*
* Create Space tiles
*
******************************/
System.out.println("creating space tiles...");
tilectr = 0;
for(s= 0; s < numspace; s++) {
tiledeck[tilectr] = "000";
System.out.println(tilectr + " " + tiledeck[tilectr]);
tilectr++;
}
/**************************
*
* Create Planet tiles
*
*************************/
System.out.println("creating planet tiles...");
for(p = 0; p < numplanets; p++) {
energy = (int) (Math.random()*3 + 1);
ore = (int) (Math.random()*3 +1);
capacity = (int) (Math.random()*3 +1);
StringBuffer stringBuffer = new StringBuffer();
stringBuffer.append("");
stringBuffer.append(energy);
stringBuffer.append(ore);
stringBuffer.append(capacity);
String planetCode = stringBuffer.toString();
tiledeck[tilectr] = planetCode;
System.out.println(tilectr + " " + tiledeck[tilectr]);
tilectr++;
}
}
private void drawBoard() {
// TODO Auto-generated method stub
int xloc = 10;
int yloc = 61;
int hexctr = 0;
int colnum = 7;
int rownum = 4;
xloc = 10;
yloc = 61;
hexctr = 0;
colnum = 7;
rownum = 4;
int row = 0, col = 0, numtiles = 31;
for(int c = 0; c < numtiles; c ++) {
if(tiledeck[c] == "000") {
System.out.println(c + " " + tiledeck[c] + " tile is space");
tileenergy[c] = 0;
tileore[c] = 0;
tilecapacity[c] = 0;
tiletype[c] = "space";
tilename[c] = "space";
tileicon = new ImageIcon(getClass().getResource("/000.png"));
tilelabel[c] = new JLabel();
tilelabel[c].setIcon(tileicon);
tilelabel[c].setBounds(xloc, yloc, 115, 100);
add(tilelabel[c]);
yloc = yloc + 102;
row++;
if(row == rownum) {
xloc = xloc + 88;
row = 0;
col++;
if(col % 2 == 0) {
yloc = 61;
rownum = rownum - 1;
}
else {
yloc = 10;
rownum = rownum + 1;
}
}
}
else {
System.out.println(c + " " + tiledeck[c] + " tile is planet");
tileenergy[c] = Integer.parseInt(tiledeck[c].substring(0, 1));
tileore[c] = Integer.parseInt(tiledeck[c].substring(1, 2));
tilecapacity[c] = Integer.parseInt(tiledeck[c].substring(2, 3));
tiletype[c] = "planet";
tilemeeple[c] = 0;
tileicon = new ImageIcon(getClass().getResource("/" + tiledeck[c] + ".png"));
tilelabel[c] = new JLabel();
tilelabel[c].setIcon(tileicon);
tilelabel[c].setBounds(xloc, yloc, 115, 100);
add(tilelabel[c]);
yloc = yloc + 102;
row++;
if(row == rownum) {
xloc = xloc + 88;
row = 0;
col++;
if(col % 2 == 0) {
yloc = 61;
rownum = rownum - 1;
}
else {
yloc = 10;
rownum = rownum + 1;
}
}
}
}
}
private Object i(int numtiles2, int i) {
// TODO Auto-generated method stub
return null;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
spacebattle2 board = new spacebattle2();
board.setSize(900, 600);
board.setResizable(false);
board.setTitle("Space Battle");
board.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
board.setVisible(true);
}//End void main
}
我建议重组程序以使用“tile”类来保存与给定tile相关的所有信息。拥有一个“瓦片管理器”类也可能会有所帮助,该类知道瓦片的集合以及它们之间的相互关系。
以下是您的程序的tile类可能的样子。我试图不改变任何功能,只是为了重新组织。您应该能够将所有内容与原始程序相匹配。
class TileInfo {
TileManager manager;
public JLabel label = new JLabel();
public JLabel hexlabel = new JLabel();
int xloc;
int yloc;
int energy;
int ore;
int capacity;
String type;
String name;
int meeple;
String hexnum;
int hexxloc;
int hexyloc;
String hexempty;
// etc...
public TileInfo(Icon tileicon, int x, int y, TileManager manager) {
this.manager = manager;
label.setIcon(tileicon);
label.setBounds(x, y, 115, 100);
label.addMouseListener(new MouseAdapter() {
public void mouseClicked(MouseEvent e) {
manager.clickedTile(TileInfo.this);
};
});
}
};
然后,您可以为“space”和“planet”tile扩展此基类:
class SpaceTile extends TileInfo {
public SpaceTile(Icon icon, int x, int y, TileManager manager) {
super(icon, x, y, manager);
energy = 0;
ore = 0;
capacity = 0;
type = "space";
name = "space";
}
};
class PlanetTile extends TileInfo {
public PlanetTile(Icon icon, int x, int y,
int energy, int ore, int capacity, TileManager manager) {
super(icon, x, y, manager);
this.energy = energy;
this.ore = ore;
this.capacity = capacity;
type = "planet";
meeple = 0;
}
};
在您的示例中,子类并不是严格必需的,但在每种情况下,tile构造略有不同,这有助于保持它们的直线。
每个TileInfo
都会创建自己的鼠标侦听器,但会将事件传递给磁贴管理器。 tile管理器就像一个容器并保存数组:
class TileManager {
public int numtiles;
public TileInfo[] tile;
public String tiledeck[];
public TileManager(int numtiles) {
this.numtiles = numtiles;
this.tile = new TileInfo[numtiles];
this.tiledeck = new String[numtiles];
System.out.printf("TileManager(%d): tile[%d]\n", numtiles, numtiles);
}
public void clickedTile(TileInfo tile) {
if (tile instanceof SpaceTile) {
System.out.println("clicked space tile " + tile.label.getBounds());
} else if (tile instanceof PlanetTile) {
System.out.println("clicked planet tile " + tile.label.getBounds());
}
}
};
现在请注意,您只需要一个数组。如果你更喜欢那样,TileManager
可以覆盖ArrayList
;我想尽可能地贴近你原来的节目。 clickedTile()
方法处理tile上的鼠标点击,但由于它位于tile管理器中,因此它可以看到所有tile而不是一个。例如,如果要在单击图块B时取消选择图块A,则需要能够看到两个图块。
拥有单独的磁贴管理器并非绝对必要;您可以在spacebattle2
类中保留此功能。我喜欢有一个管理器类来分离创建,操作和绘制图块组的功能,与游戏玩法分开。它有点像“瓷砖库”。
最后,这一切如何适合您的主要课程。为清楚起见,省略了大量代码。
public class spacebattle2 extends JFrame {
TileManager tiles = new TileManager(31);
// didn't change anything except tiledeck[] now lives inside tiles
// this method could be moved into the TileManager
private void shuffleDeck() {
for(int startIndex = 0; startIndex < tiles.numtiles; startIndex++) {
swapIndex = r.nextInt(tiles.numtiles);
if(swapIndex != startIndex) {
temp = tiles.tiledeck[swapIndex];
tiles.tiledeck[swapIndex] = tiles.tiledeck[startIndex];
tiles.tiledeck[startIndex] = temp;
}
}
}
void createTile(String deck, int xloc, int yloc) {
tileicon = new ImageIcon(getClass().getResource("/" + deck + ".png"));
if (deck.equals("000")) {
tiles.tile[c] = new SpaceTile(tileicon, xloc, yloc, tiles);
} else {
int energy = Integer.parseInt(deck.substring(0, 1));
int ore = Integer.parseInt(deck.substring(1, 2));
int capacity = Integer.parseInt(deck.substring(2, 3));
tiles.tile[c] = new PlanetTile(tileicon, xloc, yloc, 0, 0, 0, tiles);
}
add(tiles.tile[c].label);
}
private void drawBoard() {
/* ... */
for(int c = 0; c < tiles.numtiles; c ++) {
createTile(tiles.tiledeck[c], xloc, yloc);
yloc = yloc + 102;
row++;
if(row == rownum) {
xloc = xloc + 88;
row = 0;
col++;
if(col % 2 == 0) {
yloc = 61;
rownum = rownum - 1;
} else {
yloc = 10;
rownum = rownum + 1;
}
}
}
}
}
drawBoard()
中的循环被简化;它有很多重复的代码,所以我考虑了并添加了一个createTile()
方法来创建两种类型的tile。
Thare仍然可以进行改进。我不认为具有公共TileInfo变量的公共数组是理想的访问数据的方式,但不想更改它以至于无法识别。
这并不意味着是最终设计,而是建议一种方式来组织代码,使其更容易使用,并回答有关如何将数据与切片关联的问题。