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

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

ただいまの
回答率

90.48%

  • Java

    14153questions

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

  • Swing

    230questions

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

java キー入力で画像を表示させてそのあと左に移動させたい

解決済

回答 1

投稿

  • 評価
  • クリップ 0
  • VIEW 495

Alpa

score 24

Aキーを押したら弾の画像が表示されて
そのあと左に連続で移動するようにしたいです
どうしたらいいでしょうか?

シューティングゲームで弾の発射に使うつもりです
(本当はもっと滑らかにできればいいのですが・・・)
(なんなら自機の移動ももっと・・・)

弾の画像サイズはX:20 Y:20 です
自機のサイズはX:80 Y:40 です

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JLabel;
import javax.swing.ImageIcon;

import java.awt.BorderLayout;
import java.awt.event.KeyEvent;

public class MyGame extends JFrame{

    int zikiX[] = {750};
    int zikiY[] = {225};

    int zikidamaX[] = {zikiX[0]-30};
    int zikidamaY[] = {zikiY[0]};

    ImageIcon icon1 = new ImageIcon
    ("C:\\Users\\miyab\\Desktop\\シューティングゲーム\\自機.png");//画像ファイル指定
    ImageIcon icon2 = new ImageIcon
    ("C:\\Users\\miyab\\Desktop\\シューティングゲーム\\自機弾.png");

    JLabel ziki = new JLabel(icon1);//JLabelに自機の画像ファイル設定
    JLabel zikizahyou = new JLabel();//自機の座標を生成
    JLabel zikidama = new JLabel(icon2);//JLabelに自機の弾の画像ファイル設定

    JPanel panel = new JPanel();//panel設定

    public static void main(String[] args){

        MyGame frame = new MyGame();//ウィンドウを内部的に作成
        frame.setSize(900, 550);//ウィンドウサイズ設定
        frame.setTitle("シューティングゲーム");
        frame.setLocationRelativeTo(null);//ウィンドウの位置を中央に設定

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //ウィンドウを×で閉じるようにする設定

        frame.setVisible(true);//ウィンドウを可視化

    }

    MyGame(){

        panel.setLayout(null);//レイアウトマネージャー無効化

        ziki.setBounds(zikiX[0], zikiY[0], 80, 40);//zikiのサイズと座標設定
        zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//自機の座標を設定
        zikizahyou.setBounds(5, 5, 150, 15);//自機の座標の座標とサイズを設定

        panel.add(ziki);//自機画像をpanelに追加
        panel.add(zikizahyou);//自機の座標を画面に表示

        getContentPane().add(panel, BorderLayout.CENTER);//???

        enableEvents(java.awt.AWTEvent.KEY_EVENT_MASK);//キーイベントの有効化

    }

    protected void processKeyEvent(java.awt.event.KeyEvent e){//キーイベントの関数

        if(e.getID() == java.awt.event.KeyEvent.KEY_PRESSED){

            if(e.getKeyCode() == java.awt.event.KeyEvent.VK_LEFT){

                zikiX[0] -= 10;//座標を左に移動
                if(zikiX[0] <= 0){//座標が画面外に行ったら左端に戻す

                    zikiX[0] = 0;//zikiのX座標を0に設定

                }
                ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定
                zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新

            }

            if(e.getKeyCode() == java.awt.event.KeyEvent.VK_RIGHT){

                zikiX[0] += 10;//座標を右に移動
                if(zikiX[0] >= 804){//座標が画面外に行ったら右端に戻す

                    zikiX[0] = 804;//zikiのX座標を804に設定

                }
                ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定
                zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新

            }

            if(e.getKeyCode() == java.awt.event.KeyEvent.VK_UP){

                zikiY[0] -= 10;//座標を上に移動
                if(zikiY[0] <= 1){//座標が画面外に行ったら上端に戻す

                    zikiY[0] = 1;//zikiのY座標を1に設定

                }
                ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定
                zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新

            }

            if(e.getKeyCode() == java.awt.event.KeyEvent.VK_DOWN){

                zikiY[0] += 10;//座標を下に移動
                if(zikiY[0] >= 471){//座標が画面外に行ったら下端に戻す

                    zikiY[0] = 471;//zikiのY座標を471に設定

                }
                ziki.setLocation(zikiX[0],zikiY[0]);//座標を再設定
                zikizahyou.setText("X座標:"+zikiX[0]+" Y座標:"+zikiY[0]);//座標表示を更新

            }

            if(e.getKeyCode() == java.awt.event.KeyEvent.VK_A){

                zikidama.setBounds(zikidamaX[0], zikidamaY[0], 20, 20);
                panel.add(zikidama);

                for(int i = 0; i < 100; i++){

                    zikidamaX[0] -= 30;

                }

                System.out.println(zikidamaX[0]);//座標確認用
                System.out.println(zikidamaY[0]);

            }

        }
    }

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 1

checkベストアンサー

+1

弾を動かすためには一定時間ごとに移動させるようにすればよいです。自機の移動も「キーを押した時のみ移動」ではなく「キーを押して(keyPressed)から、離す(keyReleased)までの間、一定時間ごとに移動」とすれば滑らかな移動になります。

一定時間ごとに何かをするにはswingアプリケーションではjavax.swing.Timerクラスを利用するのが典型的な方法です。考えやすい方法としてjavax.swing.Timerは常に動かしっぱなしにし、毎回「弾が表示中か・自機の移動中か」を判定して、しかるべき動きをさせるように考えるとよいかと思います。


追記:javax.swing.Timerの単純なサンプルを書いてみました。

import javax.swing.*;
import java.awt.*;

public class TimerSample extends JFrame {
    public static void main(String[] args) {
        new TimerSample().setVisible(true);
    }

    final int PanelWidth = 300;
    JLabel movingLabel;
    int labelX = 0;

    TimerSample() {
        super("timer sample");
        Container content = getContentPane();

        JPanel panel = new JPanel(null);
        panel.setPreferredSize(new Dimension(PanelWidth, 200));
        content.add(panel, BorderLayout.CENTER);

        movingLabel = new JLabel("moving");
        movingLabel.setBackground(Color.CYAN);
        movingLabel.setOpaque(true);
        movingLabel.setSize(80, 20);
        panel.add(movingLabel);

        initTimer();

        setDefaultCloseOperation(EXIT_ON_CLOSE);
        pack();
    }

    void initTimer() {
        Timer timer = new Timer(30, event -> {
            // このラムダ式が30ミリ秒ごとに自動的に実行される
            labelX += 2;
            if (labelX > PanelWidth - movingLabel.getWidth()) {
                labelX = 0;
            }
            movingLabel.setLocation(labelX, 90);
        });
        timer.start();
    }
}


この例ではTimerを使って、30ミリ秒ごとにラムダ式が永久に実行されるようにしています。ラムダ式の中では、ラベルを左から少しずつ右へ移動しつつ、右端に達したらまた左端へ戻すようにしています。このラムダ式の中で一定時間ごとにやりたいアニメーションの処理を色々と書けばよいわけです。
(ラムダ式はJava8以降でしか使えないので念のため。業務でない限りJava7以前ではないだろうと推測してJava8の文法で書いています)

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2017/10/01 17:05

    ありがとうございます
    Timerクラスを使ってみます

    キャンセル

  • 2017/10/01 18:07

    すいません
    使い方が調べてもよくわからないので例を教えていただけないでしょうか?

    キャンセル

関連した質問

同じタグがついた質問を見る

  • Java

    14153questions

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

  • Swing

    230questions

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