ゲーム用のフォントを作成しようとしていますが、ロードするたびに次のエラーが発生します。
Exception in thread "main" java.lang.NullPointerException
at image.ImageFont.load(ImageFont.java:78)
at image.ImageFont.<init>(ImageFont.java:47)
at image.ImageFontTest.init(ImageFontTest.java:26)
at image.GameCore.run(GameCore.java:65)
at image.ImageFontTest.main(ImageFontTest.java:11)
そのためのファイルもあります:
ImageFontTest
public class ImageFontTest extends GameCore {
public static void main(String[] args) {
new ImageFontTest().run();
}
private static final long TOTAL_TIME = 6500;
private ImageFont bigFont;
private ImageFont medFont;
private long remainingTime;
private CharMovement[] charMovement;
public void init() {
super.init();
remainingTime = TOTAL_TIME;
// load image fonts
bigFont = new ImageFont("fonts/big");
medFont = new ImageFont("fonts/medium");
String message = "Good Times!";
int stringWidth = medFont.stringWidth(message);
charMovement = new CharMovement[message.length()];
for (int i=0; i<message.length(); i++) {
charMovement[i] = new CharMovement(message, i,
(screen.getWidth() - stringWidth) / 2,
screen.getHeight() / 2);
}
}
public void update(long elapsedTime) {
remainingTime -= elapsedTime;
if (remainingTime <= 0) {
stop();
}
}
public void draw(Graphics2D g) {
// erase background
g.setColor(Color.BLACK);
g.fillRect(0,0,screen.getWidth(), screen.getHeight());
// draw some aligned text
medFont.drawString(g, "Left", 0, 0,
ImageFont.LEFT | ImageFont.TOP);
medFont.drawString(g, "Center", screen.getWidth()/2, 0,
ImageFont.HCENTER | ImageFont.TOP);
medFont.drawString(g, "Right", screen.getWidth(), 0,
ImageFont.RIGHT | ImageFont.TOP);
// draw seconds remaining
String timeLeft = "" + (remainingTime / 1000);
bigFont.drawString(g, timeLeft, 0, screen.getHeight());
// draw moving characters
double p = (double)(TOTAL_TIME - remainingTime) / TOTAL_TIME;
for (int i=0; i<charMovement.length; i++) {
charMovement[i].draw(g, p);
}
}
/**
Simple animation class to animate a character along a
path.
*/
public class CharMovement {
char ch;
Point[] path;
public CharMovement(String s, int charIndex, int x, int y) {
int stringWidth = medFont.stringWidth(s);
for (int i=0; i<charIndex; i++) {
x+=medFont.charWidth(s.charAt(i));
}
ch = s.charAt(charIndex);
path = new Point[4];
// start offscreen
path[0] = new Point(x-2000, y);
// move to the center of the screen and pause there
path[1] = new Point(x, y);
path[2] = path[1];
// "explode" at a random angle far away
double angle = Math.random() * 2 * Math.PI;
double distance = 1000 + 1000*Math.random();
path[3] = new Point(
(int)Math.round(x + Math.cos(angle) * distance),
(int)Math.round(y + Math.sin(angle) * distance));
}
/**
Draws this character in the path, where p is the
location in the path from 0 to 1.
*/
public void draw(Graphics g, double p) {
int points = path.length - 1;
int index = (int)(p*points);
p = p * points - index;
Point start = path[index % path.length];
Point goal = path[(index + 1) % path.length];
int x = (int)Math.round(goal.x * p + start.x * (1-p));
int y = (int)Math.round(goal.y * p + start.y * (1-p));
medFont.drawChar(g, ch, x, y);
}
}
}
画像フォント
/**
The ImageFont class allows loading and drawing of text
using images for the characters.
Reads all the png images in a directory in the form
"charXX.png" where "XX" is a decimal unicode value.
Characters can have different widths and heights.
*/
public class ImageFont {
public static final int HCENTER = 1;
public static final int VCENTER = 2;
public static final int LEFT = 4;
public static final int RIGHT = 8;
public static final int TOP = 16;
public static final int BOTTOM = 32;
private char firstChar;
private Image[] characters;
private Image invalidCharacter;
/**
Creates a new ImageFont with no characters.
*/
public ImageFont() {
this(null);
firstChar = 0;
characters = new Image[0];
}
/**
Creates a new ImageFont and loads character images from
the specified path.
*/
public ImageFont(String path) {
if (path != null) {
load(path);
}
// make the character used for invalid characters
invalidCharacter =
new BufferedImage(10, 10, BufferedImage.TYPE_INT_RGB);
Graphics g = invalidCharacter.getGraphics();
g.setColor(Color.RED);
g.fillRect(0,0,10,10);
g.dispose();
}
/**
Loads the image files for each character from the
specified path. For example, if "../fonts/large"
is the path, this method searches for all the images
names "charXX.png" in that path, where "XX" is a
decimal unicode value. Not every character image needs
to exist; you can only do numbers or uppercase letters,
for example.
*/
public void load(String path) throws NumberFormatException {
// in this directory:
// load every png file that starts with 'char'
File dir = new File(path);
File[] files = dir.listFiles();
// find min and max chars
char minChar = Character.MAX_VALUE;
char maxChar = Character.MIN_VALUE;
for (int i=0; i<files.length; i++) {
int unicodeValue = getUnicodeValue(files[i]);
if (unicodeValue != -1) {
minChar = (char)Math.min(minChar, unicodeValue);
maxChar = (char)Math.max(maxChar, unicodeValue);
}
}
// load the images
if (minChar < maxChar) {
firstChar = minChar;
characters = new Image[maxChar - minChar + 1];
for (int i=0; i<files.length; i++) {
int unicodeValue = getUnicodeValue(files[i]);
if (unicodeValue != -1) {
int index = unicodeValue - firstChar;
characters[index] = new ImageIcon(
files[i].getAbsolutePath()).getImage();
}
}
}
}
private int getUnicodeValue(File file)
throws NumberFormatException
{
String name = file.getName().toLowerCase();
if (name.startsWith("char") && name.endsWith(".png")) {
String unicodeString =
name.substring(4, name.length() - 4);
return Integer.parseInt(unicodeString);
}
return -1;
}
/**
Gets the image for a specific character. If no image for
the character exists, a special "invalid" character image
is returned.
*/
public Image getImage(char ch) {
int index = ch - firstChar;
if (index < 0 || index >= characters.length ||
characters[index] == null)
{
return invalidCharacter;
}
else {
return characters[index];
}
}
/**
Gets the string width, in pixels, for the specified string.
*/
public int stringWidth(String s) {
int width = 0;
for (int i=0; i<s.length(); i++) {
width += charWidth(s.charAt(i));
}
return width;
}
/**
Gets the char width, in pixels, for the specified char.
*/
public int charWidth(char ch) {
return getImage(ch).getWidth(null);
}
/**
Gets the char height, in pixels, for the specified char.
*/
public int charHeight(char ch) {
return getImage(ch).getHeight(null);
}
/**
Draws the specified string at the (x, y) location.
*/
public void drawString(Graphics g, String s, int x, int y) {
drawString(g, s, x, y, LEFT | BOTTOM);
}
/**
Draws the specified string at the (x, y) location.
*/
public void drawString(Graphics g, String s, int x, int y,
int anchor)
{
if ((anchor & HCENTER) != 0) {
x-=stringWidth(s) / 2;
}
else if ((anchor & RIGHT) != 0) {
x-=stringWidth(s);
}
// clear horizontal flags for char drawing
anchor &= ~HCENTER;
anchor &= ~RIGHT;
// draw the characters
for (int i=0; i<s.length(); i++) {
drawChar(g, s.charAt(i), x, y, anchor);
x+=charWidth(s.charAt(i));
}
}
/**
Draws the specified character at the (x, y) location.
*/
public void drawChar(Graphics g, char ch, int x, int y) {
drawChar(g, ch, x, y, LEFT | BOTTOM);
}
/**
Draws the specified character at the (x, y) location.
*/
public void drawChar(Graphics g, char ch, int x, int y,
int anchor)
{
if ((anchor & HCENTER) != 0) {
x-=charWidth(ch) / 2;
}
else if ((anchor & RIGHT) != 0) {
x-=charWidth(ch);
}
if ((anchor & VCENTER) != 0) {
y-=charHeight(ch) / 2;
}
else if ((anchor & BOTTOM) != 0) {
y-=charHeight(ch);
}
g.drawImage(getImage(ch), x, y, null);
}
}
問題は ImageFont の読み込み中にあると表示されていますが、修正方法がわかりません。