2009年7月27日月曜日

画面のフェードイン・フェードアウトと音の再生

ロゴ画面を作成してみました。
画像と音はPCゲーム用のやつをそのまま再利用。
メディアデータはそのまま使えていいですなー。


ちゃんと再生できました!

2009年7月26日日曜日

最初のゲームっぽいアプリテスト

タッチした座標にキャラが歩くというテストアプリを作ってみました。


メモリリークの原因調査に半日くらいを費やしてしまいました(泣)
シミュレータだと動いていたものの、実機だとメモリをまたたく間に食いつくしてしまったようです。

タイマー、タッチ判定、ドット絵の加工がひとまずできるようになりました♪
お作法がまだわからないことが多いのですが、少しずつ理解していけることと思います。

ピクセルデータへのアクセス

ゲームを作るのに必須の手段。ピクセルデータへの直接アクセス方法です。

元画像としてUIImageへアクセスします。

UIImage *img;
int width = CGImageGetWidth (img.CGImage);
int height = CGImageGetHeight (img.CGImage);
CFDataRef inputData = CGDataProviderCopyData (CGImageGetDataProvider (img.CGImage)); UInt8 *pData = (UInt8 *)CFDataGetBytePtr (inputData);

pDataに先頭アドレスが入っているのでここからRGBと明るさの順でアクセスできます。
変更後は新しいUIImageへ変換してあげます。

CFDataRef data = CFDataCreate (NULL, m_pData, CFDataGetLength (inputData));
CGDataProviderRef dataProv = CGDataProviderCreateWithCFData (data);
CGImageRef img = CGImageCreate (width, height, 8, 32, width * 4,
CGColorSpaceCreateDeviceRGB (),
kCGImageAlphaLast,
dataProv, NULL, 0, kCGRenderingIntentDefault);
UIImage *pImage = [[UIImage alloc] initWithCGImage:img];
[pImage autorelease];

pImageに新しいUIImageが出来上がります。後はこれを画面に表示させるもよし、保存するもよし。
UIImageを作り直さずに更新できればいいのですが、どうもよくわからないです。

最後に、使い終わったリソースを解放します。
どれを解放すればいいのかわからずに、UIImageViewのimageを更新し続けるとメモリリークして実機で落ちる現象が出てかなり悩みました。

CGImageRelease (img);
CGDataProviderRelease (dataProv);
CFRelease (data);
CFRelease (inputData);

矩形のコピーは以下のようにできます。

for (int y = 0; y < height; y ++) {
int posSrc = ((srcY + y) * widthSrcSize) + (srcX * 4);
int posDst = ((dstY + y) * widthDstSize) + (dstX * 4);
for (int x = 0; x < width; x ++, posSrc += 4, posDst += 4) {
UInt8 *pDataSrcTmp = &pDataSrc[posSrc];
UInt8 *pDataDstTmp = &m_pData[posDst];
pDataDstTmp[0] = pDataSrcTmp[0];
pDataDstTmp[1] = pDataSrcTmp[1];
pDataDstTmp[2] = pDataSrcTmp[2];
pDataDstTmp[3] = 255;
}
}

初めは UInt8 ではなく unsigned char でやっていたのですが、UInt8 にするとかなりスピードアップしました。何か変換が内部で走るのでしょうかね。

256色画像からフルカラーへ変換

お手軽な画素変換方法。

元画像を読み込んでUIImageに放り込んでおきます。
UIImage *img;

まずは画像情報の取得

CGImageRef cgImageTmp = img.CGImage;
int width = CGImageGetWidth (cgImageTmp);
int height = CGImageGetHeight (cgImageTmp);
int nDataSize = width * height * 4;

他にもCGImageGet*****というのがあるようです。

そして画像の変換

CGSize size = {width, height};
UIGraphicsBeginImageContext (size);
[img drawInRect:CGRectMake (0, 0, width, height)];
UIImage *imgSrcTmp = UIGraphicsGetImageFromCurrentImageContext ();
UIGraphicsEndImageContext ();

コンテキストに描画するとその状態に合った形式に変換されるようです。
コンテキストが何者なのか?詳しくはまだよくわかってません。
Windowsでいうデバイスコンテキストのようなものでしょか。
サイズの変更もできるようですが、拡大するとぼやけた感じになりますね。