質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

Q&A

解決済

2回答

1626閲覧

JPanelを斜めに移動させる方法

cretter

総合スコア91

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Swing

SwingはJavaに標準で付属するグラフィック関連のクラスライブラリを指します。

1グッド

0クリップ

投稿2021/09/03 09:32

前提・実現したいこと

現在、独学でシューティングゲームを作っています。その際に玉(JPanel)を斜めに動かす必要があります。もし角度が45°であれば各座標を定める変数に1ずつ足せばいい(ソースコード①のBallクラスのgoメソッド)と思うのですが、その角度がもっと斜めだった場合にどうすればいいのかわかりません。案としてソースコード②が思いついたのですが、他にいい方法はありませんか?
ソースコード②はsetLocationをする際に数値を1/10にすることで精度を保っているつもりです。
また、他にソースコードの改善点があれば教えてください。

元のソースオード①

Java

1import javax.swing.*; 2import java.awt.*; 3public class Main{ 4 public static void main(String[] args){ 5 new Main(); 6 } 7 Main(){ 8 Game f = new Game(); 9 f.setVisible(true); 10 while(true){ 11 long st = System.currentTimeMillis(); 12 13 f.ball.go(f.fx,f.fy); 14 15 long en = System.currentTimeMillis(); 16 try{ 17 Thread.sleep(1000/f.fps-(en-st)); 18 }catch(Exception ex){ 19 System.out.println("<Error> +"+(1000/f.fps-(en-st))+"ms"); 20 } 21 } 22 } 23} 24class Game extends JFrame{ 25 int fps = 60; 26 int fx=500,fy=500; //フレームサイズ 27 Ball ball; 28 Game(){ 29 setTitle("ゲーム画面"); 30 setSize(fx+14,fy+37); 31 setLocationRelativeTo(null); 32 setLayout(null); 33 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 34 setBackground(Color.white); 35 36 ball = new Ball(); 37 add(ball); 38 } 39} 40class Ball extends JPanel{ 41 int x=0,y=0; //座標 42 Ball(){ 43 setBounds(x,y,10,10); 44 setBackground(Color.black); 45 } 46 void go(int fx,int fy){ 47 if(fx==x || fy==y){ 48 x=0; 49 y=0; 50 } 51 x++; 52 y++; 53 setLocation(x,y); 54 } 55}

変更点②

Java

1class Ball extends JPanel{ 2 int x=0,y=0; //座標 3 Ball(){ 4 setBounds(x,y,10,10); 5 setBackground(Color.black); 6 } 7 void go(int fx,int fy){ 8 if(fx==x/10 || fy==y/10){ 9 x=0; 10 y=0; 11 } 12 x+=9; 13 y+=3; 14 setLocation(x/10,y/10); 15 } 16}

補足情報(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)

TN8001👍を押しています

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

そんなまどろっこしいことをするくらいなら、xydoubleで持てばよくないですか?

Java

1class Ball extends JPanel { 2 double x = 0; 3 double y = 0; 4 double rad = Math.toRadians(18); 5 6 Ball() { 7 setBounds((int) x, (int) y, 10, 10); 8 setBackground(Color.black); 9 } 10 11 void go(int fx, int fy) { 12 if (fx <= x || fy <= y) { 13 x = 0; 14 y = 0; 15 } 16 17 x += Math.cos(rad); 18 y += Math.sin(rad); 19 setLocation((int) x, (int) y); 20 } 21}

JavaでゲームならProcessingもおすすめです^^
Welcome to Processing! / Processing.org

投稿2021/09/03 13:41

編集2023/08/14 13:24
TN8001

総合スコア9862

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

cretter

2021/09/04 01:12

たしかに! 言われるまで気づきませんでした。 ありがとうございます。
guest

0

他にいい方法はありませんか?

基本的には 2 番の感じになると思います。

他にソースコードの改善点があれば

フレームを表示して以降は、Swing の部品を外部から操作してはいけません。(より正確には、フレームの表示自体もSwing上でやらないといけないのですが…。)
また、JFrame内をJPanelが動き回る構造よりも、JPanelをゲーム画面としてその中に各キャラクタを画像として書き込むほうが、自由度が高く、JPanelという重そうな(計ったことはありません)モノを使うより良いように思います。

ボタンを押すとボールが動き回ります。

java

1package teratail_java.q357613; 2 3import java.awt.Color; 4import java.awt.Dimension; 5import java.awt.FlowLayout; 6import java.awt.Graphics; 7import java.awt.Rectangle; 8import java.awt.event.ActionEvent; 9import java.awt.event.ActionListener; 10import java.util.concurrent.Executors; 11import java.util.concurrent.ScheduledExecutorService; 12import java.util.concurrent.TimeUnit; 13 14import javax.swing.JButton; 15import javax.swing.JFrame; 16import javax.swing.JPanel; 17 18public class GameFrame extends JFrame { 19 public static void main(String[] args) { 20 new GameFrame().setVisible(true); 21 } 22 GameFrame() { 23 super("ゲーム画面"); 24 setLocationRelativeTo(null); 25 setDefaultCloseOperation(EXIT_ON_CLOSE); 26 setResizable(false); 27 add(new GamePanel()); 28 pack(); 29 } 30 private class GamePanel extends JPanel { 31 private Ball ball; 32 private Rectangle frame; 33 private ScheduledExecutorService executor; 34 GamePanel() { 35 super(new FlowLayout()); 36 Dimension size = new Dimension(200, 200); 37 setPreferredSize(size); 38 frame = new Rectangle(size); 39 40 ball = new Ball(90, 100, 0.9f, 0.5f); 41 42 executor = Executors.newSingleThreadScheduledExecutor(); 43 44 JButton startButton = new JButton("start"); 45 add(startButton); 46 startButton.addActionListener(new ActionListener() { 47 @Override 48 public void actionPerformed(ActionEvent e) { 49 startButton.setEnabled(false); 50 executor.scheduleAtFixedRate(new Runnable() { 51 @Override 52 public void run() { 53 ball.move(frame); 54 repaint(); 55 } 56 }, 10, 10, TimeUnit.MILLISECONDS); 57 } 58 }); 59 } 60 @Override 61 public void paintComponent(Graphics g) { 62 super.paintComponent(g); 63 ball.draw(g); 64 } 65 } 66 private class Ball { 67 private float x, y, dx, dy; 68 private int w=20, h=20; 69 Ball(int x, int y, float dx, float dy) { 70 this.x = x; 71 this.y = y; 72 this.dx = dx; 73 this.dy = dy; 74 } 75 void move(Rectangle frame) { 76 for(boolean xover=false, yover=false; !xover || !yover; ) { 77 xover = frame.contains(x+dx, y, w, h); 78 if(!xover) dx *= -1; 79 yover = frame.contains(x, y+dy, w, h); 80 if(!yover) dy *= -1; 81 } 82 x += dx; 83 y += dy; 84 } 85 void draw(Graphics g) { 86 g.setColor(Color.BLUE); 87 g.fillOval((int)x, (int)y, w, h); 88 } 89 } 90}

投稿2021/09/03 11:22

編集2021/09/03 13:56
jimbe

総合スコア13209

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問