ビー玉はじきバーチャルパッド

このホームページの「スマホ版ビー玉はじき」を、傾きで操作から、バーチャルパッドで操作に変えたものです。バーチャルパッドの中央か、指を離せば、自機は止まります。パソコンの矢印キーでも操作できます。
自機のビー玉を操って、敵ビー玉をはじき出してください。赤い壁にぶつけると、「ビー玉大」→「ビー玉中」→「ビー玉小」の順に小さくなっていきます。「ビー玉小」を赤い壁にぶつけると消滅させることができます。PC9801名作ゲーム蟹味噌をリメイクしたものです。

バーチャルキーパッドにしてみると、思った方向に入力するのがかなり難しいとわかりました。すなわち押している感覚がないため、思ったタイミングで思った方向に入力出来ない事があります。
対策として、指がキーパッドの端を超えて動いたらキーパッドを端の位置に移動させる事にしました。これで、指が常にキーパッドの中に置けるようになります。それなりの効果はあるようです。
バーチャルキーパッドは表示したいけれど目立つと気になるので、この位にしました。
index.html

<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<style type="text/css">
* {margin: 0;padding: 0;background-color:#808080;}
html, body { width:100%; height:100%; }
.view {
  position: absolute;
  left: 0;
  width: 800px;
  height: 800px; }
  .view canvas {
    width: 100%;
    height: 100%; }
.guideimg {
  position: absolute;
  background-image: url('pad.png');
  background-size: 100% 100%;}
  .guideimg canvas {
    width: 100%;
    height: 100%;}
</style>
</head>
<body ontouchmove="event.preventDefault()">
<script src="matter.min.js"></script>
<script src="three.min.js"></script>
<div id="js-view" class="view"></div>
<div id="js-engine" style="display:none;" class="engine"></div>
<div id="js-guideimg" class="guideimg"></div>
<script src="main.js"></script>
</body>
</html>

cssで”guideimg”に、100%のサイズでバックグラウンドイメージとして’pad.png’を貼り付けてます。
main.js

main.js
(function() {
    /*バーチャルキーパッド以外の部分は省いてあります。
    cssで設定した"js-guideimg"をウインドウ上に表示する。*/
    const c2 = document.getElementById('js-guideimg');
    if (window.innerWidth < window.innerHeight) {//スマホの縦ならバーチャルキーパッド表示
        imagesize = 100;//バーチャルキーパッド半径
        imcenterX = window.innerWidth - imagesize - window.innerWidth * 0.03;//バーチャルキーパッドのX方向中心
        imcenterY = window.innerHeight - imagesize - window.innerWidth * 0.03;//バーチャルキーパッドのY方向中心
        c2.style.left = imcenterX - imagesize + 'px';//画面の左から'px'の位置
        c2.style.top = imcenterY - imagesize + 'px';//画面の上から'px'の位置
        c2.style.width = imagesize * 2 + 'px';//画像の幅
        c2.style.height = imagesize * 2 + 'px';//画像の高さ
        c2.style.backgroundColor = 'transparent';//pngの画像の透明部分を透明にする
    }

    //デジタルパッド
    window.addEventListener('touchstart', (e) => {//タッチを開始
        e.preventDefault();
        ex = e.changedTouches[0].pageX;ey = e.changedTouches[0].pageY;//タッチの位置
        imcenterX = ex;//タッチのX方向をバーチャルキーパッドのX方向中心に設定
        if (window.innerHeight > ey + imagesize) {//画像が画面内に収まれば
             imcenterY = ey//タッチのY方向をバーチャルキーパッドのY方向中心に設定
        } else {//画像が画面内に収まらなければ
             imcenterY = window.innerHeight - imagesize//画面の一番下にバーチャルキーパッドのY方向中心を設定
        }
        c2.style.left = imcenterX - imagesize + 'px';//画面の左から'px'の位置に表示
        c2.style.top = imcenterY - imagesize + 'px';//画面の上から'px'の位置に表示
    },{passive: false});
    window.addEventListener('touchmove', (e) => {//タッチの移動
        e.preventDefault();
        RIGHT = false;LEFT = false;DOWN = false;UP = false;//4方向の移動キャンセル
        ex = e.changedTouches[0].pageX;ey = e.changedTouches[0].pageY;//タッチ移動の位置
        x = ex - imcenterX;//タッチと画像とのX距離
        y = ey - imcenterY;//タッチと画像とのY距離
        dist = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));//タッチと画像との距離
        if(dist < 70){return;}//キーパッド真ん中は反応しない
        if(Math.abs(x) > Math.abs(y)){//タッチと画像とのX距離が大きければ左右、Y距離が大きければ上下
            if(x < 0){LEFT = true;}else{RIGHT = true;}//距離がマイナスなら左プラスなら右
        }else{
            if(y < 0){UP = true;}else{DOWN = true;}//距離がマイナスなら上プラスなら下
        }
        angle = Math.atan2(ex, ey, imcenterX, imcenterY);//タッチ位置と画像中心の角度ラジアン
        if(dist > imagesize){//キーパッドより出たらキーパッド移動
            if (x > 0) {
                imcenterX = imcenterX + Math.cos(angle) * (dist - imagesize)//キーパッドの中心をタッチと画像の距離だけ移動
            } else {
                imcenterX = imcenterX - Math.cos(angle) * (dist - imagesize)//マイナス移動なら左
            }
            if (y > 0) {
                if (window.innerHeight > imcenterY + Math.sin(angle) * (dist - imagesize) + imagesize) {//画像が画面内に収まれば
                    imcenterY = imcenterY + Math.sin(angle) * (dist - imagesize)
                }
            } else {
                imcenterY = imcenterY - Math.sin(angle) * (dist - imagesize)//マイナス移動なら上
            }
            c2.style.left = imcenterX - imagesize + 'px';//画面の左から'px'の位置に表示
            c2.style.top = imcenterY - imagesize + 'px';画面の上から'px'の位置に表示
        }
    },{passive: false});
    window.addEventListener('touchend', function(e) {
        e.preventDefault();
        RIGHT = false;LEFT = false;DOWN = false;UP = false;//4方向の移動キャンセル
    },{passive: false});

コメント