【cocos2d-x】Spineスケルタルアニメーションを左右反転
Spineで作成したスケルタルアニメーションを左右反転する方法です。
(環境:cocos2d-x-3.2, spine 1.9.15)
ランタイムのドキュメントにある Skeleton > flipX,flipY というフィールドが左右反転に使えます。
SkeletonAnimation* animation = SkeletonAnimation::createWithFile("spine.json", "spine.atlas", 0.20f); /* 以下のようにして向きを変更できます 反転させるには1.0を指定。元のままの場合は0.0。 */ float flip = 1.0f; animation->skeleton->flipX = flip; animation->setAnimation(1, "idle", true);
以上です。
※参考:
Spine cocos2d-xランタイムドキュメント:http://ja.esotericsoftware.com/spine-using-runtimes
関係ないですけど、spineのatlasファイルの「size: 〜,〜」っていう行があると、spineアニメーション生成時にエラーが発生します。
この行を消すとエラーは解消されますが、他に対処法はないのでしょうか。。
【Objective-C】UICollectionViewでのページスクロール
UICollectionViewをページスクロールにしたいときのメモです。
(環境:xcode5.1.1, iOS 7.1)
pagingEnabled = YES とすればできますが、各セルの間に間隔をいれたいときは、これだと表示位置がずれていってしまいます。
そこで、UICollectionViewFlowLayout (UICollectionViewのレイアウトをカスタマイズできるクラス) を継承したクラスを作成し、セルが画面の中央に常にくるように処理を書きます。
targetContentOffsetForProposedContentOffset::メソッドをオーバーライドします。
下記の例は、1列のシンプルなコレクションビューで、セルの真ん中(x軸)が画面の真ん中にくるように設定しています。
/*HogeCollectionViewFlowLayout.m*/ - (CGPoint)targetContentOffsetForProposedContentOffset:(CGPoint)proposedContentOffset withScrollingVelocity:(CGPoint)velocity { CGFloat offsetAdjustment = MAXFLOAT; CGFloat horizontalCenter = proposedContentOffset.x + (CGRectGetWidth(self.collectionView.bounds) / 2.0); CGRect targetRect = CGRectMake(proposedContentOffset.x, 0.0, self.collectionView.bounds.size.width, self.collectionView.bounds.size.height); NSArray* array = [self layoutAttributesForElementsInRect:targetRect]; for (UICollectionViewLayoutAttributes* layoutAttributes in array) { if (layoutAttributes.representedElementCategory != UICollectionElementCategoryCell) continue; CGFloat itemHorizontalCenter = layoutAttributes.center.x; offsetAdjustment = itemHorizontalCenter - horizontalCenter; layoutAttributes.alpha = 0; if (velocity.x < 0) break; } return CGPointMake(proposedContentOffset.x + offsetAdjustment, proposedContentOffset.y); }
また、ページングの動作に近くするため、UICollectionViewクラスでスクロールの速度を速くします。
/*HogeCollectionViewController.m*/ //viewDidLoadなどで... self.collectionView.decelerationRate = UIScrollViewDecelerationRateFast;
以上です。
【Android】画像をローディング(ぐるぐる)にする
ローディングを使う際、AndroidではProgressBarのスタイルを progressBarStyle に設定することでデフォルトのぐるぐる部品が表示されます。そのぐるぐる画像を変えたいときのメモです。
(環境:android 4.2, 確認端末:F-03F)
こちらのサイトをそのまま使えばOKでした。
まず、custom_progress_background.xml (名前は何でもいいです)を用意し、drawableフォルダに格納します。
上記サイトの例では2つの画像を用意してそれらが逆向きに回るローディングを作成しています。
<?xml version="1.0" encoding="utf-8"?> <layer-list xmlns:android="http://schemas.android.com/apk/res/android"> <item> <rotate android:drawable="@drawable/spinner_outer" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="0" android:toDegrees="1080" /> </item> <item> <rotate android:drawable="@drawable/spinner_inner" android:pivotX="50%" android:pivotY="50%" android:fromDegrees="720" android:toDegrees="0" /> </item> </layer-list>
画像をdrawableフォルダにいれます。
あとは呼び出したいアクティビティで作成したプログレスバーを指定します。
<ProgressBar android:id="@+id/custom_progress" android:indeterminate="true" style="?android:attr/progressBarStyleLarge" android:layout_width="210dip" android:layout_height="210dip" android:layout_gravity="center" android:indeterminateDrawable="@drawable/custom_progress_background" />
- イメージ
以上です。
※参考
http://pankajchunchun.wordpress.com/2011/09/10/customization-of-spinner-progress/
【cocos2d-x】picojsonでJSONファイルを読み込む
cocos2d-x 3.x になってから2.x系から大幅に変更があって戸惑いました。(クラス名の頭からCCがとれたからそう感じるだけでしょうか。)
ローカルのjsonを読み込むメモです。cocos2d-xプロジェクトへ追加したjsonを使用します。
picojsonというjsonをパースしてくれる便利なライブラリを使います。
(環境:xcode5.1, cocos2d-x-3.1rc0)
{ "hoge" :[ {"x":1, "y":1, "z":1}, {"x":2, "y":1, "z":1} ] }
- jsonの読込み
//ファイルパスの取得 FileUtils* fileUtils = FileUtils::getInstance(); const char* path = "hogehoge.json"; std::string fullpath = fileUtils->fullPathForFilename(path); // ファイルオープン ifstream inputStream; string thisLine; inputStream.open(fullpath.c_str()); if (!inputStream.is_open()) { cerr << "cannot open file!" << endl; exit(1); } stringstream sstream; while (getline(inputStream, thisLine)) { sstream << thisLine; } inputStream.close(); cout << "finish opening file!" << endl; CCLOG("sstream:%s", sstream.str().c_str()); // JSONのパース picojson::value v; picojson::parse(v, sstream); picojson::object& all = v.get<picojson::object>(); picojson::array& array = all["hoge"].get<picojson::array>(); for (picojson::array::iterator it = array.begin(); it != array.end(); it++) { picojson::object& tmpObject = it->get<picojson::object>(); int x = (int)tmpObject["x"].get<double>(); int y = (int)tmpObject["y"].get<double>(); int z = (int)tmpObject["z"].get<double>(); CCLOG("x:%d, y:%d, z:%d", x, y, z); }
以上です。
参考
http://taichino.com/programming/2068
http://nirasan.hatenablog.com/entry/2013/10/24/232905
http://stackoverflow.com/questions/12171445/file-i-o-using-cocos2d-x
【cocos2d-x】CCScrollViewでページスクロール
スクロールビューを使って、ページ切り替えをしたいときのメモです。
(環境:xcode5.1, cocos2d-x 2.2.2)
iPhone開発ではUIScrollViewにpagingEnabledというプロパティがあり、これをオンにするだけで実装可能ですが、cocos2d-xでは同じようなプロパティはないみたいです。
なのでCCScrollViewを少しいじってページ切り替えを出来るようにします。
まずヘッダーを編集します。以下の宣言を追加します。
/** * CCScrollView.h */ //...略 public: bool isPagingEnabled() { return _isPagingEnabled; } void setEnablePaging(bool isPagingEnabled) { _isPagingEnabled = isPagingEnabled; } void setPageSize(CCSize _pageSize){ pageSize = _pageSize; } CCSize getPageSize(){ return pageSize; } protected: bool _isPagingEnabled; CCSize pageSize; //略...
次にrelocateContatiner(bool animated)というメソッドに以下のように追記します。
/** * CCScrollView.cpp */ void CCScrollView::relocateContainer(bool animated) { //...略 newX = oldPoint.x; newY = oldPoint.y; // ここから { if (_isPagingEnabled) { int horizontalPageNum = roundf(newX / pageSize.width); int verticalPageNum = roundf(newY / pageSize.height); if (m_eDirection == kCCScrollViewDirectionBoth || m_eDirection == kCCScrollViewDirectionHorizontal){ newX = horizontalPageNum * pageSize.width; } if (m_eDirection == kCCScrollViewDirectionBoth || m_eDirection == kCCScrollViewDirectionVertical){ newY = verticalPageNum * pageSize.height; } } } // ここまで追記 if (m_eDirection == kCCScrollViewDirectionBoth || m_eDirection == kCCScrollViewDirectionHorizontal) { newX = MAX(newX, min.x); newX = MIN(newX, max.x); } //略... }
実際にスクロールビューを使うときには以下のようにして、ページ切替機能をオンにしてあげます。
CCScrollView *scrollView = CCScrollView::create(CCSize(visibleSize.width, visibleSize.height)); // スクロールビューをお好みで設定... scrollView->setEnablePaging(true);
以上です。
※参考
http://blackxxxwhite.blogspot.jp/2013/07/cocos2d-x-ccscrollview-semi-paging.html
- 2014/8/9追記
cocos2d-x-3.x以降の場合は下記のようにします。
/** * CCScrollView.h */ //...略 public: bool isPagingEnabled() { return _isPagingEnabled; } void setEnablePaging(bool isPagingEnabled) { _isPagingEnabled = isPagingEnabled; } void setPageSize(Size _pageSize){ pageSize = _pageSize; } Size getPageSize(){ return pageSize; } protected: bool _isPagingEnabled; Size pageSize; //...略
/** * CCScrollView.cpp */ void CCScrollView::relocateContainer(bool animated) { //...略 newX = oldPoint.x; newY = oldPoint.y; // ここから { if (_isPagingEnabled) { int horizontalPageNum = roundf(newX / pageSize.width); int verticalPageNum = roundf(newY / pageSize.height); if (_direction == Direction::BOTH || _direction == Direction::HORIZONTAL){ newX = horizontalPageNum * pageSize.width; } if (_direction == Direction::BOTH || _direction == Direction::VERTICAL){ newY = verticalPageNum * pageSize.height; } } } // ここまで追記 if (_direction == Direction::BOTH || _direction == Direction::HORIZONTAL) { newX = MAX(newX, min.x); newX = MIN(newX, max.x); } //略... }
【Android】ExpandableListViewの文字色を変える
これからはAndroidの開発メモも残していきます(次の案件がAndroidなので。。)
AndroidSDK付属のレイアウト(android.R.layout.simple_expandable_list_item_1, android.R.layout.simple_expandable_list_item_2)を使ってExpandableListViewをつくる際に、文字色を変える方法です。
(環境:Android4.2.2)
SimpleExpandableListAdapterをオーバーライドします。
※ExpandableListViewの基本的な使い方は、ここを参考にしました。
SimpleExpandableListAdapter adapter = new SimpleExpandableListAdapter( getApplicationContext(), groupData, android.R.layout.simple_expandable_list_item_1, new String[] {"group"}, new int[] {android.R.id.text1}, childData, android.R.layout.simple_expandable_list_item_2, new String[] {"name", "group"}, new int[] {android.R.id.text1, android.R.id.text2}) { @Override public View getChildView(int groupPosition, int childPosition, boolean isLastChild, View convertView, ViewGroup parent) { final View itemRenderer = super.getChildView(groupPosition, childPosition, isLastChild, convertView, parent); final TextView tv1 = (TextView)itemRenderer.findViewById(android.R.id.text1); final TextView tv2 = (TextView)itemRenderer.findViewById(android.R.id.text2); tv1.setTextColor(0xff000000); // 子リストのタイトルは黒に設定 tv2.setTextColor(0xff0000ff); // 子リストのサブタイトルは青に設定 return itemRenderer; } @Override public View getGroupView(int groupPosition, boolean isExpanded, View convertView, ViewGroup parent) { final View itemRenderer = super.getGroupView(groupPosition, isExpanded, convertView, parent); final TextView tv1 = (TextView)itemRenderer.findViewById(android.R.id.text1); tv1.setTextColor(0xff0000ff); // 親リストのタイトルは青に設定 return itemRenderer; } }; ExpandableListView listView = (ExpandableListView)findViewById(R.id.hogelistView); listView.setAdapter(adapter);
以上です。
【Objective-C】SDWebImageで画像サイズを変える
SDWebImageはFacebookアプリにも使われていると言われている、ものすご便利〜なライブラリです。
- SDWebImage
https://github.com/rs/SDWebImage
サーバーからイメージを取得する前に、アプリ側で画像サイズ変えられないですか?みたいな事態が生じたので、めんどくさいな〜と思いつつ、方法を探してみました。デリゲートメソッドを使用する方法です。
まずヘッダファイルではSDWebImageManagerDelegateプロトコルを採用します。
// HogeFugaViewController.h @interface HogeFugaViewController : UITableViewController <SDWebImageManagerDelegate>
どこかでデリゲートを設定します。
// HogeFugaViewController.m // webイメージ読み込みデリゲート設定 SDWebImageManager.sharedManager.delegate = self;
デリゲートメソッドを実装します。
// HogeFugaViewController.m - (UIImage *)imageManager:(SDWebImageManager *)imageManager transformDownloadedImage:(UIImage *)image withURL:(NSURL *)imageURL { /*イメージをリサイズする*/ CGSize resizedImageSize = CGSizeMake(50, 50); UIGraphicsBeginImageContextWithOptions(resizedImageSize, NO, 0.0); [image drawInRect:CGRectMake(0, 0, resizedImageSize.width, resizedImageSize.height)]; UIImage* resizedImage = UIGraphicsGetImageFromCurrentImageContext(); UIGraphicsEndImageContext(); image = resizedImage; return image; }
上記のように実装するとSDWebImageライブラリを使って画像を設定する際、画像がキャッシュに保存される前にイメージをリサイズしてくれます。
NSURL* url = /*イメージのURL*/; UIImage* placeholder = /*プレースホルダイメージ*/; [cell.hogeImage setImageWithURL:url placeholderImage:placeholder];
しかし、上記の対応だけではSDWebImageでキャッシュするイメージがスケール1.0で保存されてしまっていました。。
SDWebImageライブラリだとURLに @2x という名前がないとUIImageのスケールが 1.0 で保存されるっぽいです。(ちゃんとは確かめてません)
スクリーンのスケールからRetinaディスプレイかどうか判断して,Retinaディスプレイの場合はUIImageのスケールを2倍に設定し直すようにライブラリを修正しました。(微妙な対応ですね。。もっといい方法はないでしょうか)
// UIImageView+WebCache.m - (void)setImageWithURL:(NSURL *)url placeholderImage:(UIImage *)placeholder options:(SDWebImageOptions)options progress:(SDWebImageDownloaderProgressBlock)progressBlock completed:(SDWebImageCompletedBlock)completedBlock { /*略*/ if (!wself) return; dispatch_main_sync_safe(^{ if (!wself) return; if (image) { //ここから if ([UIScreen mainScreen].scale == 2.0) { wself.image = [UIImage imageWithCGImage:image.CGImage scale:2.0f orientation:UIImageOrientationUp]; } else { //ここまで追記 wself.image = image; } [wself setNeedsLayout]; } /*略*/ }
以上です。
※補足
上記の例ではイメージのサイズを幅50、高さ50で固定でしたので、以下のライブラリを使えば出来そうです。
https://github.com/toptierlabs/ImageCacheResize
ただし、動的にサイズを変えたいときはデリゲートを使うのが良さそうです。
■参考ページ
https://github.com/rs/SDWebImage
http://hackemist.com/SDWebImage/doc/Protocols/SDWebImageManagerDelegate.html#//api/name/imageManager:transformDownloadedImage:withURL:
http://stackoverflow.com/questions/12928103/sdwebimage-process-images-before-caching