CocoStudio sample讲解 DemoShop商店界面
CocoStuido sample----DemoShop源代码地址
https://github.com/chukong/CocoStudioSamples
大家可以预先下载这个源代码, 本教程所有内容均包含在内
一、目标
本节目标是做一个商店界面,包括商品的展示和购买,用户的交互以及动态改变购买的物品属性。效果如下图:
<img title = '01.gif' src='http://cdn.cocimg.com/bbs/attachment/Fid_48/48_183396_9552c0d64d139b0.gif' >
二、分析界面
本节的内容较为复杂,开始之前我们分解一下界面,这个商品demo分为主窗口层、商品层、排行榜层、购买弹出层。
<img title = '2.png' src='http://cdn.cocimg.com/bbs/attachment/Fid_48/48_183396_c91c7d022ecf472.png' >
三、构建界面
打开UI编辑器,创建一个新的UI工程,起名为“DemoShop”,资源可以在示例中获取。
开始编辑之前先把给根节点配置一个背景图片,接下来就可以开始布局界面了。
如上图所示,出来有两个文本作为标题外还有两个滚动层及右下角一个按钮。这样就完成了主体,下面制作物品单元,由于界面中的所有商品单元都是十分类似,所以我们可以先制作一个,然后采用复制并逐个调整的办法。
下图中是用一个panel中添加的所有子控件,为了清晰暂未给容器添加背景。
添加完成子控件后可以配置容器的图片,然后记得将颜色混合设置为“无颜色”。
接下来是复制单元格,开始复制前先将这个单元格拖动到对应滚动层内,注意这里说的不是位置上的关系的“内”,而是层级关系的“内”。
将单元格复制到左侧的商品层内就可以开始使用复制的功能了,这里可以使用“Ctrl+C”、“Ctrl+V”来快速完成。这里注意由于每一次复制后的空间都会保持跟原控件相同,所以每一次复制都要将复制后的控件移动到其他位置,复制完成后可以通过布局快捷键快速的调整位置。
如选中左侧的4个单元个,分别设置纵向对其、纵向等距即可快速的调整到合适位置。
接下来是右侧的滚动层,我们也可以先将一个单元格拖入到右侧的滚动层,保证在层级关系和位置都在右侧的滚动层内,如下图:
右侧的列表是一个可以滚动的容器,里面包含了8个单元格,明显超出了显示的区域,我们需要先将滚动层的“滚动区域高度”设置大于滚动层本身的高度。如下图:
快速复制控件并调整位置,商品的界面完成,制作完成后就可以勾选“裁剪”属性,这样滚动层超出自身区域的内容将不会显示,清理滚动层的背景颜色。将两个滚动层的颜色设置为“无颜色”。
下面还剩一个弹出层,这个弹出层虽然内容较多,但是都是前面介绍过的内容,这里不做细述。制作完成后将其放置在画布中央并隐藏即可。
注意,由于本示例中控件非常多,关于给每一个控件的命名请自行参考示例程序,如果是自己定义的,一定要在程序中修改对应控件的名称。
四、代码实现
头文件(定义宏及全局变量)
#ifndef __TestCpp__CocosGUIExamplesWeaponScene__
#define __TestCpp__CocosGUIExamplesWeaponScene__
#include "cocos2d.h"
#include "cocos-ext.h"
//#include "../../testBasic.h"
USING_NS_CC;
USING_NS_CC_EXT;
using namespace gui;
#define WEAPON_ITEM_LAYOUT_TAG 1
//shop中两个滚动层子容器的item起始tag值
#define SHOP_ITEM_LAYOUT_TAG 100
#define RANKING_ITEM_LAYOUT_TAG 200
//定义三种货币的默认金额
#define COUPON_MAX 300
#define BINDING_MAX 400
#define MEDAL_MAX 500
class CocosGUIExamplesWeaponScene : public CCScene
{
public:
CocosGUIExamplesWeaponScene();
~CocosGUIExamplesWeaponScene();
virtual void onEnter();
virtual void onExit();
protected:
// a selector callback
void menuCloseCallback(CCObject* pSender, TouchEventType type);
// shop
void ShopInit();
// popup
void popupInit();
void popupClose(CCObject* pSender, TouchEventType type);
void popupLogic(CCObject* pSender, TouchEventType type);
void popupCalculate(CCObject* pSender, TouchEventType type);
protected:
TouchGroup* m_pUILayer;
int m_nIndex;//记录点击的物品层索引
int m_nCount;//全局记录购买数量
int m_nCoupon;//优惠券的数额
int m_nBinding;//绑定的金钱数额
int m_nMedal;//奖励的金钱数额
};
#endif /* defined(__TestCpp__CocosGUIExamplesWeaponScene__) */
实现文件
#include "CocosGUIExamplesWeaponScene.h"
//商品图片索引
const char* shop_textures =
{
"cocosgui/gui_examples/DemoShop/armour.png",
"cocosgui/gui_examples/DemoShop/helmet.png",
"cocosgui/gui_examples/DemoShop/shield.png",
"cocosgui/gui_examples/DemoShop/sword.png",
"cocosgui/gui_examples/DemoShop/gloves.png",
"cocosgui/gui_examples/DemoShop/dimensity.png",
"cocosgui/gui_examples/DemoShop/dart.png",
"cocosgui/gui_examples/DemoShop/backpack.png",
};
//商品名称数组
const char* shop_names =
{
"Armour",
"Helmet",
"Shield",
"Sword",
"Gloves",
"Dimensity",
"Dart",
"Backpack",
};
//商品种类数组
const char* shop_price_units =
{
"Counpon",
"Binding",
"Medal",
"Counpon",
"Binding",
"Medal",
"Counpon",
"Binding",
};
//商品价格索引
const int shop_prices =
{
19,
10,
22,
20,
8,
17,
5,
4,
};
//初始化函数
CocosGUIExamplesWeaponScene::CocosGUIExamplesWeaponScene()
: m_nIndex(-1)
, m_nCount(0)
, m_nCoupon(COUPON_MAX)
, m_nBinding(BINDING_MAX)
, m_nMedal(MEDAL_MAX)
{
CCScene::init();
}
//析构函数
CocosGUIExamplesWeaponScene::~CocosGUIExamplesWeaponScene()
{
}
//进入场景
void CocosGUIExamplesWeaponScene::onEnter()
{
CCScene::onEnter();
m_pUILayer = TouchGroup::create();
m_pUILayer->scheduleUpdate();
addChild(m_pUILayer);
ShopInit();
popupInit();
// BuyInit();
}
//退出场景
void CocosGUIExamplesWeaponScene::onExit()
{
//移除主体层
m_pUILayer->removeFromParent();
//清理内存
SceneReader::sharedSceneReader()->purge();
GUIReader::shareReader()->purge();
cocos2d::extension::ActionManager::shareManager()->purge();
CCScene::onExit();
}
//关闭按钮回调方法
void CocosGUIExamplesWeaponScene::menuCloseCallback(CCObject* pSender, TouchEventType type)
{
//判断点击抬起,如果抬起执行结束
if (type == TOUCH_EVENT_ENDED)
{
CCDirector::sharedDirector()->end();
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
exit(0);
#endif
}
}
// 初始化画面
void CocosGUIExamplesWeaponScene::ShopInit()
{
// 从json文件加载UI界面
Layout* shop_root = static_cast<Layout*>(GUIReader::shareReader()->widgetFromJsonFile("cocosgui/gui_examples/DemoShop/DemoShop.json"));
m_pUILayer->addWidget(shop_root);
//获取左侧商品层
ScrollView* shop_scrollview = static_cast<ScrollView*>(shop_root->getChildByName("shop_ScrollView"));
//遍历所有的子容器
for (int i = 0; i < shop_scrollview->getChildren()->count(); ++i)
{
//获取指定索引的子容器
Layout* shop_layout = static_cast<Layout*>(shop_scrollview->getChildren()->objectAtIndex(i));
shop_layout->setTag(SHOP_ITEM_LAYOUT_TAG + i);
//查找指定容器内的名为“buy_Button”按钮
Button* buy_button = static_cast<Button*>(shop_layout->getChildByName("buy_Button"));
buy_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesWeaponScene::popupLogic));
}
// 获取右侧排行榜层
ScrollView* ranking_scrollview = static_cast<ScrollView*>(shop_root->getChildByName("ranking_ScrollView"));
//遍历排行榜内的子容器
for (int i = 0; i < ranking_scrollview->getChildren()->count(); ++i)
{
Layout* ranking_layout = static_cast<Layout*>(ranking_scrollview->getChildren()->objectAtIndex(i));
for (int j = 0; j < shop_scrollview->getChildren()->count(); ++j)
{
Layout* shop_layout = static_cast<Layout*>(shop_scrollview->getChildren()->objectAtIndex(j));
if (strcmp(ranking_layout->getName(), shop_layout->getName()) == 0)
{
ranking_layout->setTag(RANKING_ITEM_LAYOUT_TAG + (shop_layout->getTag() - SHOP_ITEM_LAYOUT_TAG));
}
}
}
for (int i = 0; i < ranking_scrollview->getChildren()->count(); ++i)
{
Layout* ranking_layout = static_cast<Layout*>(ranking_scrollview->getChildren()->objectAtIndex(i));
// 购买按钮
Button* buy_button = static_cast<Button*>(ranking_layout->getChildByName("buy_Button"));
buy_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesWeaponScene::popupLogic));
}
// 获取返回按钮并添加事件监听(右下角按钮)
Button* back_button = static_cast<Button*>(shop_root->getChildByName("back_Button"));
back_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesWeaponScene::menuCloseCallback));
}
//初始化弹出框
void CocosGUIExamplesWeaponScene::popupInit()
{
// 获取弹出框
Layout* buy_layout = static_cast<Layout*>(m_pUILayer->getWidgetByName("buy_Panel"));
// 添加数量按钮
Button* add_button = static_cast<Button*>(buy_layout->getChildByName("add_Button"));
add_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesWeaponScene::popupCalculate));
// 减少数量按钮
Button* sub_button = static_cast<Button*>(buy_layout->getChildByName("sub_Button"));
sub_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesWeaponScene::popupCalculate));
//
LabelAtlas* number_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("number_LabelAtlas"));
number_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nCount)->getCString());
// coupon number labelatlas
LabelAtlas* couponNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("coupon_number_LabelAtlas"));
couponNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nCoupon)->getCString());
// binding number labelatlas
LabelAtlas* bindingNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("binding_number_LabelAtlas"));
bindingNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nBinding)->getCString());
// medal number labelatlas
LabelAtlas* medalNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("medal_number_LabelAtlas"));
medalNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nMedal)->getCString());
// 购买按钮
Button* buy_button = static_cast<Button*>(buy_layout->getChildByName("buy_Button"));
buy_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesWeaponScene::popupClose));
buy_button->setTouchEnabled(true);
// 关闭按钮
Button* close_button = static_cast<Button*>(buy_layout->getChildByName("close_Button"));
close_button->addTouchEventListener(this, toucheventselector(CocosGUIExamplesWeaponScene::popupClose));
}
//点击弹出框的关闭按钮的事件
void CocosGUIExamplesWeaponScene::popupClose(CCObject *pSender, TouchEventType type)
{
if (type == TOUCH_EVENT_ENDED)
{
//查找购买弹出框并隐藏
Layout* buy_layout = static_cast<Layout*>(m_pUILayer->getWidgetByName("buy_Panel"));
buy_layout->setVisible(false);
// process shop ranking touchEnabled
CCObject* obj = NULL;
//左侧商品滚动层
ScrollView* shop_scrollview = static_cast<ScrollView*>(m_pUILayer->getWidgetByName("shop_ScrollView"));
//遍历控件,
CCARRAY_FOREACH(shop_scrollview->getChildren(), obj)
{
Layout* shop_layout = static_cast<Layout*>(obj);
// 将所有的buy_button设置为可点击
Button* buy_button = static_cast<Button*>(shop_layout->getChildByName("buy_Button"));
buy_button->setTouchEnabled(true);
}
// 排行榜层
ScrollView* ranking_scrollview = static_cast<ScrollView*>(m_pUILayer->getWidgetByName("ranking_ScrollView"));
// ranking scrollview children
CCARRAY_FOREACH(ranking_scrollview->getChildren(), obj)
{
Layout* ranking_layout = static_cast<Layout*>(obj);
//
Button* buy_button = static_cast<Button*>(ranking_layout->getChildByName("buy_Button"));
buy_button->setTouchEnabled(true);
}
}
}
//弹出购买层
void CocosGUIExamplesWeaponScene::popupLogic(CCObject *pSender, TouchEventType type)
{
if (type == TOUCH_EVENT_ENDED)
{
Widget* widget = static_cast<Widget*>(pSender);
Widget* parent = static_cast<Widget*>(widget->getParent());
// buy layout
Layout* buy_layout = static_cast<Layout*>(m_pUILayer->getWidgetByName("buy_Panel"));
buy_layout->setVisible(true);
// icon imageview
ImageView* icon_imageview = static_cast<ImageView*>(buy_layout->getChildByName("icon_ImageView"));
// name labelBMFont
LabelBMFont* name_labelBMFont = static_cast<LabelBMFont*>(buy_layout->getChildByName("name_LabelBMFont"));
// price unit labelBMFont
LabelBMFont* priceUnit_labelBMFont = static_cast<LabelBMFont*>(buy_layout->getChildByName("price_unit_LabelBMFont"));
// price labelBMFont
LabelBMFont* price_labelBMFont = static_cast<LabelBMFont*>(buy_layout->getChildByName("price_LabelBMFont"));
ScrollView* shop_scrollview = static_cast<ScrollView*>(m_pUILayer->getWidgetByName("shop_ScrollView"));
ScrollView* ranking_scrollview = static_cast<ScrollView*>(m_pUILayer->getWidgetByName("ranking_ScrollView"));
int tag = parent->getTag();
int index = 0;
//通过点击的按钮tag值设置index值,用于加载不同的图片
if (tag >= SHOP_ITEM_LAYOUT_TAG && tag <= shop_scrollview->getChildren()->count() + SHOP_ITEM_LAYOUT_TAG)
{
index = tag - SHOP_ITEM_LAYOUT_TAG;
}
else if (tag >= RANKING_ITEM_LAYOUT_TAG && tag <= ranking_scrollview->getChildren()->count() + RANKING_ITEM_LAYOUT_TAG)
{
index = tag - RANKING_ITEM_LAYOUT_TAG;
}
m_nIndex = index;
icon_imageview->loadTexture(shop_textures);//根据索引加载商品图片
name_labelBMFont->setText(shop_names);//设置商品名称
priceUnit_labelBMFont->setText(shop_price_units);//设置商品种类
price_labelBMFont->setText(CCString::createWithFormat("%d", shop_prices)->getCString());//设置价格
//重置购买数量
m_nCount = 0;
// number labelatlas
LabelAtlas* number_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("number_LabelAtlas"));
number_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nCount)->getCString());
m_nCoupon = COUPON_MAX;
m_nBinding = BINDING_MAX;
m_nMedal = MEDAL_MAX;
// coupon number labelatlas
LabelAtlas* couponNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("coupon_number_LabelAtlas"));
couponNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nCoupon)->getCString());
// binding number labelatlas
LabelAtlas* bindingNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("binding_number_LabelAtlas"));
bindingNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nBinding)->getCString());
// medal number labelatlas
LabelAtlas* medalNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("medal_number_LabelAtlas"));
medalNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nMedal)->getCString());
// process shop ranking touchEnabled
CCObject* obj = NULL;
// shop scrollview children
CCARRAY_FOREACH(shop_scrollview->getChildren(), obj)
{
Layout* shop_layout = static_cast<Layout*>(obj);
// buy button
Button* buy_button = static_cast<Button*>(shop_layout->getChildByName("buy_Button"));
buy_button->setTouchEnabled(false);
}
// ranking scrollview children
CCARRAY_FOREACH(ranking_scrollview->getChildren(), obj)
{
Layout* ranking_layout = static_cast<Layout*>(obj);
// buy button
Button* buy_button = static_cast<Button*>(ranking_layout->getChildByName("buy_Button"));
buy_button->setTouchEnabled(false);
}
}
}
//控制数量的按钮回调
void CocosGUIExamplesWeaponScene::popupCalculate(CCObject *pSender, TouchEventType type)
{
if (type == TOUCH_EVENT_ENDED)
{
Button* button = static_cast<Button*>(pSender);
Widget* buy_layout = static_cast<Widget*>(button->getParent());
int price = shop_prices;
if (strcmp(button->getName(), "add_Button") == 0) // 判断是添加数量按钮
{
if (strcmp(shop_price_units, "Counpon") == 0)
{
if (m_nCoupon >= price)
{
m_nCount++;
m_nCoupon -= price;
}
}
else if (strcmp(shop_price_units, "Binding") == 0)
{
if (m_nBinding >= price)
{
m_nCount++;
m_nBinding -= price;
}
}
if (strcmp(shop_price_units, "Medal") == 0)
{
if (m_nMedal >= price)
{
m_nCount++;
m_nMedal -= price;
}
}
}
else if (strcmp(button->getName(), "sub_Button") == 0) // 如果是减少按钮
{
if (m_nCount > 0)
{
m_nCount--;
if (strcmp(shop_price_units, "Counpon") == 0)
{
m_nCoupon += price;
}
else if (strcmp(shop_price_units, "Binding") == 0)
{
m_nBinding += price;
}
if (strcmp(shop_price_units, "Medal") == 0)
{
m_nMedal += price;
}
}
}
//设置数值
LabelAtlas* number_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("number_LabelAtlas"));
number_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nCount)->getCString());
// coupon number labelatlas
LabelAtlas* couponNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("coupon_number_LabelAtlas"));
couponNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nCoupon)->getCString());
// binding number labelatlas
LabelAtlas* bindingNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("binding_number_LabelAtlas"));
bindingNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nBinding)->getCString());
// medal number labelatlas
LabelAtlas* medalNumber_labelAtlas = static_cast<LabelAtlas*>(buy_layout->getChildByName("medal_number_LabelAtlas"));
medalNumber_labelAtlas->setStringValue(CCString::createWithFormat("%d", m_nMedal)->getCString());
}
}


忍不住要赞一个,希望有更多这样的教程~