(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>
←動作確認に戻る