スポンサーサイト

上記の広告は1ヶ月以上更新のないブログに表示されています。
新しい記事を書く事で広告が消せます。

作曲に使うシーケンサー

ゲーム音楽を作曲するのに当たって打ち込みに使えそうなシーケンサー(どれもゲームソフトですが…;)が色々ありどれを使おうか悩みました。

今回はプログラムコードの紹介ではなく、お世話になったシーケンサー(作曲ツール)を紹介していこうかと思います。
…ちなみに作曲はちょっとだけ俺の得意分野だったりもします^^

1.コルグ(DS版)

M01_DS_screen_564_277_in1.jpg

こちらはニンテンドーDS用ソフトの「KORG M01」です。ぶっちゃけ真っ先に考えたのがこれ!

コルグは音質がとてもすばらしく、音の制限数やテンポなども、他のソフトに比べて自由度は高いのですが、手軽に作れるかというとそうでもない気がします。
まあ俺がただ単にキーボードに慣れてないだけだと思いますが、ちょっと操作に難有りな点があり1つの曲を作るのに時間がかかります。

ちなみにこれの1つ前に発売されたシンセサイザー(?)の方は、購入したのは良いものの使い方が良く分からず、押入れの中で眠っています;

とまあ、曲のデータ数もいっぱいということもあり、少しこれはおいときます…。



2.メイ俺

SCE6wQFAUPLGFT541ItiU84e7wXmlBJs.jpg

続いては任天堂から発売したメイドイン俺ですね。

これは先ほどのコルグと違い手軽に曲を作ます。
大体2時間あれば1曲作ることができるぐらい手軽で、一見とても便利なんですが………!

1.楽器の種類が少ない。(確か20個程度)
2.小節は2オクターブまで。
3.メロディのトラック(同時に鳴らせる数)が4つまで、などなど…。

かなりの制限があります…;

いちおう楽器の種類に関しては"ファミコンっぽい音源"があり、それを使えば"ファミコンっぽい音楽"なりますが、それでも制限がきついせいでどれも似たり寄ったりの曲になってしまい、やっぱり本格的な作曲ツールとしては不向きなんでしょうね。(もともとプチゲームの音楽を作曲する機能なので仕方ないといっちゃあ仕方ないんですが^^;)

でも、がんばればこれくらいのクオリティの音楽は作れます。



…と、いうわけで今回の作曲にいたっては任天堂さんから発売された「大合奏!バンドブラザーズP」というソフトを使用させていただこうかと思います。

61hq0Ps2U8L.jpg

