我正在尝试制作一个滚动游戏 - 玩家(在太空中)始终位于屏幕的中心。当他左右上下移动时,背景spritesheet将随机生成彩色星星 - 因此移动的星星将指示玩家向哪个方向移动。
我现在遇到的问题是,当我运行游戏时,星星不显示。每个图块应该是32x32,每个图块包含至少一个星形,“nostars”图块为空。当我运行游戏时,我只是得到一个黑屏。
RandomLevel.java:
protected void generateLevel() {
for(int y = 0; y < height; y++) {
for(int x = 0; x < width; x++) {
bgtiles[x + y * width] = random.nextInt(4);
}
}
}
Level.java
public void render(int xScroll, int yScroll, Screen screen) {
screen.setOffset(xScroll, yScroll);
int x0 = xScroll >> 5;
int x1 = (xScroll + screen.width + 32) >> 5;
int y0 = yScroll >> 5;
int y1 = (yScroll + screen.height + 32) >> 5;
for(int y = y0; y < y1; y++) {
for(int x = x0; x < x1; x++) {
getTile(x, y).render(x, y, screen);
}
}
}
public Tile getTile(int x, int y) {
if(x < 0 || y < 0 || x >= width || y >= height) return Tile.nostars;
if(bgtiles[x + y * width] == 0) return Tile.stars1;
if(bgtiles[x + y * width] == 1) return Tile.stars2;
if(bgtiles[x + y * width] == 2) return Tile.stars3;
if(bgtiles[x + y * width] == 3) return Tile.stars4;
else return Tile.nostars;
}
SpaceTile.java
public class SpaceTile extends Tile {
public SpaceTile(Sprite sprite) {
super(sprite);
}
public void render(int x, int y, Screen screen) {
screen.renderTile(x << 5, y << 5, this);
}
}
SpriteSheet.java
public static SpriteSheet bgtiles = new SpriteSheet("/textures/bgsheet.png", 256);
Sprite.java
public static Sprite spaceSprite = new Sprite(32, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars1 = new Sprite(64, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars2 = new Sprite(96, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars3 = new Sprite(128, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars4 = new Sprite(160, 0, 0, SpriteSheet.bgtiles);
Tile.java
public class Tile {
public int x, y;
public Sprite sprite;
public static Tile nostars = new SpaceTile(Sprite.spaceSprite);
public static Tile stars1 = new SpaceTile(Sprite.stars1);
public static Tile stars2 = new SpaceTile(Sprite.stars2);
public static Tile stars3 = new SpaceTile(Sprite.stars3);
public static Tile stars4 = new SpaceTile(Sprite.stars4);
public Tile(Sprite sprite) {
this.sprite = sprite;
}
public void render(int x, int y, Screen screen) {
}
public boolean solid() {
return false;
}
}
Game.java
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
public static String title = "Game";
private Thread thread;
private JFrame frame;
private Keyboard key;
private Level level;
private boolean running = false;
private Screen screen;
private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
public Game() {
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
screen = new Screen(width, height);
frame = new JFrame();
key = new Keyboard();
level = new RandomLevel(64, 64);
addKeyListener(key);
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Display");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
requestFocus();
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while(delta >= 1) {
update();
updates++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer >= 1000) {
timer += 1000;
frame.setTitle(title + " | " + updates + " ups, " + frames + " fps");
frames = 0;
updates = 0;
}
}
stop();
}
int x, y = 0;
public void update() {
key.update();
if(key.up == true) y--;
if(key.down == true) y++;
if(key.left == true) x--;
if(key.right == true) x++;
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
screen.clear();
level.render(x, y, screen);
for(int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle(Game.title);
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
bgsheet.png https://i.imgur.com/0yUKql2.png?1
在generatelevel()中,我只尝试使用前4个图块,而不是所有64个图块。
当我运行游戏时,我希望看到四处散落的星星,但我只是得到一个黑屏。
提前感谢您的帮助!
答案 0 :(得分:1)
从发布的代码中,您似乎忘记将背景加载到图像中。我将此代码放入一个名为loadAssets()的新公共方法中。在调用game.start()之前调用它。
public void loadAssets() {
try {
image = ImageIO.read(new URL("https://i.imgur.com/0yUKql2.png?1"));
} catch (MalformedURLException ex) {
Logger.getLogger(GameTwo.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(GameTwo.class.getName()).log(Level.SEVERE, null, ex);
}
}
我还在render()中注释掉了以下代码。
screen.clear();
level.render(x, y, screen);
for(int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
}
答案 1 :(得分:0)
因此,根据我的理解,您使用BufferedImage图像调用绘图,但是您实际上并未将图像数据加载到变量图像中。我将提供您可能需要定制的代码片段
File imageFile = new File("/path/to/image.file");
BufferedImage image = ImageIO.read(imageFile);
可能有一种更快的方法,因为你已经调用了
private BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
但是你可以想象,实际上并没有将图像变量连接到图像文件。我最好的猜测是我提供的代码可以使用,但老实说,你必须尝试它。
如果您有任何问题,请尽快编码并发表评论!
答案 2 :(得分:0)
问题原来只是我为每个精灵设置了错误的坐标。很抱歉浪费你的时间并感谢你的帮助!
public static Sprite spaceSprite = new Sprite(32, 0, 0, SpriteSheet.bgtiles);
public static Sprite stars1 = new Sprite(32, 1, 0, SpriteSheet.bgtiles);
public static Sprite stars2 = new Sprite(32, 2, 0, SpriteSheet.bgtiles);
public static Sprite stars3 = new Sprite(32, 3, 0, SpriteSheet.bgtiles);
public static Sprite stars4 = new Sprite(32, 4, 0, SpriteSheet.bgtiles);