[cocos2d]シーンの切り替えで使用メモリが増えていく

iPhone Game「社畜!ナカムラくん」の制作で解決したのでメモ。

deallocメソッドでreleaseしていても
cocos2dだとreplaceSceneを繰り返すと使用メモリが増えていく。
下記コードをdeallocメソッドに入れると解決。

[CCAnimationCache purgeSharedAnimationCache];
[[CCTextureCache sharedTextureCache] removeAllTextures];

cocos2dが画像やらアニメやらをキャッシュしてる。

[cocos2d]アニメーション

iPhone Game「社畜!ナカムラくん」で実践していた方法。
おおまかな作業の流れは下記。
1. Flashでアニメーションを制作
2. pngシーケンスで書き出す
3. Zwoptex(有料)で一枚のpngに出力
4. CCSpriteに表示

1. Flashでアニメーションを制作
30fpsでアニメーションを作ります
作ったものがこれ

2. pngシーケンスで書き出す
Flashにて「ファイル」→「書き出し」→「ムービーの書き出し」
でフォーマットを「pngシーケンス」にして任意のフォルダへ書き出す。

3. Zwoptex(有料)で一枚のpngに出力
Zwoptexで一枚にしてplistファイルを書き出します。
Zwoptexはcocos2dで使用するSpriteSheetを書き出すツールです。
公式サイトはこちらZwoptex
15ドルでMacAppStoreからも買えます。
・Zwoptexを起動
・「File」→[New]
・pngシーケンスをドロップ
・「Layout」クリック
・「Publish」
で一枚pngとplistファイルが書き出されます。

4. CCSpriteに表示
XcodeのResourceフォルダあたりに一枚pngとplistファイルをドロップします。
そして下記コードからCCSpriteに表示します。

-(NSString*)pzero:(int)a keta:(int)keta{
    NSString *b=[NSString stringWithFormat:@"%d",a];
    while ([b length]=enno; a--) {
            NSString* file=[NSString stringWithFormat:@"%@%@.png",frame,[self pzero:a keta:4]];
            CCSpriteFrameCache* frameCache=[CCSpriteFrameCache sharedSpriteFrameCache];
            CCSpriteFrame* sframe=[frameCache spriteFrameByName:file];
            [frames addObject:sframe];
        }
    }
    return [[[CCAnimation alloc]initWithFrames:frames delay:delay]autorelease];
}
-(void)initAnimeFrames:(NSString*)key animename:(NSString*)animename stno:(int)stno enno:(int)enno delay:(float)delay{
    CCAnimation* ani=[[CCAnimationCache sharedAnimationCache] animationByName:animename];
    if(ani!=nil)return;
    
    CCAnimation* anim = [self animationWithFrame:key stno:stno enno:enno delay:delay];
    [[CCAnimationCache sharedAnimationCache] addAnimation:anim name:animename];
}
-(void)initPlist:(NSString*)plistkey{
    CCSpriteFrameCache* frameCache = [CCSpriteFrameCache sharedSpriteFrameCache];
    NSString *s=[NSString stringWithFormat:@"%@.plist",plistkey];
	[frameCache addSpriteFramesWithFile:s];
}
-(void)initAnime{
    [self initPlist:@"walk"];
    [self initAnimeFrames:@"walk" animename:@"walk" stno:1 enno:33 delay:0.05f];
}
-(id)init{
    self=[super init];
    if (self) {
        [self initAnime];
    }
    return self;
}


-(CCAnimation*)getAnime:(NSString*)key{
    return [[CCAnimationCache sharedAnimationCache] animationByName:key];
}
-(void)setAnime:(CCSprite*)sp animename:(NSString*)animename repeat:(BOOL)repeat{
    NSString* n=animename;
    CCAnimation* anim =[self getAnime:n];
    if(anim==nil){
        return;
    }
    CCAnimate* animate=[CCAnimate actionWithAnimation:anim];
    if (repeat) {
        CCRepeatForever* ccrepeat = [CCRepeatForever actionWithAction:animate];
        [sp runAction:ccrepeat];
        [sp setDisplayFrameWithAnimationName:n index:0];
    }else{
        id act=[CCSequence actions:animate, nil];
        [sp runAction:act];
        [sp setDisplayFrameWithAnimationName:n index:0];
    }
}

CCSpriteに表示するときはこう

CCSprite*sp=[[CCSprite alloc]init];
[anime setAnime:sp animename:@"walk" repeat:YES];
[mynode addChild:sp z:22];
[self initAnimeFrames:@"walk" animename:@"walk" stno:1 enno:33 delay:0.05f];

