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

标签 java swing canvas jframe

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

这是主类:

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);



    }

最佳答案

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

编辑:

假设您的图像与 Canvas 大小不同,请使用 g.drawImage(dbImage, 0, 0, getWidth(), getHeight(), null) 用您的图像填充 Canvas .

关于java - 当我尝试使用 Canvas 显示背景图像时出现问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27464458/

相关文章:

java - 从 Java 发送 JSON 对象并在 PHP 中解码 JSON 对象

java - 为什么在单条记录上调用 Spring Data JPA save() 比在记录列表上调用它慢?

java - 显示我的 LinkedList 的元素不起作用

javascript - KineticJS:动力学警告:无法获取数据 URL

javascript - 使用 Canvas 动画化 JS 中的排序算法

java - 用于文本填充的带有 HTML CSS 的 GWT 标签

java - 在 Netbeans 中重新生成所有 Java Swing 页面的快速方法?

java - 处理 JPopupMenu 关闭

java - 对 JPanel 中的 JButton 进行排序

javascript - 将 Canvas 坐标保存到本地文件 php 中