前提・実現したいこと
矢印キーを押している間、画像が任意の方向に上下左右に動くプログラムを作っています。そこで初めは矢印キーを押した瞬間にすこし反応し、一瞬反応しなくなった後に連続で反応するようになっていました。しかし、初めに少し止まるのはあまりよくなかったので、次はwhile
文を使ってFPS
制御にし、矢印キーを押すと押した方向に進むメソッドを有効にする方法に変えました。しかし、それだと矢印キーを離しても動き続けてしまいました。なので次は、矢印キーを離したときに進むメソッドを無効にするようにしようとしていますが、これが最適なのでしょうか。教えてください。理想はマインクラフトやマリオなどのボタンから手を離した時に止まる動きです。
追伸:
画像はswing
のJFrame
に色付きJPanel
を表示しています。
矢印キーの読み込みはKeyListener
を使用しています。
サンプルコードは少し待ってください。
追伸:
ソースコードを追加しました。
ソースコード1が一番最初の案でソースコード2が一番新しいものです。
###ソースコード1
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Test extends JFrame implements KeyListener{ final int SPEED=5; int x=50,y=50;//xとy座標 JPanel panel; public static void main(String[] args){ Test cl = new Test("Test"); } Test(String title){ setTitle(title); setSize(600,400); setLocationRelativeTo(null); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(null); panel = new JPanel(); panel.setBackground(Color.BLACK); panel.setBounds(x,y,50,50); add(panel); setVisible(true); addKeyListener(this);//KeyListener } @Override public void keyTyped(KeyEvent e){/*何かのキー(aなど)を押した場合の処理*/} @Override public void keyPressed(KeyEvent e){/*キーを入力した際の処理*/ switch(e.getKeyCode()){ case KeyEvent.VK_UP://上キー 上移動 y-=SPEED; break; case KeyEvent.VK_DOWN://下キー 下移動 y+=SPEED; break; case KeyEvent.VK_LEFT://左キー 左移動 x-=SPEED; break; case KeyEvent.VK_RIGHT://右キー 右移動 x+=SPEED; break; } panel.setBounds(x,y,50,50); } @Override public void keyReleased(KeyEvent e){/*キーを離した際の処理*/} }
###ソースコード2
import javax.swing.*; import java.awt.*; import java.awt.event.*; public class Main{ public static void main(String[] args){ Test cl=new Test("Test"); try{ while(true){ long s_Time = System.currentTimeMillis();//計測開始 for(int i=0;i<4;i++){ cl.movePanel(i,cl.wsad[i]); } cl.repaint(); long e_Time = System.currentTimeMillis();//計測終了 //FPS制御 try{ Thread.sleep(1000/cl.FPS-(e_Time-s_Time)); }catch(Exception e){ System.out.println("<Error>"+cl.FPS+"FPSの許容範囲を超えています ["+(1000/cl.FPS-(e_Time-s_Time))+"ms必要]"); } } }catch(Exception ee){ ee.printStackTrace(); } } } class Test extends JFrame implements KeyListener{ final int SPEED=2; final int FPS=60; int x=50,y=50;//xとy座標 JPanel panel,ball; boolean[] wsad = new boolean[4]; Test(String title){ setTitle(title); setSize(600,400); setLocationRelativeTo(null); setResizable(false); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLayout(null); panel = new JPanel(); panel.setBackground(Color.BLACK); panel.setBounds(x,y,50,50); add(panel); setVisible(true); addKeyListener(this);//KeyListener } @Override public void keyTyped(KeyEvent e){/*何かのキー(aなど)を押した場合の処理*/} @Override public void keyPressed(KeyEvent e){/*キーを入力した際の処理*/ switch(e.getKeyCode()){ case KeyEvent.VK_UP://上キー 上移動 wsad[0]=true; break; case KeyEvent.VK_DOWN://下キー 下移動 wsad[1]=true; break; case KeyEvent.VK_LEFT://左キー 左移動 wsad[2]=true; break; case KeyEvent.VK_RIGHT://右キー 右移動 wsad[3]=true; break; } } @Override public void keyReleased(KeyEvent e){/*キーを離した際の処理*/ switch(e.getKeyCode()){ case KeyEvent.VK_UP://上キー 上移動 wsad[0]=false; break; case KeyEvent.VK_DOWN://下キー 下移動 wsad[1]=false; break; case KeyEvent.VK_LEFT://左キー 左移動 wsad[2]=false; break; case KeyEvent.VK_RIGHT://右キー 右移動 wsad[3]=false; break; } } void movePanel(int c,boolean go){ if(!go) return; int x,y; switch(c){ case 0: x=0; y=-1; break; case 1: x=0; y=1; break; case 2: x=-1; y=0; break; default: x=1; y=0; break; } this.x+=x*SPEED; this.y+=y*SPEED; panel.setLocation(this.x,this.y); } }
補足情報(FW/ツールのバージョンなど)
java version "16.0.1" 2021-04-20
Java(TM) SE Runtime Environment (build 16.0.1+9-24)
Java HotSpot(TM) 64-Bit Server VM (build 16.0.1+9-24, mixed mode, sharing)
回答1件
あなたの回答
tips
プレビュー