Cocos studio sample讲解 DemoShop商店界面

cocostuido sample---- DemoShop 源代码地址    
https://github.com/chukong/CocoStudioSamples  
大家可以预先下载这个源代码 本教程所有内容均包含在内  
 
一、 目标  
本节目标是做一个商店界面,包括商品的展示和购买,用户的交互以及动态改变购买的物品属性。效果如下图:       
   
 
二、 分析界面  
本节的内容较为复杂,开始之前我们分解一下界面,这个商品 demo 分为主窗口层、商品层、排行榜层、购买弹出层。  
   
三、 构建界面  
打开 UI 编辑器,创建一个新的 UI 工程,起名为“ DemoShop ”,资源可以在示例中获取。  
开始编辑之前先把给根节点配置一个背景图片,接下来就可以开始布局界面了。  

  

如上图所示,出来有两个文本作为标题外还有两个滚动层及右下角一个按钮。这样就完成了主体,下面制作物品单元,由于界面中的所有商品单元都是十分类似,所以我们可以先制作一个,然后采用复制并逐个调整的办法。  
下图中是用一个 panel 中添加的所有子控件,为了清晰暂未给容器添加背景。  

添加完成子控件后可以配置容器的图片,然后记得将颜色混合设置为“无颜色”。  
 
接下来是复制单元格,开始复制前先将这个单元格拖动到对应滚动层内,注意这里说的不是位置上的关系的“内”,而是层级关系的“内”。  

   

将单元格复制到左侧的商品层内就可以开始使用复制的功能了,这里可以使用“ Ctrl+C ”、“ Ctrl+V ”来快速完成。这里注意由于每一次复制后的空间都会保持跟原控件相同,所以每一次复制都要将复制后的控件移动到其他位置 , 复制完成后可以通过布局快捷键快速的调整位置。  
如选中左侧的 4 个单元个,分别设置纵向对其、纵向等距即可快速的调整到合适位置。  

  

接下来是右侧的滚动层,我们也可以先将一个单元格拖入到右侧的滚动层,保证在层级关系和位置都在右侧的滚动层内 , 如下图:  
   
  右侧的列表是一个可以滚动的容器,里面包含了 8 个单元格,明显超出了显示的区域,我们需要先将滚动层的“滚动区域高度”设置大于滚动层本身的高度。如下图:  
  
 
快速复制控件并调整位置,商品的界面完成,制作完成后就可以勾选“裁剪”属性,这样滚动层超出自身区域的内容将不会显示,清理滚动层的背景颜色。将两个滚动层的颜色设置为“无颜色”。  
     

下面还剩一个弹出层,这个弹出层虽然内容较多,但是都是前面介绍过的内容,这里不做细述。制作完成后将其放置在画布中央并隐藏即可。  
 
注意,由于本示例中控件非常多,关于给每一个控件的命名请自行参考示例程序,如果是自己定义的,一定要在程序中修改对应控件的名称。  

四、 代码实现  

头文件(定义宏及全局变量 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#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__) */

实现文件 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
#include "CocosGUIExamplesWeaponScene.h"
//商品图片索引
const char * shop_textures[8] =
{
     "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[8] =
{
     "Armour" ,
     "Helmet" ,
     "Shield" ,
     "Sword" ,
     "Gloves" ,
     "Dimensity" ,
     "Dart" ,
     "Backpack" ,
};
//商品种类数组
const char * shop_price_units[8] =
{
     "Counpon" ,
     "Binding" ,
     "Medal" ,
     "Counpon" ,
     "Binding" ,
     "Medal" ,
     "Counpon" ,
     "Binding" ,
};
//商品价格索引
const int shop_prices[8] =
{
     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[index]); //根据索引加载商品图片
         name_labelBMFont->setText(shop_names[index]); //设置商品名称
         priceUnit_labelBMFont->setText(shop_price_units[index]); //设置商品种类
         price_labelBMFont->setText(CCString::createWithFormat( "%d" , shop_prices[index])->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[m_nIndex];
         if ( strcmp (button->getName(), "add_Button" ) == 0)   // 判断是添加数量按钮
         {
             if ( strcmp (shop_price_units[m_nIndex], "Counpon" ) == 0)
             {
                 if (m_nCoupon >= price)
                 {
                     m_nCount++;
                     m_nCoupon -= price;
                 }               
             }
             else if ( strcmp (shop_price_units[m_nIndex], "Binding" ) == 0)
             {
                 if (m_nBinding >= price)
                 {
                     m_nCount++;
                     m_nBinding -= price;
                 }
             }
             if ( strcmp (shop_price_units[m_nIndex], "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[m_nIndex], "Counpon" ) == 0)
                 {
                     m_nCoupon += price;
                 }
                 else if ( strcmp (shop_price_units[m_nIndex], "Binding" ) == 0)
                 {
                     m_nBinding += price;
                 }
                 if ( strcmp (shop_price_units[m_nIndex], "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());
     }
}


来源网址:http://www.cocoachina.com/bbs/read.php?tid=194296

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值