I'm following a tutorial from theChernoProject, however in episode 22 i keep getting a nullPointerException whem trying to render the pixels array from the sprite ?
Error:
Exception in thread "Game" java.lang.ExceptionInInitializerError
at com.santec.game.learning.thecherno.graphics.Screen.render(Screen.java:40)
at com.santec.game.learning.thecherno.Game.render(Game.java:109)
at com.santec.game.learning.thecherno.Game.run(Game.java:78)
at java.lang.Thread.run(Unknown Source)
Caused by: java.lang.NullPointerException
at com.santec.game.learning.thecherno.graphics.Sprite.load(Sprite.java:23)
at com.santec.game.learning.thecherno.graphics.Sprite.<init>(Sprite.java:17)
at com.santec.game.learning.thecherno.graphics.Sprite.<clinit>(Sprite.java:10)
... 4 more
Classes:
Game.java :
package com.santec.game.learning.thecherno;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import com.santec.game.learning.thecherno.graphics.Screen;
import com.santec.game.learning.thecherno.input.Keyboard;
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 = "Rain";
private Thread thread;
private JFrame frame;
private boolean running = false;
private Screen screen;
private Keyboard key;
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();
addKeyListener(key);
}
public synchronized void start() {
running = true;
thread = new Thread(this, "Game");
thread.start();
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
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");
updates = 0;
frames = 0;
}
}
stop();
}
int x = 0, y = 0;
public void update() {
key.update();
if(key.up) y--;
if(key.down) y++;
if(key.right) x++;
if(key.left) x--;
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if(bs == null) {
createBufferStrategy(3);
return;
}
screen.clear();
screen.render(x, y);
for(int i = 0; i < pixels.length; i++) {
pixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
{
g.setColor(Color.cyan);
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();
}
}
graphics/SpriteSheet.java :
package com.santec.game.learning.thecherno.graphics;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SpriteSheet {
private String path;
public final int SIZE;
public int[] pixels;
// Spritesheets
public static SpriteSheet terrain = new SpriteSheet("/textures/terrain.png", 96);
public SpriteSheet(String path, int size) {
this.path = path;
SIZE = size;
pixels = new int[SIZE * SIZE];
load();
}
private void load() {
try {
BufferedImage image = ImageIO.read(SpriteSheet.class.getResource(path));
int w = image.getWidth();
int h = image.getHeight();
image.getRGB(0, 0, w, h, pixels, 0, w);
} catch (IOException e) {
e.printStackTrace();
}
}
}
graphics/Screen.java :
package com.santec.game.learning.thecherno.graphics;
import java.util.Random;
public class Screen {
private int width, height;
public int[] pixels;
public final int MAP_SIZE = 8;
public final int MAP_SIZE_MASK = MAP_SIZE - 1;
public int[] tiles = new int[MAP_SIZE * MAP_SIZE];
private Random random = new Random();
public Screen(int width, int height) {
this.width = width;
this.height = height;
pixels = new int[width * height];
for(int i = 0; i < MAP_SIZE * MAP_SIZE; i++) {
tiles[i] = random.nextInt(0xffffff);
tiles[0] = 0;
}
}
public void clear() {
for(int i = 0; i < pixels.length; i++) {
pixels[i] = 0;
}
}
public void render(int xOffset, int yOffset) {
for(int y = 0; y < height; y++) {
int yy = y + yOffset;
if(yy >= height || yy < 0) break;
for(int x = 0; x < width; x++) {
int xx = x + xOffset;
if(xx >= width || xx < 0) break;
int tileIndex = ((xx >> 4) & MAP_SIZE_MASK) + ((yy >> 4) & MAP_SIZE_MASK) * 8;
pixels[x + y * width] = Sprite.grass.pixels[(xx & 15) + (yy & 15) * Sprite.grass.SIZE];
}
}
}
}
graphics/Sprite.java :
package com.santec.game.learning.thecherno.graphics;
public class Sprite {
public final int SIZE;
private int x, y;
public int[] pixels;
private SpriteSheet sheet;
public static Sprite grass = new Sprite(16, 0, 1, SpriteSheet.terrain);
public Sprite(int size, int x, int y, SpriteSheet sheet) {
SIZE = size;
this.x = x * size;
this.y = y * size;
this.sheet = sheet;
load();
}
private void load() {
for(int y = 0; y < SIZE; y++) {
for(int x = 0; x < SIZE; x++) {
pixels[x + y * SIZE] = sheet.pixels[(x + this.x) + (y + this.y) * sheet.SIZE];
}
}
}
}
You never initialize the pixels array.
add
this.pixels = new int[SIZE*SIZE]; // assuming that's the desired length or that array
to the start of your load method.
Related
I am trying to add the image sprite_sheet.png to my game project but I get these errors:
Exception in thread "main" java.lang.IllegalArgumentException: input == null!
at javax.imageio.ImageIO.read(Unknown Source)
at az.rehman.gfx.SpriteSheet.<init>(SpriteSheet.java:16)
at az.rehman.game.Game.<init>(Game.java:29)
at az.rehman.game.Game.main(Game.java:127)
Here are my classes:
package az.rehman.gfx;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SpriteSheet {
public String path;
public int width;
public int height;
public int[] pixels;
public SpriteSheet(String path) {
BufferedImage image = null;
try {
image = ImageIO.read(SpriteSheet.class.getResource(path));
} catch (IOException e) {
System.out.println("SpriteSheet file exception");
e.printStackTrace();
}
if(image == null)
return;
this.path = path;
this.width = image.getWidth();
this.height = image.getHeight();
pixels = image.getRGB(0, 0, width, height, null, 0, width);
for(int i = 0; i < pixels.length; i++) {
pixels[i] = (pixels[i] & 0xff/64);
}
for(int i = 0; i < 8; i++) {
System.out.println(pixels[i]);
}
} // constructer end
} // class end
package az.rehman.game;
import az.rehman.gfx.SpriteSheet;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
public class Game extends Canvas implements Runnable {
public static final long serialVersionUID = 1L;
public static final int WIDTH = 160;
public static final int HEIGHT = WIDTH / 12 * 9;
public static final int SCALE = 3;
public static final String NAME = "Game";
private JFrame frame;
public boolean running = false;
public int tickCount = 0;
private BufferedImage image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
private SpriteSheet spriteSheet = new SpriteSheet("\\sprite_sheet.png");
public Game() {
setMinimumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setMaximumSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
setPreferredSize(new Dimension(WIDTH * SCALE, HEIGHT * SCALE));
frame = new JFrame(NAME);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(this, BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public synchronized void start() {
running = true;
new Thread(this).start();
}
public synchronized void stop() {
running = false;
}
public void run() {
long lastTime = System.nanoTime();
double nsPerTick = 1000000000D / 60D;
int ticks = 0;
int frames = 0;
long lastTimer = System.currentTimeMillis();
double delta = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / nsPerTick;
lastTime = now;
boolean shouldRender = true;
while (delta >= 1) {
ticks++;
tick();
delta -= 1;
shouldRender = true;
}
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
if (shouldRender) {
frames++;
render();
}
if (System.currentTimeMillis() - lastTimer >= 1000) {
lastTimer += 1000;
System.out.println(ticks + " ticks, " + frames + " frames");
frames = 0;
ticks = 0;
}
}
}
public void tick() {
tickCount++;
for (int i = 0; i < pixels.length; i++) {
pixels[i] = i + tickCount;
}
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public static void main(String[] args) {
new Game().start();
}
}
So I have been trying to follow a tutorial
But it isn't working. It is a tutorial on making a sprite sheet with JFrame. I could get other things to work, but for some reason this won't. It is supposed to display a tiled image, but instead it displays a black screen.
Game.java
package ca.colescheler.game;
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import ca.colescheler.game.gfx.Screen;
import ca.colescheler.game.gfx.SpriteSheet;
#SuppressWarnings("unused")
public class Game extends Canvas implements Runnable {
/**
*
*/
private static final long serialVersionUID = 9086760045199246082L;
private BufferedImage image = new BufferedImage(WIDTH,HEIGHT,BufferedImage.TYPE_INT_RGB);
private int[] pixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
public boolean running;
private static final long serialVesionUID = 1;
public static final int WIDTH = 160;
public static final int HEIGHT = WIDTH/12*9;
public static final int SCALE=3;
public static final String NAME="Game";
private JFrame frame;
int tickCount=1;
private SpriteSheet spriteSheet = new SpriteSheet("/sprite_sheet.png");
private Screen screen;
public static long getSerialvesionuid() {
return serialVesionUID;
}
public Game() {
setMinimumSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
setMaximumSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
setPreferredSize(new Dimension(WIDTH*SCALE,HEIGHT*SCALE));
frame = new JFrame(NAME);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(this, BorderLayout.CENTER);
frame.pack();
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public void init() {
screen = new Screen(WIDTH,HEIGHT,new SpriteSheet("/sprite_sheet.png"));
}
public void tick() {
tickCount++;
}
long now = System.nanoTime();
public synchronized void stop() {
// TODO Auto-generated method stub
}
public synchronized void start() {
// TODO Auto-generated method stub
//new Thread(this).start();
running = true;
run();
frames = 1;
ticks = 1;
}
static int frames = 0;
static int ticks = 0;
public void run() {
long lastTime = System.nanoTime();
double nsPerTick = 1000000000d/60d;
long lastTimer = System.currentTimeMillis();
double delta=0;
while (running) {
init();
long now = System.nanoTime();
delta += (now - lastTime) / nsPerTick;
lastTime = now;
boolean shouldRender = false;
while (delta >= 1) {
ticks++;
tick();
delta -= 1;
shouldRender = true;
}
if (shouldRender) {
render();
}
if (System.currentTimeMillis() - lastTimer > 1000) {
lastTimer += 1000;
System.out.println(frames + ", " + ticks);
frames=0;
ticks=0;
}
}
}
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
this.createBufferStrategy(3);
return;
}
screen.render(pixels, 0, WIDTH);
Graphics g = bs.getDrawGraphics();
//g.drawRect(0, 0, getWidth(), getHeight());
//g.drawImage(image, 0, 0, getWidth(), getHeight(), null);
g.dispose();
bs.show();
}
public static void main(String args[]) {
new Game().start();
}
}
SpriteSheet.java
package ca.colescheler.game.gfx;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
public class SpriteSheet {
public String path;
public int width;
public int height;
public int[] pixels;
public SpriteSheet(String path) {
BufferedImage image = null;
try {
image = ImageIO.read(SpriteSheet.class.getResourceAsStream(path));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
if (image == null) {
return;
}
this.path = path;
this.width = image.getWidth();
this.height = image.getHeight();
pixels = image.getRGB(0, 0, width, height, null, 0, width);
//AARRGGBB
for (int i=0; i<pixels.length;i++) {
pixels[i] = (pixels[i] & 0xff)/64;
}
for(int i=0; i<8;i++) {
System.out.println(pixels[i]);
}
//85*0
}
}
Screen.java
package ca.colescheler.game.gfx;
public class Screen {
public static final int MAP_WIDTH = 64;
public static final int MAP_WIDTH_MASK = MAP_WIDTH - 1;
public int[] tiles = new int[MAP_WIDTH * MAP_WIDTH];
public int[] colours = new int[MAP_WIDTH * MAP_WIDTH * 4];
public int xOffset = 0;
public int yOffset = 0;
public int width;
public int height;
public SpriteSheet sheet;
public Screen(int width, int height, SpriteSheet sheet) {
this.width = width;
this.height = height;
this.sheet = sheet;
for (int i=1;i<MAP_WIDTH*MAP_WIDTH;i++) {
colours[i*4+0] = 0xff00ff;
colours[i*4+1] = 0x00ffff;
colours[i*4+2] = 0xffff00;
colours[i*4+3] = 0xffffff;
}
}
public void render(int[] pixels, int offset, int row) {
for (int yTile = yOffset>>3;yTile <-(yOffset + height) >>3; yTile++) {
int yMin = yTile * 8 - yOffset;
int yMax = yMin + 8;
if (yMin < 0) yMin = 0;
if (yMax > height) yMax = height;
for (int xTile = xOffset >>3; xTile <=(xOffset+width) >>3; xTile++) {
int xMin = xTile * 8 - xOffset;
int xMax = xMin + 8;
if (xMin < 0) xMin = 0;
if (xMax > width) xMax = height;
int tileIndex = (xTile &(MAP_WIDTH_MASK)) + (yTile & (MAP_WIDTH_MASK)) * MAP_WIDTH;
for (int y = yMin;y<yMax;y++) {
int sheetPixel = ((y+yOffset) & 7) * sheet.width + ((xMin + xOffset) & 7);
int tilePixel = offset + xMin + y * row;
for (int x=xMin; x<xMax;x++) {
int colour = tileIndex * 4 + sheet.pixels[sheetPixel++];
pixels[tilePixel++]=colours[colour];
}
}
}
}
}}
Link to tutorial
In the file Screen.java, there is a typo. You should change height to width in the following line:
if (xMax > width) xMax = height;
I am trying to rotate a perspective vertically, but the image/texture is getting distorted in the middle of the window. The origin is in the middle of the window, positive x-axis is to the right, positive y-axis is to the bottom, and positive z-axis is into the computer screen. yDepth is 0 and z is infinity at the middle of window(height/2). The line that is creating the problem is double yp = yDepth * rotCos + z * rotSin in the class Render3D.java. In short, yp and z are inversely related to give the impression of depth/distance into the screen, and because of this, z is becoming 0 at the origin, causing a distortion. How can I fix this? Is there a better way of doing this?
Note: Use a 32 px by 32 px texture/image as the texture image or use any square image but change the line private static final int TEXTURE_WIDTH = 32 in the render class to private static final int TEXTURE_WIDTH = Texture.image.getWidth(). Thanks.
Here are the classes:
Love.java:
import java.awt.BorderLayout;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Love extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static void main(String[] args) {
Love game = new Love();
JFrame frame = new JFrame("Love");
JPanel panel = new JPanel(new BorderLayout());
panel.add(game, BorderLayout.CENTER);
frame.setContentPane(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
game.start();
}
public Love() {
Dimension size = new Dimension(width, height);
setSize(size);
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
input = new InputHandler();
addKeyListener(input);
addFocusListener(input);
addMouseListener(input);
addMouseMotionListener(input);
image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
imagePixels = ((DataBufferInt) image.getRaster().getDataBuffer()).getData();
screen = new Screen(width, height);
game = new Game();
}
public void start() {
tick++;
if (gameover) {
return;
}
thread = new Thread(this);
thread.start();
}
public void stop() {
if (gameover) {
return;
}
gameover = true;
try {
thread.join();
} catch (Exception e) {
e.printStackTrace();
System.exit(0);
}
}
public void run() {
int frames = 0;
double unprocessedSeconds = 0;
long lastTime = System.nanoTime();
double secondsPerTick = 1 / 60.0;
int tickCount = 0;
requestFocus();
while (!gameover) {
long now = System.nanoTime();
long passedTime = now - lastTime;
lastTime = now;
if (passedTime < 0) passedTime = 0;
if (passedTime > 100000000) passedTime = 100000000;
unprocessedSeconds += passedTime / 1000000000.0;
boolean ticked = false;
while (unprocessedSeconds > secondsPerTick) {
tick();
unprocessedSeconds -= secondsPerTick;
ticked = true;
tickCount++;
if (tickCount % 60 == 0) {
System.out.println(frames + " fps");
lastTime += 1000;
frames = 0;
}
}
if (ticked) {
render();
frames++;
} else {
try {
Thread.sleep(1);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public void tick() {
game.tick(InputHandler.key);
}
public void render() {
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
screen.draw(game);
for (int i = 0; i < width * height; i++) {
imagePixels[i] = screen.pixels[i];
}
Graphics g = bs.getDrawGraphics();
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
bs.show();
}
public static int width = 640;
public static int height = 480;
private InputHandler input;;
private BufferedImage image;
private int tick = 0;
private boolean gameover = false;
private int[] imagePixels;
private Thread thread;
private Screen screen;
private Game game;
public static int r;
}
Game.java:
import java.awt.event.KeyEvent;
public class Game {
public Game() {
player = new Player();
}
public void tick(boolean[] key) {
tick++;
boolean up = key[KeyEvent.VK_UP];
boolean down = key[KeyEvent.VK_DOWN];
player.move(up, down);
}
public int tick;
public Player player;
}
Player.java:
public class Player {
public void move(boolean up, boolean down) {
double rotationSpeed = 0.00275;
if (up) {
rotationa -= rotationSpeed;
}
if (down) {
rotationa += rotationSpeed;
}
rotation += rotationa;
rotationa *= 0.4;
}
public double rotation, rotationa;
}
Render.java:
public class Render3D extends Render {
private static final int TEXTURE_WIDTH = 32;
private static final int TEXTURE_FACTOR = TEXTURE_WIDTH - 1;
int ceiling;
public Render3D(int width, int height) {
super(width, height);
zBuffer = new double[width * height];
zBufferWall = new double[width];
}
public void draw(Game game) {
for (int x = 0; x < width; x++) {
zBufferWall[x] = 0;
}
double floorPosition = TEXTURE_WIDTH;
double ceilingPosition = TEXTURE_WIDTH;
double rotation = game.player.rotation;
rotSin = Math.sin(rotation);
rotCos = Math.cos(rotation);
for (int y = 0; y < height; y++) {
double yDepth = (y - height / 2.0) / height;
for (int x = 0; x < width; x++) {
double xDepth = (x - width / 2.0) / height;
z = (floorPosition) / yDepth;
ceiling = 0;
if (yDepth < 0) {
z = (ceilingPosition) / -yDepth;
ceiling = 1;
}
double yp = yDepth * rotCos + z * rotSin;
double zp = z * rotCos - yDepth * rotSin;
z = (floorPosition) / yp;
ceiling = 0;
if (yp < 0) {
z = (ceilingPosition) / -yp;
ceiling = 1;
}
xDepth *= z;
int xPix = (int) (xDepth);
int zPix = (int) (z);
zBuffer[x + y * width] = z / 4;
if (ceiling == 0) {
pixels[x + y * width] = Texture.texture.pixels[((xPix & TEXTURE_FACTOR)) + (zPix & TEXTURE_FACTOR) * Texture.image.getWidth()];
} else {
pixels[x + y * width] = Texture.texture.pixels[((xPix & TEXTURE_FACTOR)) + (zPix & TEXTURE_FACTOR) * Texture.image.getWidth()];
}
}
}
}
public void renderDistanceLimiter() {
for (int i = 0; i < width * height; i++) {
int colour = pixels[i];
int brightness = (int) (renderDistance / (zBuffer[i]));
if (brightness < 0) {
brightness = 0;
}
if (brightness > 255) {
brightness = 255;
}
int r = (colour >> 16) & 0xff;
int g = (colour >> 8) & 0xff;
int b = (colour) & 0xff;
r = r * brightness / 255;
g = g * brightness / 255;
b = b * brightness / 255;
pixels[i] = r << 16 | g << 8 | b;
}
}
private double z;
public double[] zBuffer;
public double[] zBufferWall;
private double rotSin, rotCos;
public double renderDistance = 5000;
}
Screen.java:
public class Screen extends Render {
private static final int WIDTH = 640;
public Screen(int width, int height) {
super(width, height);
render3D = new Render3D(WIDTH, height);
}
public void draw(Game game) {
for (int i = 0; i < width * height; i++) {
pixels[i] = 0;
}
render3D.draw(game);
render3D.renderDistanceLimiter();
draw(render3D, 0, 0);
}
private Render3D render3D;
}
Render3D.java:
public class Render3D extends Render {
private static final int TEXTURE_WIDTH = 32;
private static final int TEXTURE_FACTOR = TEXTURE_WIDTH - 1;
int ceiling;
public Render3D(int width, int height) {
super(width, height);
zBuffer = new double[width * height];
zBufferWall = new double[width];
}
public void draw(Game game) {
for (int x = 0; x < width; x++) {
zBufferWall[x] = 0;
}
double floorPosition = TEXTURE_WIDTH;
double ceilingPosition = TEXTURE_WIDTH;
double rotation = game.player.rotation;
rotSin = Math.sin(rotation);
rotCos = Math.cos(rotation);
for (int y = 0; y < height; y++) {
double yDepth = (y - height / 2.0) / height;
for (int x = 0; x < width; x++) {
double xDepth = (x - width / 2.0) / height;
z = (floorPosition) / yDepth;
ceiling = 0;
if (yDepth < 0) {
z = (ceilingPosition) / -yDepth;
ceiling = 1;
}
double yp = yDepth * rotCos + z * rotSin;
double zp = z * rotCos - yDepth * rotSin;
z = (floorPosition) / yp;
ceiling = 0;
if (yp < 0) {
z = (ceilingPosition) / -yp;
ceiling = 1;
}
xDepth *= z;
int xPix = (int) (xDepth);
int zPix = (int) (z);
zBuffer[x + y * width] = z / 4;
if (ceiling == 0) {
pixels[x + y * width] = Texture.texture.pixels[((xPix & TEXTURE_FACTOR)) + (zPix & TEXTURE_FACTOR) * Texture.image.getWidth()];
} else {
pixels[x + y * width] = Texture.texture.pixels[((xPix & TEXTURE_FACTOR)) + (zPix & TEXTURE_FACTOR) * Texture.image.getWidth()];
}
}
}
}
public void renderDistanceLimiter() {
for (int i = 0; i < width * height; i++) {
int colour = pixels[i];
int brightness = (int) (renderDistance / (zBuffer[i]));
if (brightness < 0) {
brightness = 0;
}
if (brightness > 255) {
brightness = 255;
}
int r = (colour >> 16) & 0xff;
int g = (colour >> 8) & 0xff;
int b = (colour) & 0xff;
r = r * brightness / 255;
g = g * brightness / 255;
b = b * brightness / 255;
pixels[i] = r << 16 | g << 8 | b;
}
}
private double z;
public double[] zBuffer;
public double[] zBufferWall;
private double rotSin, rotCos;
public double renderDistance = 5000;
}
Texture.java:
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class Texture {
public static Render texture = loadTexture("Texture.png"); //The texture has to be 32 px by 32 px.
public static Render loadTexture(String filename) {
try {
image = ImageIO.read(new File(filename));
int width = image.getWidth();
int height = image.getHeight();
Render render = new Render(width, height);
image.getRGB(0, 0, width, height, render.pixels, 0, width);
return render;
} catch (IOException e) {
throw new RuntimeException (e);
}
}
public int getWidth() {
return image.getWidth();
}
public static BufferedImage image;
}
InputHandler.java:
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
public class InputHandler implements KeyListener, FocusListener, MouseListener, MouseMotionListener {
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
}
#Override
public void mouseClicked(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseReleased(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void focusGained(FocusEvent e) {
// TODO Auto-generated method stub
}
#Override
public void focusLost(FocusEvent e) {
for (int i = 0; i < key.length; i++) {
key[i] = false;
}
}
#Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode > 0 && keyCode < key.length) {
key[keyCode] = true;
}
}
#Override
public void keyReleased(KeyEvent e) {
int keyCode = e.getKeyCode();
if (keyCode > 0 && keyCode < key.length) {
key[keyCode] = false;
}
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
public static int mouseX;
public static int mouseY;
public static boolean[] key = new boolean[68836];
}
I wrote a game in Java and I want to put it on a HTML page. I know how, but the problem is that it gives me a AcessControlException (java.io.FilePermission "/SomePath/SomeFile.SomeExtension" "read").
Here is the Game class (loads the files at initGame method and init the JApplet):
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.swing.JApplet;
public class Game extends JApplet implements Runnable {
private static final long serialVersionUID = 1L;
private Thread thread;
public static BufferedImage level;
public static BufferedImage background;
public static Image2d tileset;
public static Sprite red;
public static Sprite green;
public static Sprite player;
public static boolean mouse_left, mouse_right;
public static boolean jumping;
public static boolean play;
private boolean running = false;
private Image screen;
public static RandomLevel map;
public static Listener listener;
public static Gui gui;
public static int FALL_SPEED = 3;
public static int JUMP_SPEED = 3;
public static int JUMP_HEIGHT = 20;
public static int jump_amount = 0;
public static float START_OFFSET_SPEED = 3.0f;
public static float OFFSET_SPEED = 2.0f;
public static final int sxOffset = 0, syOffset = 0;
public static int xOffset = 0, yOffset = 0;
public static final int CURR_COLOR_SCALE = 32;
public static Sprite[] tiles = new Sprite[2];
public static int selected_color = 0;
public static int SCORE = 0;
public static final int TILE_SIZE = 16;
public static final int SCALE = TILE_SIZE * 2;
public static boolean left, right;
public static int currTime = 0;
public static final Dimension size = new Dimension(800, 600);
public static final Dimension pixel = new Dimension(size.width - SCALE, size.height - SCALE);
public void initGame() {
try {
URL levelUrl = new URL(getCodeBase(), "res/map.png");
level = new Image2d(levelUrl).getImage();
URL backgroundUrl = new URL(getCodeBase(), "res/background.png");
background = new Image2d(backgroundUrl).getImage();
URL tilesetUrl = new URL(getCodeBase(), "res/tileset.png");
tileset = new Image2d(tilesetUrl);
} catch (IOException e) {
}
red = new Sprite(new Image2d(tileset.crop(0, 0, Game.TILE_SIZE, Game.TILE_SIZE)));
green = new Sprite(new Image2d(tileset.crop(1, 0, Game.TILE_SIZE, Game.TILE_SIZE)));
player = new Sprite(new Image2d(tileset.crop(2, 0, Game.TILE_SIZE, Game.TILE_SIZE)));
tiles[0] = red;
tiles[1] = green;
gui = new Gui();
listener = new Listener();
player.setX((size.width - player.getImage().getWidth(null)) / 2);
player.setY((size.height - player.getImage().getHeight(null)) / 2 + 100);
map = new RandomLevel(10000, 20, TILE_SIZE, SCALE, size, xOffset, yOffset);
map.addCollsion(tiles[0]);
addMouseListener(listener);
addMouseMotionListener(new Mouse());
}
public static void switchCollision(Sprite tile) {
map.collision.add(0, tile);
for (int i = 0; i < map.collision.size(); i++) {
if (i != 0)
map.collision.remove(i);
}
}
public void resetGame() {
xOffset = sxOffset;
yOffset = syOffset;
OFFSET_SPEED = START_OFFSET_SPEED;
Game.SCORE = 0;
play = false;
map.generateLevel();
}
public void startGame() {
if (running)
return;
initGame();
running = true;
thread = new Thread(this);
thread.start();
}
public void stopGame() {
if (!running)
return;
running = true;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
screen = createVolatileImage(pixel.width, pixel.height);
requestFocus();
while (running) {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
while (running) {
long now = System.nanoTime();
delta += (now - lastTime) / ns;
lastTime = now;
while (delta >= 1) {
update();
delta--;
}
render();
if (System.currentTimeMillis() - timer > 100) {
timer += 1000;
}
}
stop();
}
}
public void update() {
if (!play && mouse_left)
play = true;
if (play) {
switchCollision(tiles[selected_color]);
if (yOffset > 180)
resetGame();
map.update();
map.setxOffset(xOffset);
map.setyOffset(yOffset);
player.update(25);
gui.update();
if (!map.getTileDownCollision(player))
yOffset += FALL_SPEED;
if (!Game.map.getTileRightCollision(player))
xOffset += Math.round(OFFSET_SPEED);
if (SCORE > 20)
OFFSET_SPEED = 4.0f;
if (SCORE > 40)
OFFSET_SPEED = 5.0f;
if (SCORE > 60)
OFFSET_SPEED = 6.0f;
if (SCORE > 80)
OFFSET_SPEED = 7.0f;
if (SCORE > 100)
OFFSET_SPEED = 8.0f;
if (SCORE > 120)
OFFSET_SPEED = 9.0f;
if (SCORE > 140)
OFFSET_SPEED = 10.0f;
if (jumping) {
FALL_SPEED = 0;
yOffset -= JUMP_SPEED;
jump_amount++;
if (jump_amount >= JUMP_HEIGHT) {
jumping = false;
FALL_SPEED = 3;
jump_amount = 0;
}
}
}
}
public void render() {
Graphics g = screen.getGraphics();
g.setColor(Color.black);
g.fillRect(0, 0, size.width, size.height);
map.render(g);
g.drawImage(player.getImage(), Math.round(player.getX()), Math.round(player.getY()), Game.TILE_SIZE + Game.SCALE, Game.TILE_SIZE + Game.SCALE, null);
g.setFont(new Font("new Font", Font.PLAIN, 10));
g.setColor(Color.white);
g.drawString("CLICK ON THIS SIDE TO JUMP", 200 - xOffset, 240);
g.drawString("CLICK ON THIS SIDE TO SWITCH COLOR", size.width - 350 - xOffset, 240);
g.drawImage(background, 0, 0, null);
g.drawImage(map.collision.get(0).getImage(), (size.width - (Game.TILE_SIZE + CURR_COLOR_SCALE)) / 2, CURR_COLOR_SCALE / 2 - 5, Game.TILE_SIZE + CURR_COLOR_SCALE, Game.TILE_SIZE + CURR_COLOR_SCALE, null);
gui.render(g);
g.setFont(new Font("new Font", Font.BOLD, 32));
g.setColor(Color.yellow);
g.drawString("SCORE: " + SCORE, 10, 32);
g = getGraphics();
g.drawImage(screen, 0, 0, size.width, size.height, 0, 0, pixel.width, pixel.height, null);
g.dispose();
}
public void destroy() {
System.exit(0);
}
public void init() {
setSize(size);
setVisible(true);
startGame();
}
}
EDIT: Here is the Image2d class(holds ImageIO.read command)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
public class Image2d{
private BufferedImage image;
public Image2d(URL url) {
try {
image = ImageIO.read(url);
} catch (IOException e) {
System.err.println("No file found at: " + url);
}
}
public Image2d(String path) {
try {
image = ImageIO.read(new File(path));
} catch (IOException e) {
System.err.println("No file found at: " + path);
}
}
public static BufferedImage load(URL url) {
try {
return ImageIO.read(url);
} catch (IOException e) {
System.err.println("No file found at: " + url.getPath());
return null;
}
}
public static BufferedImage load(String path) {
try {
return ImageIO.read(new File(path));
} catch (IOException e) {
System.err.println("No file found at: " + path);
return null;
}
}
public Image2d(BufferedImage image) {
this.image = image;
}
public BufferedImage crop(int x, int y, int w, int h) {
return image.getSubimage(x * w, y * h, w, h);
}
public static BufferedImage insert(Image2d target, Image2d component) {
BufferedImage tile = new BufferedImage(target.getImage().getWidth(), target.getImage().getHeight(), BufferedImage.TYPE_INT_RGB);
Graphics g = tile.getGraphics();
g.drawImage(component.getImage(), 0, 0, component.getImage().getWidth(), component.getImage().getHeight(), null);
g.drawImage(target.getImage(), 0, 0, target.getImage().getWidth(), target.getImage().getHeight(), null);
return tile;
}
public static BufferedImage switchColor(BufferedImage image, Color color1, Color color2) {
Graphics g = image.getGraphics();
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
Color color = new Color(image.getRGB(x, y));
if (color.getRed() == color1.getRed() && color.getGreen() == color1.getGreen() && color.getBlue() == color1.getBlue() && color.getAlpha() == color1.getAlpha()) {
g.setColor(color2);
g.fillRect(x, y, 1, 1);
}
}
}
return image;
}
public static BufferedImage fill(Color color, int width, int height) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics g = image.getGraphics();
g.setColor(color);
g.fillRect(0, 0, width, height);
return image;
}
public static BufferedImage switchColor(BufferedImage image, Color[] color1, Color[] color2) {
Graphics g = image.getGraphics();
for (int y = 0; y < image.getHeight(); y++) {
for (int x = 0; x < image.getWidth(); x++) {
Color color = new Color(image.getRGB(x, y));
for (int i = 0; i < color1.length; i++)
if (color.getRed() == color1[i].getRed() && color.getGreen() == color1[i].getGreen() && color.getBlue() == color1[i].getBlue() && color.getAlpha() == color1[i].getAlpha()) {
g.setColor(color2[i]);
g.fillRect(x, y, 1, 1);
}
}
}
return image;
}
public static BufferedImage createYDropShadow(int width, int height, int startAlpha, float density, float offset, Color color) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
int alpha = startAlpha;
for (int y = 0; y < image.getHeight(); y++) {
if (alpha >= density)
alpha -= density;
for (int x = 0; x < image.getWidth(); x++) {
g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha));
g.fillRect(x + Math.round(offset), y + Math.round(offset), 1 + Math.round(offset), 1 + Math.round(offset));
}
}
return image;
}
public static BufferedImage createXDropShadow(int width, int height, int startAlpha, float density, float offset, Color color) {
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
int alpha = startAlpha;
for (int x = 0; x < image.getWidth(); x++) {
if (alpha >= density)
alpha -= density;
for (int y = 0; y < image.getHeight(); y++) {
g.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), alpha));
g.fillRect(x + Math.round(offset), y + Math.round(offset), 1 + Math.round(offset), 1 + Math.round(offset));
}
}
return image;
}
public BufferedImage getImage() {
return image;
}
}
And here is html code (it is inside a jar file called Blocks.jar):
<!DOCTYPE html>
<html>
<body>
<applet code="Game.class" archive="Blocks.jar" width="600" height="600"> </applet>
</body>
</html>
I saw people getting the same error but, no answer gave me a solution that worked. So what shoud I do for load the images without erros?
PS: The JApplet is running fine in eclipse, but at the html page throws me this error.
Thanks!
I recently was coding but encountered an null pointer exception
the stack trace says
Exception in thread "main" java.lang.NullPointerException
at com.masterkgames.twisteddream.level.SpawnLevel.generateLevel(SpawnLevel.java:34)
at com.masterkgames.twisteddream.level.Level.<init>(Level.java:22)
at com.masterkgames.twisteddream.level.SpawnLevel.<init>(SpawnLevel.java:16)
at com.masterkgames.twisteddream.Game.<init>(Game.java:49)
at com.masterkgames.twisteddream.Game.main(Game.java:138)
below are the 3 mentioned classes
Spawnlevel.java:
package com.masterkgames.twisteddream.level;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.masterkgames.twisteddream.level.tile.Tile;
public class SpawnLevel extends Level {
private Tile[] tiles;
private int[] levelPixels;
public SpawnLevel(String path) {
super(path);
}
protected void loadLevel(String path){
try{
BufferedImage image = ImageIO.read(SpawnLevel.class.getResource(path));
int w = image.getWidth();
int h = image.getHeight();
tiles = new Tile[w * h];
levelPixels = new int[w * h];
image.getRGB(0,0,w,h,levelPixels,0,w);
}catch(IOException e){
e.printStackTrace();
}
}
protected void generateLevel(){
for(int i = 0; i < levelPixels.length; i++){
if(levelPixels[i] == 0xff00) tiles[i] = Tile.Grass;
if(levelPixels[i] == 0xffff00) tiles[i] = Tile.Rose;
if(levelPixels[i] == 0x7f7f00) tiles[i] = Tile.Stone;
}
}
}
level.java:
package com.masterkgames.twisteddream.level;
import com.masterkgames.twisteddream.graphics.Screen;
import com.masterkgames.twisteddream.level.tile.Tile;
public class Level {
public Screen screen;
protected int width, height;
protected Tile[] tiles;
protected int[] tilesInt;
public Level(int width, int height) {
this.width = width;
this.height = height;
tilesInt = new int[width * height];
generateLevel();
}
public Level(String path) {
loadLevel(path);
generateLevel();
}
protected void generateLevel() {
}
private void loadLevel(String path) {
}
public void update() {
}
private void time() {
}
public void render(int xScroll, int yScroll, Screen screen) {
screen.setOffset(xScroll, yScroll);
int x0 = xScroll >> 4;
int x1 = (xScroll + screen.width + 16) >> 4;
int y0 = yScroll >> 4;
int y1 = (yScroll + screen.height + 16) >> 4;
for (int y = y0; y < y1; y++) {
for (int x = x0; x < x1; x++) {
// getTile(x, y).render(x, y, screen);
if (x + y * 16 < 0 || x + y * 16 >= 256) {
Tile.Void.render(x, y, screen);
continue;
}
tiles[x + y * 16].render(x, y, screen);
}
}
}
public Tile getTile(int x, int y) {
if (x < 0 || y < 0)
return Tile.Void;
if (x >= width || y >= height)
return Tile.Void;
if (tilesInt[x + y * width] == 0)
return Tile.Grass;
if (tilesInt[x + y * width] == 1)
return Tile.Rose;
if (tilesInt[x + y * width] == 2)
return Tile.Stone;
return Tile.Void;
}
}
and lastly
game.java:
package com.masterkgames.twisteddream;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
import com.masterkgames.twisteddream.entity.mob.Player;
import com.masterkgames.twisteddream.graphics.Screen;
import com.masterkgames.twisteddream.input.Keyboard;
import com.masterkgames.twisteddream.level.Level;
import com.masterkgames.twisteddream.level.SpawnLevel;
public class Game extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
public static int width = 300;
public static int height = 168;
public static int scale = 3;
public String Title = "Twisted Dream";
private Thread thread;
private boolean running = false;
private Screen screen;
private Keyboard key;
private Level level;
private Player player;
private JFrame frame;
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);
key = new Keyboard();
level = new SpawnLevel("/textures/level.png");
player = new Player(key);
frame = new JFrame();
addKeyListener(key);
}
public synchronized void start() {
thread = new Thread(this, "Display");
thread.start();
running = true;
}
public synchronized void stop() {
running = false;
try {
thread.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
public void run() {
long lastTime = System.nanoTime();
long timer = System.currentTimeMillis();
final double ns = 1000000000.0 / 60.0;
double delta = 0;
int frames = 0;
int updates = 0;
requestFocus();
while (running) {
long nowTime = System.nanoTime();
delta += (nowTime - lastTime) / ns;
lastTime = nowTime;
while (delta >= 1){
update();
updates++;
delta--;
}
render();
frames++;
if(System.currentTimeMillis() - timer > 1000){
timer += 1000;
System.out.println(updates + " ups, " + frames + " fps");
frame.setTitle(Title + " | " + updates + " ups, " + frames + " fps");
updates = 0;
frames = 0;
}
}
stop();
}
public void update() {
key.update();
player.update();
}
public void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
screen.clear();
int xScroll = player.x - screen.width / 2;
int yScroll = player.y - screen.height / 2;
level.render(xScroll, yScroll, screen);
player.render(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.setFont(new Font("arial", 0, 15));
g.setColor(Color.white);
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();
}
}
p.s this issue according to the stack trace is in the line for(int i = 0; i < levelPixels.length; i++) in SpawnLevel.java
in Level contructor you have generateLevel(); where you are using levelPixels, which is not initialized
contructor call
private void loadLevel(String path) {
}
from class Level, you have to call method loadLevel in SpawnLevel constructor
You are accessing the null array levelPixels.
Here is where your error is:
In your main you call a new SpawnLevel(path)
But SpawnLevel(path) calls the super constructor, which calls its blank yet defined loadLevel and generateLevel. The loadLevel and generateLevel in SpawnLevel are never called, and the member variables are never initialized.
So basically, you tried to use the Level class as an abstract class but you didnt do it correctly. The member variables should be in the Level class if they are to be shared by children of that class. Im guessing this is what you want to do.
you should really get familiar with the debugger, it will be a lifesaver for little problems like this.