![見出し画像](https://assets.st-note.com/production/uploads/images/136698307/rectangle_large_type_2_2080b00be10703fa93addd8202ee5dff.png?width=1200)
JavaScript+html+Canvas でゲーム作成(効果音出力)
「キーボード入力(トリガ)」を使って効果音を出してみました。
SPACEキーでジャンプ時に指定した音が鳴ります。
音のファイルは、<音ファイル名>を自由に設定してください。
ファイルフォーマットは、mp3, wav, mp4, flac, m4aが使えるようです。
例:
音ファイルがhtmlと同じフォルダにある時、
se_jump.src = "./sound_effect.mp3";
音出力の際、.play()の前に.load()を入れています。
.load()を入れないと前の音出力が終了しないと次の音が出ないため、
連続で音を出そうとした時に音が出なくなるのを防いでいます。
以下、プログラム。(音出力追加部分には[#sound#]で括ってます。)
<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 でゲーム作成 ####>
//音出力サンプル
//[#sound#]------------------------------------------------------------
// 音出力準備
const se_jump = document.createElement("audio");
se_jump.src = <音ファイル名>; // <音ファイル名>を指定★
se_jump.preload = "auto"; // 事前に音声データを読み込む
//[#sound#]------------------------------------------------------------
//[#key input#]------------------------------------------------------------
// キーボード入力を取得する
document.addEventListener("keydown", keyDownHandler, false);
document.addEventListener("keyup", keyUpHandler, false);
//[#key input#]------------------------------------------------------------
// パラメータ
var RADIUS = 2; // 点の半径
var DDOT = 2; // 隣り合う点の間隔 x2(0以外の偶数)
// 変数
var XSIZE = canvas.width / DDOT; // Xサイズ(描画サイズは、XSIZE * DDOT)
var YSIZE = canvas.height / DDOT; // Yサイズ(描画サイズは、YSIZE * DDOT)
// インベーダーキャラクタ
// 0 1 2 3 4 5 6 7 8 9 a b c d
//0:□□□□□■■■■□□□□□
//1:□□■■■■■■■■■■□□
//2:□■■■■■■■■■■■■□
//3:□■■■□□■■□□■■■□
//4:□■■■■■■■■■■■■□
//5:□□□■■■□□■■■□□□
//6:□□■■□□■■□□■■□□
//7:□□□■■□□□□■■□□□
var dottbl_0 = new Array(0x7e);
// ■の座標:xpos, ypos,,,,
dottbl_0 = [
0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,
0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,
0x01,0x02,0x02,0x02,0x03,0x02,0x04,0x02,0x05,0x02,0x06,0x02,0x07,0x02,0x08,0x02,0x09,0x02,0x0a,0x02,0x0b,0x02,0x0c,0x02,
0x01,0x03,0x02,0x03,0x03,0x03,0x06,0x03,0x07,0x03,0x0a,0x03,0x0b,0x03,0x0c,0x03,
0x01,0x04,0x02,0x04,0x03,0x04,0x04,0x04,0x05,0x04,0x06,0x04,0x07,0x04,0x08,0x04,0x09,0x04,0x0a,0x04,0x0b,0x04,0x0c,0x04,
0x03,0x05,0x04,0x05,0x05,0x05,0x08,0x05,0x09,0x05,0x0a,0x05,
0x02,0x06,0x03,0x06,0x06,0x06,0x07,0x06,0x0a,0x06,0x0b,0x06,
0x03,0x07,0x04,0x07,0x09,0x07,0x0a,0x07,
0xff,0xff]; // 終端
// 0 1 2 3 4 5 6 7 8 9 a b c d
//0:□□□□□■■■■□□□□□
//1:□□■■■■■■■■■■□□
//2:□■■■■■■■■■■■■□
//3:□■■■□□■■□□■■■□
//4:□■■■■■■■■■■■■□
//5:□□□□■■□□■■□□□□
//6:□□□■■□■■□■■□□□
//7:□■■□□□□□□□□■■□
var dottbl_1 = new Array(0x7c);
// ■の座標:xpos, ypos,,,,
dottbl_1 = [
0x05,0x00,0x06,0x00,0x07,0x00,0x08,0x00,
0x02,0x01,0x03,0x01,0x04,0x01,0x05,0x01,0x06,0x01,0x07,0x01,0x08,0x01,0x09,0x01,0x0a,0x01,0x0b,0x01,0x01,0x02,
0x02,0x02,0x03,0x02,0x04,0x02,0x05,0x02,0x06,0x02,0x07,0x02,0x08,0x02,0x09,0x02,0x0a,0x02,0x0b,0x02,0x0c,0x02,
0x01,0x03,0x02,0x03,0x03,0x03,0x06,0x03,0x07,0x03,0x0a,0x03,0x0b,0x03,0x0c,0x03,
0x01,0x04,0x02,0x04,0x03,0x04,0x04,0x04,0x05,0x04,0x06,0x04,0x07,0x04,0x08,0x04,0x09,0x04,0x0a,0x04,0x0b,0x04,0x0c,0x04,
0x04,0x05,0x05,0x05,0x08,0x05,0x09,0x05,
0x03,0x06,0x04,0x06,0x06,0x06,0x07,0x06,0x09,0x06,0x0a,0x06,
0x01,0x07,0x02,0x07,0x0b,0x07,0x0c,0x07,
0xff,0xff]; // 終端
var pos = new Array( XSIZE * YSIZE ); // 画面座標
const COLOR_BLACK = 0; // 黒
const COLOR_WHITE = 1; // 白
// 点描画
// xp : x座標
// yp : y座標
// colnum : 色番号(0:black, 1:white)
function draw_point( xp, yp, colnum ) {
var offset = yp * XSIZE + xp;
ctx.beginPath();
if( colnum == 0 ) {
ctx.fillStyle = "rgb(" + (~~0x00) + ", " + (~~0x00) + ", " + (~~0x00) + ")";
} else {
ctx.fillStyle = "rgb(" + (~~0xFF) + ", " + (~~0xFF) + ", " + (~~0xFF) + ")";
}
ctx.fillRect( pos[offset][0], pos[offset][1], RADIUS, RADIUS);
ctx.closePath();
}
// 指定された位置のパターンを描画
// dx : x座標
// dy : y座標
// dn : パターン番号
// dc : 色番号(0:black, 1:white)
function dot_pattern_put( dx, dy, dn, dc )
{
var i = 0;
if( dn == 0 ){
while (dottbl_0[i*2] != 0xff){
draw_point( dx + dottbl_0[i*2+0], dy + dottbl_0[i*2+1], dc);
i++;
}
} else {
while (dottbl_1[i*2] != 0xff){
draw_point( dx + dottbl_1[i*2+0], dy + dottbl_1[i*2+1], dc);
i++;
}
}
}
// 初期化
// 画面座標セット
for( var y = 0; y < YSIZE; y++ ){
for (var x = 0; x < XSIZE; x++) {
pos[y * XSIZE + x] = new Array(2); // x,y
pos[y * XSIZE + x][0] = x * ( DDOT & 0xfe ); // xpos
pos[y * XSIZE + x][1] = y * ( DDOT & 0xfe ); // ypos
}
}
const anim_time_max = 40; // アニメーションスピード 40/60 sec
var anim_time = anim_time_max; // アニメーション時間カウンタ
var anim_pattern = 0; // アニメーションパターン
var xpos = 0x20; // x座標
var ypos = 0x20; // y座標
//[#jump#]------------------------------------------------------------
var ypos_offset = 0; // y座標加算値
var jump_switch = 0; // ジャンプ中判定
var jump_counter = 0; // ジャンプテーブルカウンタ
var jumptbl = new Array(19);
jumptbl = [ -4,-4,-3,-3,-2,-2,-1,-1,0,0,1,1,2,2,3,3,4,4,0xFF ];
//[#jump#]------------------------------------------------------------
function draw() {
// 前回のアニメーションパターンを削除
dot_pattern_put( xpos, ypos, anim_pattern, COLOR_BLACK );
// アニメーションタイミング
if( anim_time < anim_time_max ){
anim_time++;
}else{
anim_time = 0;
// 次のパターン番号セット
anim_pattern = ( anim_pattern + 1 ) & 1;
}
//[#key input#]------------------------------------------------------------
// 入力取得
getKey = get_input();
if( getPressRIGHT() ) { // 右移動
// キー入力後の位置を更新
xpos = xpos + 1;
} else if( getPressLEFT() ) { // 左移動
// キー入力後の位置を更新
xpos = xpos - 1;
}
//[#key input#]------------------------------------------------------------
//[#jump#]------------------------------------------------------------
// ジャンプ加算値クリア
ypos_offset = 0;
// ジャンプ中でない時にSPACEキーをチェック
if( ( jump_switch == 0 ) && getInputSPACE() ) {
// ジャンプ中セット
jump_switch = 1;
jump_counter = 0;
//[#sound#]------------------------------------------------------------
se_jump.load(); //ロード
se_jump.play(); //音出力
//[#sound#]------------------------------------------------------------
}
// ジャンプ中の時
if( jump_switch == 1 ) {
ypos_offset = jumptbl[jump_counter];
jump_counter++;
if( jumptbl[jump_counter] == 0xff ) {
// 次でジャンプ終了ならジャンプ中クリア
jump_switch = 0;
}
}
// ジャンプ実行
ypos = ypos + ypos_offset;
//[#jump#]------------------------------------------------------------
// 今回のアニメーションパターンを描画
dot_pattern_put( xpos, ypos,anim_pattern, COLOR_WHITE);
}
//[#key input#]------------------------------------------------------------
// 入力
// 定数
const KEY_LEFT = 0;
const KEY_RIGHT = 1;
const KEY_SPACE = 2;
// 変数
var getKey = 0;
var trgKey = 0;
var keypress_R = 0;
var keypress_L = 0;
var keypress_SPACE = 0;
const KEYCODE_SPACE = 32; // SPACEキーコード
// キーON
function keyDownHandler(e) {
if( e.key == "Right" || e.key == "ArrowRight" ) {
keypress_R = 1;
} else if( e.key == "Left" || e.key == "ArrowLeft" ) {
keypress_L = 1;
} else if( e.keyCode == KEYCODE_SPACE ) {
keypress_SPACE = 1;
}
}
// キーOFF
function keyUpHandler(e) {
if( e.key == "Right" || e.key == "ArrowRight" ) {
keypress_R = 0;
} else if( e.key == "Left" || e.key == "ArrowLeft" ) {
keypress_L = 0;
} else if( e.keyCode == KEYCODE_SPACE ) {
keypress_SPACE = 0;
}
}
// キーボード入力を取得する
function get_input() {
var keypress = 0;
if( 1 == keypress_R ) { keypress |= 1 << KEY_RIGHT; } else { keypress &= ~(1 << KEY_RIGHT); }
if( 1 == keypress_L ) { keypress |= 1 << KEY_LEFT; } else { keypress &= ~(1 << KEY_LEFT); }
if( 1 == keypress_SPACE ) { keypress |= 1 << KEY_SPACE; } else { keypress &= ~(1 << KEY_SPACE); }
return (keypress);
}
// SPACEキートリガ
function getInputSPACE() {
if( getKey & ( 1 << KEY_SPACE ) ) {
if( trgKey & ( 1 << KEY_SPACE ) ) {
return 0;
} else {
trgKey |= ( 1 << KEY_SPACE );
return 1;
}
} else {
trgKey &= ~( 1 << KEY_SPACE );
return 0;
}
}
// カーソル左押下
function getPressLEFT() {
if( getKey & ( 1 << KEY_LEFT ) ) {
return 1;
} else {
return 0;
}
}
// カーソル右押下
function getPressRIGHT() {
if( getKey & ( 1 << KEY_RIGHT ) ) {
return 1;
} else {
return 0;
}
}
//[#key input#]------------------------------------------------------------
//-----<#### JavaScript+html+Canvas でゲーム作成 s####>
/* draw()関数がsetIntervalの中で16ミリ秒おきに実行 */
setInterval(draw, 16);
</script>
</body>
</html>
この記事が気に入ったらサポートをしてみませんか?