当我尝试使用Canvas显示背景图像时出现问题

时间:2014-12-13 22:49:14

标签: java swing canvas jframe

我试图在g.drawImage内使用Canvas Jframe显示背景图片,但我没有显示任何内容,屏幕仍为白色,当我尝试使用任何颜色填充屏幕时使用g.fillRect

这是Main类:

import org.jbox2d.collision.shapes.PolygonShape;
import org.jbox2d.common.Vec2;
import org.jbox2d.dynamics.Body;
import org.jbox2d.dynamics.BodyDef;
import org.jbox2d.dynamics.FixtureDef;
import org.jbox2d.dynamics.World;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.Iterator;

import javax.swing.ImageIcon;

public class Main extends Canvas implements Runnable, KeyListener {


    private static final long serialVersionUID = 1L;

    public static final int WIDTH = 600, HEIGHT = WIDTH / 12 * 9;

    // rate to convert meters to pixels in the physics engine
    public static final float RATE = 30;

    // counts how many loops are made in the main thread
    private int counter = 49;

    // image and graphics used for double buffering
    private ImageIcon bgImage = new ImageIcon("res/bgImage.png");
    private Image dbImage;
    private Graphics dbg;

    /* boolean to define when the game will be started and stopped */

    private boolean running = false;


    // variables for the Box2D world
    Vec2 gravity = new Vec2(0.0f, 10.0f);
    boolean doSleep = true;
    World world = new World(gravity, doSleep);

    // new array list to hold Ball references
    ArrayList<Ball> balls = new ArrayList<Ball>();

    // create a new player
    Player character = new Player(world);



    public Main() {

        addKeyListener(this);

        // add a ground floor to our Box2D world
        BodyDef groundBodyDef = new BodyDef();
        groundBodyDef.position.set(300.0f / RATE, 400.0f / RATE);
        Body groundBody = world.createBody(groundBodyDef);
        PolygonShape groundBox = new PolygonShape();
        groundBox.setAsBox(300.0f / RATE, 0);
        groundBody.createFixture(groundBox, 0.0f);

        // wall fixture
        FixtureDef fixtureDef = new FixtureDef();
        fixtureDef.shape = groundBox;
        fixtureDef.density = 2.0f;
        fixtureDef.filter.groupIndex = -1;

        // left wall
        groundBodyDef.position.set(0.0f / RATE, 350.0f / RATE);
        groundBody = world.createBody(groundBodyDef);
        groundBox.setAsBox(0, 50.0f / RATE);
        groundBody.createFixture(fixtureDef);

        // right wall
        groundBodyDef.position.set(600.0f / RATE, 350.0f / RATE);
        groundBody = world.createBody(groundBodyDef);
        groundBox.setAsBox(0, 50.0f / RATE);
        groundBody.createFixture(fixtureDef);

        /**
         * @WIDHT : width of jpanel screen
         * @HEIGHT : height of the jpanel screen
         * @param : title of jpanel screen
         * @this : refered to our main game instance 
         */

        new Window(WIDTH, HEIGHT, "Apocalypse 2D v0.0", this);


    }

    @Override
    public int getWidth() { // Width of the CustomPanel
        return WIDTH;
    }

    @Override
    public int getHeight() { // Height of the CustomPanel
        return HEIGHT;
    }

    @Override
    public Dimension getPreferredSize() { // Dimension of the CustomPanel
        return new Dimension(getWidth(), getHeight());
    }



    public void start() {
        // starts a new thread
        running = true;
        Thread th = new Thread(this);
        th.start();
    }

    public void stop() {
        running = false;
    }

    public void destroy() {

    }


    public void run() {
        Thread.currentThread().setPriority(Thread.MIN_PRIORITY);

        while (running) {
            counter++;

            // Simulate the world
            float timeStep = 1.0f / 60.0f;
            int velocityIterations = 6;
            int positionIterations = 2;
            world.step(timeStep, velocityIterations, positionIterations);


            // add new balls to the world every 50th loop
            if (counter % 80 == 0)
                balls.add(new Ball(world));

            repaint();

            // pause for 10 milliseconds
            try {
                Thread.sleep(10);
            } catch (InterruptedException ex) {
                // do nothing
            }

            Thread.currentThread().setPriority(Thread.MAX_PRIORITY);
        }
    }

    public void paint(Graphics g) {

        /*g.setColor(Color.black);*/
        /*g.fillRect(0, 0, getWidth(), getHeight());*/
        g.drawImage(bgImage, getWidth(), getHeight(), null);

        // loop through each ball and call it's draw method
        Iterator<Ball> itr = balls.iterator();
        while (itr.hasNext()) {
            Ball b = itr.next();
            b.DrawBall(g);

            // if the ball should be removed then remove it
            if (b.shouldDelete())
                itr.remove();
        }

        // draw the main character.
        character.draw(g);



    }

    // sets up double buffering for graphics
    public void update(Graphics g) {
        if (dbImage == null) {
            dbImage = createImage(this.getSize().width, this.getSize().height);
            dbg = dbImage.getGraphics();
        }

        dbg.setColor(getBackground());
        dbg.fillRect(0, 0, this.getSize().width, this.getSize().height);

        dbg.setColor(getForeground());
        paint(dbg);

        g.drawImage(dbImage, 0, 0, this);

        character.animplayer();

        for (Ball ball : balls) {
            ball.animBalls();
        }

    }

    public void keyPressed(KeyEvent key) {
        character.keyPress(key);
    }

    public void keyReleased(KeyEvent key) {
        character.keyRelease(key);
    }

    public void keyTyped(KeyEvent key) {
    }

    public static void main(String[] args) {
        new Main();
    }

}

这是我尝试将图像填充到屏幕的绘画方法:

public void paint(Graphics g) {

        /*g.setColor(Color.black);*/
        /*g.fillRect(0, 0, getWidth(), getHeight());*/
        g.drawImage(bgImage, getWidth(), getHeight(), null);

        // loop through each ball and call it's draw method
        Iterator<Ball> itr = balls.iterator();
        while (itr.hasNext()) {
            Ball b = itr.next();
            b.DrawBall(g);

            // if the ball should be removed then remove it
            if (b.shouldDelete())
                itr.remove();
        }

        // draw the main character.
        character.draw(g);



    }

1 个答案:

答案 0 :(得分:1)

drawImage()方法有多个重载,您使用的方法是drawImage(BufferedImage img, int x, int y, ImageObserver observer)xy是画布上的左上角坐标。现在这些是画布的宽度和高度,因此图像被绘制在面板之外。尝试拨打g.drawImage(dbImage, 0, 0, null)

编辑:

假设您的图片尺寸与画布不同,请使用g.drawImage(dbImage, 0, 0, getWidth(), getHeight(), null)在图片上填充图片。