(C)WorldWideSoftware

<!DOCTYPE html>
<html lang="ja">
 <head>
  <meta charset="utf-8">
  <title>ベルトスクロール</title>
 </head>
 <body>
  <a href="http://www.wwsft.com">(C)WorldWideSoftware</a><br>
  <canvas id="bg" width="640" height="480"></canvas><br>
ベルトスクロールのサンプルです<br>
カーソルキーで4方向(同時押しで8方向)に移動、スペースキーかZでジャンプします<br>
座標は(X,Y,Z)の3次元で管理しており、左右がX軸、奥行きがY軸、高さ(ジャンプ)がZ軸です<br>
3次元座標(X,Y,Z) → 画面の2D座標(x,y)に変換するところがポイントです<br>
敵キャラ等との接触判定は、地面上ならX,Yのみで可能ですが、ジャンプ中であればZを加味します<br>
  <a href="belt00src.html">ソースコードの確認</a>

  <script>
  //描画面(キャンバス)の準備
  var cvs = document.getElementById("bg");
  var ctx = cvs.getContext("2d");

  //キー入力
  var key = [];
  for(var i=0; i<256; i++) key[i] = 0;
  window.onkeydown = function(event) { key[event.keyCode]++; }
  window.onkeyup = function(event) { key[event.keyCode] = 0; }

  //ベルト型の画面上の座標
  function beltX(x, y, z) { return parseInt(x-y/2); }
  function beltY(y, y, z) { return parseInt(y+320-z); }

  //自キャラ
  var myX = 320, myY = 80, myZ = 0;//座標
  var jZP = 0;//ジャンプ用 Y座標の変化量
  var jFL = 0;//ジャンプ用 ジャンプ中というフラグ
  var scrl = 0;//画面スクロール用

  //線を描く関数
  ctx.lineWidth = 2;
  function line(x1, y1, x2, y2, col) {
   ctx.strokeStyle = col;
   ctx.beginPath();
   ctx.moveTo(x1, y1);
   ctx.lineTo(x2, y2);
   ctx.stroke();
  }

  //円を描く関数
  function circle(x, y, r, col) {
   ctx.fillStyle = col;
   ctx.beginPath();
   ctx.arc(x, y, r, 0, Math.PI*2);
   ctx.fill();
  }

  //文字表示
  function text(str, x, y) {
   ctx.font = "30px monospace";
   ctx.fillStyle = "white";
   ctx.fillText(str, x, y);
  }

  //メイン処理
  function mainProc() {
   var i;

   //背景
   ctx.fillStyle = "navy"; ctx.fillRect(0,   0, 640, 320);
   ctx.fillStyle = "gray"; ctx.fillRect(0, 320, 640, 160);
   for(i=0; i<12; i++) {
    x = i*64-scrl%64;
    y = 0;
    line(beltX(x,y,0), beltY(x,y,0), beltX(x,y+160,0), beltY(x,y+160,0), "silver");
   }

   //自キャラの移動
   if(key[37] > 0) {
    if(myX > 50) myX -= 10;
   }
   if(key[39] > 0) {
    if(myX < 500) myX += 10; else scrl += 10;
   }
   if(key[38] > 0) {
    if(myY > 0) myY -= 10;
   }
   if(key[40] > 0) {
    if(myY < 140) myY += 10;
   }
   //ジャンプするか?
   if(key[32] > 0 || key[90] > 0) {
    if( jFL == 0 ) {
     jZP = 48;
     jFL = 1;
    }
   }
   if( jFL == 1 ) {//ジャンプ中のZ座標の変化
     myZ += jZP;
     if(key[32] > 0 || key[90] > 0)
      jZP -= 4;
     else
      jZP -= 12;
     if(myZ < 0) {myZ=0; jYP=0; jFL=0;}
   }
   circle(beltX(myX,myY,0), beltY(myX,myY,0)+20, 16, "black");//自キャラの影
   circle(beltX(myX,myY,myZ), beltY(myX,myY,myZ), 30, "lime");//自キャラ本体

   text("myX="+myX, 50, 80);
   text("myY="+myY, 50, 160);
   text("myZ="+myZ, 50, 240);
  }

  setInterval(mainProc, 1000/20);//リアルタイム処理
  </script>
 </body>
</html>

←動作確認に戻る