タイトル画面をクリックして遷移する

タイトル画面をクリックして遷移する

「MainLoop.java」ファイルを新規作成します。このColorゲームはクリックだけで操作します。ここではタイトル画面をクリックしたらJPanelクラスの画面が遷移します。他にもタイトル画面、メインループ画面、ゲームオーバー画面、ステージクリア画面があります。

・サンプルコード「Title.java」ファイル

import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

public class Title extends JPanel {
  private BufferedImage image;

  public Title(JFrame frame) {
    try {
      image = ImageIO.read(new File("./images/Title.png"));
    } catch (IOException e) {
      e.printStackTrace();
    }

    addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
        frame.getContentPane().removeAll(); // 画面を消す
        frame.add(new MainLoop(frame)); // メインループ画面追加
        frame.revalidate(); // 更新
        frame.repaint(); // 再描画
      }
    });
  }

  @Override
  protected void paintComponent(Graphics g) {
(中略)
  }
}

【サンプルコードの解説】
「addMouseListener」メソッドでクリック時の処理を登録し、クリックされると「JFrame」から現在の画面を消し、MainLoopクラスを追加して更新・再描画します。

・サンプルコード「MainLoop.java」ファイル

import javax.swing.JPanel;
import javax.swing.JFrame;

public class MainLoop extends JPanel {
  public MainLoop(JFrame frame) {
  }
}

【サンプルコードの解説】
「JPanel」で空のメインループ画面(メインのゲーム画面)を作成します。

色ブロックを表示する

ここで、ゲームらしく色ブロックを表示させます。「ColorBlock.java」ファイルを新規作成し、1個ずつの色ブロックを「ColorBlock」クラスで設計図を書きます。
ステージ(面)の数値はゲームウィンドウのタイトル文字をそのまま数値にしたものです。1面(ステージ)が"2"のタイトルになります。手抜きですが、解説を簡単にするためです。

図3:色ブロックの表示

・サンプルコード「ColorBlock.java」ファイル

import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Random;
import javax.imageio.ImageIO;

public class ColorBlock {
  public BufferedImage image;
  public int color;
  public int[] pos = new int[2];
  public int[] delta = new int[2];

  public ColorBlock(int color) {
    Random rand = new Random();
    this.color = color;
    try {
      image = ImageIO.read(new File("./images/"+color+".png"));
    } catch (IOException e) {
      e.printStackTrace();
    }
    for (int i = 0; i < 3*2; i++ ) {
      pos[0] = rand.nextInt(1800-50);
      pos[1] = rand.nextInt(900-50);
      delta[0] = rand.nextInt(7)-3;
      delta[1] = rand.nextInt(7)-3;
    }
  }

  public int update(int w,int h) {
    pos[0] += delta[0];
    pos[1] += delta[1];
    if (pos[0] < -100 || pos[0] > w || pos[1] < -100 || pos[1] > h) return 0;
    return 1;
  }
}

【サンプルコードの解説】
colorには色ブロックの「0(赤)」「1(緑)」「2(青)」が入ります。
色ブロックの(pos[0],pos[1])は(X,Y)座標、(delta[0],delta[1])は(増分X,増分Y)座標です。それぞれ初期値にはランダムな値を入れます。
「update」メソッドで(X,Y)座標に増分を加算して、色ブロックが画面外に出たら戻り値に0を返し、画面内なら戻り値に1を返します。

・サンプルコード「MainLoop.java」ファイル

import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.*;
import java.util.ArrayList;
import javax.swing.Timer;

public class MainLoop extends JPanel {
  private ArrayList<ColorBlock> colors = new ArrayList<ColorBlock>();
  private JFrame frame;
  private Timer timer;

  public MainLoop(JFrame frame) {
    this.frame = frame;
    int stage = Integer.parseInt(frame.getTitle());
    for (int i = 0; i < 3*stage; i++) colors.add(new ColorBlock(i%3));
    timer = new Timer(100, e -> {
      // 毎フレームの処理 (更新・再描画)
      frame.repaint();
    });
    timer.start();
  }

