我一直想用随机生成的 JPanel 制作一组 JPanel(3 x 3 数组),该 JPanel 可以是森林或平原,中心的总是称为房屋的 JPanel。总会有一个可见的,并且我希望它,因此当称为字符的 JLabel 的 x 位置到达 x 位置 0 时,它将检查该数组中的哪个 JPanel 正在用作 ContentPane,并且如果此事件发生在JPanel 位于第一列,它将执行 System.out.Println("Hello!") 之类的操作,但如果这种情况发生在其他两列中,则内容窗格将设置为发生在第一列上的任何行。这与此 JLabel 的 y 位置相同。我是否需要将其放在线程中,因为它应该不断检查 x 或 y 位置是否已达到 0?如果需要,我可以发布代码,但我只需要一个示例。拥有整个 Swing 窗口的类扩展了 JFrame,如果有必要,主类会调用包含所有内容的对象 Window,例如窗口和 JLabel。
我希望它像《我的世界》世界一代一样,但如果它是 2D,用 Java Swing 制作,并且为了细节而只有一个块。我试过这个:
while(true){
switch(guineaXPosition) {
case 0:
for (int i = 0; i < world.length; i++) {
for(int j=0;i<world.length;j++) {
if (frame.getContentPane()==world[i][0]) {
// The guinea is in the JPanel at index [i][j].
// Perform the desired action.
System.out.println("Edge of world, nothing you can do!");
}else {
frame.setContentPane(world[i][j-1]);
}}
}
break;
case 1300:
break;
default:
break;
}
}
在一个线程中并在另一个线程中执行此操作:
Random random = new Random();
int terrainTypeGen=random.nextInt(2)+1;
for(int i=0;i<world.length;i++) {
for(int j=0;j<world[0].length;j++) {
if(i==1&&j==1) {
world[i][j]=new JPanel();
}else {
String terrainType=null;
if(terrainTypeGen==1) {
world[i][j]=new JPanel();
world[i][j].setBackground(Color.GREEN);
}else if(terrainTypeGen==2) {
world[i][j]=new JPanel();
world[i][j].setBackground(Color.GREEN);
}
}
}
}
}
请不要评判我。 如果需要更多详细信息,请告诉我。
您能否举一个我将使用的代码类型的示例?
你可能会后悔。
首先,您应该首先定义一些描述数据的模型。这允许您将 UI 与数据解耦(这是“模型-视图-控制器”概念的基础)...
public enum Biome {
FOREST, PLAINS
}
public interface Chunk {
public Biome getBiome();
public Point getLocation();
}
public interface World {
public Chunk getChunkAt(int x, int y);
}
这是非常基本的,但我们还需要某种方法来创建随机块,在这种情况下我们可以使用工厂的概念......
public interface ChunkFactory {
public Chunk createChunk(Point worldLocation);
}
但是我们为什么要使用
s?interface
接口允许您定义代码的契约,而无需绑定到单独的实现。将其与“依赖注入”原则联系起来。
接下来,我们需要定义某种模型来存储我们的块,该模型可以随机访问,并且可以根据放入其中的数据动态增长。
为此,我会考虑某种“矩阵”。你可以使用二维数组,但是那有什么乐趣呢😉.
以下是由
Map
支持的“矩阵”概念...
// This basically acts a multi dimensional matrix of values, keyed by the
// x/y coordinates.
public interface Matrix<Type> {
public Type get(int x, int y);
public void put(Type value, int x, int y);
}
public class HashMapMatrix<Type> implements Matrix<Type> {
private Map<Integer, Map<Integer, Type>> values = new HashMap<>(8);
@Override
public Type get(int x, int y) {
Map<Integer, Type> rows = values.get(y);
if (rows == null) {
return null;
}
return rows.get(x);
}
@Override
public void put(Type value, int x, int y) {
Map<Integer, Type> rows = values.get(y);
if (rows == null) {
rows = new HashMap<Integer, Type>(8);
values.put(y, rows);
}
rows.put(x, value);
}
}
现在,我们可以开始一些初步的实现......
public class DefaultChunkFactory implements ChunkFactory {
private List<Biome> listOfBiomes = new ArrayList<>(Arrays.asList(Biome.values()));
protected List<Biome> getListOfBiomes() {
return listOfBiomes;
}
@Override
public Chunk createChunk(Point worldLocation) {
List<Biome> biomes = new ArrayList<>(getListOfBiomes());
Collections.shuffle(biomes);
Biome biome = biomes.get(0);
return new DefaultChunk(biome, worldLocation);
}
}
public class DefaultChunk implements Chunk {
private Biome biome;
private Point location;
public DefaultChunk(Biome biome, Point location) {
this.biome = biome;
this.location = new Point(location);
}
@Override
public Biome getBiome() {
return biome;
}
@Override
public Point getLocation() {
return location;
}
}
public class DefaultWorld implements World {
private Matrix<Chunk> chunkMatrix = new HashMapMatrix<>();
private ChunkFactory chunkFactory;
public DefaultWorld(ChunkFactory chunkFactory) {
this.chunkFactory = chunkFactory;
}
public ChunkFactory getChunkFactory() {
return chunkFactory;
}
protected Matrix<Chunk> getChunks() {
return chunkMatrix;
}
@Override
public Chunk getChunkAt(int x, int y) {
Chunk chunk = getChunks().get(x, y);
if (chunk == null) {
chunk = getChunkFactory().createChunk(new Point(x, y));
getChunks().put(chunk, x, y);
}
return chunk;
}
}
这些都是非常基本的,但它们构建了“世界”和“块”的概念。
最后,我们可以开始使用 UI!
首先,一个可以代表
Chunk
的组件
public class ChunkPane extends JPanel {
private Chunk chunk;
public ChunkPane(Chunk chunk) {
this.chunk = chunk;
switch (chunk.getBiome()) {
case FOREST:
setBackground(Color.GREEN);
break;
case PLAINS:
setBackground(Color.YELLOW);
break;
}
setLayout(new GridBagLayout());
Point location = chunk.getLocation();
JLabel label = new JLabel(location.x + "x" + location.y);
add(label);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
这是非常基本的,它根据生物群系设置背景颜色并显示世界中的区块位置。
好吧,接下来,我们需要一个“世界”窗格,它可以根据玩家的位置管理区块的显示。
public class SwingCraft extends JPanel {
protected enum Direction {
UP, DOWN, LEFT, RIGHT
}
private Matrix<ChunkPane> chunkMatrix = new HashMapMatrix<ChunkPane>();
private World world;
private Point playerLocation = new Point(0, 0);
public SwingCraft(World world) {
setLayout(new BorderLayout());
this.world = world;
setChunk(playerLocation);
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), Direction.LEFT);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), Direction.RIGHT);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), Direction.UP);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), Direction.DOWN);
actionMap.put(Direction.LEFT, new MoveAction(-1, 0));
actionMap.put(Direction.RIGHT, new MoveAction(1, 0));
actionMap.put(Direction.UP, new MoveAction(0, -1));
actionMap.put(Direction.DOWN, new MoveAction(0, 1));
}
public void setChunk(Point location) {
ChunkPane pane = chunkMatrix.get(location.x, location.y);
if (pane == null) {
Chunk chunk = world.getChunkAt(location.x, location.y);
pane = new ChunkPane(chunk);
chunkMatrix.put(pane, location.x, location.y);
}
removeAll();
add(pane);
revalidate();
repaint();
}
protected void moveBy(int xDelta, int yDelta) {
int targetX = playerLocation.x + xDelta;
int targetY = playerLocation.y + yDelta;
playerLocation.x = targetX;
playerLocation.y = targetY;
setChunk(playerLocation);
}
protected class MoveAction extends AbstractAction {
private int xDelta, yDelta;
public MoveAction(int xDelta, int yDelta) {
this.xDelta = xDelta;
this.yDelta = yDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
moveBy(xDelta, yDelta);
}
}
}
这是非常基本的。它提供了使用键绑定的简单导航,该绑定将显示缓存的生物群系窗格(如果可用)或创建新的块和窗格并显示它。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame();
frame.add(new SwingCraft(new DefaultWorld(new DefaultChunkFactory())));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SwingCraft extends JPanel {
protected enum Direction {
UP, DOWN, LEFT, RIGHT
}
private Matrix<ChunkPane> chunkMatrix = new HashMapMatrix<ChunkPane>();
private World world;
private Point playerLocation = new Point(0, 0);
public SwingCraft(World world) {
setLayout(new BorderLayout());
this.world = world;
setChunk(playerLocation);
InputMap inputMap = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), Direction.LEFT);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), Direction.RIGHT);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), Direction.UP);
inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), Direction.DOWN);
actionMap.put(Direction.LEFT, new MoveAction(-1, 0));
actionMap.put(Direction.RIGHT, new MoveAction(1, 0));
actionMap.put(Direction.UP, new MoveAction(0, -1));
actionMap.put(Direction.DOWN, new MoveAction(0, 1));
}
public void setChunk(Point location) {
ChunkPane pane = chunkMatrix.get(location.x, location.y);
if (pane == null) {
Chunk chunk = world.getChunkAt(location.x, location.y);
pane = new ChunkPane(chunk);
chunkMatrix.put(pane, location.x, location.y);
}
removeAll();
add(pane);
revalidate();
repaint();
}
protected void moveBy(int xDelta, int yDelta) {
int targetX = playerLocation.x + xDelta;
int targetY = playerLocation.y + yDelta;
playerLocation.x = targetX;
playerLocation.y = targetY;
setChunk(playerLocation);
}
protected class MoveAction extends AbstractAction {
private int xDelta, yDelta;
public MoveAction(int xDelta, int yDelta) {
this.xDelta = xDelta;
this.yDelta = yDelta;
}
@Override
public void actionPerformed(ActionEvent e) {
moveBy(xDelta, yDelta);
}
}
}
public class ChunkPane extends JPanel {
private Chunk chunk;
public ChunkPane(Chunk chunk) {
this.chunk = chunk;
switch (chunk.getBiome()) {
case FOREST:
setBackground(Color.GREEN);
break;
case PLAINS:
setBackground(Color.YELLOW);
break;
}
setLayout(new GridBagLayout());
Point location = chunk.getLocation();
JLabel label = new JLabel(location.x + "x" + location.y);
add(label);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
// This basically acts a multi dimensional matrix of values, keyed by the
// x/y coordinates.
public interface Matrix<Type> {
public Type get(int x, int y);
public void put(Type value, int x, int y);
}
public class HashMapMatrix<Type> implements Matrix<Type> {
private Map<Integer, Map<Integer, Type>> values = new HashMap<>(8);
@Override
public Type get(int x, int y) {
Map<Integer, Type> rows = values.get(y);
if (rows == null) {
return null;
}
return rows.get(x);
}
@Override
public void put(Type value, int x, int y) {
Map<Integer, Type> rows = values.get(y);
if (rows == null) {
rows = new HashMap<Integer, Type>(8);
values.put(y, rows);
}
rows.put(x, value);
}
}
public enum Biome {
FOREST, PLAINS
}
public interface Chunk {
public Biome getBiome();
public Point getLocation();
}
public interface World {
public Chunk getChunkAt(int x, int y);
}
public interface ChunkFactory {
public Chunk createChunk(Point worldLocation);
}
public class DefaultChunkFactory implements ChunkFactory {
private List<Biome> listOfBiomes = new ArrayList<>(Arrays.asList(Biome.values()));
protected List<Biome> getListOfBiomes() {
return listOfBiomes;
}
@Override
public Chunk createChunk(Point worldLocation) {
List<Biome> biomes = new ArrayList<>(getListOfBiomes());
Collections.shuffle(biomes);
Biome biome = biomes.get(0);
return new DefaultChunk(biome, worldLocation);
}
}
public class DefaultChunk implements Chunk {
private Biome biome;
private Point location;
public DefaultChunk(Biome biome, Point location) {
this.biome = biome;
this.location = new Point(location);
}
@Override
public Biome getBiome() {
return biome;
}
@Override
public Point getLocation() {
return location;
}
}
public class DefaultWorld implements World {
private Matrix<Chunk> chunkMatrix = new HashMapMatrix<>();
private ChunkFactory chunkFactory;
public DefaultWorld(ChunkFactory chunkFactory) {
this.chunkFactory = chunkFactory;
}
public ChunkFactory getChunkFactory() {
return chunkFactory;
}
protected Matrix<Chunk> getChunks() {
return chunkMatrix;
}
@Override
public Chunk getChunkAt(int x, int y) {
Chunk chunk = getChunks().get(x, y);
if (chunk == null) {
chunk = getChunkFactory().createChunk(new Point(x, y));
getChunks().put(chunk, x, y);
}
return chunk;
}
}
}