Java

オブジェクト指向でRPGを作ってみる – 装備を使えるようにする

投稿日:

以前、コンソールアプリで勇者がひのきの棒を装備すようにしていましたので、敵と遭遇したりアイテムを拾ったりするのと同様に、装備を拾えるように実装を追加してみましょう。

まず、以前に作成した Arms クラスがありますが、新しく rpg.model.arms パッケージを作成してこちらに移動します。

package rpg.model.arms;

public class Arms {
  private String name;

  public Arms(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }
}

Arms クラスを継承して HinokiRod クラスを作成します。

package rpg.model.arms;

public class HinokiRod extends Arms {
  public HinokiRod() {
    super("ひのきの棒");
  }
}

RpgFrame の中で、勇者が移動したときに確率で装備を拾う処理を追加します。

  @Override
  public void keyPressed(KeyEvent e) {
    if (e.getKeyCode() == KeyEvent.VK_LEFT) {
      if (braveX > 0) braveX--;
    }
    if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
      if (braveX < FieldWidth - 1) braveX++;
    }
    if (e.getKeyCode() == KeyEvent.VK_UP) {
      if (braveY > 0) braveY--;
    }
    if (e.getKeyCode() == KeyEvent.VK_DOWN) {
      if (braveY < FieldHeight - 1) braveY++;
    }
    drawField();
    System.out.println("x=" + braveX + ", y=" + braveY);
    if (isEncount()) {
      System.out.println("敵と遭遇しました。");
      BattleFrame bf = new BattleFrame();
      bf.setBrave(rpg.getBrave());
      Monster m = rpg.getMonster();
      bf.setMonster(m);
      bf.setMonsterLabel(getMonsterLabel(m));
      SwingUtilities.invokeLater(new WindowInvoker(bf));
    } else if (isItemFound()) {
      //アイテムを拾う処理
      Item item = rpg.getItem();
      Brave brave = rpg.getBrave();
      brave.addItem(item);
      System.out.println(item.getName() + "を見つけた");
      String msg = item.getName() + "を見つけた!";
      JOptionPane.showMessageDialog(
        this, msg,
        "アイテム", JOptionPane.INFORMATION_MESSAGE);
    } else if (isArmsFound()) {
      // 装備を拾う処理
      Arms arms = rpg.getArms();
      Brave brave = rpg.getBrave();
      brave.setArms(arms);
      String msg = arms.getName() + "を見つけた!";
      JOptionPane.showMessageDialog(
        this, msg,
        "アイテム", JOptionPane.INFORMATION_MESSAGE);
    }
  }
  private IconLabel getMonsterLabel(Monster m) {
    MonsterCreator mc = new MonsterCreator();
    return mc.getMonsterLabel(m);
  }
  @Override
  public void keyReleased(KeyEvent e) {
    //
  }
  private boolean isEncount() {
    double v = Math.random();
    return v < 0.05;
  }
  private boolean isItemFound() {
    double v = Math.random();
    return v < 0.05;
  }
  private boolean isArmsFound() {
    double v = Math.random();
    return v < 0.05;
  }

Rpgクラスに getArms() を追加して、ひのきの棒を拾えるようにします。
モンスターやアイテムは複数から確率で発生するようにしていますが、ここではひのきの棒のみにしおきます。
あとで別の装備を拾えるようにしたくなったら、修正すればいいですね!

package rpg.model;

import rpg.model.arms.Arms;
import rpg.model.arms.HinokiRod;
import rpg.model.item.Item;
import rpg.model.monster.Monster;

public class Rpg {
  private Brave brave;
  public Rpg() {
    brave = new Brave();
    brave.setName("ヨシヒコ");
  }
  public Brave getBrave() {
    return brave;
  }
  public Monster getMonster() {
    MonsterCreator mc = new MonsterCreator();
    return mc.createMonster();
  }
  public Item getItem() {
    ItemCreator ic = new ItemCreator();
    return ic.createItem();
  }
  public Arms getArms() {
    return new HinokiRod();
  }
}

装備を拾った時に、いきなり装備するのではなくて、所持品として追加するように変更します。

勇者が装備を所持しているけれども装備していない状態を作ります。

勇者のクラスを修正します。

package rpg.model;
import java.util.ArrayList;
import java.util.List;

import rpg.model.arms.Arms;
import rpg.model.item.Item;

public class Brave extends Chara {
  private int exp = 1;
  private int mp = 10;
  private int gold = 0;
  private Arms arms;
  private List<Arms> armses = new ArrayList<>();
  private List<Item> items = new ArrayList<>();
  public Brave() {
    hp = 10;
    setName("ヨシヒコ");
  }
  public int getExp() {
    return exp;
  }
  public void addExp(int p) {
    exp += p;
  }
  public void setArms(Arms arms) {
    this.arms = arms;
  }
  public void addArms(Arms arms) {
    armses.add(arms);
  }
  public void addItem(Item item) {
    items.add(item);
  }

RpgFrameで、装備を拾うところのコードも修正します。

    } else if (isArmsFound()) {
      // 装備を拾う処理
      Arms arms = rpg.getArms();
      Brave brave = rpg.getBrave();
      brave.addArms(arms);
      String msg = arms.getName() + "を見つけた!";
      JOptionPane.showMessageDialog(
        this, msg,
        "アイテム", JOptionPane.INFORMATION_MESSAGE);
    }