このコードのdelayの値が1フレームの表示時間なので早くするなら小さい値を
遅くするなら大きい値を。

[iPhone Apps, Android Apps]チルトシフトフォト (TiltShiftPhoto)

iPhone Apps「チルトシフトフォト」をリリースしました。
Androidバージョンもあります。「チルトシフトフォト

チルトシフトフォトは写真をチルトシフトレンズで撮ったミニチュアのような写真に加工するアプリです。
Twitter,Facebookに対応しており、作った写真をすぐにアップロードすることが出来ます。

TiltShiftPhoto is photo retouch App.
Enable to convert the photo that look like they were taken with tilt shift lens photos.
You can upload photos to Twitter,Facebook.

[iPhone Game]社畜!ナカムラくん

iPhone Game「社畜!ナカムラくん」をリリースしました。

社畜のナカムラくんを会社へ導くパズルアクションゲームです。
ナカムラくんは毎日休まず会社へ行きます。
そんなナカムラくんを橋やジャンプ台、はしご、大砲などを駆使して会社へ導きましょう。
全80ステージあり、頭を使うので社畜の方もそうでない方も楽しめますよ!
さぁ!出社せよ!

社畜!ナカムラくん
社畜!ナカムラくん

プレイ動画@YouTube

[PHP]listing.php

下図の赤線のhtmlへのリンクを書き出すphp。

Sample

 

index.php

<ul>
<?php

function getDirList($trgDir){
  $a = array();
  if ($dir = opendir($trgDir)) {
    while (($file = readdir($dir)) !== false) {
      if ($file != "." && $file != "..") {
        if(is_dir($trgDir.'/'.$file)){
          array_push($a, $file);
        }
      }
    }
  closedir($dir);
  return $a;
  }
}
function getFileList($dir,$ext){
    $res_dir = opendir($dir);
    $list=array();
    while( $file_name = readdir( $res_dir ) ){
        if($ext){
            $n=explode('.' , $file_name);
            if($n[1]==$ext)array_push($list,$file_name);
        }else{
            array_push($list,$file_name);
        }
    }
    closedir( $res_dir );
    return $list;
}
function sortByTimestamp($list){
    usort($list,'sortByTimestampCmp');
    return $list;
}
function sortByTimestampCmp($a,$b){
    $at=filemtime($a);
    $bt=filemtime($b);
    if($at==$bt)return 0;
    return ($at<$bt)?-1:1;
}
function echoList($list,$format){
    foreach($list as $dir){
        $n=getFileList($dir,"html");
        foreach($n as $f){
            $m=$dir . '/' . $f;
            if($format){
                echo preg_replace('/%@/',$m,$format);
            }else{
                echo $m;
            }
        }
    }
}

$dir_list=getDirList("./");
$dir_list=sortByTimestamp($dir_list);
$dir_list=array_reverse($dir_list);
echoList($dir_list,'<li><a href="%@" target="_self">%@</a></li>');

?>
</ul>

[javascript]swfobject周りテンプレ

タイトル通り

Sample

基本形

var m=get_query();
var flashvars={};
flashvars.browser=navigator.userAgent;
flashvars.id=(m.id)?m.id:'';

var params={};
params.base=".";
params.menu="false";
params.wmode="opaque";
params.allowfullscreen="false";
params.allowscriptaccess="always";

swfobject.embedSWF("swf/main.swf", "flashcontent", "100%", "100%", "9.0.45", null, flashvars, params);

 

FlashPlayerのバージョン判定だけ

swfobject.hasFlashPlayerVersion("9.0.45")

 

flashの上にhtmlを重ねる

 

動的にFlash領域の大きさを変える

$(window).bind('resize',when_window_resize);
function when_window_resize(){
    var n=$('#flashcontent');
    var wt=$(window).height();
    n.css({height:(wt-80)+'px'});
}

[jQuery]xmlを解析する

タイトル通り

Sample

 data.xml

<?xml version="1.0" encoding="UTF-8" ?>
<data>
<item id="A">あいうえお</item>
<item id="B">かきくけこ</item>
<item id="C">さしすせそ</item>
<item id="D">なにぬねの</item>
</data>

 

JavaScript

$.ajax({
    type:"GET",
    url:"data.xml",
    dataType:"xml",
    async:true,
    success:function(xml){
        $("#status").empty();
        $(xml).find("item").each(function(){
            var id=$(this).attr("id");
            var tex=$(this).text();
            $("#status").append("id:"+id+" text:"+tex+"<br/>");
        });
    }
});