Little Strange Software

スマホアプリの開発を行う LittleStrangeSoftware のブログです。

【JavaScript】スタミナシステムを作ってみました

 どうも!LSSです!!

 

スマホゲームによくある「スタミナ」というシステム。(名称はゲームによって違ったりしますが)

ゲームを起動していても、していなくても、時間経過で徐々に数値が貯まっていって、それを消費してゲームを回せるアレ。

 

作れる自信だけありましたが、今回それを試しに作ってみました。

 

 

スタミナシステム

 

 

「スタート!」ボタンを押すと開始します。

初めて開始した場合は、初期値として「1000」のポイントが与えられます。

ポイントの上限は5000。

 

それから3分ごとにポイントが1増えます。

3分で1ポイントなので1時間で20、1日で480ポイントになります。

…ためたところで使い途を用意していないんですけどねw

 

 

コード

<p><input id="gsbtn" type="button" value="スタート!" /></p>
<div id="gamen"></div>
<p>
<script>
stmnmax=5000;
gsbtn.addEventListener('click',gstart,false);
function gstart(){
 if(isNaN(localStorage.stmnchk)){
  localStorage.stmnchk=Date.now().toString();
  localStorage.points='1000';
 }
 hantei();
}
function hantei(){
 stmna=Date.now();
 stmng=Math.floor((stmna-parseInt(localStorage.stmnchk))/180000);
 if(stmng>0){
  localStorage.points=(Math.min(parseInt(localStorage.points)+stmng,stmnmax)).toString();
  localStorage.stmnchk=(parseInt(localStorage.stmnchk)+stmng*180000).toString();
 }
 gamen.innerHTML=localStorage.points+' / '+stmnmax;
 setTimeout(hantei,parseInt(localStorage.stmnchk)+180000-Date.now());
}
</script>

 

 

コード解説

localStorageを使用しています。

かなり前にちょっとだけ試した事がありましたね。

little-strange.hatenablog.com

 

クッキー同様に、ブラウザごとに用意された保存領域にデータを保存し、クッキーよりも はるかに多くのデータを保存できる、という仕組みです。

 

取り扱いが容易なのが利点で、

localStorage.キー名=データ;

を実行するだけでデータを保存でき、ブラウザを閉じてもそのデータは保持されています。

取り出す時は、

localStorage.キー名

で取り出せます。(データは文字列型である必要があります)

 

Sだけ大文字にしないといけないところが要注意ですね。

 

 

まずスクリプト冒頭で、

gsbtn.addEventListener('click',gstart,false);

これは、ボタンに「クリックされた時、gstartと名付けた関数を呼び出す」というイベントリスナーを設定しています。

 

次にgstart内では、

function gstart(){
 if(isNaN(localStorage.stmnchk)){
  localStorage.stmnchk=Date.now().toString();
  localStorage.points='1000';
 }
 hantei();
}

まず、if文で「isNaN(localStorage.stmnchk)」を判定。

「localStorageにstmnchkというキーが存在して、そこに数値とみなせるデータが無い?」という判定を行っています。

localStorage.stmnchkには数値を文字列型にしたデータを入れる予定ですが、初めての実行時にはstmnchkというキー自体存在しないため、判定が真となります。

判定が真の時、初期化として、

localStorage.stmnchk=Date.now().toString();
localStorage.points='1000';

が実行され、「stmnchkというキーに対してはDate.now()(1970年1月1日からの経過ミリ秒をあらわす数値)を、toString()(文字列型に変換)」したものを保存。
「points」というキーに対しては「'1000'」という文字列を保存する事になります。

判定が偽の場合(2回目以降の開始時など)には前回のデータが入ったままのはずなので、上記の初期化処理は行われません。

 

判定がどちらであっても、その後、

hantei();

で、hanteiという関数を呼び出します。

 

function hantei(){
 stmna=Date.now();
 stmng=Math.floor((stmna-parseInt(localStorage.stmnchk))/180000);
 if(stmng>0){
  localStorage.points=(Math.min(parseInt(localStorage.points)+stmng,stmnmax)).toString();
  localStorage.stmnchk=(parseInt(localStorage.stmnchk)+stmng*180000).toString();
 }
 gamen.innerHTML=localStorage.points+' / '+stmnmax;
 setTimeout(hantei,parseInt(localStorage.stmnchk)+180000-Date.now());
}

 

stmna=Date.now();

hantei内ではまず、再び Date.now() を呼び出し、その時点での「1970年1月1日からの経過ミリ秒をあらわす数値」を変数smtnaに代入。

 

stmng=Math.floor((stmna-parseInt(localStorage.stmnchk))/180000);

そして変数stmngに「stmnaからlocalStorage.stmnchkを引いたもの=以前から何ミリ秒経過したか?という数値」を、180000で割り、小数点以下を削除。

この「180000」は「3分=180秒=180000ミリ秒」を意味しています。

つまり「現時点で、最後にチェックした時刻から3分が何回あった?」の回数がstmngに代入される事になります。

 

 if(stmng>0){
  localStorage.points=(Math.min(parseInt(localStorage.points)+stmng,stmnmax)).toString();
  localStorage.stmnchk=(parseInt(localStorage.stmnchk)+stmng*180000).toString();
 }

 

stmngが0以上(つまりポイントに換算されるべき時間経過があった場合)の時に、 localStorage.pointsstmngを加算(ポイント増加)すると同時に、localStorage.stmnchkは「最終チェック時刻にポイントに変換した分の時間を加算して、最終チェック時刻を更新」しています。

 

gamen.innerHTML=localStorage.points+' / '+stmnmax;

それらの処理後に、画面上に「現在のポイント / ポイント上限」を書き出しています。

 

setTimeout(hantei,parseInt(localStorage.stmnchk)+180000-Date.now());

そして、「次にポイントアップするべきタイミングに再度hanteiを呼び出す」というタイマーをセットして完了、です。

 

 

あとがき

実際、作ってみたあとの感想としては…
アルゴリズム(仕組み)を考えるのに少々手間取った」
ものの、スクリプトとしてはそう難しくないものでしたね^^

 

これを作れるようになっていると、各種放置ゲーが色々作れそうですw

 

 

 

ってなとこで、今回はこのへんで!

次回もまた、よろしくお願いします^^