【问题标题】:Java Applet paint() method flickeringJava Applet paint() 方法闪烁
【发布时间】:2017-03-17 09:53:07
【问题描述】:

我一直在用 Java 进行细胞进化模拟。众所周知,我是一名初级/中级 Java 程序员。我知道几乎所有的基础知识,然后一点点,但我不太具备从头开始编写代码的技能。我这里的代码大致基于我在网上找到的一个源代码,我添加了我自己的触摸以及我在网上找到的一些其他部分。它似乎工作得很好,除了屏幕闪烁。似乎每次调用 repaint() 时它都会闪烁,可能是清除和重绘。它创造了几乎不可能看到的东西。我的代码中没有错误。我是使用小程序的新手,所以如果有更好的方法可以做到这一点,请告诉我。如何阻止屏幕闪烁?有没有一种简单的方法来缓冲图像以防止这种情况发生?这是绘制小程序的类

/* <!-- Defines the applet element used by the appletviewer. -->
<applet code='CellLife.java' width='1920' height='1080'></applet> */

import java.applet.Applet;
import java.awt.Event;
import java.awt.Graphics;
import java.util.Enumeration;
import java.util.Vector;

public class CellLife extends Applet implements Runnable {
// ========================================================================
// VARIABLES
// ========================================================================

// Data

/** Thread object for CellLife applet */
private Thread m_cellLife = null;

// Static constants

/**
 * the maximum number of creatures in the world. When the number of
 * creatures alive drops below half this, a new one is created to bring the
 * numbers back up.
 */
protected static final int MAX_CREATURES = 60;

// Data

/**
 * A list of the creatures currently alive. Stores CLCreature references.
 */
protected Vector creatures;

/** The world is a rectangle from (0,0) to (limit.x,limit,y) */
protected CL2dVector limit;

/**
 * The number of creatures that have been born since the simulation started
 */
protected long generations;

/** A test creature controllable by the user to allow response testing */
private CLCreature testCreature;

/** space-partitioning structure to speed collision detection */
protected CLBuckets buckets;

// ========================================================================
// METHODS
// ========================================================================

public CellLife() {
    creatures = new Vector();
    limit = new CL2dVector(500.0F, 500.0F);
    generations = 0;

    // initilaize our bucket structure
    float bucketScale = CLCell.RADIUS; // could stretch to root-two times
                                        // this
    buckets = new CLBuckets(bucketScale, (int) Math.ceil(limit.x / bucketScale), (int) Math.ceil(limit.y / bucketScale));
}

public String getAppletInfo() {
    return "Name: Cell Evolution\r\n" + "Author: Josh Marchand\r\n" + "Made in Eclipse";
}

// first time initialazion
public void init() {
    resize((int) limit.x, (int) limit.y);

    for (int i = 0; i < MAX_CREATURES; i++) {
        CLCreature new_creature = new CLCreature();
        new_creature.InitSimple(limit, buckets);
        creatures.addElement(new_creature);
    }
}

public void destroy() {
    // TODO: Place applet cleanup code here
}

public void paint(Graphics g) {
    g.drawString("No. creatures: " + creatures.size(), 0, 11);
    g.drawString("Births: " + generations, 0, 22);

    // draw cells
    for (int i = 0; i < creatures.size(); i++) {
        ((CLCreature) creatures.elementAt(i)).Draw(g);
    }

    // DEBUG: also indicate the contents of the buckets
    // buckets.Draw(g);

    // get all creatures to do their stuff
    CLCreature creature;
    for (int i = 0; i < creatures.size(); i++) {

        creature = (CLCreature) creatures.elementAt(i);

        if (creature.DoTimeStep(g, buckets, limit) && creatures.size() < MAX_CREATURES) {
            // inherit new creature from current
            CLCreature newCreature = new CLCreature();
            newCreature.InheritFrom(creature, buckets, limit);
            creatures.addElement(newCreature);
            generations++;
        }
    }

    // delete the ones that died doing it
    for (Enumeration e = creatures.elements(); e.hasMoreElements();) {
        creature = (CLCreature) e.nextElement();
        if (creature.hasDied) creatures.removeElement(creature);
    }

    // breed nwe creatures if pop. is low
    if (creatures.size() < MAX_CREATURES / 2) {
        // just add one for now,fix later
        CLCreature newCreature = new CLCreature();
        newCreature.InheritFrom((CLCreature) creatures.elementAt((int) Math.random() * creatures.size()), buckets, limit);
        creatures.addElement(newCreature);
        generations++;
    }

}

public void start() {
    if (m_cellLife == null) {
        m_cellLife = new Thread(this);
        m_cellLife.start();
    }
    // TODO: place any additional startup code here
}

public void stop() {
    if (m_cellLife != null) {
        m_cellLife.stop();
        m_cellLife = null;
    }
}

public void run() {
    while (true) {
        try {
            repaint();

            // quick nap here to allow user interface to catch up
            Thread.sleep(100);
        } catch (InterruptedException e) {
            stop();
        }
    }
}

public boolean mouseDown(Event e, int x, int y) {
    // create a single celled creature at specific loc
    testCreature = new CLCreature();
    testCreature.rootCell.location.x = x;
    testCreature.rootCell.location.y = y;
    testCreature.rootCell.type = CLGene.RED;
    creatures.addElement(testCreature);
    buckets.PutCell(testCreature.rootCell);
    return true;
}

public boolean mouseDrag(Event e, int x, int y) {
    testCreature.rootCell.location.x = x;
    testCreature.rootCell.location.y = y;
    return true;
}

public boolean mouseUp(Event evt, int x, int y) {
    creatures.removeElement(testCreature);
    buckets.RemoveCell(testCreature.rootCell);
    return true;
}
}

非常感谢大家的帮助,也很抱歉我的“菜鸟”,我正在努力自学!

【问题讨论】:

    标签: java applet draw


    【解决方案1】:

    我会考虑使用称为双缓冲的技术,您可以在其中创建一个绑定到 Image 的屏幕外 Graphics 对象,在其上执行所有绘图,然后将结果绘制到屏幕上。 您可以找到关于从图像 here 创建图形的便捷教程。更完整的示例可以在here找到。

    【讨论】:

    • 非常感谢您!它运行良好,并且完全没有滞后于应用程序。幸运的是,我正在使用一个非常小的窗口,如果我们正在使用大图像,我可以看到一个可能的问题。不断更改一个非常大的图像不会滞后于小程序吗?
    • @JoshMarchand 虽然双缓冲有时会降低一些性能,但对于当今的硬件来说这不是问题。如果您遇到性能问题,它会在其他地方。
    猜你喜欢
    • 1970-01-01
    • 2015-09-24
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 1970-01-01
    • 2015-01-18
    • 2014-07-05
    • 2013-03-12
    相关资源
    最近更新 更多