将每秒更新的计时器打印成一个简单的游戏

时间:2017-06-26 01:51:32

标签: java timer jframe jpanel repaint

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.ArrayList;
import java.util.Random;

import javax.swing.JFrame;
import javax.swing.Timer;

public class FinalFlappy implements ActionListener, MouseListener, 
KeyListener
{
public static FinalFlappy finalFlappy;
public final int WIDTH = 800, HEIGHT = 800;
public FinalFlappyRend renderer;
public Rectangle bee;
public ArrayList<Rectangle> rect_column;
public int push, yMotion, score;
public boolean gameOver, started;
public Random rand;

public FinalFlappy()
{
    JFrame jframe = new JFrame();
    Timer timer = new Timer(16, this);

    renderer = new FinalFlappyRend();
    rand = new Random();
    jframe.add(renderer);
    jframe.setTitle("Flappy Bee");
    jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    jframe.setSize(WIDTH, HEIGHT);
    jframe.addMouseListener(this);
    jframe.addKeyListener(this);
    jframe.setResizable(false);
    jframe.setVisible(true);
    bee = new Rectangle(WIDTH / 2 - 10, HEIGHT / 2 - 10, 40, 40);
    rect_column = new ArrayList<Rectangle>();
    addColumn(true);
    addColumn(true);
    addColumn(true);
    addColumn(true);
    timer.start();
}

public void addColumn(boolean start)
{
    int space = 300;
    int width = 60;
    int height = 50 + rand.nextInt(300);

    if (start)
    {
        rect_column.add(new Rectangle(WIDTH + width + rect_column.size() * 300, HEIGHT - height - 120, width, height));
        rect_column.add(new Rectangle(WIDTH + width + (rect_column.size() - 1) * 300, 0, width, HEIGHT - height - space));
    }
    else
    {
        rect_column.add(new Rectangle(rect_column.get(rect_column.size() - 1).x + 600, HEIGHT - height - 120, width, height));
        rect_column.add(new Rectangle(rect_column.get(rect_column.size() - 1).x, 0, width, HEIGHT - height - space));
    }
}
public void jump()
{
    if (gameOver)
    {
        bee = new Rectangle(WIDTH / 2 - 10, HEIGHT / 2 - 10, 40, 40);
        rect_column.clear();
        yMotion = 0;
        score = 0;
        addColumn(true);
        addColumn(true);
        addColumn(true);
        addColumn(true);
        gameOver = false;
    }
    if (!started)
    {
        started = true;
    }
    else if (!gameOver)
    {
        if (yMotion > 0)
        {
            yMotion = 0;
        }
        yMotion -= 10;
    }
}

@Override
public void actionPerformed(ActionEvent e)
{
    int speed = 10;
    push++;

    if (started)
    {
        for (int i = 0; i < rect_column.size(); i++)
        {
            Rectangle column = rect_column.get(i);

            column.x -= speed;
        }

        if (push % 2 == 0 && yMotion < 15)
        {
            yMotion += 2;
        }

        for (int i = 0; i < rect_column.size(); i++)
        {
            Rectangle column = rect_column.get(i);

            if (column.x + column.width < 0)
            {
                rect_column.remove(column);

                if (column.y == 0)
                {
                    addColumn(false);
                }
            }
        }
        bee.y += yMotion;

        for (Rectangle column : rect_column)
        {
            if (column.y == 0 && bee.x + bee.width / 2 > column.x + column.width / 2 - 10 && bee.x + bee.width / 2 < column.x + column.width / 2 + 10)
            {
                score++;
            }

            if (column.intersects(bee))
            {
                gameOver = true;

                if (bee.x <= column.x)
                {
                    bee.x = column.x - bee.width;

                }
                else
                {
                    if (column.y != 0)
                    {
                        bee.y = column.y - bee.height;
                    }
                    else if (bee.y < column.height)
                    {
                        bee.y = column.height;
                    }
                }
            }
        }

        if (bee.y > HEIGHT - 120 || bee.y < 0)
        {
            gameOver = true;
        }

        if (bee.y + yMotion >= HEIGHT - 120)
        {
            bee.y = HEIGHT - 120 - bee.height;
            gameOver = true;
        }
    }

    renderer.repaint();
}
public void paintColumn(Graphics g, Rectangle column)
{
    g.setColor(Color.green.darker());
    g.fillRect(column.x, column.y, column.width, column.height);
    g.fillRect(column.x-20, column.y+column.height-10, column.width+40, 10);
    g.fillRect(column.x-20, column.y-10, column.width+40, 10);

}

public void repaint(Graphics g)
{
    g.setColor(new Color(153,204,255));
    g.fillRect(0, 0, WIDTH, HEIGHT);
    g.setColor(new Color(255,255,255));
    g.fillOval(50, 50, 100, 100);
    g.setColor(Color.YELLOW);
    g.fillOval(600, 50, 100, 100);
    g.setColor(new Color(156,93,82));
    g.fillRect(0, HEIGHT - 120, WIDTH, 120);
    g.setColor(new Color(128,255,0));
    g.fillRect(0, HEIGHT - 120, WIDTH, 20);
    g.setColor(Color.YELLOW);
    g.fillRect(bee.x, bee.y, bee.width, bee.height);

    for (Rectangle column : rect_column)
    {
        paintColumn(g, column);
    }

    g.setColor(Color.white);
    g.setFont(new Font("Times New Roman", 1, 100));

    if (!started)
    {
        g.drawString("Push A to start", 100, HEIGHT / 2 - 50);
    }

    if (gameOver)
    {
        g.drawString("Game Over", 100, HEIGHT / 2 - 50);
        g.drawString("A to replay", 100, HEIGHT / 2 + 90);
    }
}

public static void main(String[] args)
{
    finalFlappy = new FinalFlappy();
}

@Override
public void mouseClicked(MouseEvent e)
{
    jump();
}

@Override
public void keyReleased(KeyEvent e)
{
    if (e.getKeyCode() == KeyEvent.VK_A)
    {
        jump();
    }
}

@Override
public void mousePressed(MouseEvent e)
{
}

@Override
public void mouseReleased(MouseEvent e)
{
}

@Override
public void mouseEntered(MouseEvent e)
{
}

@Override
public void mouseExited(MouseEvent e)
{
}

@Override
public void keyTyped(KeyEvent e)
{

}

@Override
public void keyPressed(KeyEvent e)
{

}

}

