一个对象中的图形正在影响另一个对象的图形 - JAVA

时间:2017-07-19 05:44:03

标签: java swing graphics concurrency

第一篇文章,所以我尽量保持清醒。 基本上,我想要做的就是创造一个小游戏,你有一艘船,你可以用它射击子弹。船使用切线公式相应地旋转到玩家的deltaX和deltaY。我使用像这样的标准游戏循环:

pk=6

我的游戏"在JPanel的一个孩子上运行,这个类叫做Board。在循环中,我调用方法tick(),它更新信息,repaint(),它作为一个渲染方法。这是我的paintComponent(Graphics g)方法:

public void run() {
    long lastTime = System.nanoTime();
    double amountOfTicks = 60.0;
    double ns = 1000000000 / amountOfTicks;
    double delta = 0;
    long timer = System.currentTimeMillis();
    @SuppressWarnings("unused")
    int frames = 0;
    while(running){
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;
        while(delta >=1){
                tick();
                delta--;
            }
        if(running)
        repaint();
        frames++;

        if(System.currentTimeMillis() - timer > 1000)
        {
            timer += 1000;
            frames = 0;
        }
    }
    stop();
}

可以看出,我不会在我的Board课上渲染所有东西。我是在处理程序上这样做的。这就是我处理处理程序的方式:

public void paintComponent(Graphics g) {
    //This is for background
    Graphics2D g2d = (Graphics2D) g;
    g2d.setColor(Color.black);
    g2d.fill(new Rectangle(0, 0, Constants.width, Constants.height));

    //This is where actual game rendering occurs
    handler.render(g);
    g.dispose();
}

LinkedList handlerList包含实体。 实体是一个抽象类,它是Creature的父级,它是Player和Bullet的父级。 这是呈现Player实例的代码:

public void render(Graphics g) {
    for (int i = 0; i < handlerList.size(); i++) {
        //handlerList is a LinkedList
        handlerList.get(i).render(g);
    }
}

有一个布尔值&#34;已停止&#34;它跟踪对象的状况。我使用Graphics2D而不是Graphics,因为我想能够旋转我的船。

这里是子弹渲染的代码:

public void render(Graphics g) {        
    float centerX = x + (width / 2);
    float centerY = y + (height / 2);

    double theta = findAngle(deltaX, deltaY);

    Graphics2D g2d = (Graphics2D) g;
    if(!stopped) g2d.rotate(theta, centerX, centerY);
    else g2d.rotate(stoppedTheta, centerX, centerY);
    g2d.drawImage(shipImage, (int)x, (int)y, (int)width, (int)height, null);
}

就我所知,它看起来是正确的。每当我没有子弹时,游戏运行正常,正如您在this GIF中看到的那样: 免责声明:对于低质量和水印,我很抱歉,我只是将电脑格式化,没有时间安装适当的东西....

当我添加子弹this时:

子弹的x和y位置没有变化,但子弹随船一起旋转。我假设它与误用&#34; dispose()&#34;有关。方法,但我不确定如何解决它。

提前谢谢。

1 个答案:

答案 0 :(得分:1)

  1. 永远不会在您未明确创建的dispose上下文(或使用Graphics创建快照)上调用create,这可能会导致渲染管道进一步出现问题。
  2. Graphics是一个共享的上下文,因此您需要注意对其所做的更改并撤消任何重要的&#34;你所做的改变,特别是转型
  3. 如果是我,我会在每次调用Graphicsrender之后创建dispose上下文的快照,例如

    public void render(Graphics g) {
        for (int i = 0; i < handlerList.size(); i++) {
            //handlerList is a LinkedList
            Graphics2D g2d = (Graphics2D)g.create();
            handlerList.get(i).render(g2d);
            g2d.dispose();
        }
    }
    

    这可确保在呈现下一个元素之前撤消renderGraphics上下文所做的更改

    如果更改正在复合,那么我会在循环开始前制作快照,然后在dispose之后制作快照。

    在任何一种情况下,都意味着您可以控制所做的更改以及它们如何影响其他元素。

    另外,请记住,转换正在复合