如何在计时器中绘制2D对象

时间:2018-10-20 19:06:31

标签: java swing paintcomponent

我正在尝试使用OOP制作蛇游戏。对我来说,OOP是一个新概念,因为我通常使用函数式编程。

我有一个计时器,当它执行时,它应该画蛇和食物。

@Override
protected void paintComponent(Graphics g) {

    Timer timer = new Timer();

    TimerTask timerTask = new TimerTask() {

        @Override
        public void run() {

            //SNAKE AND FOOD DO NOT SHOW UP HERE

            g.setColor(Color.GREEN);
            drawSnake(g, snek);
            drawFood(g, foodPack);  
            snek.changeYDir(10);
            snek.moveHeadY();
            System.out.println("Timer is running");
            System.out.println(snek.getHeadY());
            System.out.println(snek.getChunkX(0));

        }
    };
    timer.scheduleAtFixedRate(timerTask, 0, 1000);



    //If code in timer is put here, snake and food show up


}

**我推断出一些线索!

  1. 计时器正在运行
  2. 头部正在移动-显示在控制台中
  3. 蛇形存在-显示在控制台中

控制台日志:

Timer is running
340
130

这里是整个项目的链接。 https://files.fm/u/b8kvgebq

1 个答案:

答案 0 :(得分:0)

首先阅读Painting in AWT and SwingPerforming Custom Painting,以更好地了解Swing中的绘画工作原理。

接下来,阅读Concurrency in Swing,以了解线程在Swing中的工作方式。

paintComponent应该只绘制组件的当前状态,绝不执行任何可能触发新绘制过程的操作。

由于paintComponent可以在任何时间被调用,由于多种原因,许多您无法控制,因此尝试在其中安排新的TimerTask是非常非常非常糟糕的理念。您可能会遇到许多尝试更改UI的计时器,这将降低性能并可能相互冲突。

由于Graphics本身也是短暂的,因此切勿在{{1​​}}方法范围之外维护对它的引用。

首先,请查看How to use Swing Timers,以获得更好的基本解决方案。您应该创建一个paint来更新组件的状态并调用Timer,这将间接调用您的repaint,这时将绘制组件的当前状态。

例如,请参见SnakeGame how to make the tail follow the head?