SlideShare a Scribd company logo
MPS Setagaya 第7回 (2015/10/11) ミーティング
JavaScript でパックマン! 第4回
金子純也
Morning Project Samurai 代表
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
本日の目標
• パックマンに口パクさせる!

- Canvas 上でのアニメーションの実現
• キーボードでパックマンを動かす!

- ブラウザでのキーボードイベントの処理
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
window.requestAnimationFrame()
• ブラウザにアニメーションの描画を要求

- 描画のタイミングはブラウザが決定

(フレームレートをきっちり決めることはできない)
• 引数に指定した関数が実行される

例: function drawPackman(timestamp){ … }

window.requestAnimationFrame(drawPackman);
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
window.requestAnimationFrame() 

によるアニメーション
function animation_loop() {
// 描画処理をここに書く
// …
window.requestAnimationFrame(animation_loop);
}
window.requestAnimationFrame(animation_loop);
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
window.requestAnimationFrame() 

によるアニメーション
function animation_loop() {
// 描画処理をここに書く
// …
window.requestAnimationFrame(animation_loop);
}
window.requestAnimationFrame(animation_loop);
これから作るところ
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
口パクまでの道のり
1. 手動でパクパクできるようにする
2. 自動でパクパクさせる
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
Step1. 手動で口パク!
var cv = document.getElementById(‘pac-man');
var ctx = cv.getContext("2d");
function drawPacman(ctx ,cx, cy){
ctx.strokeStyle="#FF0000";
ctx.fillStyle="#FF0000";
ctx.beginPath();
ctx.arc(cx, cy, 50, 30 * Math.PI / 180, 330 * Math.PI / 180);
ctx.lineTo(cx, cy);
ctx.lineTo(cx + 50 * Math.cos(30 * Math.PI / 180), cy + 

50 * Math.sin(30 * Math.PI / 180));
ctx.fill();
}
drawPacman(ctx, 50, 50);
θ=30
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
Step1. 手動で口パク!
var cv = document.getElementById(‘pac-man');
var ctx = cv.getContext("2d");
function drawPacman(ctx ,cx, cy, theta){
ctx.strokeStyle="#FF0000";
ctx.fillStyle="#FF0000";
ctx.beginPath();
ctx.arc(cx, cy, 50, theta * Math.PI / 180, 

(360 - theta) * Math.PI / 180);
ctx.lineTo(cx, cy);
ctx.lineTo(cx + 50 * Math.cos(theta * Math.PI / 180), 

cy + 50 * Math.sin(theta * Math.PI / 180));
ctx.fill();
}
drawPacman(ctx, 50, 50, 30);
drawPacman(ctx, 150, 50, 10);
θ=theta
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
Step2. 自動でパクパクさせる
var cv = document.getElementById(‘pac-man');
var ctx = cv.getContext("2d");
var cx = 50, cy = 50, theta = 30, dTheta = -1;
function drawPacman(ctx ,cx, cy, theta){ … }
function animationLoop(timestamp) {
if (theta >= 30) dTheta = -1;

else if (theta <=0 ) dTheta = 1;

theta += dTheta;
ctx.clearRect(0, 0, cv.width, cv.height);
drawPacman(ctx, cx, cy, theta);
window.requestAnimationFrame(animationLoop);
}
window.requestAnimationFrame(animationLoop);MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
パックマン操作までの道のり
• キー押下イベント (onkeydown) に対応する

イベント処理関数を作り登録
• キーが離されたイベント (onkeyup) に

対応するイベント処理関数を作り登録
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
ユーザーの入力とイベント
• ブラウザはブラウザ上でのユーザーの操作をイベント

として取り扱う

- 例: マウスのクリック、キーの押下
• ブラウザは関連する要素へとイベントを通知
• プログラマは要素に対し、JavaScript を用いて

イベントへの対処方を事前登録 (イベントハンドラの登録)
• 要素はイベントを受け取ると対応する登録された

イベントハンドラを起動する
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
イベント処理の流れ
ブラウザキャンバス要素 cv
キーが
押下された!
フォーカスは

Canvas要素
キーを押下cv.onkydown に登録された
イベントハンドラで対処するぜ !
ユーザー
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
イベントの例
• onkeydown: キーの押下イベント
• onkeyup: キーが離されたイベント
• onmousedown: マウスのボタンが押下された
• onmouseup: マウスのボタンが離された
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
要素へのイベントハンドラの登録
cv.tabIndex = 1;
cv.onkeydown = function(event) {
event.preventDefault();
switch(event.keyCode) {
case 37:

cx -= 1; break;
case 38:
cy -= 1; break;
case 39:
cx += 1; break;
case 40:

cy += 1; break;
}
};
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
なんだかカクカク動く・・・
ブラウザ
Canvas
cx, cy
キー押下発生!
位置更新!
イベントハンドラによる
cx, cy の更新に基づく描画
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
なんだかカクカク動く・・・
イベントハンドラによる
cx, cy の更新に基づく描画
ブラウザ
Canvas
cx, cy
キー押下発生!
位置更新!イベントハンドラが

終了するたびに
移動も終了してしまう!
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
滑らかに動かす工夫
movingDirectionに基づき
cx, cy を更新して描画
ブラウザ
Canvas
movingDirection[0] = 1
movingDirection[1] = 0
キー押下発生!
移動量更新!一度移動量を決めれば、
新たに onkeydown イベントが
起こらなくてもパックマンが
移動し続ける!! MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
改良版 onkeydown イベントハンドラ
var moveDirection = [0, 0] //x, y
cv.tabIndex = 1;
cv.onkeydown = function(event) {
event.preventDefault();
switch(event.keyCode) {
case 37:
moveDirection[0] = -1; break;
case 38:
moveDirection[1] = -1; break;
case 39:
moveDirection[0] = 1; break;
case 40:
moveDirection[1] = 1;
}
}; MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
改良版 描画関数
function animationLoop(timestamp) {
if (theta >= 30) dTheta = -1;

else if (theta <=0 ) dTheta = 1;

theta += dTheta;
cx += moveDirection[0];
cy += moveDirection[1];
ctx.clearRect(0, 0, cv.width, cv.height);
drawPacman(ctx, cx, cy, theta);
window.requestAnimationFrame(animationLoop);
}
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
滑らかに動くが止まらない !!
onkeyup イベントハンドラの中で
キーが離されたら対応する方向の移動量を0にする
MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko
cv.onkeyup = function(event) {
event.preventDefault();
switch(event.keyCode) {
case 37:
moveDirection[0] = 0;
break;
case 38:
moveDirection[1] = 0;
break;
case 39:
moveDirection[0] = 0;
break;
case 40:
moveDirection[1] = 0;
}
}; MPS Setagaya 第7回 (2015/10/11) ミーティング (c) Junya Kaneko

More Related Content

PDF
JavaScript でパックマン!第1回
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 12
PDF
Python で画像処理をやってみよう! -SIFT 第7回-
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 9
PDF
Python で画像処理をやってみよう! -SIFT 第6回-
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 8
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 7
PDF
Python で画像処理をやってみよう! -SIFT 第5回-
JavaScript でパックマン!第1回
数学的基礎から学ぶ Deep Learning (with Python) Vol. 12
Python で画像処理をやってみよう! -SIFT 第7回-
数学的基礎から学ぶ Deep Learning (with Python) Vol. 9
Python で画像処理をやってみよう! -SIFT 第6回-
数学的基礎から学ぶ Deep Learning (with Python) Vol. 8
数学的基礎から学ぶ Deep Learning (with Python) Vol. 7
Python で画像処理をやってみよう! -SIFT 第5回-

More from Project Samurai (20)

PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 6
PDF
Mpsy20160423
PDF
Make your Artificial Intelligence
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 4
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 3
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 2
PDF
数学的基礎から学ぶ Deep Learning (with Python) Vol. 1
PDF
Python で画像処理をやってみよう!第11回 - SIFT Vol.1 キーポイント候補 -
PDF
Instagram API を使ってウェブアプリを作ろう!
PDF
Pythonで画像処理をやってみよう!第8回 - Scale-space 第7回 -
PDF
JavaScript でパックマン!第7回 (一旦最終回)
PDF
Pythonで画像処理をやってみよう!第7回 - Scale-space 第6回 -
PDF
JavaScript でパックマン!第6回
PDF
JavaScript で パックマン! 第5回
PDF
Pythonで画像処理をやってみよう!第6回 - Scale-space 第3回 -
PDF
JavaScript でパックマン!第3回
PDF
JavaScript でパックマン! 第2回
PDF
Python で OAuth2 をつかってみよう!
PDF
(Pythonで作って学ぶ) Youtube の動画リストを作るアプリの開発 
第4回
PDF
(Pythonで作って学ぶ) Youtube の動画リストを作るアプリの開発 
第2回
数学的基礎から学ぶ Deep Learning (with Python) Vol. 6
Mpsy20160423
Make your Artificial Intelligence
数学的基礎から学ぶ Deep Learning (with Python) Vol. 4
数学的基礎から学ぶ Deep Learning (with Python) Vol. 3
数学的基礎から学ぶ Deep Learning (with Python) Vol. 2
数学的基礎から学ぶ Deep Learning (with Python) Vol. 1
Python で画像処理をやってみよう!第11回 - SIFT Vol.1 キーポイント候補 -
Instagram API を使ってウェブアプリを作ろう!
Pythonで画像処理をやってみよう!第8回 - Scale-space 第7回 -
JavaScript でパックマン!第7回 (一旦最終回)
Pythonで画像処理をやってみよう!第7回 - Scale-space 第6回 -
JavaScript でパックマン!第6回
JavaScript で パックマン! 第5回
Pythonで画像処理をやってみよう!第6回 - Scale-space 第3回 -
JavaScript でパックマン!第3回
JavaScript でパックマン! 第2回
Python で OAuth2 をつかってみよう!
(Pythonで作って学ぶ) Youtube の動画リストを作るアプリの開発 
第4回
(Pythonで作って学ぶ) Youtube の動画リストを作るアプリの開発 
第2回
Ad

JavaScript でパックマン!第4回