user2164148
user2164148

Reputation: 11

Image as background and paintComponent

I am simply trying make a game for college that is a ball that player navigates with keyboard to get through maze. The only thing I am stuck on is my background is an image of a maze, when I add the "ball" it repaints the background (defualt color, no image) when I comment out the paint and paint component, the maze background is back, but no ball of course.

I am a new to java and I have searched this and can't see a good soulition for the code I already have. is it setOpaque? isOpaque?.... is opaque even the right direction?

Once I get this... i totally understand using collision detection to detect collisions with the maze "wall"

Trying to figure this out, being new to java, can make a grown man cry.

main.java

public class Main{

public static void main (String[] args){

    //System.out.println("Start of the Game");

    GameFrame game1 = new GameFrame();
}

JavaGame.java

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import java.io.File;
import java.io.IOException;


public class GameFrame extends JFrame{        

private int frameWidth = 240, frameHeight =315;
    int x, y;
    private Image dbImage;
    private Graphics dbg;

//Below is the constructor        

public GameFrame(){          

        super("OperationMaze!");
        addKeyListener(new AL());
        setResizable(false);
        //setTitle("OperationMaze!2");
        //setSize(250, 302);
        setSize(frameWidth, frameHeight); //Set height and width
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);            


            //Because of opening file, there needs to be a try catch just incase there is an error opening.
            //Plus java won't let you unless you try catch.
    try{

                setContentPane(new JLabel(new ImageIcon(ImageIO.read(new File("C:/Documents and Settings/brando/My Documents/NetBeansProjects/GameFrame/src/maze.jpg")))));

    }   catch (IOException e) {
                e.printStackTrace();                    
                }       


        //Show the frame


        setVisible(true);
        //setOpaque(false);    
        y = 35;
        x = 15;
}

    public void paint(Graphics g) {

       dbImage = createImage(getWidth(), getHeight());
       dbg = dbImage.getGraphics();
       paintComponent(dbg);
       g.drawImage(dbImage, 0, 0, this);           
    }

    public void paintComponent(Graphics g) {                

        g.fillOval(x, y, 15, 15);
        //g.setOpaque(false);

        repaint();        
    }   

   // private void setOpaque(boolean b) {
   //     throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.

   // }

    public class AL extends KeyAdapter { 

        public void keyPressed(KeyEvent e) {
            int keyCode = e.getKeyCode();
            if(keyCode == e.VK_LEFT) {
                if(x <= 5)
                    x = 5;
                else 
                    x += -5;
            }
            if(keyCode == e.VK_RIGHT) {
                if(x >= 230)
                    x = 230;
                else
                    x += +5;
            } 
            if(keyCode == e.VK_UP) {
                if(y <= 23)
                    y=23;
                else
                    y += -5;
            } 
            if(keyCode == e.VK_DOWN) {
                if(y >= 277)
                    y = 277;
                else
                    y += +5;
            } 
    }
    }
}

Upvotes: 1

Views: 3282

Answers (1)

Reimeus
Reimeus

Reputation: 159754

Ok, lets's see what's going wrong here:

when I add the "ball" it repaints the background (default color, no image)

In this scenario, when you are using your custom paint method, you don't call super.paint(g), so the JLabel with the Image doesnt get drawn.

The Image that you do create is blank:

dbImage = createImage(getWidth(), getHeight());

(Graphics offers a convenient overloaded method of drawImage that allows you to specify width & height, allowing you to avoid doing this.)

The result: no background image.

when I comment out the paint and paint component, the maze background is back, but no ball of course.

Now Swing is calling the default paint implementation which ensures that all child components are drawn but now you're not calling your fillOval method, net result: background Image, no ball.

Where next:

To allow Swing do the work of custom painting you need to override paintComponent rather than calling it directly. However this cannot be done in a top level container like JFrame. Sub-classing a JComponent and overriding paintComponent in that new component will allow Swing to call that method without you having to do it directly. Adding the @Override will allow the compiler to check that you are indeed overriding the method. As you're intending to paint the Image, you could simply load the Image and save the reference for use when you need to paint it:

dbImage = ImageIO.read(new File("MyImage.jpg"));

Then in your new JComponent-based class:

@Override
protected void paintComponent(Graphics g) {
   super.paintComponent(g);
   g.drawImage(dbImage, 0, 0, getWidth(), getHeight(), this);
   g.fillOval(x, y, 15, 15);
}

Upvotes: 2

Related Questions