[英]Java How to constantly repaint
I'm trying to make the game Snake, although I'm currently having trouble constantly repainting the snake. 我正在努力制作游戏Snake,尽管我现在无法重新粉刷蛇。 I'm using a timer, and when I set the interval to 150 milliseconds, it works, although when I set it to something faster like 30 milliseconds, nothing shows on the screen.
我正在使用计时器,当我将间隔设置为150毫秒时,它可以正常工作,但是当我将它设置为更快的速度(如30毫秒)时,屏幕上没有任何显示。 The timer w/ repaint() call are in the Game class.
带有repaint()调用的计时器在Game类中。 Thanks!
谢谢!
Game Class 游戏类
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Panel;
import java.awt.RenderingHints;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.*;
import java.util.*;
import java.util.Timer;
import java.util.TimerTask;
public class Game extends JFrame{
JPanel mainPanel = new JPanel();
BorderLayout layout = new BorderLayout();
//Game game;
Snake snake = new Snake(this);
public Game(){
super("Snake by Alex 2017");
setSize((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth()),(int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight()));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
mainPanel.setLayout(null);
mainPanel.setSize((int)(Toolkit.getDefaultToolkit().getScreenSize().getWidth()),(int)(Toolkit.getDefaultToolkit().getScreenSize().getHeight()));
mainPanel.setBackground(Color.BLACK);
add(mainPanel);
mainPanel.setVisible(true);
start();
addKeyListener(new KeyListener() {
@Override
public void keyTyped(KeyEvent e) {
}
@Override
public void keyReleased(KeyEvent e) {
}
@Override
public void keyPressed(KeyEvent e) {
snake.keyPressed(e);
}
});
setFocusable(true);
}
public void paint(Graphics g){
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
snake.paint(g2d);
//System.out.println("hello");
}
Timer timer = new Timer();
TimerTask task = new TimerTask() {
public void run() {
try {
move();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
TimerTask update = new TimerTask() {
public void run() {
repaint();
}
};
public void start(){
timer.scheduleAtFixedRate(task, 0, 250);
timer.schedule(update, 0, 30);
}
public void move() throws InterruptedException{
snake.move();
}
public static void main(String[] args) throws InterruptedException{
Game game = new Game();
}
}
Snake Class 蛇类
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.event.KeyEvent;
import javax.swing.RepaintManager;
public class Snake {
public int x = 60;
public int y = 80;
public int xa = 0;
public int ya = 0;
public int speed = 20;
private Game game;
public Snake(Game game){
this.game = game;
}
public void move(){
x += xa;
y += ya;
}
public void keyPressed(KeyEvent e){
//RIGHT
if(e.getKeyCode() == 39){
xa = speed;
ya = 0;
}
//LEFT
if(e.getKeyCode() == 37){
xa = -speed;
ya = 0;
}
//UP
if(e.getKeyCode() == 38){
ya = -speed;
xa = 0;
}
//DOWN
if(e.getKeyCode() == 40){
ya = speed;
xa = 0;
}
//move();
//game.repaint();
}
public Rectangle getBounds(){
return new Rectangle(x, y, 20, 20);
}
public void paint(Graphics2D g2d){
g2d.setColor(new Color(48, 255, 55));
g2d.fillRect(x, y, 20, 20);
}
}
What you have to do is to create a Thread that loops all the time and renders your game, like: 你要做的就是创建一个一直循环并呈现游戏的线程,如:
public void run() {
while (true) {
render();
}
}
your run method is correct, but you also need to extends Thread to repaint in an extra thread over and over again see this post for multithreading . 你的run方法是正确的,但是你还需要一次又一次地在一个额外的线程中扩展Thread来重新显示多线程的这篇文章 。
For all the details concerning BufferStrategy and more follow this Tutorial . 有关BufferStrategy等的所有细节,请参阅本教程 。 I think it is really good explained, and I used it my self.
我认为它解释得非常好,我用它自己。
Try to use javax.swing.Timer;
尝试使用
javax.swing.Timer;
as described in https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html Implement ActionListener and put there repaint()
, then create Timer like this 如https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html中所述实现ActionListener并将其放在
repaint()
,然后像这样创建Timer
Timer timer = new Timer(5, this);
timer.start();
This will invoke actionPerformed()
where you have repaint()
这将调用
actionPerformed()
,你有repaint()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.