一人でパットゴルフ

パターだけで打ち進める簡易ゴルフゲームです。全てパー3で9ホールあります。周りが囲まれているのでコースアウトは起きません。そのうちに2台のスマートフォンでプレイできるゲームにする予定で、そのたたき台となるバージョンです。

このゲームのプログラムの肝の部分です。
新規作成で新しいフォルダを作り、「test2game」など適当に名前を付けて下さい。メモ帳を開き、下記のソースリスト2つをコピーして「index.html」、「main.js」の名前を付けて文字コードUTF8でペーストして、作成したフォルダ「test2game」 に保存して下さい。もう一つ https://brm.io/matter-js/からダウンロードした「matter.min.js」もコピーして保存して下さい。
出来上がったものは下記から実行できます。スマートフォンでも動作確認してみてください。
test2game
index.html

<!doctype html>
<html>
<head>
<meta charset="UTF-8"/>
<script src="matter.min.js"></script>
<!-- cssの部分 -->
<style type="text/css">
* {margin: 0;padding: 0;}
html, body { width:100%; height:100%; }
.engine {
  position: absolute;
  left: 0;
  width: 700px;
  height: 1000px; }
  .engine canvas {
    width: 100%;
    height: 100%; }
</style>
</head>
<!-- スマートフォンなどでデフォルトアクションを行わない -->
<body ontouchmove="event.preventDefault()">
<!-- ゲームは、このIDの中で実行 -->
<div id="js-engine" class="engine"></div>
<script src="main.js"></script>
</body>
</html>

main.js

