Plistを利用してTableViewに表示さし該当の画像をクリックしたら画面遷移して画像を表示する方法を示しています。
Plistの設置場所は、Resourcesの中に置いています。置き場所については限定されるわけではありません。他の場所に置き動作検証済みです。
画像ファイルについても、このように同じ場所に設置しています。
Plistについては、キーなし配列型Plistを使用しています。
キー型を使用したかったのですが、iOSでは動作しましたがAndroidでの検証で動作せず落ちましたのでやむなくキーなし配列型Plistを使用して今回は、活用しています。
キーなし配列型Plistを使用しているため、あたかもキー付き配列型のような動作をするように工夫をしています。ソースはきたなくこれが正しいかはわかりませんが問題なく動作しております。
キー付き配列型Plistの問題
キー付き配列型Plistのソース記述の場合は下記の通りですが、iOSでは問題なく動作していましたがAndroid実機で検証してみたら2行目の「ValueMap vec_map_0 = vec.at(idx).asValueMap();」で落ちてしまうことが判明しました。色々と記述を変えてみましたがiOS側で落ちたりしましたのでキー付き配列型Plist読み込みを諦めキーなし配列型Plistを採用し読み込み記述を工夫しました。
Android実機で落ちたキー付き配列型Plistのソース記述例
// Plist ValueVector & ValueMap
ValueVector vec = FileUtils::getInstance()->getValueVectorFromFile("Data.plist");
ValueMap vec_map_0 = vec.at(idx).asValueMap();
std::string vec_0 = vec_map_0.at("number").asString(); //
連番
std::string vec_1 = vec_map_0.at("ItemName").asString(); // 花火の種類
std::string vec_2 = vec_map_0.at("images").asString(); //
花火の写真
std::string vec_3 = vec_map_0.at("ImageName").asString(); // 花火の小写真
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 花火小画像
Sprite* imge_1 = Sprite::create(vec_3);
imge_1->setAnchorPoint(Point(0, 0));
imge_1->setPosition(Point(10, 0));
imge_1->setScaleX(1.5); // 1.5倍拡大
imge_1->setScaleY(1.5); // 1.5倍拡大
cell->addChild(imge_1);
// テキスト部分
auto *label_2 = LabelTTF::create(vec_1.c_str(), "Arial", 52);
label_2->setAnchorPoint(Point(0, 0));
label_2->setPosition(Point(140, 70)); // セル幅のセンター
label_2->setColor(Color3B::GREEN);
cell->addChild(label_2);
Cocos2dx 3.x C++言語
AppDelegate.hを次のように変更してみてください。
解像度の設定はAppDelegate.h内にてこの一行にて記述しています。
Android実機2台での動作確認
docomo SAMSUNG GALAXY SⅢ SC-06D Android Ver 4.1.2
Nexus7 Android Ver 4.4.4
// デザイン解像度の設定(縦) iPhone 5s SHOW_ALL
glview->setDesignResolutionSize(640, 1136, ResolutionPolicy::SHOW_ALL);
#ifndef _APP_DELEGATE_H_
#define _APP_DELEGATE_H_
#include "cocos2d.h"
/**
@brief The cocos2d Application.
The reason for implement as private inheritance is to hide some interface call by Director.
*/
class AppDelegate : private cocos2d::Application
{
public:
AppDelegate();
virtual ~AppDelegate();
virtual void initGLContextAttrs();
/**
@brief Implement Director and Scene init code here.
@return true Initialize success, app continue.
@return false Initialize failed, app terminate.
*/
virtual bool applicationDidFinishLaunching();
/**
@brief The function be called when the application enter background
@param the pointer of the application
*/
virtual void applicationDidEnterBackground();
/**
@brief The function be called when the application enter foreground
@param the pointer of the application
*/
virtual void applicationWillEnterForeground();
};
#endif // _APP_DELEGATE_H_
AppDelegate.cppを次のように変更してみてください。
#include "AppDelegate.h"
#include "TopTableView.h"
USING_NS_CC;
AppDelegate::AppDelegate() {
}
AppDelegate::~AppDelegate()
{
}
//if you want a different context,just modify the value of glContextAttrs
//it will takes effect on all platforms
void AppDelegate::initGLContextAttrs()
{
//set OpenGL context attributions,now can only set six attributions:
//red,green,blue,alpha,depth,stencil
GLContextAttrs glContextAttrs = {8, 8, 8, 8, 24, 8};
GLView::setGLContextAttrs(glContextAttrs);
}
bool AppDelegate::applicationDidFinishLaunching() {
// initialize director
auto director = Director::getInstance();
auto glview = director->getOpenGLView();
if(!glview) {
glview = GLViewImpl::create("My Game");
director->setOpenGLView(glview);
}
////////////////////////////////////////
// デザイン解像度の設定(縦) iPhone 5s SHOW_ALL
glview->setDesignResolutionSize(640, 1136, ResolutionPolicy::SHOW_ALL);
////////////////////////////////////////
// turn on display FPS
//director->setDisplayStats(true);
// set FPS. the default value is 1.0/60 if you don't call this
director->setAnimationInterval(1.0 / 60);
// create a scene. it's an autorelease object
auto scene = TopTableView::createScene();
// run
director->runWithScene(scene);
return true;
}
// This function will be called when the app is inactive. When comes a phone call,it's be invoked too
void AppDelegate::applicationDidEnterBackground() {
Director::getInstance()->stopAnimation();
// if you use SimpleAudioEngine, it must be pause
// SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
}
// this function will be called when the app is active again
void AppDelegate::applicationWillEnterForeground() {
Director::getInstance()->startAnimation();
// if you use SimpleAudioEngine, it must resume here
// SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
}
TableViewを作成していきます。
TopTableView.hを次のように変更してみてください。
TopTableView.hを次のように変更してみてください。
#ifndef __TableView02__TopTableView__
#define __TableView02__TopTableView__
#include <iostream>
#include "cocos2d.h"
#include <extensions/cocos-ext.h>
USING_NS_CC;
using namespace extension;
class TopTableView : public Layer,
public TableViewDataSource,
public TableViewDelegate
{
Size window_size;
public:
static cocos2d::Scene* createScene();
virtual bool init();
//TableViewDataSourceの抽象メソッド
virtual Size cellSizeForTable(TableView* table);
virtual TableViewCell* tableCellAtIndex(TableView* table,ssize_t idx);
virtual ssize_t numberOfCellsInTableView(TableView* table);
//TableViewDelegateの抽象メソッド
virtual void tableCellTouched(TableView* table,TableViewCell* cell);
//TableViewDelegateが継承しているScrollViewの抽象メソッド
virtual void scrollViewDidScroll(ScrollView* view){};
virtual void scrollViewDidZoom(ScrollView* view){};
CREATE_FUNC(TopTableView);
// バッククリックキー
void onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event *event);
};
#endif /* defined(__TableView02__TopTableView__) */
TopTableView.cppを次のように変更してみてください。
#include "TopTableView.h"
#include "SecondScene.h"
//音をならすためにinclude
#include "SimpleAudioEngine.h"
/// 行数格納用のキー
const char* ROW_KEY = "row";
Scene* TopTableView::createScene()
{
auto scene = Scene::create();
auto layer = TopTableView::create();
// sceneにlayerを読み込み表示する
scene->addChild(layer);
return scene;
}
// on "init" you need to initialize your instance
bool TopTableView::init()
{
// 初期化
if ( !Layer::init() ) return false;
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// バックキー処理 イベントリスナーを追加
auto keyboardListener = cocos2d::EventListenerKeyboard::create();
keyboardListener->onKeyReleased = CC_CALLBACK_2(TopTableView::onKeyReleased, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// 画面サイズサイズを取得
window_size = Director::getInstance()->getWinSize();
// バックグランドカラー
auto background = LayerColor::create(Color4B::BLACK,
window_size.width,
window_size.height);
// バックグランドカラー 第2引数は表示順
this->addChild(background, 0);
// テーブル一覧ラベルを生成
auto label1 = Label::createWithSystemFont("花火一覧", "Arial", 60);
label1->setColor(Color3B::GREEN);
// ラベルの設置
label1->setPosition(Vec2(window_size.width / 2 ,window_size.height - 70));
// ラベルタイトルを呼び込み追加
this->addChild(label1,1);
// テーブルのヘッダー空間
TableView* tableView = TableView::create(this,Size(window_size.width,window_size.height*9/10));
// テーブル全体表示
//TableView* tableView = TableView::create(this, window_size);
// 展開方向
tableView->setDirection(TableView::Direction::VERTICAL);
// 表示順序上からしたへ
tableView->setVerticalFillOrder(TableView::VerticalFillOrder::TOP_DOWN);
// 追加
tableView->setDelegate(this);
addChild(tableView);
// tableViewに呼び込む
tableView->reloadData();
return true;
}
// セルの大きさを設定する
Size TopTableView::cellSizeForTable(TableView *table){
return Size(window_size.width, 215);
}
// 1セルに表示させるValueをセット
TableViewCell* TopTableView::tableCellAtIndex(TableView *table, ssize_t idx){
// 行番号
std::string id = StringUtils::format("%zd", idx);
// セル
TableViewCell *cell = table->dequeueCell();
cell = new TableViewCell();
// autoreleaseを呼び出す
cell->autorelease();
// セルの背景色
auto background_color = Color3B::GRAY;
// Background
Sprite* bg = Sprite::create();
bg->setAnchorPoint(Point(0, 0));
bg->setTextureRect(Rect(0, 0, window_size.width, 215));
bg->setColor(background_color);
bg->setTag(100);
// Backgroundを呼び出し表示
cell->addChild(bg);
// ボーダーライン
Sprite* line = Sprite::create();
line->setAnchorPoint(Point(0, 0));
line->setTextureRect(Rect(0, 0, window_size.width, 1));
line->setColor(Color3B::WHITE);
cell->addChild(line);
//////////////////////////////////////////////
// Plist ValueVector
ValueVector vec = FileUtils::getInstance()->getValueVectorFromFile("data.plist");
// セル行数変数
long idx0 = 0;
// Cell行idxをidx01に保存
log("idx:%ld", idx);
// 最初のCellの0行目
if (idx == 0) {
idx0 = idx; // 最初のCellの1行目
} else {
idx0 = idx * 4; // 次のCellの2行目 Plist行数 x 4
}
// Plist 1行目は、idx0
long idx1 = idx0 + 1; // Plist 2行目
long idx2 = idx1 + 1; // Plist 3行目 花火小画像
long idx3 = idx2 + 1; // Plist 4行目 花火大画像
// 花火の種類ラベル表示
std::string vec_1 = vec.at(idx1).asString();
auto *label_2 = LabelTTF::create(vec_1.c_str(), "Arial", 52);
label_2->setAnchorPoint(Point(0, 0));
label_2->setPosition(Point(140, 70)); // セル幅のセンター
label_2->setColor(Color3B::GREEN);
cell->addChild(label_2);
// 花火小画像
std::string vec_3 = vec.at(idx3).asString();
Sprite* imge_1 = Sprite::create(vec_3);
imge_1->setAnchorPoint(Point(0, 0));
imge_1->setPosition(Point(10, 0));
imge_1->setScaleX(1.5); // 1.5倍拡大
imge_1->setScaleY(1.5); // 1.5倍拡大
cell->addChild(imge_1);
return cell;
}
// セル数
ssize_t TopTableView::numberOfCellsInTableView(TableView *table){
return 19;
}
// セルがタッチされた時のcallback
void TopTableView::tableCellTouched(TableView* table, TableViewCell* cell){
log("%ziのセルがタッチされました", cell->getIdx());
// cell 行番号
float row = cell->getIdx();
////////////////////////////////////////////////
// UserDefault 保存
// 行番号保存
UserDefault::getInstance()->setIntegerForKey(ROW_KEY, row);
////////////////////////////////////////////////
// 効果音を鳴らす
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("onepoint26.mp3");
// 遷移先の画面のインスタンス
Scene *pScene = SecondScene::createScene();
// 0.5秒かけてフェードアウトしながら次の画面に遷移します
// 引数1:フィードの時間
// 引数2:移動先のシーン
// 引数3:フィードの色(オプション)
TransitionFade* transition = TransitionFade::create(0.5f, pScene);
// 遷移実行 遷移時のアニメーション http://study-cocos2d-x.info/scenelayer/55/
// 直前のsceneはもう使わないから捨ててしまう方法。基本はこれになります。
Director::getInstance()->replaceScene(transition);
}
// バックキー処理 onKeyReleased()でバックキーのイベントを取得
void TopTableView::onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event * event)
{
if (keyCode == EventKeyboard::KeyCode::KEY_ESCAPE)
{
Director::getInstance()->end(); // アプリを終了させる
}
}
画像表示作成していきます。
SecondScene.hを次のように変更してみてください。
SecondScene.hを次のように変更してみてください。
#ifndef __TableView02__SecondScene__
#define __TableView02__SecondScene__
#include "cocos2d.h"
class SecondScene : public cocos2d::Layer
{
public:
//初期化のメソッド
virtual bool init();
static cocos2d::Scene* createScene();
// スタートボタン押下時の処理宣言 戻る Object → Ref に変更
void pushBack(cocos2d::Ref *pSender);
// create()を使えるようにしている。
CREATE_FUNC(SecondScene);
// バッククリックキー
void onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event *event);
};
#endif /* defined(__TableView02__SecondScene__) */
SecondScene.cppを次のように変更してみてください。
#include "SecondScene.h"
#include "TopTableView.h"
//音をならすためにinclude
#include "SimpleAudioEngine.h"
// 名前空間 #define USING_NS_CC using namespace cocos2d
USING_NS_CC;
using namespace std; // String*
Scene* SecondScene::createScene()
{
// 「シーン」は自動解放オブジェクトです
auto scene = Scene::create();
// 「レイアウト」は自動解放オブジェクトです
auto layer = SecondScene::create();
// シーンに子としてレイヤーを追加
scene->addChild(layer);
// シーンを返す
return scene;
}
// 「INIT」初期化
bool SecondScene::init()
{
if ( !Layer::init() )
{
return false;
}
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// バックキー処理 イベントリスナーを追加
auto keyboardListener = cocos2d::EventListenerKeyboard::create();
keyboardListener->onKeyReleased = CC_CALLBACK_2(SecondScene::onKeyReleased, this);
_eventDispatcher->addEventListenerWithSceneGraphPriority(keyboardListener, this);
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
//画面の座標関係の詳しい説明はここ http://www.cocos2d-x.org/wiki/Coordinate_System
//画面サイズを取得
Size winSize = Director::getInstance()->getVisibleSize();
Point origin = Director::getInstance()->getVisibleOrigin();
// バックグランドカラー
auto background = LayerColor::create(Color4B::BLUE,
winSize.width,
winSize.height);
//バックグランドカラー追加 第2引数は表示順
this->addChild(background, 0);
// UserDefault 読込 LOG表示
auto userRead = cocos2d::UserDefault::getInstance();
log("row 行番号: %d", userRead->getIntegerForKey("row"));
// int型 UserDefaultのrowを呼び込む
auto row = userRead->getIntegerForKey("row");
//////////////////////////////////////////////
// Plist ValueVector
ValueVector vec = FileUtils::getInstance()->getValueVectorFromFile("data.plist");
// row行数変数
long idx0 = 0;
// 最初の0行目を選択した時
if (row == 0) {
idx0 = row; // 最初のCellの1行目
} else {
idx0 = row * 4; // 次のCellの2行目 Plist行数 x 4
}
// Plist 1行目は、idx0 = row 連番
long idx1 = idx0 + 1; // Plist 2行目 花火の種類
long idx2 = idx1 + 1; // Plist 3行目 花火の写真
long idx3 = idx2 + 1; // Plist 4行目 花火の小写真
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// Plist 花火の写真画像CCSpriteクラスを初期化しています。
std::string vec_3 = vec.at(idx2).asString();
auto sprite1 = Sprite::create(vec_3);
//位置を設定
sprite1->setPosition(Vec2(winSize.width/2, winSize.height/2));
//画面に追加をしています。
this->addChild(sprite1);
//_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/_/
// Plist 花火の種類タイトルを設置
std::string vec_1 = vec.at(idx1).asString();
auto lbl_title = Label::createWithSystemFont(vec_1, "Arial", 40);
lbl_title->setPosition(Point(origin.x + winSize.width/2,
origin.y + winSize.height - 8
-lbl_title->getContentSize().height));
lbl_title->setColor(Color3B::GREEN);
this->addChild(lbl_title,1);
//戻るボタンを設置
auto backButton = MenuItemImage::create(
"Back.png", //表示
"BackSelected.png", //タップ時の画像
CC_CALLBACK_1(SecondScene::pushBack, this));
backButton->setPosition(Point(winSize.width /2 - 260 ,winSize.height/2 + 520));
//create menu, it's an autorelease object
auto menu = Menu::create(backButton, NULL);
menu->setPosition(Point::ZERO);
this->addChild(menu, 1);
return true;
}
// pushBackボタン
void SecondScene::pushBack(Ref *pSender)
{
// 効果音を鳴らす
CocosDenshion::SimpleAudioEngine::getInstance()->playEffect("onepoint26.mp3");
// 遷移先の画面のインスタンス
Scene *pScene = TopTableView::createScene();
// 0.5秒かけてフェードアウトしながら次の画面に遷移します
// 引数1:フィードの時間
// 引数2:移動先のシーン
// 引数3:フィードの色(オプション)
TransitionFade* transition = TransitionFade::create(0.5f, pScene);
//遷移実行 遷移時のアニメーション http://study-cocos2d-x.info/scenelayer/55/
Director::getInstance()->replaceScene(transition);
}
// バックキー処理 onKeyReleased()でバックキーのイベントを取得
void SecondScene::onKeyReleased(cocos2d::EventKeyboard::KeyCode keyCode, cocos2d::Event * event)
{
if (keyCode == EventKeyboard::KeyCode::KEY_ESCAPE)
{
//Director::getInstance()->end(); // アプリを終了させる
// 遷移先の画面のインスタンス
Scene *pScene = TopTableView::createScene();
// 0.5秒かけてフェードアウトしながら次の画面に遷移します
// 引数1:フィードの時間
// 引数2:移動先のシーン
// 引数3:フィードの色(オプション)
TransitionFade* transition = TransitionFade::create(0.5f, pScene);
//遷移実行 遷移時のアニメーション http://study-cocos2d-x.info/scenelayer/55/
// (replaceScene)直前のsceneはもう使わないから捨ててしまう方法
Director::getInstance()->replaceScene(transition);
}
}
GitHub TableView02
Androidのビルドに必要なAndroid.mkの編集
クラスを追加した場合には、Android.mkファイルの修正が必要です。
HelloWorld.cppの書き換えと追加クラス名を追加します。
これをしておかないと表示が変わらず真黒な画面が表示されますので注意してください。
Android.mkディレクトリーの場所
TableView02/proj.android/jni/Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/external)
$(call import-add-path,$(LOCAL_PATH)/../../cocos2d/cocos)
LOCAL_MODULE := cocos2dcpp_shared
LOCAL_MODULE_FILENAME := libcocos2dcpp
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp
\
../../Classes/TopTableView.cpp \
<- ※HelloWorld.cppを書き換え
../../Classes/SecondScene.cpp <-
※追加
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes
LOCAL_STATIC_LIBRARIES := cocos2dx_static
include $(BUILD_SHARED_LIBRARY)
$(call import-module,.)
Android実機での動作確認
docomo SAMSUNG GALAXY SⅢ SC-06D Android Ver 4.1.2
Nexus7 Android Ver 4.4.4
▫️参考にしたページ
Cocos2dx 3.0でPLISTを解析できませんCocos2dx 3.0でPLISTを解析できません
コメントをお書きください