所以,正如标题所示,我试图在我的java游戏中添加偏移量。我被朋友给了一个提示,我需要减去我将瓷砖渲染到屏幕上的偏移量。
所以我创建了一个随机的世界生成器并做了偏移的事情,但我遇到了一个问题。
我的代码:
public void generateMap(Graphics g) {
block = seed.nextInt(2);
//Render Dirt
if(block == 0) {
g.drawImage(Assets.dirt, x - GameState.xOffset, y - GameState.yOffset, null);
x += 32;
}
//Render Grass
if(block == 1) {
g.drawImage(Assets.grass, x - GameState.xOffset, y - GameState.yOffset, null);
x += 32;
}
//Check Where the X is
if(x > xFinish) {
if(y < yFinish) {
x = xStart;
y += 32;
}
}
}
看起来很简单吧?在我这样做之后,我创建代码以在每次循环时向偏移量添加一个:
public void tick() {
xOffset += 1;
}
所以在完成之后我会运行它,但它会这样做:
有什么简单的方法可以解决这个问题,以便屏幕显示“滚动”到左边?
答案 0 :(得分:0)
我有什么简单的方法可以解决这个问题......
可能不是。游戏很复杂。不要让那个劝阻你。
您正在生成游戏世界并使用相同的方法绘图 - 您不希望这样做。 Separation of responsibility非常重要 - 你不希望在一个地方做一大堆代码做同样的事情。在这种情况下,需要拆分生成世界和绘图代码的功能。
对于世界一代,生成一次游戏世界,并使用您喜欢的任何格式将其保存到存储中。 远离绘图代码 - 它没有位置。
为了代表世界上的街区,请考虑以下内容:
class Block {
public BlockType getType() {
return type;
}
public int getxPosition() {
return xPosition;
}
public int getyPosition() {
return yPosition;
}
// hashCode(), equals(), etc omitted, they should be implemented
public static enum BlockType {
Dirt(Assets.dirt),
Grass(Assets.grass);
private final BufferedImage image;
BlockType(BufferedImage image) {
this.image = image;
}
public BufferedImage getImage() {
return image;
}
}
private final BlockType type;
private final int xPosition;
private final int yPosition;
private Block(BlockType type, int xPosition, int yPosition) {
this.type = type;
this.xPosition = xPosition;
this.yPosition = yPosition;
}
public static Block getInstance(BlockType type, int xPosition, int yPosition) {
return new Block(type, xPosition, yPosition);
}
}
然后,您可以使用Block.getInstance()
生成地图一次,如下所示:
class GameState {
private final int WORLD_SIZE = 1024;
private Block[][] _world = new Block[WORLD_SIZE][WORLD_SIZE];
private static Random seed = new Random();
public void generateMap() {
int blockTypeLength = Block.BlockType.values().length;
for (int x = 0; x < WORLD_SIZE; x++) {
for (int y = 0; y < WORLD_SIZE; y++) {
int blockType = seed.nextInt(blockTypeLength);
_world[x][y] = Block.getInstance(Block.BlockType.values()[blockType], x, y);
}
}
}
public Block[][] getMap() {
return _world; // not thread safe, shares internal state, all the usual warnings
}
这显然不是生成世界的唯一方法 - 你可能会生成一个世界并保存,然后在以后的游戏中从磁盘加载(除非它是一个短暂的游戏 - 我不知道,这是你的电话)。
一旦你完成整个世界,你就会转向另一个可以处理绘图的模块。假设GameState有两个字段playerX
和playerY
代表玩家在游戏世界中的坐标(注意:像这样的直接字段是不好的做法,但用于简化这个例子):
public void paintComponent(Graphics g) {
super.paintComponent(g);
Block[][] screen = new Block[16][16]; // declare a screen buffer to draw
// Assumes player is in the center of the screen
int screenRadiusX = GameFrame.Assets.SCREENBOUNDS_X / 2 / blockSize;
int screenRadiusY = GameFrame.Assets.SCREENBOUNDS_Y / 2 / blockSize;
for (int x = state.playerX - 8, xS = 0; x < state.playerX + 8; x++, xS++) {
for (int y = state.playerY - 8, yS = 0; y < state.playerY + 8; y++, yS++) {
screen[xS][yS] = world[x][y];
}
}
for (int x = 0; x < screen.length; x++) {
for (int y = 0; y < screen.length; y++) {
Block current = screen[x][y];
g.drawImage(current.getType().getImage(),
x * blockSize, // blockSize is the pixel dimension of
y * blockSize,
null
);
}
}
}
如果这有帮助,那就太好了!我很高兴能够提供帮助。如果没有,或者某些想法仍然不清楚,那么我会考虑通过一本指导你制作游戏的教程或书籍。不要忘记在这样的过程中学习您正在编写的平台。