I have tried numerous solutions, and I can't seem to find the issue with my code. I have checked the path names, the permissions for the files, and tried several different file names for the image. The image isn't showing up.
private Character player;
private Image image, sprite;
private URL base;
private Graphics second;
#Override
public void init() {
setSize(500,500);
setBackground(Color.white);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame)this.getParent().getParent();
frame.setTitle("Joules");
try {
base = getDocumentBase();
sprite = getImage(base,"kips.PNG");
} catch (Exception e) {
}
// sprite = getImage(base,"kips.PNG");
}
#Override
public void start() {
player = new Character();
Thread thread = new Thread(this);
thread.start();
}
#Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(sprite,player.getCenterX(),player.getCenterY(),this);
}
#Override
public void run() {
while (true) {
repaint();
try {
Thread.sleep(34);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
Please help...
I just had this issue and found that getDocumentBase() is returning a huge path which is the base of the current applet, not the project.
Instead, I used getCodeBase() which returns "../projectName/bin/", so navigate back one folder in your relative paths in the code.
base = getCodeBase();
sprite = getImage(base,"../kips.PNG");
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 trying to build up a game, and i'm doing this with the help of a tutorial. My problem is, the run() method I show below is not working. I tried the sample code of the tutorial, it is exactly the same run() method and it works.
In my code, run() is never called and I don't get why.
package thisproject;
public class StartingClass extends Applet implements Runnable, KeyListener,
MouseListener {
private Builder builder;
private Image image,currentSprite, character,characterWalk, background;
private Graphics second;
private URL base;
private static Background bg1;
#Override
public void init() {
setSize(800, 400);
setBackground(Color.BLACK);
setFocusable(true);
addKeyListener(this);
Frame frame = (Frame) this.getParent().getParent();
frame.setTitle("Castle Fight");
try {
base = getDocumentBase();
} catch (Exception e) {
// TODO: handle exception
}
// Image Setups
background = getImage(base, "data/background2.png");
character = getImage(base, "data/builder.png");
currentSprite = character;
}
#Override
public void start() {
bg1 = new Background(0, 0);
builder = new Builder();
Thread thread = new Thread();
thread.start();
}
#Override
public void stop() {
// TODO Auto-generated method stub
}
#Override
public void destroy() {
// TODO Auto-generated method stub
}
#Override
public void run() {
while (true) {
System.out.println("this thing");
builder.update();
bg1.update();
repaint();
try {
Thread.sleep(17);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
#Override
public void update(Graphics g) {
if (image == null) {
image = createImage(this.getWidth(), this.getHeight());
second = image.getGraphics();
}
second.setColor(getBackground());
second.fillRect(0, 0, getWidth(), getHeight());
second.setColor(getForeground());
paint(second);
g.drawImage(image, 0, 0, this);
}
#Override
public void paint(Graphics g) {
g.drawImage(background, bg1.getBgX(), bg1.getBgY(), this);
g.drawImage(currentSprite, builder.getCenterX() - 61, builder.getCenterY() - 63, this);
}
}
}
Please, keep in mind that I took out the imports and the key events so the code didn't take much room, but I do have all the imports necessary.
Hopefully someone can give me some light on this.
You never supply the Runnable. Change
Thread thread = new Thread();
thread.start();
to
Thread thread = new Thread(this);
thread.start();
I need to make my background in a game move up all the time..
I know that I need to use some thread that added variable to 'y' coordinate of the image
I tried to do something but when it started moving all the background get streaking in some reason, cant understand why...
picture : streaking background
public class Background {
private BufferedImage image;
.....
....
public Background(int x, int y) {
this.x = x;
this.y = y;
// Try to open the image file background.png
try {
BufferedImageLoader loader = new BufferedImageLoader();
image = loader.loadImage("/backSpace.png");
}
catch (Exception e) { System.out.println(e); }
}
/**
* Method that draws the image onto the Graphics object passed
* #param window
*/
public void draw(Graphics window) {
// Draw the image onto the Graphics reference
window.drawImage(image, getX(), getY(), image.getWidth(), image.getHeight(), null);
// Move the x position left for next time
this.y +=1 ;
}
public class ScrollingBackground extends Canvas implements Runnable {
// Two copies of the background image to scroll
private Background backOne;
private Background backTwo;
private BufferedImage back;
public ScrollingBackground() {
backOne = new Background();
backTwo = new Background(backOne.getImageWidth(), 0);
new Thread(this).start();
setVisible(true);
}
#Override
public void run() {
try {
while (true) {
Thread.currentThread().sleep(5);
repaint();
}
}
catch (Exception e) {}
}
#Override
public void update(Graphics window) {
paint(window);
}
public void paint(Graphics window) {
Graphics2D twoD = (Graphics2D)window;
if (back == null)
back = (BufferedImage)(createImage(getWidth(), getHeight()));
Graphics buffer = back.createGraphics();
backOne.draw(buffer);
backTwo.draw(buffer);
twoD.drawImage(back, null, 0, 0);
}
You dont need a new thread for it, that just overcomplicates things in this case.
You just need to add a factor to the Y coordinate of the background continuesly.
For example:
float scrollFactor = 0.5f; //Moves the background 0.5 pixels up per call of the draw method
public void draw(Graphics window) {
window.drawImage(image, getX(), getY(), image.getWidth(), image.getHeight(), null);
this.y += scrollFactor;
}
I have a JTextPane with an image for its background.
prevWords = new JTextPane()
{
public void paint(Graphics g)
{
BufferedImage img;
try
{
img = ImageIO.read(new File("Images/logo.png"));
img.getGraphics().setColor(new Color(Color.TRANSLUCENT));
g.drawImage(img, 0, 0, null);
}
catch (IOException e)
{
System.out.println("Failed to load logo.");
}
super.paintComponents(g);
}
};
When I write text to the the pane, it I cannot see it. I have set the text in pane to be white as well.
This is a complete hack.
The problem here is, the UI is painting the background twice...
You need to circumvent the UI in such a way so that you can paint the image into the background while still getting the text to render over the top.
In the end, I had to make the text pane transparent so I could force the UI not to paint the background.
public class TextPaneBackground {
public static void main(String[] args) {
new TextPaneBackground();
}
public TextPaneBackground() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception ex) {
}
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new JScrollPane(new TextPaneWithBackground()));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TextPaneWithBackground extends JTextPane {
private BufferedImage background;
public TextPaneWithBackground() {
try {
background = ImageIO.read(new File("C:/Users/shane/Dropbox/MegaTokyo/Evil_Small.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
setForeground(Color.WHITE);
setOpaque(false);
}
#Override
public Dimension getPreferredScrollableViewportSize() {
return background == null ? super.getPreferredScrollableViewportSize() : new Dimension(background.getWidth(), background.getHeight());
}
#Override
public Dimension getPreferredSize() {
return background == null ? super.getPreferredSize() : new Dimension(background.getWidth(), background.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
if (isOpaque()) {
g2d.setColor(getBackground());
g2d.fillRect(0, 0, getWidth(), getHeight());
}
if (background != null) {
int x = (getWidth() - background.getWidth()) / 2;
int y = (getHeight()- background.getHeight()) / 2;
g2d.drawImage(background, x, y, this);
}
getUI().paint(g2d, this);
g2d.dispose();
}
}
}
Reimeus hinted at the ability to insert an image into the Document directly, this might be a better, long term solution.
I've followed these tutorials and produced the following.
http://www.youtube.com/playlist?list=PL54DB126285ED0420
Main.java:
public class Main extends JFrame {
GamePanel gp;
public Main() {
gp = new GamePanel();
setSize(500, 400);
setVisible(true);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
add(gp);
}
public static void main(String[] args) {
Main m = new Main();
}
}
GamePanel.java:
public class GamePanel extends JPanel implements Runnable {
// Double Buffering Variables
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;
public GamePanel() {
setPreferredSize(gameDim);
setBackground(Color.WHITE);
setFocusable(true);
requestFocus();
// Handle all key inputs from the user
addKeyListener(new KeyAdapter() {
#Override public void keyPressed(KeyEvent e) {}
#Override public void keyReleased(KeyEvent e) {}
#Override public void keyTyped(KeyEvent e) {}
});
}
public void run() {
while (running) {
gameUpdate();
gameRender();
paintScreen();
}
}// END run
private void gameUpdate() {
if (running && game != null) {
// update the game state
}
}
private void gameRender() {
// create the buffer
if (dbImage == null) {
dbImage = createImage(GWIDTH, GHEIGHT);
if (dbImage == null) {
System.err.println("dbImage is still null!!!");
return;
} else {
dbg = dbImage.getGraphics();
}
}
// Clear the screen
dbg.setColor(Color.WHITE);
dbg.fillRect(0, 0, GWIDTH, GHEIGHT);
// Draw the game elements
draw(dbg);
}
// draw all game content
public void draw(Graphics g) {}
private void paintScreen() {
Graphics g;
try {
g = this.getGraphics();
if (dbImage != null && g != null)
g.drawImage(dbImage, 0, 0, null);
// For Linux
Toolkit.getDefaultToolkit().sync();
g.dispose();
} 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);
}
}
It should just print a "Hello World" string on the screen but it's not performing. I've gone over the code couple of times but couldn't see what was wrong.
So what's absent that causes it not to display the string.
Thanks.
All right. Finally just found it.
In my Main.java I'd to place the add(gp); code to the top. Because basically it was falling under.
P.S. Just mentioning again. Accidentally I erased the contents of the draw method. Silly of me. Sorry for that. It should've g.drawString("Hello World!", 100, 100); in it.
Thanks.
So what's absent that causes it not to display the string.
For starters, the "Hello World" string itself is absent.
I suggest you go over the tutorials that you referenced again as you appear to be new to Java and require more practice.