import java.awt.Graphics;
import javax.swing.JPanel;

public class FinalFlappyRend extends JPanel
{
@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);

    FinalFlappy.finalFlappy.repaint(g);
}

}

我正在制作Flappy鸟类游戏,我仍然坚持如何制作并显示一个计时器,每秒更新一次到屏幕上 当游戏结束时,如何在游戏开始和结束时启动它?

2 个答案:

答案 0 :(得分:1)

有几种方法可以实现您的要求。需要记住的重要一点是,任何解决方案都会有一定程度的漂移,这意味着它不太可能绝对准确,漂移程度将取决于很多因素,所以请注意。

您可以使用Swing Timer

它是定期更新用户界面最安全的方法之一,如果您的主循环已基于Swing Timer

,它也很有用

有关详细信息,请参阅How to Use Swing Timers

你可以......

在主循环中保持某种计数器。这假设你正在使用一个单独的线程(虽然你可以用Swing Timer做同样的事情)并且只是以一致的速率循环

long tick = System.nanoTime();
long lastUpdate = -1;
while (true) {
    long diff = System.nanoTime() - tick;
    long seconds = TimeUnit.SECONDS.convert(diff, TimeUnit.NANOSECONDS);
    if (seconds != lastUpdate) {
        lastUpdate = seconds;
        updateTimerLabel(seconds);
    }
    Thread.sleep(100);
}

这基本上运行while-loop,它计算给定时间点(tick)与现在之间的差异,如果它是&#34;第二个&#34;差异,然后更新UI(而不是不断更新具有相同值的UI)

updateTimerLabel方法基本上使用指定的时间更新标签,但是以线程安全的方式执行

protected void updateTimerLabel(long seconds) {
    if (EventQueue.isDispatchThread()) {
        timerLabel.setText(Long.toString(seconds));
    } else {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                updateTimerLabel(seconds);
            }
        });
    }
}

答案 1 :(得分:-1)

要制作并显示每秒更新的计时器,请将此代码放入主类:

private Timer timer = new Timer();
private JLabel timeLabel = new JLabel(" ", JLabel.CENTER);

timer.schedule(new UpdateUITask(), 0, 1000);

private class UpdateUITask extends TimerTask {

    int nSeconds = 0;

    @Override
    public void run() {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                timeLabel.setText(String.valueOf(nSeconds++));
            }
        });
    }
}