(我知道NullPointerException是什么,在这种情况下我只是无法弄清楚是什么原因引起的。)
我正在尝试用Java做一个小型平台器,但是我似乎无法解决这个问题。运行此代码时,屏幕上的图像开始闪烁,并且在控制台中收到此错误:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
at main.EntityManager.render(EntityManager.java:16)
at main.Level.render(Level.java:48)
at main.Game.paintComponent(Game.java:27)
at javax.swing.JComponent.paint(Unknown Source)
我已将问题缩小到Block类中的“ g.drawImage()”方法。如果我将g.drawImage()替换为g.drawRect(),则不会发生闪烁,也不会出错,因此Java尝试绘制图像似乎存在问题。另外,如果我将level [] []数组从[20] [20]减少到[5] [5],则不会出现闪烁,也不会发生错误。
似乎有一些导致闪烁的根本原因:
1)屏幕上显示太多纹理 2)显示纹理而不是g.drawRect()
我也不认为这是我的计算机的问题,因为我有另一个程序,该程序具有类似的处理带有纹理的渲染的方法,并且当我用与我拥有的纹理大小相同的纹理填充屏幕时在这里,它工作得非常好,所以我不确定是什么引起了这里的差异。
以下是相关的课程:
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import entities.Block;
import entities.FloorBlock;
public class Level
{
public Block[][] level;
int blockDim;
private Component component;
private EntityManager em;
public Level(String path, Component component)
{
this.component = component;
blockDim = component.width/30;
em = new EntityManager();
loadLevelFromImage(ImageLoader.loadImage(path));
}
public void loadLevelFromImage(BufferedImage image)
{
//level = new Block[image.getWidth()][(component.getHeight()-image.getHeight())/blockDim + 1]; //The +1 is just to avoid any rounding errors.
level = new Block[5][5];
for(int x = 0; x < level.length; x++)
for(int y = 0; y < level[x].length; y++)
level[x][y] = new FloorBlock(x * blockDim, y * blockDim, blockDim, blockDim);
}
public void update()
{
em.clear();
for(int x = 0; x < level.length; x++)
for(int y = 0; y < level[x].length; y++)
if(level[x][y] != null)
em.add(level[x][y]);
}
public void render(Graphics g)
{
em.render(g);
}
}
import java.awt.image.BufferedImage;
public class Frames
{
public static BufferedImage floorBlock,qBlock,brickBlock,wallBlock, coin;
public static BufferedImage unloaded;
public static void init()
{
SpriteSheet sheet = new SpriteSheet("yh.png", 16, 16);
floorBlock = sheet.crop(0, 0);
qBlock = sheet.crop(0, 1);
brickBlock = sheet.crop(0, 2);
wallBlock = sheet.crop(0, 3);
coin = sheet.crop(1, 0);
unloaded = ImageLoader.loadImage("unloaded.png");
}
}
import java.awt.Graphics;
import java.util.ArrayList;
import entities.Entity;
public class EntityManager
{
public ArrayList<Entity> entities = new ArrayList<Entity>();
public void render(Graphics g)
{
for(int i = 0; i < entities.size(); i++)
entities.get(i).render(g);
}
public void add(Entity e)
{
entities.add(e);
}
public void clear()
{
entities.clear();
}
}
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Game extends JPanel
{
public Component component;
private Input input;
Level level;
public Game(Component component)
{
setBackground(Color.CYAN);
this.component = component;
input = new Input(component);
level = new Level("testLevel.png", component);
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
level.render(g);
}
public void update()
{
level.update();
}
}
import java.awt.Graphics;
abstract public class Entity
{
public int x, y, width, height;
public Entity(int x, int y, int width, int height)
{
this.x = x; this.y = y; this.width = width; this.height = height;
}
abstract public void render(Graphics g);
}
```package entities;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import main.Frames;
public class Block extends Entity
{
public BufferedImage texture;
public int id;
public static final int FLOORBLOCK_ID = 1, QBLOCK_ID = 2, BRICKBLOCK_ID = 3, WALLBLOCK_ID = 4, COIN_ID = 5;
public Block(int x, int y, int width, int height, int id)
{
super(x, y, width, height);
this.id = id;
switch(id)
{
case FLOORBLOCK_ID:
texture = Frames.floorBlock;
break;
case QBLOCK_ID:
texture = Frames.qBlock;
break;
case BRICKBLOCK_ID:
texture = Frames.brickBlock;
break;
case WALLBLOCK_ID:
texture = Frames.wallBlock;
break;
case COIN_ID:
texture = Frames.coin;
break;
default:
texture = Frames.unloaded;
break;
}
}
@Override
public void render(Graphics g)
{
if(texture != null)
g.drawImage(texture, x, y, width, height, null);
else
g.drawImage(Frames.unloaded, x, y, width, height, null);
}
}
public class FloorBlock extends Block
{
public FloorBlock(int x, int y, int width, int height)
{
super(x, y, width, height, Block.FLOORBLOCK_ID);
}
}
import java.awt.image.BufferedImage;
public class Frames
{
public static BufferedImage floorBlock,qBlock,brickBlock,wallBlock, coin;
public static BufferedImage unloaded;
public static void init()
{
SpriteSheet sheet = new SpriteSheet("yh.png", 16, 16);
floorBlock = sheet.crop(0, 0);
qBlock = sheet.crop(0, 1);
brickBlock = sheet.crop(0, 2);
wallBlock = sheet.crop(0, 3);
coin = sheet.crop(1, 0);
unloaded = ImageLoader.loadImage("unloaded.png");
}
}