自己紹介
- 現在プログラミングの学習中の者です
- 言い回しや知識に関して、諸所間違い等あるかと思います
- その際は、ご指摘いただけますと幸いです
やりたいこと
Railsでポケモンのように「経験値に連動して、レベルアップする機能」を実装すること。
問題点
どのようにテーブルを設計するのかわからない。
結論
では早速参ります。
###1.テーブル設計
- モデル名:User、カラム名:level, experience_point
- モデル名:LevelSetting、カラム名:level, thresold
以上、2つのモデルを作成してください。名称はお任せします。
但し、データ型は全てintegerでお願いします。
ちなみに、ここでUserのlevelカラムのdefaultを1にして、experience_pointのdefaultを0にすることをお勧めします。(nilだと「加算」の時にエラーが起こりやすいため)
db:migrate前にマイグレーションファイルに追記するだけなので、是非調べてみてください。
rails g model [レベルアップさせたいもの] level:integer experience_point:integer
こんな感じになります。
###2.考え方の説明(できれば先に読んで欲しい)
全部設定してから考え方を知りたい!と言う方は3にお進みください。
まず、どのようにして「経験値に連動して、レベルアップする」のかをご説明します。
ここが先に頭に入っていると、処理の意味が理解しやすいからです。
レベルと経験値を持たせたいモデルをA、レベルと閾値のモデルをBとします。
※閾値:そのレベルになるために最低限必要なポイントだと思ってください。
Aのモデルを「レベルアップ」させるためには、何か基準が必要です。
例えば、ポケモンにおいては、レベルアップするために必要なものが経験値として定まっていますね。
今回、その基準の役割をしているのがBのモデルになります。
Bのモデルにはレベルと対応する閾値を設定したレコードをあらかじめ作っておきます。
例)
Level 2, thresold 50
Level 3, thresold 100
.
.
.
といった感じで。
私の場合ユーザーのデフォルトのレベルを1にしているので、2から作成しています。
さぁこれでどうするかと言うと、Aのモデルに経験値が加算される処理のタイミングで、このBのモデルの閾値(thresold)を合計の経験値と比較させる処理をすることで、次のレベルにアップできるかどうかを判定させます。
…難しいですね。
今はもやっとしたままで大丈夫です!
これを頭の片隅に置いたまま、次に進んでください。
###3.実際の処理
def levelUp
user = User.find(params[:id])
monster = Monster.find(params[:monster_id])
#この二行は適当なものに置き換えてください。
totalExp = user.experience_point
#変数に現在のユーザーの経験値を入れる
totalExp += monster.point
# 得られた経験値をユーザーの経験値に加算
user.experience_point = totalExp
#改めて、加算した経験値をuserの総経験値を示す変数に入れ直す
user.update(experience_point: totalExp)
#更新の処理をさせる
levelSetting = LevelSetting.find_by(level: user.level + 1);
#ここから重要です!レベルセッティングのモデルから、今の自分のレベルより1高いレコードを探させます。
#そしてそれを変数に入れておきます
if levelSetting.thresold <= user.experience_point
#探してきたレコードの閾値よりもユーザーの総経験値が高かった場合
user.level = user.level + 1
user.update(level: user.level)
#レベルを1増やして更新
end
end
もっといい書き方があるor必要ないものがあると思いますが、エラーをつぶしていった結果こちらでうまくいったので、今回はこのコードとさせていただきます。
monster.pointの部分は「経験値が得られる処理」であればなんでも構いません。
所感
経験値に連動するレベルアップの機能を実装しようとした際に、様々な方法で検索しましたが「エンジニアとしてのスキルをレベルアップ」「経験がなくても〜」といった記事に沢山引っ掛かったのでまとめてみました。
よく分からない部分も多いかと思うので、コメントを頂ければ時間のある時に返答させていただきます。
ここまで読んでいただき、ありがとうございました。