【问题标题】:How to stop an applet from blinking?如何阻止小程序闪烁?
【发布时间】:2016-11-10 08:32:28
【问题描述】:

我一直在尝试将我的一个游戏转换为 Applet,但由于这是我第一次使用 Applet,我遇到了问题。基本上每当我打开游戏时,屏幕就会开始闪烁。我很确定这是因为没有 BufferStrategy,但是每当我尝试创建像“BufferStrategy bg = this.getBufferStrategy()”这样的一个时,它就不起作用。有人可以帮忙吗?

package main;

import java.awt.Color;
import java.awt.Graphics;

import javax.swing.JApplet;

import Handling.Handler;
import Other.HUD;
import Other.KeyInput;


public class Game  extends JApplet implements Runnable{

    private static final long serialVersionUID = 9021342660060318393L;

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

    private Thread thread;
    private boolean running = false;

    private Handler handler;
    private HUD hud;
    private Spawner spawner;
    private Menu menu;

    public enum STATE{
        Menu(),
        Help(),
        Settings(),
        DeathScreen(),
        Game();
    };

    public enum DIFFICULTY{
        Easy(),
        Mediuм(),
        Hard();
    };

    public STATE GameState = STATE.Menu;
    public DIFFICULTY difficulty = DIFFICULTY.Easy;







    private void tick(){
        handler.tick();
        if(GameState == STATE.Game){
            hud.tick();
            spawner.tick();
        }else if(GameState == STATE.Menu){
            menu.tick();
        }
    }

    public void paint(Graphics g){

        //DRAW HERE
        g.setColor(Color.black);
        g.fillRect(0, 0, WIDTH, HEIGHT);

        handler.paint(g);

        if(GameState == STATE.Game){
            hud.paint(g);
        }else if(GameState == STATE.Menu || GameState == STATE.Help || GameState == STATE.Settings || GameState == STATE.DeathScreen){
            menu.paint(g);
        }
        //STOP DRAWING

        g.dispose();
    }








    public void init(){
        setSize(WIDTH,HEIGHT);

        handler = new Handler();
        menu = new Menu(this, handler);
        this.requestFocusInWindow(true);
        this.setFocusable(true);
        this.addKeyListener(new KeyInput(handler));
        this.addMouseListener(menu);
        hud = new HUD();
        spawner = new Spawner(handler, hud, this);
    }

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

    public void destroy(){}

    public void stop(){
        try {
            System.exit(1);
            thread.join();
            running = false;
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

    }

    public void run() {
        this.requestFocus();
        long LastTime = System.nanoTime();
        double amountOfTicks = 60.0;
        double ns = 1000000000 / amountOfTicks;
        double delta = 0;
        long timer = System.currentTimeMillis();
        int frames = 0;
        while(running){
            long now = System.nanoTime();
            delta += (now - LastTime) / ns;
            LastTime = now;
            while(delta >= 1){
                tick();
                repaint();
                delta--;
            }
            frames++;

            if(System.currentTimeMillis() - timer > 1000){
                timer += 1000;
                System.out.println("FPS: " + frames);
                frames = 0;
            }
            try {
                thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        stop();
    }

}

【问题讨论】:

  • 您是否尝试过手动双缓冲或添加例如要在其上绘制的 JPanel(默认情况下应为双缓冲)?
  • 1) g.dispose(); 永远不要处置不是您的代码创建的 Graphics 对象。 2) 将public void paint(Graphics g){ //DRAW HERE 更改为public void paint(Graphics g){ super.paint(g); //DRAW HERE,以尊重油漆链。 3) 为了尽快获得更好的帮助,请发布minimal reproducible exampleShort, Self Contained, Correct Example。 4) 见Java Plugin support deprecatedMoving to a Plugin-Free Web
  • 5) public void stop(){ try { System.exit(1); A) Java 安全系统应该阻止对System.exit(int) 的调用 当 JVM 告诉它时,applet 将被停止 - 这意味着 applet 本身应该停止处理,小程序本身不应试图停止 JVM。 B) 但请注意,除0 之外的任何整数都保留用于异常退出,而stop() 方法由其他进程调用以指示正常,否则完全预期停止到 (current)小程序活动。
  • 6) public void init(){ setSize(WIDTH,HEIGHT); 你对强大的小程序开发的知识水平是..最低的。在这种情况下,小程序的大小在 HTML 中设置,它不应该尝试第二次猜测或更改该大小 - 它必须适用于已分配的任何大小。

标签: java swing applet awt japplet


【解决方案1】:

不要调用repaint(),而是尝试调用

paint(getGraphics()). 

另外,将此方法添加到您的小程序中:

public void update(java.awt.Graphics g) {}

【讨论】:

  • 这两条建议充其量是糟糕的编程,最坏的情况是完全搞砸了。极不建议使用巫毒编程。
  • 第二个tip是一个很老的tip,19年前用在Java代码中。不确定它是否过时,但由于 Java 仍然支持 1.1,它可能是有效的。
  • “不确定它是否过时了” 是的。不要使用针对 AWT 的建议。即便如此,这也是非常糟糕的建议。你在哪里看到的(链接)?
猜你喜欢
  • 2014-08-12
  • 1970-01-01
  • 1970-01-01
  • 2020-12-14
  • 2011-10-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多