JavaScriptで2Dゲームが作れる無料のWebサービス「Bitomelo」を使って、ゲームを作ってみた!

JavaScriptで2Dゲームが作れる無料のWebサービス「Bitomelo」を使って、ゲームを作ってみた!

JavaScriptを使って、Web上でマリオみたいなファミコン風の2Dゲームを開発できるサービスBitmeloを使ってみました!とても楽しく、簡単にゲーム開発を楽しむことができたので、使い方や機能について、ご紹介したいと思います!

Bitmeloとは

Bitomeloは、とても簡単にWeb上で、2Dゲームを開発・公開できるサービスです。画面は、ピクセルアートで作ります。

Bitmeloの公式サイトはこちらです。

https://bitmelo.com/

どんなゲームを作ることができるのか

デフォルトで入っているゲームは、きのこをとると文字の色が変わったり、はねたりするシンプルなゲームです。アレンジ次第で、マリオみたいなピクセルアートの2Dゲームを作ることができます。

マリオとはほど遠いですが、私もデフォルトのゲームをアレンジして、ゲームを作ってみました。下記の画面をClickして、遊んでみてください。キャラクター操作時に音がでます。

Bitmeloの機能

Bitomeloには、ゲームで使う素材を作るための様々なエディターが備わっており、すぐにでもゲーム開発をスタートすることができます。どのようなエディターがあるのか、またそれぞれの機能をご紹介していきます。

Tile Editor タイルを作成してみよう

ゲームで使用するためのドット絵が作成できるTile Editorです。キャラクターや背景など、すべてこのエディターで作成します。

タイルひとつにつき、ひとつのタイルを登録できる仕組みで、プログラム部分では、IDで表示を出し分けます。

Tilemap Edtor タイルを配置してみよう

作ったタイルを配置するためのTilemap Editorです。 配置したいタイルを選択して、Mapに置いていくだけです。

Sound Editor ゲームの音を作ってみよう

ゲームで使う音楽を作るためのSound Editorです。

Code コードを書いてみよう

プログラムを書くための、Code Edtitorです。実際にキャラクターを動かしたり、素材を配置するには、コードを書くことになります。JavaScriptの基本的なことを理解されている方であれば、簡単に記述することができます。サイドバーにリファレンスが用意されているので、使い方を確認しながら開発を進めることが可能です。

Project ゲームの画面設定や、インポート・エクスポートしてみよう

プロジェクトの画面幅を決めたり、プロジェクトをインポート・エクスポートするための機能です。Export HTML Gameをクリックすると、HTMLにScriptが組み込まれたファイルをダウンロードすることができ、そのままサーバーにアップすればすぐに、ゲームを公開・楽しむことができます。

Introduction ゲームの説明をつけよう

ゲームの説明を表示するための機能です。どんな操作をすると、どのような動きになるのか説明があると親切です。

実際のゲーム画面では、ゲーム画面の下に説明文が表示されます。

Publish 作ったゲームを公開してみよう

作ったゲームをオンライン上で公開するための機能です。ボタンひとつで、全世界に公開することが可能です。

Publishボタンをクリックすると、プロジェクト名(ゲームのタイトル)やどのようなライセンスで公開するのかを選択する画面が表示されます。

規約に同意するチェックボックスにチェックを入れて、Publishボタンを押すと、公開されます。

公開されると、最新のデータ公開日時とプロジェクト名、ゲームのURLが表示されます。

URLにアクセスすると、ゲームのページに飛びます。

私の作ったゲームのURLはこちら https://bitmelo.com/user/mai12345/games/maifirstgame

作ったゲームをすぐに公開して遊べるのは、すごく便利ですし、テンションが上がりますね!

JavaScirptのコードの中身

コードの中身はデフォルトで、こんな感じになってます。キャラクターを表示したり、動かす部分はコードが含まれています。コードを眺めているだけでも、ゲームがどんな風に作られているのか簡単に学ぶことができます。

例えば、これは、きのこを表示する配列。x座標とy座標を設定して、位置を決めます。

const mushrooms = [
	{  
		x: 40,
		y: 100,
		wasGrabbed: false
	},
	{  
		x: 20,
		y: 30,
		wasGrabbed: false
	},
	{  
		x: 120,
		y: 50,
		wasGrabbed: false
	},
	{  
		x: 50,
		y: 100,
		wasGrabbed: false
	}
];

きのこを表示するためのスクリプト。scr.drawTile()という関数が、タイルを表示するためのスクリプトです。これをきのこの配列分、ループ処理しています。

function drawMushrooms() {
	mushrooms.forEach( mushroom => {
		if ( !mushroom.wasGrabbed ) {
			scr.drawTile(
				5,
				mushroom.x - 8, // center on the position
				mushroom.y - 8, // center on the position
				0
			);
		}
	} );
}

キャラクターを表示するスクリプト。frameGIDというのが、タイルエディターで作成した際の登録IDです。

	
	// draw the player
	let frameGID = 1;
	if ( player.isWalking ) {
		if ( player.framesSinceWalkStart % 16 < 8 ) {
			frameGID = 2;
		}
		else {
			frameGID = 3;
		}
	}
	
	scr.drawTile(
		frameGID,
		Math.floor( player.x ) - 8, // center the tile on the position
		Math.floor( player.y ) - 8, // center the tile on the position
		player.flip
	);
}

