简体   繁体   中英

Printing a timer that updates every second into a simple game

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);
}

}

I am working on making a Flappy bird game and I am stuck on how to make and display a timer that updates every second onto the screen How do I make it start as the game starts and end as the game over pops up?

There are a few ways you might achieve what you're asking. The important thing to remember is, any solution is going to have a degree of drift, meaning that it's unlikely to absolutely accurate, the degree of drift will depend on a lot of factors, so just beware.

You could use a Swing Timer

It's among the safest means for updating the UI on a regular basis, it's also useful if your main loop is already based on a Swing Timer

See How to Use Swing Timers for more details

You could...

Maintain some kind of counter within in your main loop. This assumes that you're using a separate thread (although you can do the same thing with a Swing Timer ) and are simply looping at some consistent rate

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);
}

This basically runs a while-loop , which calculates the difference between a given point in time ( tick ) and now, if it's a "second" difference, it then updates the UI (rather than constantly updating the UI with the same value)

The updateTimerLabel method basically updates the label with the specified time, but does so in a manner which is thread safe

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

To make and display a timer that updates every second, Put this code in your main class:

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++));
            }
        });
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM