Monaca+HTML+JS(Canvas)で早押しアプリを作る!

ざっくり、早押しアプリを作りたいと思います。

現在21:51分。日付が変わるまでに完成させたいな〜と思いながら作業開始!

 

21:51

プロジェクトの作成

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-30-21-51-47

Monacaにログイン後、新規プロジェクトの作成

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-30-21-51-57

プロジェクトは特に何も追加の機能を利用するつもりは無いので「最小限のテンプレート」を選択しました。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-30-21-52-15

プロジェクト名「firster」 ちょっとこの名前には思い出が…。

早押しゲームということで、「firster」と命名しました。実は以前、HTML5+JS(Canvas)を利用した環境でwindowsストアアプリを作成したことがあります。この時のアプリ名が「firster」でした。この名前は、「より早く」的な意味で命名したのですが、スペルが間違っています。

fast: 速い

first: 一番目の,最も重要な,最高の

なんやかんやで、それも面白いかな〜と今では思っているので、この名前で行きたいと思います。

 

22:00

とりあえず、デフォルト構成でアプリの作成。まだ何もありません。
とりあえず、画面全体のcanvasを作成します。

参考: ブラウザいっぱいのキャンバスを作る – Qiita

ライブラリを使わない素のJavaScriptでDOM操作 – Qiita

とりあえず、このあたりを参考にして画面いっぱいのcanvasを作成しました。現在のソースコードは以下のような感じ。

ここまでに、jsディレクトリとfirster.jsファイルを作成しました。これらの作成は左側のメニューから行えます。

index.html
<!-- bodyの中身のみを表示 -->
<body>
 <div id="canvas_cover">
 </div>
 <script type="text/javascript" src="js/firster.js"></script>
</body>
index.css
/* 謎のマージンが入らないように */
body {
 margin: 0;
}

/* canvasが動かないように */
#canvas_cover{
 overflow: hidden;
}
firster.js
/* firster.js */

// canvas要素を作成する。
var canvas = document.createElement('canvas');
canvas.style.width = window.innerWidth + 'px';
canvas.style.height = window.innerHeight + 'px';
canvas.width = window.innerWidth * window.devicePixelRatio;
canvas.height = window.innerHeight * window.devicePixelRatio;

// div要素で作成したcanvasの入れ物をにcanvasを追加
var canvas_div = document.getElementById('canvas_cover');
canvas_div.appendChild(canvas);
console.log("hoge");

// スワイプによるスクロールを禁止させる
document.body.addEventListener('touchstart', function(event) {
 event.preventDefault();
});



wait_display();

function wait_display(){
 var ctx = canvas.getContext('2d');
 ctx.beginPath(20,20);
 ctx.moveTo(20, 20);
 ctx.lineTo(120, 20);
 ctx.lineTo(120, 120);
 ctx.lineTo(20, 20);
 ctx.closePath();
 ctx.stroke();
}

 

謎の三角形を表示することができました。

 

22:40頃?

タップを取得

参考サイト: マルチタッチ ウェブブラウザ向けの開発 – HTML5 Rocks

さまざまな図形を描く – Canvas – HTML5.JP

jQueryからDOM Elementを取得 – ゆっくり*ゆっくり

とりあえず、タップイベントを取得できるようになったのですが、座標がずれる問題にぶちあたりました。。。解決するのに30分以上…。

問題は、動的にcanvasを生成した際に正しくwidthとheightが設定されておらず、実際はcanvasが引き伸ばされたようの表示になっていたため、取得した座標に対して実際に描画される座標が縮尺された位置になってしまっていました。

 

ついでに、このあたりで要素をいじるのが面倒になってjQueryを導入しました。

 

23:17

やっと座標があった。。。

ざっくり説明飛ばしますが、現状です。タップした座乗に対して黒丸を表示することができるようになりました。変更のあったjsソースのみ載せます。原因はcanvas要素の幅などを指定するさいに、以前の方法では要素としての大きさは設定できたけど、canvas内で利用する座標とはうんぬんかんぬん…(よくわからない)みたいな感じでした。

jQueryの導入はMonacaのタブにある[設定]->[JS/CSSコンポーネントの追加と削除] からjqueryを選択で簡単に導入することができます。

%e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-30-23-03-06 %e3%82%b9%e3%82%af%e3%83%aa%e3%83%bc%e3%83%b3%e3%82%b7%e3%83%a7%e3%83%83%e3%83%88-2016-10-30-23-03-24

firster.js
/* firster.js */

// canvas要素を作成する。
//var canvas_div = document.getElementById('canvas_cover');
$("#canvas_cover").append('&lt;canvas id="game_canvas"&gt;&lt;/canvas&gt;');
$("#game_canvas").attr('width', window.innerWidth);
$("#game_canvas").attr('height', window.innerHeight);

var canvas = $("#game_canvas").get(0);
var ctx = canvas.getContext('2d');

// スワイプによるスクロールを禁止させる
document.body.addEventListener('touchstart', function(event) {
 event.preventDefault();
});

wait_display();

/* ここからゲームに関する記述 */
function wait_display(){
 ctx.beginPath(20,20);
 ctx.moveTo(20, 20);
 ctx.lineTo(120, 20);
 ctx.lineTo(120, 120);
 ctx.lineTo(20, 20);
 ctx.closePath();
 ctx.stroke();
}
 
// 画面をタップした(瞬間の)座標を取得
canvas.addEventListener('touchstart', function(e) {
 for(var i=0; i&lt; e.touches.length; i++){
 var touch = e.touches[i];
 ctx.beginPath();
 ctx.arc(touch.clientX, touch.clientY, 20, 0, Math.PI*2, true);
 ctx.fill();
 ctx.stroke();
 }
 console.log("タップされた");
}, false);

screenshot_20161030-231650

なんともまぁ雑な感じですが、タップした座標に黒丸が表示されるようになりました。

 

24:00

ゲームにする

ちょっとブログ用にメモとかを取るのを忘れてガリゴリプログラムを書いて…24:00 になりました。ちょっと完成しなかったのですが、一通りゲームの流れができたので一応載せておきます。

もうちょい完成度を高めてブログを更新します><

現状!

  1. wait画面
    1+乱数(0.0<3.0)秒
  2. タップ画面に遷移
    3秒待つ
  3. 結果表示
    色が変わってからタップまでの時間(ms)と順位

 

screenshot_20161031-000149 screenshot_20161031-000153 screenshot_20161031-000449
/* firster.js */

// canvas要素を作成する。
//var canvas_div = document.getElementById('canvas_cover');
$("#canvas_cover").append('<canvas id="game_canvas"></canvas>');
$("#game_canvas").attr('width', window.innerWidth);
$("#game_canvas").attr('height', window.innerHeight);

var canvas = $("#game_canvas").get(0);
var ctx = canvas.getContext('2d');

console.log("hoge");

// スワイプによるスクロールを禁止させる
document.body.addEventListener('touchstart', function(event) {
 event.preventDefault();
});


/* ここからゲームに関する記述 */
var c_w = canvas.width;
var c_h = canvas.height;

var font_size = "20px";

var startTime, endTime;

ctx.font = font_size + "'MS ゴシック'";

function game(){
 var game_state = 0;
 var good_datas = [];
 var bad_datas = [];
 
 wait();
 function wait(){
 game_state = 1;
 // 背景色を設定
 ctx.fillStyle = '#bfbfbf';
 ctx.fillRect(0, 0, c_w, c_h);
 // Waitの文字を描画
 ctx.fillStyle = '#ff7856';
 ctx.fillText("Wait", (c_w/2), (c_h/2));
 // wait画面
 // 1秒 + 0~3秒でwaitを表示
 setTimeout(touch, 1000 + Math.random()*3000);
 }
 function touch(){
 startTime = new Date();
 game_state = 2;
 ctx.fillStyle = '#a5eeff'
 ctx.fillRect(0,0,canvas.width, canvas.height);
 setTimeout(game_end, 3000);
 }
 
 // スコアの表示、その他
 function game_end(){
 // 背景色を設定
 ctx.fillStyle = '#acfc62';
 ctx.fillRect(0, 0, c_w, c_h);
 ctx.fillStyle = '#fcbf32';
 for (var i=0; i < good_datas.length; i++){
 ctx.fillText((i+1) + "位" + good_datas[i][2] + "ms", good_datas[i][0], good_datas[i][1]);
 console.log("スコア表示");
 }
 game_state = 3;
 
 // setTimeout(wait, 10000);
 }
 
 // 画面をタップした(瞬間の)座標を取得
 canvas.addEventListener('touchstart', function(e) {
 for(var i=0; i< e.touches.length; i++){
 var touch = e.touches[i];
 ctx.beginPath();
 ctx.arc(touch.clientX, touch.clientY, 20, 0, Math.PI*2, true);
 ctx.stroke();
 
 endTime = new Date();
 var touch_data = [touch.clientX, touch.clientY, endTime - startTime];
 good_datas.push(touch_data);
 }
 }, false);
}
 
//ゲーム開始
game();

とりあえず、こんな感じです。今後実装する機能として、

  • 同じ箇所を何度もタップできないようにする。
  • wait画面でタップした際に(miss)と表示する
  • アプリが終わらない…><
  • 順位の描画をもっと綺麗に
  • 見た目!

などなど、やらなきゃいけないことはたくさんありますが…。とりあえずゲームとしての流れができました。今日は絶対に日付が変わったらそれ以上開発をしないと決めていたので(明日は1限から授業です><)ここまでにしておきます。

なんとか汚いコードでも機能を実装してしまおうと、雑な書き方や頭のわるい書き方をいっぱいした気がしますが…近いうちにもうちょいまともにして…アプリ制作勉強の成果としてストアに公開しようと思います。

 

ひゃ〜疲れた〜。。。 次回の更新をお楽しみに〜(たぶん書きます。

 

2016/11/6 追記

続きのブログを作成しました!

アプリを完成させるまで: Monaca+HTML+JS(Canvas)で早押しアプリを作る! – part2 –

完成させたアプリを公開するまで: Monaca+HTML+JS(Canvas)で早押しアプリを作る! – part3 –

 

3 thoughts on “Monaca+HTML+JS(Canvas)で早押しアプリを作る!

  1. Pingback: Monaca+HTML+JS(Canvas)で早押しアプリを作る! – part2 – | たくのこ Web

  2. Pingback: Monaca+HTML+JS(Canvas)で早押しアプリを作る! – part3 – | たくのこ Web

  3. Pingback: CordovaでCrosWalkを使う。(AjaxをAndroid4.X使う | たくのこ Web

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

このサイトはスパムを低減するために Akismet を使っています。コメントデータの処理方法の詳細はこちらをご覧ください