パターだけで打ち進める簡易ゴルフゲームです。全てパー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 );
})();
コメント
めっちゃ面白いから
新しいやつ作って❤