I'm trying to make a 2D tile based game. I have been encountering an issue when attempting to draw new graphics and the old ones don't seem to have been removed.
If anyone knows why g.dispose isn't clearing the graphics then please help.
Here's my "Main" class:
package Main;
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
public class Main extends Canvas implements Runnable {
private static final long serialVersionUID = 1L;
private JFrame frame;
static int size = 40;
static int tilesX = 20;
static int tilesY = 20;
static int width = size * 10;
static int height = size * 10;
private boolean running = false;
public static STATE state = STATE.MENU;
public static PLAYER type = PLAYER.ARCHER;
private Thread thread;
static tileMap grid = new tileMap();
tile[][] map = tileMap.map;
public Main() {
addKeyListener(new controls());
addMouseListener(new mouse());
Dimension wSize = new Dimension(width, height);
setPreferredSize(wSize);
frame = new JFrame();
}
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 enum STATE {
MENU, GAME
}
public enum PLAYER {
ARCHER, KNIGHT
}
public static void main(String[] args) {
Main game = new Main();
game.frame = new JFrame("Game");
game.frame.add(game);
game.frame.setResizable(false);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setVisible(true);
game.start();
}
public void run() {
while (running) {
if (state == STATE.MENU) {
menu();
} else if (state == STATE.GAME) {
tick();
render();
}
try {
Thread.sleep(16);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
private void menu() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(2);
return;
}
Graphics g = bs.getDrawGraphics();
g.drawRect(Main.width / 8, 20, Main.width / 3, 200);
g.drawString("Archer", Main.width / 8, 20);
g.drawRect((Main.width - Main.width / 3) - Main.width / 8, 20,
Main.width / 3, 200);
g.drawString("Knight", (Main.width - Main.width / 3) - Main.width / 8,
20);
g.dispose();
bs.show();
}
private void render() {
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
Graphics2D d = (Graphics2D) g;
camera.setCam();
g.translate(-camera.camX, -camera.camY);
for (int i = 0; i < map.length; i++) {
for (int j = 0; j < map[i].length; j++) {
d.setColor(map[i][j].getC());
d.fillRect(map[i][j].getX(), map[i][j].getY(), Main.size, Main.size);
d.setColor(Color.BLACK);
d.drawRect(map[i][j].getX(), map[i][j].getY(), Main.size, Main.size);
}
}
map[player.p.getX()][player.p.getY()].setC(player.p.getC());
if (type == PLAYER.ARCHER) {
d.drawString("Archer", 5, 15);
} else if (type == PLAYER.KNIGHT) {
d.drawString("Knight", 5, 15);
}
g.dispose();
bs.show();
}
static public void moved() {
tileMap.map[player.p.getX()][player.p.getY()].setC(Color.GREEN);
}
private void tick() {
if (player.p == null) {
player.createP();
}
}
}
Graphics#dispose releases any internal resources that the Graphics context may be holding, reducing the memory overhead, it does not "clear" the context.
From the JavaDocs
Disposes of this graphics context and releases any system resources that it is using. A Graphics object cannot be used after dispose has been called.
What it doesn't do is effect the underlying content, that would be, well, annoying, as using a copy of a Graphics object is a good and easy way to make complex changes without effecting the original context.
To "clear" the context you could use fillRect to paint a color/background before you performing you next cycle of painting. Do this just after Graphics g = bs.getDrawGraphics();
Related
Please read the latest update down below
So I am trying to make a brick breaker game and while everything works in terms of gameplay I am having trouble adding a menu system. Basically this is how my code works
public class Game extends Canvas implements Runnable{
public Graphics g;
private Menu menu;
protected Ball ball;
protected Player player;
protected BufferedImage image;
protected BufferStrategy bufferStrategy;
protected Thread thread;
protected JFrame frame;
protected volatile boolean running, gameOver;
private enum STATE{
MENU,
GAME,
ABOUT,
OPTIONS,
};
private STATE State = STATE.MENU;
public Game(){
//Set the Jframe
}
private void init()
{
image = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
requestFocus();
menu = new Menu();
//init everything else aswell
}
public void update()
{
//Update every moving object
}
#Override
public void run()
{
init();
long initialTime = System.nanoTime();
double timePerFrame = 1000000000/FPS;
double delta = 0;
int ticks = 0;
long timer = 0;
while (running)
{
long currentTime = System.nanoTime();
long elapsedTime = currentTime - initialTime;
delta += elapsedTime/timePerFrame;
timer += elapsedTime;
if (delta >= 1)
{
update();
delta--;
ticks++;
}
render();
initialTime = currentTime;
if (timer >= 1000000000)
{
currentFPS = ticks;
ticks = 0;
timer = 0;
}
}
stop();
}
And when I render everything that is in the STATE GAME it works just fine but when I try to add an else if statement that does menu.draw(g) it all falls apart and I just get a blank frame
Here is how I render
public void render()
{
bufferStrategy = getBufferStrategy();
if (bufferStrategy == null)
{
createBufferStrategy(3);
return;
}
g = bufferStrategy.getDrawGraphics();
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
g.setColor(BG_COLOR);
g.fillRect(0, 0, WIDTH, HEIGHT);
if(State == STATE.GAME){
player.draw(g);
ball.draw(g);
blockController.draw(g); **THESE WORK JUST FINE**
}
else if(State == STATE.MENU){
menu.draw(g); **DOES NOT WORK**
}
bufferStrategy.show();
g.dispose();
}
And my Menu class has no difference in terms of the draw method
public class Menu implements GUI
{
#Override
public void draw(Graphics g) {
g.setFont(new Font("arial", Font.BOLD, 50));
g.setColor(Color.black);
g.drawString("MENU", Game.WIDTH / 2, 100);
}
}
Any idea why this might be happening I am doing the same render litteraly but keep getting
Exception in thread "Thread-0" java.lang.ClassCastException: class sun.java2d.NullSurfaceData cannot be cast to class sun.java2d.d3d.D3DSurfaceData error or g is null error
How can I fix this?
UPDATE ----------------------------------
The menu.draw() in the render works when I remove the lines
g.setFont(new Font("arial", Font.BOLD, 50));
g.setColor(Color.black);
g.drawString("MENU", Game.WIDTH / 2, 100);
And instead add something like
g.setColor(Color.CYAN);
g.fillRect(5, 5, 200, 200);
This does work but why the setfont, setColor and drawString don't work I don't understand I wanted to add buttons aswell but they don't work either. Is it because I set the entire frame with a rectangle in the render with the line g.fillRect(0, 0, WIDTH, HEIGHT); but then can I add objects like paddle,ball,bricks but not a string or a button?
The following example seems to work fine.
import java.awt.Canvas;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setVisible(true);
}
});
}
public class TestPane extends Canvas {
private Thread thread;
private volatile boolean render = false;
public TestPane() {
}
#Override
public void addNotify() {
super.addNotify();
start();
}
#Override
public void removeNotify() {
super.removeNotify();
stop();
}
protected void start() {
if (thread != null) {
render = false;
try {
thread.join();
} catch (InterruptedException ex) {
}
}
render = true;
thread = new Thread(new Runnable() {
#Override
public void run() {
while (render) {
render();
try {
Thread.sleep(16);
} catch (InterruptedException ex) {
}
}
}
});
thread.start();
}
protected void stop() {
render = false;
if (thread == null) {
return;
}
try {
thread.join();
} catch (InterruptedException ex) {
}
thread = null;
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
private Menu menu = new Menu();
protected void render() {
BufferStrategy strategy = getBufferStrategy();
if (strategy == null) {
createBufferStrategy(3);
strategy = getBufferStrategy();
}
if (strategy == null) {
return;
}
do {
// The following loop ensures that the contents of the drawing buffer
// are consistent in case the underlying surface was recreated
do {
// Get a new graphics context every time through the loop
// to make sure the strategy is validated
Graphics graphics = strategy.getDrawGraphics();
graphics.setColor(Color.BLACK);
graphics.fillRect(0, 0, getWidth(), getHeight());
menu.render(graphics, getSize());
graphics.dispose();
// Repeat the rendering if the drawing buffer contents
// were restored
} while (strategy.contentsRestored());
// Display the buffer
strategy.show();
// Repeat the rendering if the drawing buffer was lost
} while (strategy.contentsLost());
}
}
public class Menu {
public void render(Graphics g, Dimension bounds) {
// This is probably going to cost you a lot of
// performance and it might be better to
// pre-create the font instead
g.setFont(new Font("Arial", Font.BOLD, 50));
g.setColor(Color.WHITE);
String text = "MENU";
FontMetrics fm = g.getFontMetrics();
g.drawString("MENU", (bounds.width - fm.stringWidth(text)) / 2, (bounds.height / 2) - fm.getAscent());
}
}
}
If you continue to have issues, continue providing a runnable example which demonstrates your issue
I'm following a Java game programming series on youtube, and all have been going well until we add some code to the program. The code for the program is:
package com.fagyapong.rain;
import javax.swing.*;
import java.awt.*;
import java.awt.image.*;
public class Game extends Canvas implements Runnable{
private static final long serialVersionUID = -247215114548172830L;
public static int width = 300;
public static int height = width / 16 * 9;
public static int scale = 3;
private JFrame frame;
public Thread thread;
private boolean running = false;
public Game() {
// Setup Game window
Dimension size = new Dimension(width * scale, height * scale);
setPreferredSize(size);
frame = new JFrame();
}
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() {
while (running) {
update();
render();
}
}
public void update() {
}
public void render() {
// Get the canvas' BufferStragy object
BufferStrategy bs = getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
return;
}
Graphics g = bs.getDrawGraphics();
g.setColor(Color.GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
bs.show();
}
public static void main(String[] args) {
Game game = new Game();
game.frame.setResizable(false);
game.frame.setTitle("Rain");
game.frame.add(game);
game.frame.pack();
game.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
game.frame.setLocationRelativeTo(null);
game.frame.setVisible(true);
game.start();
}
}
Below is code that causes the system freeze(it has been commented out in the above code)
Graphics g = bs.getDrawGraphics();
g.setColor(Color.GRAY);
g.fillRect(0, 0, getWidth(), getHeight());
g.dispose();
bs.show();
Okay, I figured out the problem a bit. I was having the same issue. The issue for me was the triple buffering. Instead, set the code to:
createBufferStrategy(2);
That way it's only double buffering. I don't have a fantastic computer, so I had to set it to 1 instead of 2. At that point, my guess is that it's not buffering at all. This is how I got it to work though.
I am just starting to get into graphics and when I am trying to get the graphics, I get the error"run:
Exception in thread "Thread-2" java.lang.NullPointerException
at gamedev.Display.render(Display.java:97)
at gamedev.Display.run(Display.java:108)
at java.lang.Thread.run(Thread.java:724)"
and I have no clue on what is going on! Any help is greatly appreciated.
//The display class for the game
//Crated: 10-30-2013
//Last Modified: 10-30-2013
package gamedev;
import gamedev.Graphics.Render;
import gamedev.Graphics.Screen;
import java.awt.Canvas;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.image.BufferStrategy;
import java.awt.image.BufferedImage;
import java.awt.image.DataBufferInt;
import javax.swing.JFrame;
public class Display extends Canvas implements Runnable {
public static final int GAMEWIDTH = 600;
public static final int GAMEHEIGHT = 600;
private static Thread thread;
private static boolean running = false;
private Render render;
private Screen screen;
private BufferedImage img;
private int[] pixels;
public static void main(String[] args) {
System.out.println("display.main");
Display gameWindow = new Display();
JFrame gameFrame = new JFrame();
gameFrame.add(gameWindow);
gameFrame.setResizable(false);
gameFrame.setVisible(true);
Dimension dim = Toolkit.getDefaultToolkit().getScreenSize();
gameFrame.setLocation(dim.width / 2 - gameFrame.getSize().width / 2, dim.height / 2 - gameFrame.getSize().height / 2);
gameFrame.setSize(GAMEWIDTH, GAMEHEIGHT);
gameFrame.setTitle("Game Frame");
gameFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
gameWindow.start();
}
public Display() {
System.out.println("display.Display");
screen = new Screen(GAMEWIDTH, GAMEHEIGHT);
img = new BufferedImage(GAMEWIDTH, GAMEHEIGHT, BufferedImage.TYPE_INT_RGB);
pixels = ((DataBufferInt) img.getRaster().getDataBuffer()).getData();
}
private void start() {
System.out.println("display.Started");
if(running)
return;
running = true;
thread = new Thread(this);
thread.start();
}
private String stop() {
System.out.println("display.Stopped");
if (!running) {
System.out.println("running");
running = false;
try {
thread.join();
} catch (Exception e) {
System.exit(0);
return e.getStackTrace().toString();
}
return "Program Stopped";
} else {
return "Program Not Stopped";
}
}
private void tick() {
}
private void render() {
System.out.println("display.render");
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
}
for (int i = 0; i < GAMEWIDTH * GAMEHEIGHT; i++) {
pixels[i] = screen.PIXELS[i];
}
screen.Render();
Graphics g = bs.getDrawGraphics();
g.drawImage(img, 0, 0, GAMEWIDTH, GAMEHEIGHT, null);
g.dispose();
bs.show();
}
#Override
public void run() {
System.out.println("display.run");
while (running) {
tick();
render();
}
}
}
Change this:
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
}
to:
BufferStrategy bs = this.getBufferStrategy();
if (bs == null) {
createBufferStrategy(3);
bs = this.getBufferStrategy();
}
The problem is that if bs is null, you create a buffer strategy but don't assign anything to bs.
I decided to start understanding BufferStrategy for my graphics.
I'm not sure if using my jframe in a static form is what's cause this, but it looks alright to me. What am I missing?
Main.java
package Main;
import java.awt.Toolkit;
public class Main implements Runnable {
private Thread gameThread;
private Game game;
private boolean running = false;
public static ClientFrame frame;
public static Toolkit kit;
public static int WIDTH = 300, HEIGHT = WIDTH*16/9, SCALE = 3;
public Main() {
game = new Game();
frame = new ClientFrame(game);
kit = frame.getToolkit();
frame.setVisible(true);
start();
}
public synchronized void start() {
running = true;
gameThread = new Thread(this);
gameThread.start();
}
public synchronized void stop() {
running = false;
gameThread.interrupt();
}
public void run() {
long startTime = System.nanoTime();
double nanoSec = 1000000000/60;
double delta = 0;
while(running) {
long currentTime = System.nanoTime();
delta += (currentTime - startTime)/nanoSec;
while(delta >= 1) {
game.update();
delta--;
}
game.render();
startTime = currentTime;
}
}
public static void main(String[] args) {
new Main();
}
}
Game.java
package Main;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.image.BufferStrategy;
import javax.swing.JPanel;
public class Game extends JPanel {
Player player;
int tileArea = 32;
public Game() {
player = new Player();
setPreferredSize(new Dimension(Main.WIDTH*Main.SCALE, Main.HEIGHT*Main.SCALE));
}
public void update() {
}
public void render() {
BufferStrategy bs = Main.frame.getBufferStrategy();
if(bs == null)
Main.frame.createBufferStrategy(3);
Graphics g = bs.getDrawGraphics();
player.paint(g);
g.dispose();
bs.show();
}
}
My Player.java only contains one method:
public void paint(Graphics g) {
g.fillRect(25, 25, 50, 50);
}
ERROR:
Exception in thread "Thread-2" java.lang.NullPointerException
at Main.Game.render(Game.java:30)
at Main.Main.run(Main.java:52)
at java.lang.Thread.run(Unknown Source)
You do not try to get the buffer strategy after you have created it:
BufferStrategy bs = Main.frame.getBufferStrategy();
if(bs == null)
Main.frame.createBufferStrategy(3);
// if bs was null before, it still is null
Graphics g = bs.getDrawGraphics();
Also note the point by #MadProgrammer that the buffer strategy belongs to a different component. If your intent is to create an AWT game (I'd recommend swing instead), you should probably use Canvas, and its createBufferStrategy().
try replacing
if(bs == null)
Main.frame.createBufferStrategy(3);
with
if (bs == null) {
Main.frame.crcreateBufferStrategy(3);
return;
}
I am following a series of tutorials for Java game development tutorials. I already have a basic knowledge of Java, from thenewboston, if that helps. Anyway, I was stuck on this tutorial: http://www.youtube.com/watch?v=hN1v1ZhITDc&feature=c4-overview-vl&list=PL54DB126285ED0420 The program I am creating for this tutorial is sort of like a 2D Minecraft, and at this point, the program should display a window with several tiles of dirt, stone, and sky in specific order. When I run it, it just displays a blank JFrame and I get these errors:
at mineGameMain.World.draw(World.java:80)
at mineGameMain.GamePanel.draw(GamePanel.java:91)
at mineGameMain.GamePanel.gameRender(GamePanel.java:85)
at mineGameMain.GamePanel.run(GamePanel.java:51)
at java.lang.Thread.run(Unknown Source)
I have three classes, Main:
package mineGameMain;
import javax.swing.JFrame;
public class Main extends JFrame{
GamePanel gp;
public Main(){
gp = new GamePanel();
setSize(500, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
setResizable(false);
add(gp);
}
public static void main(String[] args){
Main m = new Main();
}
}
GamePanel:
package mineGameMain;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class GamePanel extends JPanel implements Runnable{
//Double Buffering
private Image dbImage;
private Graphics dbg;
//JPanel variables
static final int GWIDTH = 500, GHEIGHT = 400;
static final Dimension gameDim = new Dimension(GWIDTH, GHEIGHT);
//Game Variables
private Thread game;
private volatile boolean running = false;
//Game Objects
World world;
public GamePanel(){
world = new World();
setPreferredSize(gameDim);
setBackground(Color.WHITE);
setFocusable(true);
requestFocus();
//Handle all key inputs
addKeyListener(new KeyAdapter(){
public void keyPressed(KeyEvent e){
}
public void keyReleased(KeyEvent e){
}
public void Typed(KeyEvent e){
}
});
}
public void run(){
while(running){
gameUpdate();
gameRender();
paintScreen();
}
}
private void gameUpdate(){
if(running && game != null){
//Update game state
}
}
private void gameRender(){
if(dbImage == null){
dbImage = createImage(GWIDTH, GHEIGHT);
if(dbImage == null){
System.err.println("dbImage IS STILL NULL SO SHUTUPBEQUIET!");
return;
}else{
dbg = dbImage.getGraphics();
}
}
//Clear the screen
dbg.setColor(Color.WHITE);
dbg.fillRect(0, 0, GWIDTH, GHEIGHT);
//draw Game Methods
draw(dbg);
}
/*Draw all game content in this method*/
private void draw(Graphics g) {
world.draw(g);
}
private void paintScreen(){
Graphics g;
try{
g = this.getGraphics();
if(dbImage != null && g != null){
g.drawImage(dbImage, 0, 0, null);
}
Toolkit.getDefaultToolkit().sync();
}catch(Exception e){
System.err.println(e);
}
}
public void addNotify(){
super.addNotify();
startGame();
}
private void startGame(){
if(game == null || !running){
game = new Thread(this);
game.start();
running = true;
}
}
public void stopGame(){
if(running){
running = false;
}
}
private void log(String s){
System.out.println(s);
}
}
And finally, World:
package mineGameMain;
import java.awt.Image;
import java.awt.*;
import javax.swing.ImageIcon;
public class World {
private Rectangle[] blocks;
private Image[] blockImg;
private final int arrayNum = 500;
//Block images
private Image BLOCK_DIRT_TOP, BLOCK_DIRT, BLOCK_STONE, BLOCK_SKY;
private int x, y;
public World(){
BLOCK_DIRT_TOP = new ImageIcon("/MineGame/src/mineGameMain/Tile_Grass.png").getImage();
BLOCK_DIRT = new ImageIcon("/MineGame/src/mineGameMain/Tile_Dirt.png").getImage();
BLOCK_STONE = new ImageIcon("/MineGame/src/mineGameMain/Tile_Stone.png").getImage();
BLOCK_STONE = new ImageIcon("/MineGame/src/mineGameMain/Tile_Sky.png").getImage();
blocks = new Rectangle[500];
blockImg = new Image[500];
loadArrays();
}
private void loadArrays(){
for(int i = 0; i < arrayNum; i++){
if(x >= 500){
x = 0;
y += 20;
}
if( i >= 0 && i < 100){
blockImg[i] = BLOCK_SKY;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if( i >= 100 && i < 120){
blockImg[i] = BLOCK_DIRT_TOP;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if( i >= 125 && i < 220){
blockImg[i] = BLOCK_DIRT;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if( i >= 225 && i < 500){
blockImg[i] = BLOCK_STONE;
blocks[i] = new Rectangle(x, y, 20, 20);
}
x += 20;
}
}
public void draw(Graphics g){
for(int i = 0; i < arrayNum; i++){
g.drawImage(blockImg[i], blocks[i].x, blocks[i].y, null);
}
}
}
Thank you for your time. If I did something wrong by posting this or if I left out any details please let me know.
Find below a way to turn your question into an SSCCE (actually it is a fixed version of one)
There are quite a few mistakes you should avoid in your code
No need to implement double buffering yourself, Swing is double buffered by default
All access to the UI should be made on the EDT (the Event Dispacthing Thread), not from a random Thread you created. You should also start your UI from the EDT, using invokeLater
To paint a component, override paintComponent and invoke repaint() whenever you want it to be called.
Never use getGraphics on JComponent, always Graphics objects provided as method-arguments (like in paintComponent).
No need to extends JFrame here --> don't extend if you don't need to (you don't actually add behaviour to the JFrame)
Make sure to call setVisible(true) as your last statement for the JFrame.
You forgot to handle block 120 to 125 and block 220 to 225 (probably causing NullPointerException in your draw method (this is likely the root of your error).
When you post a Java error, make sure to post the whole stacktrace and the message provided above the stacktrace (make also sur that people can identify your line numbers, by adding a comment like // this is line 80 of the World class)
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Rectangle;
import java.net.MalformedURLException;
import java.net.URL;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main extends JFrame {
GamePanel gp;
public Main() throws MalformedURLException {
gp = new GamePanel();
setSize(500, 400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(gp);
pack();
setVisible(true);
}
public static class World {
private Rectangle[] blocks;
private Image[] blockImg;
private final int arrayNum = 500;
// Block images
private Image BLOCK_DIRT_TOP, BLOCK_DIRT, BLOCK_STONE, BLOCK_SKY;
private int x, y;
public World() throws MalformedURLException {
BLOCK_DIRT_TOP = new ImageIcon(new URL("http://i909.photobucket.com/albums/ac298/XxEnoAsaIxX/grass2test.png?t=1303852677"))
.getImage();
BLOCK_DIRT = new ImageIcon(new URL(
"http://i909.photobucket.com/albums/ac298/XxEnoAsaIxX/sparsedirtandgrasstile.png?t=1300172998")).getImage();
BLOCK_STONE = new ImageIcon(new URL("http://www.stonetilesupply.com/v/vspfiles/photos/MARBL-BTTCNCLASSICO-2S.jpg")).getImage();
BLOCK_SKY = new ImageIcon(new URL("http://lacoste.scene7.com/is/image/lacoste/swatch_10_CH0783-00_SVH_24?$swatch$")).getImage();
blocks = new Rectangle[500];
blockImg = new Image[500];
loadArrays();
}
private void loadArrays() {
for (int i = 0; i < arrayNum; i++) {
if (x >= 500) {
x = 0;
y += 20;
}
if (i >= 0 && i < 100) {
blockImg[i] = BLOCK_SKY;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if (i >= 100 && i < 120) {
blockImg[i] = BLOCK_DIRT_TOP;
blocks[i] = new Rectangle(x, y, 20, 20);
}
// Here missing block for 120 to 125
if (i >= 120 && i < 125) {
blockImg[i] = BLOCK_STONE;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if (i >= 125 && i < 220) {
blockImg[i] = BLOCK_DIRT;
blocks[i] = new Rectangle(x, y, 20, 20);
}
// Here missing block for 220 to 225
if (i >= 220 && i < 225) {
blockImg[i] = BLOCK_SKY;
blocks[i] = new Rectangle(x, y, 20, 20);
}
if (i >= 225 && i < 500) {
blockImg[i] = BLOCK_STONE;
blocks[i] = new Rectangle(x, y, 20, 20);
}
x += 20;
}
}
public void draw(Graphics g) {
for (int i = 0; i < arrayNum; i++) {
g.drawImage(blockImg[i], blocks[i].x, blocks[i].y, null);
}
}
}
public static class GamePanel extends JPanel {
// JPanel variables
// Game Objects
World world;
public GamePanel() throws MalformedURLException {
world = new World();
setPreferredSize(new Dimension(500, 400));
setBackground(Color.WHITE);
setFocusable(true);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
world.draw(g);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
new Main();
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
}
}