コードの全体。


// Globals
let inp = null; // input
let scr = null; // screen
let aud = null; // audio

const player = {
	x: 100,
	y: 50,
	speed: 0.5,
	isWalking: false,
	flip: 0,
	framesSinceWalkStart: 0
}

const mushrooms = [
	{  
		x: 40,
		y: 100,
		wasGrabbed: false
	},
	{  
		x: 20,
		y: 30,
		wasGrabbed: false
	},
	{  
		x: 120,
		y: 50,
		wasGrabbed: false
	},
	{  
		x: 50,
		y: 100,
		wasGrabbed: false
	}
];

let numberOfGrabbedMushrooms = 0;

let randomColor = 1;

// initialization
engine.onInit = () => {
	inp = engine.input;
	scr = engine.screen;
	aud = engine.audio;
	
	updateColors();
};


// update loop
engine.onUpdate = () => {
  scr.clear( 1 );

	scr.drawMap(
	  0,      // originX on map
	  0,      // originY on map
	  -1,     // width
	  -1,     // height
	  0,      // screenX
	  0,      // screenY
	  0       // tilemap index
	);
	
	drawMushrooms();
	
	updatePlayer();
	
	let textMainColor = 2;
	if ( numberOfGrabbedMushrooms > 0 ) {
		textMainColor = randomColor;
	}
	
	let textPositionOffset = 0;
	if ( numberOfGrabbedMushrooms > 1 ) {
		textPositionOffset = Math.sin( engine.realTimeSinceGameStart * 5 ) * 8;
	}
	
	scr.drawText(
		'Hello!! My World!',
		100,
		100 + Math.floor( textPositionOffset ),
		textMainColor,
		1,
		0
	);
};

function drawMushrooms() {
	mushrooms.forEach( mushroom => {
		if ( !mushroom.wasGrabbed ) {
			scr.drawTile(
				5,
				mushroom.x - 8, // center on the position
				mushroom.y - 8, // center on the position
				0
			);
		}
	} );
}

function updatePlayer() {
	let newX = player.x;
	let newY = player.y;
	
	let isWalking = false;
	if ( inp.left.pressed ) {
		newX -= player.speed;
		isWalking = true;
		player.flip = 1;
	}
	else if ( inp.right.pressed ) {
		newX += player.speed;
		isWalking = true;
		player.flip = 0;
	}
	
	if ( inp.down.pressed ) {
		newY -= player.speed;
		isWalking = true;
	}
	else if ( inp.up.pressed ) {
		newY += player.speed;
		isWalking = true;
	}
	
	if ( isWalking ) {
		player.framesSinceWalkStart += 1;
	}
	
	// play or stop audio
	if ( isWalking && !player.isWalking ) {
		// started walking
		player.framesSinceWalkStart = 0;
		
		let note = bitmelo.Notes.C4;
		if ( numberOfGrabbedMushrooms > 1 ) {
			note = bitmelo.Notes.C2;
		}
		else if ( numberOfGrabbedMushrooms > 0 ) {
			note = bitmelo.Notes.C3;
		}
		
		aud.playInfiniteSound(
			0,
			note,
			0.5,
			2
		);
	}
	else if ( !isWalking && player.isWalking ) {
		// stopped walking
		aud.stopInfiniteSound( 0 );
	}
	
	player.isWalking = isWalking;
	
	// make sure we are not colliding with the fence
	if ( 
		newX >= 16
		&& newX < scr.width - 16
		&& newY >= 24
		&& newY < scr.height - 16
	) {
		player.x = newX;
		player.y = newY;
	}
	
	// check mushroom collisions
	for ( let i = 0; i < mushrooms.length; i += 1 ) {
		const mushroom = mushrooms[i];
		if ( !mushroom.wasGrabbed ) {
			const deltaX = Math.abs( player.x - mushroom.x );
			const deltaY= Math.abs( player.y - mushroom.y );
			const distance = Math.sqrt( deltaX * deltaX + deltaY * deltaY );
			
			// player has grabbed a mushroom
			if ( distance <= 12 ) {
				mushroom.wasGrabbed = true;
				numberOfGrabbedMushrooms += 1;
				
				aud.playSound(
					1,
					bitmelo.Notes.E3,
					48,
					0.25,
					1
				);
			}
		}
	}
	
	// draw the player
	let frameGID = 2;
	if ( player.isWalking ) {
		if ( player.framesSinceWalkStart % 16 < 8 ) {
			frameGID = 2;
		}
		else {
			frameGID = 3;
		}
	}
	
	scr.drawTile(
		frameGID,
		Math.floor( player.x ) - 8, // center the tile on the position
		Math.floor( player.y ) - 8, // center the tile on the position
		player.flip
	);
}

function updateColors() {
	randomColor = Math.floor( Math.random() * 16 ) + 1;
	setTimeout( updateColors, 100 );
}

終わりに

以上、ざっくりですが、Bitmiloの機能と使い方を紹介しました。

動きや、キャラクターの表示を変えるには、基礎的なJavaScriptの知識が必要ですが、タイルの作成や、タイルの配置は、お子さんでもできるので、親子で一緒にゲーム作りを楽しんでみるのもおすすめです!

まい

フロントエンドエンジニア目指して、勉強中です。

JavaScriptカテゴリの最新記事