  @Override
  protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    for (int i = 0; i < colors.size(); i++) {
      Graphics2D g2d = (Graphics2D) g;
      ColorBlock c = colors.get(i);
      c.update(getWidth(),getHeight());
      g2d.drawImage(c.image, c.pos[0], c.pos[1], this);
    }
  }
}

【サンプルコードの解説】
「ArrayList」でColorBlockクラスの配列「colors」プロパティを作成し、ステージ番号*3色だけ追加します。
Timerクラスで100ミリ秒ごと(10FPS)に再描画を設定して「start」します。
ColorBlockのインスタンスをupdateして「drawImage」メソッドで描画します。

色ブロックをクリックして消す

今度は色ブロックをクリックしたら、そのブロックだけを消します。クリックした時のマウス座標と色ブロックの位置との差の絶対値が50より小さければクリック成功です。

・サンプルコード「ColorBlock.java」ファイル

(前略)
public class ColorBlock {
(中略)

  public ColorBlock(int color) {
(中略)
  }

  public int update(int w,int h) {
(中略)
  }

  public boolean click(MouseEvent e) {
    if (Math.abs(pos[0]+50-e.getX()) < 50 && Math.abs(pos[1]+50-e.getY()) < 50) return true;
    return false;
  }
}

【サンプルコードの解説】
click メソッドでは、マウスクリックの座標が「-50 < (X, Y) < 50」の範囲内であれば当たったと判定し、trueを返します。範囲外の場合はfalseを返します。

・サンプルコード「MainLoop.java」ファイル

import javax.swing.JPanel;
import javax.swing.JFrame;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import javax.swing.Timer;

public class MainLoop extends JPanel {
(中略)

  public MainLoop(JFrame frame) {
(中略)
    addMouseListener(new MouseAdapter() {
      @Override
      public void mousePressed(MouseEvent e) {
        for (int i = 0; i < colors.size(); i++) {
          if ( colors.get(i).click(e) ) {
            colors.remove(i);
            break;
          }
        }
      }
    });
  }

  @Override
  protected void paintComponent(Graphics g) {
(中略)
  }
}

【サンプルコードの解説】
メインループではイベントリスナーでマウスのクリックを検知し、色ブロックがクリックされていた場合は、そのブロックを「remove(削除)」します。

【コラム】今後足りなくなる機能

例えば、コンピュータで時間の数値は昔のままでは限度を超えてしまいます。そんな感じで今では不足する技術を見つけ出したいです。例えば「バーコードに限界がきてQRコードが生まれた」ようなことをしたいです。

人気記事トップ10

人気記事ランキングをもっと見る

企画広告も役立つ情報バッチリ! Sponsored

ClickHouse Cloudが実現した広告運用SaaS「ATOM」のデータ基盤革新、パフォーマンスを向上しながら、運用負荷とコストを削減 11月11日 6:20 AIで開発が加速する時代、品質保証はどう変わる? Tricentisが示すAIエージェント活用の実像 11月9日 6:45 悪用までの猶予が「1分」に迫るフロンティアAI時代に開発と本番を貫く脆弱性管理が必要 10月29日 8:30 欧州CRA対応とSBOM運用。AI生成コードのOSS混入問題の対策とは ――スニペット単位で検出する「FossID」「Insignary Clarity」によるSBOM運用 9月16日 6:40 PostgreSQLからTiDBへ、稼働中SaaSで進める段階的DB移行の実践と再設計への展望 9月7日 6:30 機能安全開発におけるGoogleTestの活用を支援!「Parasoft C/C++test CT」で実現する効率化&AI連携 4月14日 6:30 【CNDW2025】Grafanaが明かす「オブザーバビリティの哲学」ー最小限の労力で実用的なインサイトを得るには 1月23日 6:30 【CNDW2025】プロダクト急増に備える基盤刷新 ーウェルスナビがECSからEKSへの移行で得た知見とは 1月15日 6:30 【CNDW2025】250環境を5人で運用、構築時間は30分に ーKINTOテクノロジーズが語るインフラ基盤組織の作り方 2025年12月18日 6:30 新たな自動化で熱視線! AIエージェントの「推論能力」を支える2つのコンポーネントとは? 2025年11月28日 6:30