見出し画像

JavaScript+html+Canvas でゲーム作成(画面アニメーション)

「JavaScript+html+Canvas でゲーム作成」基本部分を使って、画面アニメーションを作ってみました。

その昔、Androidアプリで公開していたものをJavaScriptに移植して作成。
昔のことなのプログラム内容がどうだったかまでは把握してないですが、フラクタル計算式を改変させて作っていたと思います。

こんな画面アニメーションも作れますよというサンプルになります。

以下、プログラム。

<html>
<head>
<style type="text/css">
<!-- canvas { background: #000  ; } -->
</style>
</head>
<body>
<canvas id="myCanvas" width="512" height="512"></canvas>
<script language="JavaScript">
var canvas = document.getElementById("myCanvas");
var ctx = canvas.getContext("2d");
//-----<#### JavaScript+html+Canvas でゲーム作成 ベース上 ####>

	// 画面アニメーションサンプル

	// 定数
	const COLOR_MAX = 18;				// 色要素数

	// 変数
	var RADIUS = 2;						// 半径
	var DDOT = 4;						// 隣り合うドットの間隔
	var XSIZE = canvas.width / DDOT;	// Xサイズ(描画サイズは、XSIZE * DDOT)
	var YSIZE = canvas.height / DDOT;	// Yサイズ(描画サイズは、YSIZE * DDOT)

	var DEEP = COLOR_MAX * DDOT; // 深度
	var XOFFSET = (canvas.width - (XSIZE * DDOT)) / 2;	// X方向フル
	var YOFFSET = (canvas.height - (YSIZE * DDOT)) / 2;	// Y方向フル
	var ZOOM = -1;										//立体拡大率(0:平面)

	var FRAC_ANIM_SPEED_R = 0.003;	//複素平面アニメスピード:実数値0.0001
	var FRAC_ANIM_SPEED_I = 0.003;	//複素平面アニメスピード:虚数値0.0001

	var ANIM = 1.0; //アニメーション幅絶対値

	var FRAC_TYPE_MAX = 19;		// フラクタルパターン数
	var MANDEL_TYPE_MAX = 16;	// マンデルブロートパターン数

	var frac_mode = 0;	// モード(0:フラクタル、1:マンデルブロート)
	var frac_type = 0;	// パターン

	var dar = 1.0;		// アニメーションパラメータ
	var dai = 1.0;		// アニメーションパラメータ

	var offset = 0;

	// カラーテーブル
	var coltbl = new Array(18);
	coltbl = new Array(18);
	coltbl[0]  = [ 0,     0,     0   ];	//[0]
	coltbl[1]  = [ 15,    15,    15  ];	//[1]
	coltbl[2]  = [ 30,    30,    30  ];	//[2]
	coltbl[3]  = [ 45,    45,    45  ];	//[3]
	coltbl[4]  = [ 60,    60,    60  ];	//[4]
	coltbl[5]  = [ 75,    75,    75  ];	//[5]
	coltbl[6]  = [ 90,    90,    90  ];	//[6]
	coltbl[7]  = [ 105,   105,   105 ];	//[7]
	coltbl[8]  = [ 120,   120,   120 ];	//[8]
	coltbl[9]  = [ 135,   135,   135 ];	//[9]
	coltbl[10] = [ 150,   150,   150 ];	//[10]
	coltbl[11] = [ 165,   165,   165 ];	//[11]
	coltbl[12] = [ 180,   180,   180 ];	//[12]
	coltbl[13] = [ 195,   195,   195 ];	//[13]
	coltbl[14] = [ 210,   210,   210 ];	//[14]
	coltbl[15] = [ 225,   225,   225 ];	//[15]
	coltbl[16] = [ 240,   240,   240 ];	//[16]
	coltbl[17] = [ 255,   255,   255 ];	//[17]

	// フラクタルパターン
	var fractal_tbl = new Array(FRAC_TYPE_MAX);
	//     				RS      RE      IS     IE       AR        AI
	fractal_tbl[0]  = [ -1.3,   1.3,  -1.3,  1.3,   -0.75,    0.2      ];
	fractal_tbl[1]  = [ -0.1,   0.1,  -0.2,  0.0,   -1.767,   0.011005 ];
	fractal_tbl[2]  = [  0.3,   0.7,  -0.2,  0.2,    0.26,    0.0      ];
	fractal_tbl[3]  = [ -1.0,   1.0,  -1.0,  1.0,   -0.02,    0.795    ];
	fractal_tbl[4]  = [ -1.0,   1.0,  -1.0,  1.0,   -0.6945,  0.297    ];
	fractal_tbl[5]  = [ -0.5,   0.5,  -0.5,  0.5,   -0.2,    -0.675    ];
	fractal_tbl[6]  = [  0.0,   1.0,   0.0,  1.0,    0.3,     0.0      ];
	fractal_tbl[7]  = [ -0.3,   0.3,  -0.3,  0.3,   -0.38,   -0.6      ];
	fractal_tbl[8]  = [ -0.3,   0.3,  -0.3,  0.3,   -0.72,    0.305    ];
	fractal_tbl[9]  = [ -0.5,   0.5,  -0.5,  0.5,    0.36,   -0.095    ];
	fractal_tbl[10] = [ -0.3,   0.3,  -0.3,  0.3,   -1.16,   -0.27     ];
	fractal_tbl[11] = [ -0.5,   0.5,  -0.5,  0.5,   -0.04,   -0.695    ];
	fractal_tbl[12] = [ -1.0,   1.0,  -1.0,  1.0,   -0.58,   -0.45     ];
	fractal_tbl[13] = [ -0.5,   0.5,  -0.5,  0.5,   -1.2,    -0.155    ];
	fractal_tbl[14] = [ -0.3,   0.3,  -0.3,  0.3,   -1.24,    0.075    ];
	fractal_tbl[15] = [ -0.5,   0.5,  -0.5,  0.5,    0.34,   -0.4      ];
	fractal_tbl[16] = [ -1.5,   1.5,  -1.5,  1.5,    1.0,     0.0      ];
	fractal_tbl[17] = [ -0.5,   0.5,  -0.5,  0.5,   -0.1,    -0.845    ];
	fractal_tbl[18] = [ -0.25,  0.15, -0.45, 0.85,  -0.75,    0.2      ];

	// 計算変数
	var fi = 0;
	var fj = 0;
	var fk = 0;

	var rs = 0.0;
	var re = 0.0;
	var is = 0.0;
	var ie = 0.0;
	var ar = 0.0;
	var ai = 0.0;
	var ksx = 0;	// X(実数)側の長さ
	var ksy = 0;	// Y(虚数)側の長さ
	var dr = 0.0;	// X(実数差分)
	var di = 0.0; 	// Y(虚数差分)
	var zr = 0.0;
	var zi = 0.0;
	var xx = 0.0;
	var yy = 0.0;
	var rr = 0.0;
	var ii = 0.0;

	var colnum = 0;
	var fdemo_num = 0;
	var ballRadius = RADIUS;
	var posbase = new Array(XSIZE * YSIZE);
	var pos = new Array(XSIZE * YSIZE);

	// 初期座標セット
	for( var y = 0; y < YSIZE; y++ ){
		for( var x = 0; x < XSIZE; x++ ){
			posbase[y * XSIZE + x]  = new Array(2);	// x,y
			posbase[y * XSIZE + x][0] = x * DDOT;	// xpos
			posbase[y * XSIZE + x][1] = y * DDOT;	// ypos

			pos[y * XSIZE + x]  = new Array(2);		// x,y
			pos[y * XSIZE + x][0] = 0;				// xpos
			pos[y * XSIZE + x][1] = 0;				// ypos
	    }
	}

	// 描画
	function draw() {
		if( ( fdemo_num < 0) || ( fdemo_num > (FRAC_TYPE_MAX - 1) ) ){
			fdemo_num = 0;
		}

		// 画面クリア
		ctx.clearRect(0, 0, canvas.width, canvas.height);

		// PARAMETER SET
		// 複素平面
		rs = fractal_tbl[fdemo_num][0];	// + drs;
		re = fractal_tbl[fdemo_num][1];	// + dre;
		is = fractal_tbl[fdemo_num][2];	// + dis;
		ie = fractal_tbl[fdemo_num][3];	// + die;
		ar = fractal_tbl[fdemo_num][4] + dar;		// 初期差分→自動化
		ai = fractal_tbl[fdemo_num][5] + dai;
		ksx = XSIZE; 								// X(実数)側の長さ
		ksy = YSIZE; 								// Y(虚数)側の長さ
		dr = (re - rs) / ksx;						// X(実数差分
		di = (ie - is)  / ksy; 						// Y(虚数差分
		fk = fi = 0;

		fj = 0;
		for( yy = is; yy < ie; yy = yy + di ){
			fi = 0;
			for( xx = rs; xx < re; xx = xx + dr ){
				zr = xx;
				zi = yy;

				fk = 0;

				for( ;; ){
					fk++;
					if( fk > DEEP ){ //深度が高くなると処理量多くなるのでカット
					    break;
					}

					// 複素平面
					rr = (zr * zr) - (zi * zi) + ar;
					ii = (2 * zr * zi) + ai;

					if(((rr * rr) + (ii * ii)) > 4.0 ){ // 演算限界値
					    break;
					}
					zr = rr;
					zi = ii;
				}

				colnum = fk % COLOR_MAX; //coltbl[color_type][colnum][R],...

				// 描画セット
				offset = fj * XSIZE + fi;
				ctx.beginPath();
				pos[offset][0] = posbase[offset][0];
				pos[offset][1] = posbase[offset][1] + fk;
				ctx.arc(pos[offset][0], pos[offset][1], ballRadius, 0, Math.PI * 2);
				ctx.fillStyle = "rgb(" + (~~coltbl[colnum][0]) + ", " + (~~coltbl[colnum][1]) + ", " + (~~coltbl[colnum][2]) + ")";
				ctx.fill();
				ctx.closePath();

				fi++;
				if( fi >= XSIZE ){
				    break;
				} //最大値超えたら終了
			}
			for( ; fi < XSIZE; fi++ ){ //不足サイズ分埋める
				// x方向不足サイズ分描画
				offset = fj * XSIZE + fi;
				ctx.beginPath();
				pos[offset][0] = posbase[offset][0];
				pos[offset][1] = posbase[offset][1] + fk;
				ctx.arc(pos[offset][0], pos[offset][1], ballRadius, 0, Math.PI * 2);
				ctx.fillStyle = "rgb(" + (~~coltbl[colnum][0]) + ", " + (~~coltbl[colnum][1]) + ", " + (~~coltbl[colnum][2]) + ")";
				ctx.fill();
				ctx.closePath();
			}

			fj++;
			if( fj >= YSIZE ){
				break;
			} //最大値超えたら終了
		}
		for( ; fj < YSIZE; fj++ ) //不足サイズ分埋める
		{
			for( fi = 0; fi < XSIZE; fi++ ){
				// y方向不足サイズ描画
				offset = fj * XSIZE + fi;
				ctx.beginPath();
				pos[offset][0] = posbase[offset][0];
				pos[offset][1] = posbase[offset][1] + fk;
				ctx.arc(pos[offset][0], pos[offset][1], ballRadius, 0, Math.PI * 2);
				ctx.fillStyle = "rgb(" + (~~coltbl[colnum][0]) + ", " + (~~coltbl[colnum][1]) + ", " + (~~coltbl[colnum][2]) + ")";
				ctx.fill();
				ctx.closePath();
			}
		}

		// アニメ実行
		// アニメーションはマイナス方向へ
		dar -= FRAC_ANIM_SPEED_R;
		dai -= FRAC_ANIM_SPEED_I;

		// アニメ終了判定
		if( ( dar < (-1.0)*ANIM ) || ( dai < (-1.0)*ANIM ) ){
			// 初期値に戻す
			dar = ANIM;
			dai = ANIM;
			
			fdemo_num++;
		}
	}

//-----<#### JavaScript+html+Canvas でゲーム作成 ベース下 ####>
/* draw()関数がsetIntervalの中で16ミリ秒おきに実行 */
setInterval(draw, 16);

</script>
</body>
</html>

画面

この記事が気に入ったらサポートをしてみませんか?