私は現在、ヘビを絶えず再ペイントするのに困っていますが、スネークを作ろうとしています。私はタイマーを使用しています。インターバルを150ミリ秒に設定すると動作しますが、30ミリ秒ほど速く設定しても何も表示されません。 timer w/repaint()呼び出しはGameクラスにあります。ありがとう!Java継続的に再ペイントする方法
ゲームクラス
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();
}
}
スネーククラス
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);
}
}
'java.util.Timer'の代わりにSwingタイマー(' javax.swing.Timer')を使うべきです。 Swingタイマーは、Swingプログラムで動作するように設計されており、Swingスレッドで実行されます。 https://docs.oracle.com/javase/tutorial/uiswing/misc/timer.html – Radiodef
私はスイングタイマーを試しましたが、私はまだ一定の再描画のために遅延を十分に速く設定することはできません。 – Alex
他の問題があります。 Swingはタイマーから 'repaint()'を呼び出すようなパッシブレンダリングでも、かなり高い再描画レートを処理できます。私の経験では、Snakeのようなシンプルな2Dゲームでは、約200または300FPSの高いフレームレートが得られます。 (制限は、Swingイベントキューが定数イベントのポストに追いつくことができるかどうか、そして繰り返しペイントイベントが合体するかどうかです) – Radiodef