バトルの画面で勇者が攻撃すると例外が発生しますので、Braveクラスを修正します。

  public int getDealDamage() {
    int ratio = 1;
    if (arms != null) ratio = arms.getRatio();
    return ratio;
  }

戦闘画面に装備ボタンを追加して、装備を変更できるようにします。

package rpg.view;
import java.awt.Container;

import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;

import rpg.controller.ArmsAction;
import rpg.controller.BattleAction;
import rpg.controller.EscapeAction;
import rpg.controller.HealAction;
import rpg.controller.ItemAction;
import rpg.model.Brave;
import rpg.model.monster.Monster;

public class BattleFrame extends JFrame {
  private Brave brave;
  private Monster monster;
  private BraveLabel braveLabel;
  private JLabel expLabel;
  private IconLabel monsterLabel;
  private JPanel iconsPanel;
  public BattleFrame() {
    super("戦闘");
    Container pane = getContentPane();
    pane.setLayout(new BoxLayout(pane, BoxLayout.Y_AXIS));
    expLabel = new JLabel("経験値:");
    pane.add(expLabel);
    iconsPanel = new JPanel();
    iconsPanel.setLayout(new BoxLayout(iconsPanel, BoxLayout.X_AXIS));
    JPanel buttonsPanel = new JPanel();
    buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.Y_AXIS));
    pane.add(iconsPanel);
    pane.add(buttonsPanel);
    braveLabel = new BraveLabel();
    iconsPanel.add(braveLabel);
    JButton battleButton = new JButton("こうげき");
    battleButton.addActionListener(new BattleAction(this));
    buttonsPanel.add(battleButton);
    JButton escapeButton = new JButton("にげる");
    escapeButton.addActionListener(new EscapeAction(this));
    buttonsPanel.add(escapeButton);
    JButton healButton = new JButton("かいふく");
    healButton.addActionListener(new HealAction(this));
    buttonsPanel.add(healButton);
    JButton itemButton = new JButton("アイテム");
    itemButton.addActionListener(new ItemAction(this));
    buttonsPanel.add(itemButton);
    JButton armsButton = new JButton("装備");
    armsButton.addActionListener(new ArmsAction(this));
    buttonsPanel.add(armsButton);
  }

  (以下略)

ItemActionをマネしてArmsActionを作ります。

package rpg.controller;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;

import javax.swing.JOptionPane;

import rpg.model.Brave;
import rpg.model.arms.Arms;
import rpg.view.BattleFrame;

public class ArmsAction implements ActionListener {
  private BattleFrame battleFrame;

  public ArmsAction(BattleFrame battleFrame) {
    this.battleFrame = battleFrame;
  }

  @Override
  public void actionPerformed(ActionEvent e) {
    // 装備を持ってなければ何もしない
    if (!hasArms()) {
      JOptionPane.showMessageDialog(battleFrame,
      "装備がありません。",
      "装備",
      JOptionPane.INFORMATION_MESSAGE);
      return;
    }
    Object[] armses = new String[2];
    armses[0] = "装備なし";
    armses[1] = "ひのきの棒";
    Object armsName = JOptionPane.showInputDialog(
      battleFrame, 
      "装備を選択してください", 
      "装備",
      JOptionPane.PLAIN_MESSAGE, 
      null, 
      armses,
      armses[0]);
    if (armsName == null) return;
    Brave brave = battleFrame.getBrave();
    if (armsName.equals(armses[0])) {
      brave.setArms(null);
    } else {
      List<Arms> armsList = brave.getArmses();
      Arms arms = armsList.get(0);
      brave.setArms(arms);
      String msg = brave.getName() + "は、"
                 + arms.getName() + "を装備した。";
      JOptionPane.showMessageDialog(battleFrame,
      msg,
      "装備",
      JOptionPane.INFORMATION_MESSAGE);
    }
  }

  private boolean hasArms() {
    Brave brave = battleFrame.getBrave();
    return brave.hasArms();
  }
}

ArmsActionで勇者が持っている装備のリストを取得する必要があるので、Braveクラスに追加します。

  public List<Item> getItems() {
    return items;
  }
  public int getDealDamage() {
    int ratio = 1;
    if (arms != null) ratio = arms.getRatio();
    return ratio;
  }
  public boolean hasArms() {
    return armses.size() > 0;
  }
  public List<Arms> getArmses() {
    return armses;
  }

-Java
-, ,

Copyright© UMLとJavaで学ぶオブジェクト指向プログラミング入門 , 2025 All Rights Reserved Powered by STINGER.