(function() {
    const Engine = Matter.Engine,
        World = Matter.World;

    const container = document.getElementById('js-engine');
    let isTouch = false;
    let pl1x = 0;
    let pl1y = 0;
    let ar1x = 0;
    let ar1y = 0;
    let dist1x = 0;
    let dist1y = 0;
    let impact = false;
    let centang = 0;
    let range = 0;
    let move = true;
    let sound = false;//スマホで音がなるように最初のタッチで1度実行
    const pat = new Audio();//スマホで音の設定

    const engine = Engine.create(container, {
        render: {options: {wireframes: false,width: 700,height: 1000}//,background: 'floor.jpg'}
        }
    });
    //重力値
    engine.world.gravity.y = 0;

    const c1 = container;//ゲーム用の画面サイズを縦横比を維持した最大の大きさに設定
    if (window.innerHeight < window.innerWidth * 10 / 7) {
        h = window.innerHeight;
        w = window.innerHeight * 0.7;
    } else {
        w = window.innerWidth;
        h = window.innerWidth * 10 / 7;
    }
    c1.style.height = h + 'px';
    c1.style.width = w + 'px';
    const divHeight = 1000 / h;
    const divWidth = 700 / w;

    const player1 = Matter.Bodies.polygon(200, 600, 5, 14,{collisionFilter: { mask: 2, group: -1 }});//,render: {sprite: {texture: 'patter.png'}}});
    const arrow1 = Matter.Bodies.polygon(200, 600, 5, 14,{collisionFilter: { mask: 2, group: -1 }});//,render: {sprite: {texture: 'arrow.png'}}});
    const body1 = Matter.Bodies.circle(200, 600, 20,{friction: 0,frictionAir: 0.006,restitution: 1,collisionFilter: { group: -1 }});//},render: {sprite: {texture: 'golf.png'}}});

    World.add(engine.world, [player1,arrow1,body1]);
    World.add(engine.world, [//周りの壁
        Matter.Bodies.rectangle(350,0,700,100,{isStatic:true}),
        Matter.Bodies.rectangle(0,500,100,1000,{isStatic:true}),
        Matter.Bodies.rectangle(700,500,100,1000,{isStatic:true}),
        Matter.Bodies.rectangle(350,1000,700,100,{isStatic:true})
        ]);

    //フレーム毎に実行
    Matter.Events.on(engine, 'beforeUpdate', function() {
        if (isTouch == false) {pl1x = 350;pl1y = -200;ar1x = 350;ar1y = -200}//タッチしてなければpl1x,pl1y,ar1x,ar1yに画面外をセットする
        Matter.Body.setAngle(player1,Math.atan2(player1.position.y - body1.position.y,player1.position.x - body1.position.x));//player1をbody1に向かせる
        Matter.Body.setPosition(player1,{x:pl1x,y:pl1y});
        Matter.Body.setAngle(arrow1,Math.atan2(arrow1.position.y - body1.position.y,arrow1.position.x - body1.position.x));//arrow1をbody1に向かせる
        Matter.Body.setPosition(arrow1,{x:ar1x,y:ar1y});
        if (!move) {if (Math.abs(body1.velocity.x) < 0.1) {if (Math.abs(body1.velocity.y) < 0.1) {//body1が動いてる時はパットできない
            move = true;impact = false;range = 0;info.innerHTML = '次のパットをどうぞ';
        }}}
        if (impact && move) {//'touchend'か'mouseup'でbody1がほぼ止まっていればパットする
            Matter.Body.applyForce(body1, {x:body1.position.x,y:body1.position.y}, {x: Math.cos(centang) * range * 0.0002,y: Math.sin(centang) * range * 0.0002});
            impact = false;move = false;
            info.innerHTML = '止まるまで待って';
            pat.src = './pat.wav';pat.play()
        }
    });

    //物理シュミレーションを実行
    Engine.run(engine);

    //スマホでタッチイベント発生
    window.addEventListener('touchstart',function(e) {
        e.preventDefault();
        let touchx = e.changedTouches[0].pageX * divWidth;
        let touchy = e.changedTouches[0].pageY * divHeight;
        dist1x = body1.position.x - touchx;
        dist1y = body1.position.y - touchy;
        isTouch = true;
        if (!sound) {pat.src = './pat.wav';pat.play();cupin.src = './cupin.wav';cupin.play();sound = true}
    },false)
    window.addEventListener('touchmove',function(e) {
        e.preventDefault();
        let touchx = e.changedTouches[0].pageX * divWidth;
        let touchy = e.changedTouches[0].pageY * divHeight;
        pl1x = dist1x + touchx;//'touchstart'からの'touchmove'の移動距離をplayer1に足す
        pl1y = dist1y + touchy;
        ar1x = body1.position.x * 2 - pl1x;//'touchstart'からの'touchmove'の移動距離をplayer1から引く
        ar1y = body1.position.y * 2 - pl1y;
    },false)
    window.addEventListener('touchend',function(e) {
        e.preventDefault();
        isTouch = false;
        impact = true;
        centang = Math.atan2(body1.position.y - player1.position.y,body1.position.x - player1.position.x);//player1とbody1との角度
        range = Math.sqrt( Math.pow(player1.position.x - body1.position.x, 2 ) + Math.pow(player1.position.y-body1.position.y, 2) )//player1とbody1との距離
    },false)

    //パソコンでマウスイベント発生
    window.addEventListener('mousedown',function(e) {
        e.preventDefault();
        let touchx = e.clientX * divWidth;
        let touchy = e.clientY * divHeight;
        dist1x = body1.position.x - touchx;
        dist1y = body1.position.y - touchy;
        isTouch = true;
    },false)
    window.addEventListener('mousemove',function(e) {
        e.preventDefault();
        if (isTouch) {
           let touchx = e.clientX * divWidth;
           let touchy = e.clientY * divHeight;
           pl1x = dist1x + touchx;//'touchstart'からの'touchmove'の移動距離をplayer1に足す
           pl1y = dist1y + touchy;
           ar1x = body1.position.x * 2 - pl1x;//'touchstart'からの'touchmove'の移動距離をplayer1から引く
           ar1y = body1.position.y * 2 - pl1y;
        }
    },false)
    window.addEventListener('mouseup',function(e) {
        e.preventDefault();
        isTouch = false;
        impact = true;
        centang = Math.atan2(body1.position.y - player1.position.y,body1.position.x - player1.position.x);//player1とbody1との角度
        range = Math.sqrt( Math.pow(player1.position.x - body1.position.x, 2 ) + Math.pow(player1.position.y-body1.position.y, 2) )//player1とbody1との距離
    },false)

    //タイトル
    const fontsize = Math.round(window.innerHeight / 4);
    const title = document.createElement( 'div' );
    document.body.appendChild( title );
    const info = document.createElement( 'div' );
    info.style.position = 'absolute';
    info.style.left = '10%'; 
    info.style.top = '0%';
    info.style.width = '80%';
    info.style.color = "yellow";
    info.style.fontWeight = "bold";
    info.style.fontSize = String(fontsize) + "%";
    info.innerHTML = '入力方法サンプル';
    container.appendChild( info );
})();

コメント

  1. 匿名 より:

    めっちゃ面白いから
    新しいやつ作って❤