cocos2d实现SlotMachine(老*虎*机)

    实现一个四个转子,每个转子有五个花色的老*虎机。转子的转动实现原理很简单,和背景图无限滚动的原理是一样的:排成列的精灵在屏幕上向上滚动,再通过裁剪结点的裁剪就造成了转子滚动的效果。

 1 void LayerSlotMachine::on_btn_roll(CCObject* pSender, CCControlEvent event)
 2 {
 3     if (!flag_act_)
 4     {
 5         schedule(schedule_selector(XLayerSlotMachine::roll_update));
 6         stop_flag_ = 0;
 7         int target_index;
 8         float mov_dis;
 9 
10         target_index = rand() % 5;
11         CCLOG("slot1:%d", target_index);
12         mov_dis = get_mov_dis(target_index, cur_index1_);
13         cur_index1_ = target_index;
14         roll_act_start(array_1_, mov_dis);
15 
16         target_index = rand() % 5;
17         CCLOG("slot2:%d", target_index);
18         mov_dis = get_mov_dis(target_index, cur_index2_);
19         cur_index2_ = target_index;
20         roll_act_start(array_2_, mov_dis);
21 
22         target_index = rand() % 5;
23         CCLOG("slot3:%d", target_index);
24         mov_dis = get_mov_dis(target_index, cur_index3_);
25         cur_index3_ = target_index;
26         roll_act_start(array_3_, mov_dis);
27 
28         target_index = rand() % 5;
29         CCLOG("slot4:%d", target_index);
30         mov_dis = get_mov_dis(target_index, cur_index4_);
31         cur_index4_ = target_index;
32         roll_act_start(array_4_, mov_dis);
33 
34         flag_act_ = true;
35     }
36 }
37 
38 void LayerSlotMachine::roll_act_start(CCArray* aray,float mov_dis)
39 {
40     CCObject* obj;
41     CCARRAY_FOREACH(aray, obj)
42     {
43         CCCallFunc* act_end = CCCallFunc::create(this, callfunc_selector(XLayerSlotMachine::roll_act_end));
44         CCSequence* seq1 = CCSequence::create(CCMoveBy::create(mov_dis/rotate_v_, ccp(0, mov_dis))
45             , act_end
46             , NULL);
47         CCSprite* spr = (CCSprite*)obj;
48         spr->runAction(seq1);
49     }
50 }
51 
52 void LayerSlotMachine::roll_update(float dt)
53 {
54     roll_bound_test(array_1_,node_slot_1_, 1);
55     roll_bound_test(array_2_,node_slot_2_, 2);
56     roll_bound_test(array_3_,node_slot_3_, 3);
57     roll_bound_test(array_4_,node_slot_4_, 4);
58 }
59 
60 void LayerSlotMachine::roll_act_end()
61 {
62     ++stop_flag_;
63     if (stop_flag_==slot_length_*4)
64     {
65         flag_act_ = false;
66         unschedule(schedule_selector(XLayerSlotMachine::roll_update));
67     }
68 }

需要注意的问题有两个:

(1)移动距离的计算

    

 1 float LayerSlotMachine::get_mov_dis(int target_index, int cur_index)
 2 {
 3     float mov_dis;
 4     float slot_height = spr_model_->getContentSize().height;
 5     int T = 7;
 6     if (target_index > cur_index)
 7     {
 8         mov_dis = slot_height*(slot_length_*T + (target_index - cur_index));
 9     }
10     else
11     {
12         mov_dis = slot_height*(slot_length_*T + (slot_length_ - (cur_index - target_index)));
13     }
14     return mov_dis;
15 }

T:周期数

slot_height:转子的高度

slot_length:单个转子上花色的数量,本例是5

target_index:目标位置

cur_index:当前位置

这里对移动距离分两种情况计算:当target_index>cur_index时,在当前周期就能移动到指定的位置,需要移动的格数为(target_index - cur_index);

当target_index<cur_index时,由于转子只能向上滚动,所以要在下个周期才能达到指定的位置,需要移动的格数为

((slot_length_ - (cur_index - target_index)))。

 

(2)转子滚动的处理

 1 void LayerSlotMachine::roll_bound_test(CCArray* arry,CCNode* node_slot, int slot_num)
 2 {
 3     CCObject* obj;
 4     float bound_y = spr_model_->getContentSize().height*(slot_length_ - 2);
 5 
 6     CCARRAY_FOREACH(arry, obj)
 7     {
 8         CCSprite* spr = (CCSprite*)obj;
 9 
10         if (spr->getPositionY() > bound_y)
11         {
12             if (spr->getTag() - 1000*slot_num == 0)
13             {
14                 CCSprite* spr0 = (CCSprite*)node_slot->getChildByTag(1000*slot_num + slot_length_ - 1);
15                 spr->setPositionY(spr0->getPositionY() - spr_model_->getContentSize().height);
16             }
17             else
18             {
19                 CCSprite* spr0 = (CCSprite*)node_slot->getChildByTag(spr->getTag() - 1);
20                 spr->setPositionY(spr0->getPositionY() - spr_model_->getContentSize().height);
21             }
22         }
23     }
24 }

 当精灵位置高于边界高度boundY时,将精灵移到上一个精灵的下方,实现循环滚动。这里需要特别注意应该以上一个精灵的位置作为基准,否则会产生偏移。

原文地址:https://www.cnblogs.com/codingdiary/p/4172663.html