3.バンブラP(公式サイト

gakufu_image.jpg

これはバンブラシリーズの3作目にあたるもので、3DS用ソフトということもあり、前作よりも音質がパワーアップしています。ファミコン音源も複数の周波数から選択することができるので、オリジナルに近い音楽が作曲できそうです。

…が、肝心のソフトをなくしてしまい、今はとりあえず1つ前のバージョンのバンブラDXで作っていますが^^;

~オマケ~
バンブラDXで作ったマリオUSAのテーマ

スポンサーサイト

無敵マリオの実装

さて、ゲーム作りもいよいよ終盤(マリオでいうと7-1くらい)に差し掛かってきましたよ。
今回はマリオシリーズでおなじみの"マリオが無敵になるプログラム"を組んでみました。

Screenshot_2014-07-12-02-24-07.png

↓↓↓↓↓↓↓↓↓↓

Screenshot_2014-07-12-02-25-22.png

このゲームでは(☆取得以外の)"とある条件"を満たすとプレイヤーが無敵になります。
無敵中は敵や針もなんのその!おまけに攻撃力がUPしたりで良いこと尽くめです!

でも無敵だからといって油断してると…。

Screenshot_2014-07-12-02-39-19.png

穴に落ちてしまうこともあるので気をつけて!
穴に落ちた場合は本家マリオ同様"ミス扱い"となります。

プログラムコードの内容は「無敵フラグがONのときに敵に触れるとやっつける」という処理を行うだけのシンプルな内容ですが、その前に一つやらなければいけないことがあります。

"プレイヤーの変化"ですね。

「いやっふー!今の僕は無敵状態だぞ!」とアピールするために現在のプレイヤーであるマリオのグラフィックを輝かせましょう!

player_01_mario_normal.png

これはマリオの全てのグラフィックが収録された画像データで、ここから走る動作やジャンプ時の動作など、使いたい画像だけを切り取って表示しています。
そうです。以前勉強したAnimatedSprite(Animatedスプライトについての解説を開く)ですね。

…それにしてもこの画像長すぎゃしやせんか^^;
縦だけじゃなく横にも同じ大きさの画像を並べて使いたい部分だけを抜き出すプログラム(それこそマップチップのように)が組めたらいいのに。今のコードでは無理みたいですね。

まあ「俺は長くても気にならないぜっ!」って方ならいいのですが…。
でも、困ったことにこれ以上長くしたい場合など、画像の長さが2000ピクセル(本当はもうちょいあるけど目安としてはこのくらい)を超えてしまうと、問答無用で"真っ黒な画像"に切り替わってしまうので注意が必要です。

Screenshot_2014-07-12-02-50-25.png

※長くしすぎると上図のようにプレイヤーが真っ黒になります。

これでも色々と画像の不要な部分(以前あったマリオの棒立ちのコマとか、無敵の点滅のコマの一つ目)を削り、何とか画像が表示されるまでに収まりました;

ちなみにこれ以上アニメーションを増やしたい場合は、無理せず複数のマリオ変数を作ると良いかもしれませんね。
無敵でないいわゆる"ノーマル状態"のマリオのAnimatedSprite変数と、無敵状態のマリオの輝く姿のみを描画した"無敵状態"のマリオのAnimatedSpriteの二つを管理するなど、探せば色々と方法はあるはずです。(ただ、この場合処理がめんどくさそうですが…。)
もっとも、プログラムは楽をしてなんぼなので出来るだけ簡単な方法でゲームを動かしたいですね。

…では気を取り直してプログラムコードの中身を見てみましょう!

// 敵キャラとプレイヤーの接触処理
public void enemyAndPlayerContact() {
// 点滅状態でない場合のみ接触
if (状態フラグ点滅 == false ||
プレイヤーの上昇移動フラグ == false && プレイヤーの下降移動フラグ == true) {
// マリオと敵キャラの衝突判定
if (((Sprite) getChildByIndex(敵キャラ)).collidesWith(
marios.playerMarioNormal)) {
float 判定遊び = 0;
float 接触距離 = Math.abs((getChildByIndex(敵キャラ)
.getY() + ((Sprite) getChildByIndex(敵キャラ))
.getHeight() / 2) - (marios.playerMarioNormal
.getY() + (marios.playerMarioNormal
.getHeight() / 2)));
// クリボー!
if (getChildByIndex(敵キャラ).getTag() ==
Goomba.TAG_ENEMY_01_GOOMBA) {
判定遊び = 0;
if (接触距離 < marios.playerMarioNormal.getHeight()
/ 2 + ((Sprite) getChildByIndex(敵キャラ)).getHeight()
/ 2 - 判定遊び) {
// 無敵の場合、問答無用でやっつけ
if (状態フラグ無敵 == true) {
SoundPlay.seDefeat.stop();
SoundPlay.seDefeat.play();
enemyAndPlayerJumpAttackDecision(getChildByIndex(敵キャラ).getTag());
// 無敵でない場合、フラグ分岐
} else {
// プレイヤーが何もしない場合、敵キャラのこうげき
if (プレイヤーのダッシュフラグ == true || プレイヤーの上昇移動フラグ == true) {
enemyAndPlayerNormalDecision();
// プレイヤーが落下中の場合、プレイヤーのジャンプこうげきが炸裂
} else if (プレイヤーのダッシュフラグ == false && プレイヤーの上昇移動フラグ == false) {
SoundPlay.seTap.stop();
SoundPlay.seTap.play();
// 敵キャラとかを踏んだことを証明する
連続で踏んだか否か = true;
// 画面を放すと小ジャンプ
if (タッチフラグジャンプ == false) {
踏み台ジャンプの上昇移動値 = 24;
踏み台ジャンプの下降移動値 = 4.8f;
// 画面を押すと大ジャンプ
} else {
踏み台ジャンプの上昇移動値 = 48;
踏み台ジャンプの下降移動値 = 9.6f;
}
enemyAndPlayerJumpAttackDecision(getChildByIndex(敵キャラ).getTag());
}
}
}

// 省略…

// プクプク!
} else if (getChildByIndex(敵キャラ).getTag() ==
CheepCheep.TAG_ENEMY_13_CHEEP_CHEEP) {
判定遊び = 0;
if (接触距離 < marios.playerMarioNormal.getHeight()
/ 2 + ((Sprite) getChildByIndex(敵キャラ)).getHeight()
/ 2 - 判定遊び) {
// 無敵の場合、問答無用でやっつけ
if (状態フラグ無敵 == true) {
SoundPlay.seDefeat.stop();
SoundPlay.seDefeat.play();
enemyAndPlayerJumpAttackDecision(getChildByIndex(敵キャラ).getTag());
// 無敵でない場合、フラグ分岐
} else {
// プレイヤーが何もしない場合、敵キャラのこうげき
if (プレイヤーのダッシュフラグ == true || プレイヤーの上昇移動フラグ == true) {
enemyAndPlayerNormalDecision();
// プレイヤーが落下中の場合、プレイヤーのジャンプこうげきが炸裂
} else if (プレイヤーのダッシュフラグ == false && プレイヤーの上昇移動フラグ == false) {
SoundPlay.seTap.stop();
SoundPlay.seTap.play();
// 敵キャラとかを踏んだことを証明する
連続で踏んだか否か = true;
// 画面を放すと小ジャンプ
if (タッチフラグジャンプ == false) {
踏み台ジャンプの上昇移動値 = 24;
踏み台ジャンプの下降移動値 = 4.8f;
// 画面を押すと大ジャンプ
} else {
踏み台ジャンプの上昇移動値 = 48;
踏み台ジャンプの下降移動値 = 9.6f;
}
enemyAndPlayerJumpAttackDecision(getChildByIndex(敵キャラ).getTag());
}
}
}
}
}
}
}


enemyAndPlayerContact()メソッドは全ての敵キャラとの接触判定を見るメソッド、つまりプレイヤーと敵キャラが接触したときに呼び出されるメソッドです。
ここではクリボーとプクプクしか紹介していませんが、「// 省略…」の中に他の敵キャラの処理も書いています。
全部載せると非常にコードが長くなってしまうので省略させていただきました。

それでは、まずクリボーの接触コードを見てみてください。
敵キャラに触れたときプレイヤーが無敵状態であるか否かを判断していますね。
ここで無敵状態だった場合は敵キャラをやっつける"enemyAndPlayerJumpAttackDecision(getChildByIndex(敵キャラ).getTag())"という長ったらしいメソッドが呼び出されます。
このメソッド内では触れた敵キャラを削除し、得点をプラスするなどの処理が行われております。

次にプレイヤーが無敵状態ではない場合、さらに分岐が行われるのですが、これは単にプレイヤーが落下中か否かを確かめてるだけです。
プレイヤーが落下中ではなく地面を走っている場合は敵キャラの攻撃が行われミスになりますが、落下中の場合は踏んだとみなされ無敵状態で使ったものと同じ"enemyAndPlayerJumpAttackDecision(getChildByIndex(敵キャラ).getTag())"メソッドが呼び出されるというわけです。

「でもこれだとプレイヤーがどこから触れても踏んだことになるじゃん!」って思った方もおられると思いますが、実はこれでいいのです。
初代マリオをやりこんでらっしゃる方ならお分かりだと思いますが、マリオ1と2はプレイヤーが落下中の場合、マリオの全ての部分に踏みつけ判定があるんですよ!
(このテクをいかせばにっくきハンマーブロスも頭突きでイチゲキコロリですがそれはまた別のお話…。)

…とまあ、一応無敵のプログラムはこんな感じです。
だんだんとゲームの雛形が完成に近づいてきたので、コースやBGMも作っていかないといけませんね。
これからはあまり更新出来ないかもしれませんが、また暇があったら見てやってください。では!



~おまけ~

Screenshot_2014-07-12-02-57-52.png

ドット絵を差し替えてみました。

ではでは^^;(本当の本当に終わり)

壊れるブロックの実装

今回はマリオシリーズに登場するレンガブロック「tile_33_brick_block_small.png」を実装してみました。

このゲームには通常のレンガブロックと、一回りサイズの大きいデカレンガブロックの2種類が登場します。

Screenshot_2014-07-03-20-33-40.png

コードを解説する前に本家マリオに登場するレンガブロックの性質をおさらいすると…。

1.ブロック全体に接触判定があり、マリオが上に乗っかることができる。
2.スーパーマリオ、もしくはファイアマリオの状態で下から触れると割ることができる。
3.中には割れない"当たりのブロック"もあり、その場合はコインなどのアイテムが隠されている。

大まかにこの3つがマリオシリーズ共通のレンガブロックの性質ですが、
3番の「中には割れない"当たりのブロック"もあり、その場合はコインなどのアイテムが隠されている。」は"諸事情"により今回はスルーします。
(最も本家とは少し違う方法でアイテムを隠すようにはしたいですが…。)

ですので、今回の実装は1番の「ブロックの接触判定」と、2番の「下から触れた際の割れる挙動」ですね。

まず、レンガブロックの下…つまりマリオの頭部分の赤いラインにレンガブロックが触れたときの処理を見てみましょう!

public void tileAndPlayerAboveContact() {
if (((Sprite) getChildByIndex(タイル)).collidesWith(
contactLines.playerContactLineAbove)) {
float 判定遊び = 0;
float 接触距離 = Math.abs((getChildByIndex(タイル)
.getY() + ((Sprite) getChildByIndex(タイル))
.getHeight() / 2) - (contactLines.playerContactLineAbove
.getY() + (contactLines.playerContactLineAbove
.getHeight() / 2)));
// 15.地面ブロック(短い)
if (getChildByIndex(タイル).getTag() ==
GroundBlocks.TAG_TILE_15_GROUND_BLOCK_SHORT
// ※ブロックはジャンプ時のみ判定
&& プレイヤーのダッシュフラグ == false && プレイヤーのジャンプフラグ == true
&& プレイヤーの上昇移動フラグ == true) {
判定遊び = 0;
if (接触距離 < contactLines.playerContactLineAbove.getHeight()
/ 2 + ((Sprite) getChildByIndex(タイル)).getHeight()
/ 2 - 判定遊び) {
tileAndContactLineAboveDecision();
}

// 省略…

// 33.レンガブロック(小さい)
} else if (getChildByIndex(タイル).getTag() ==
BrickBlocks.TAG_TILE_33_BRICK_BLOCK_SMALL
// ※ブロックはジャンプ時のみ判定
&& プレイヤーのダッシュフラグ == false && プレイヤーのジャンプフラグ == true
&& プレイヤーの上昇移動フラグ == true) {
// ライフが2以上のとき、ブロックを破壊できる
if (現在のライフ >= 2) {
SoundPlay.seBrickBlock.stop();
SoundPlay.seBrickBlock.play();
収納用タイル.add((Sprite) getChildByIndex(タイル));
}
判定遊び = 0;
if (接触距離 < contactLines.playerContactLineAbove.getHeight()
/ 2 + ((Sprite) getChildByIndex(タイル)).getHeight()
/ 2 - 判定遊び &&
// ライフが1のときは落下判定
現在のライフ == 1) {
tileAndContactLineAboveDecision();
}

// 省略…

// 68.はり(下)
} else if (getChildByIndex(タイル).getTag() ==
Needles.TAG_TILE_68_NEEDLE_BELOW
// ※ブロックはジャンプ時のみ判定
&& プレイヤーのダッシュフラグ == false && プレイヤーのジャンプフラグ == true
&& プレイヤーの上昇移動フラグ == true) {
判定遊び = 0;
if (接触距離 < contactLines.playerContactLineAbove.getHeight()
/ 2 + ((Sprite) getChildByIndex(タイル)).getHeight()
/ 2 - 判定遊び) {
tileAndContactLineAboveDecision();
if (状態フラグ点滅 == false) {
// はりに触れた場合、敵キャラのこうげきと同じ処理
enemyAndPlayerNormalDecision();
}
}
}
}
}

tileAndPlayerAboveContact()メソッドはマリオの頭上判定…つまり、マリオの上に付いている赤いラインとメソッド内のオブジェクトが触れたとき、指定された処理内容が実行されます。

では、「// 33.レンガブロック(小さい)」に注目してください。
ここで注意しなければいけないことは、スーパーマリオ(と、ファイアマリオ)の状態で触れるとレンガブロックを割れることですよね。
「現在のライフ」という変数は以前解説しましたが、マリオの状態を管理している変数です。

1 == ならマリオ(チビ)
2 == ならスーパーマリオ
3 == ならファイアマリオ

ここでは「現在のライフ >= 2」つまり、スーパーマリオの状態でレンガブロックに触れた場合はレンガブロックが割れるようにしていますが、ここでも本家のマリオとは少し違う点があります。
本家のマリオはレンガブロックをジャンプで割った後、即座に地面へ落下しますが、このゲームはレンガブロックをジャンプで割っても画面から指を離すまで(もしくは、ジャンプ力が限界値に達するまで)マリオは落下しません。

Screenshot_2014-07-05-15-23-15.png

↓↓↓↓↓↓↓↓↓↓

Screenshot_2014-07-05-15-23-53.png

自動スクロールゲームではプレイヤーは停止できませんよね。
ですからこの場合一つ一つ割っていくより一気に破壊できた方が効率が良いのです。
無理に本家マリオを再現するより、遊びやすさを優先的に作っていった方が良いですもの。

…以上でレンガブロックの解説を終わります…っえ?マリオが横から触れた時の解説がまだだって?

それは以前解説した当たり判定"右"の実装で解説済みですよ!
この処理をメソッド化し、当たり判定のある全てのブロックは共通でこのメソッドを呼び出しているというわけです。

プロフィール

岡本 賢治

Author:岡本 賢治
 
☆☆☆☆☆☆☆☆☆☆☆☆
 
Android専用アクションゲーム
「スーパーけんじラン」好評配信中!
 
↓↓↓↓↓↓↓↓↓↓↓↓

 
・公式サイトはこちらから
http://okamotodo.jimdo.com/

最新トラックバック

アクセスカウンター

オンラインカウンター

現在の閲覧者数:

検索フォーム

ブロとも申請フォーム

QRコード

QR
上記広告は1ヶ月以上更新のないブログに表示されています。新しい記事を書くことで広告を消せます。