-
Notifications
You must be signed in to change notification settings - Fork 1
/
atom.xml
7343 lines (6572 loc) · 701 KB
/
atom.xml
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
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
<title><![CDATA[/无间落叶]]></title>
<link href="http://blog.leafsoar.com/atom.xml" rel="self"/>
<link href="http://blog.leafsoar.com/"/>
<updated>2014-10-25T22:20:41+08:00</updated>
<id>http://blog.leafsoar.com/</id>
<author>
<name><![CDATA[一叶]]></name>
</author>
<generator uri="http://octopress.org/">Octopress</generator>
<entry>
<title type="html"><![CDATA[如何优雅的管理游戏资源]]></title>
<link href="http://blog.leafsoar.com/archives/2013/11-27.html"/>
<updated>2013-11-27T20:56:00+08:00</updated>
<id>http://blog.leafsoar.com/archives/2013/res-mgr</id>
<content type="html"><![CDATA[<p>在游戏的开发过程中,<strong>前期的规划 往往比 后期的“优化”更为重要!</strong>比如多分辨率适配,如果前期没有规划好,可能导致的情况是,画面只在当前测试开发机或者一部分机型正常显示。做了多套资源适配,可以使在合适的机型使用对应的图片资源,避免在高清屏幕使用低质量的图片,在低分辨率屏幕因为图片太大而浪费硬件资源。机制与策略分离,可以让你设计出简单有效的接口。模块化的设计可以让你组织好各种逻辑流程,条理分明 ~ 前期的规划工作可以有很多,一叶也在摸索之中,以使游戏的开发尽量变的简单灵活且可控。最简单的也是最容易忽略的地方,跟我们打交道最多的要数精灵了,从图片创建一个精灵,很简单的开端,将以此展开行动 ~</p>
<p>本文使用 Cocos2d-3.0alpha1 版本,创建了一个 C++ 项目,介绍在 C++ 中,如何处理资源相关的内容,如果读者使用脚本,也可以参考本文中资源管理理念而忽略语言特性,你可以在 Github<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup> 上面看到本文所有源码。</p>
<!-- more -->
<h2>名字系统</h2>
<p>也许你可称之为“命名规范”,但显然它无法表达我所想说的内容,很多人在创建精灵的时候喜欢直接使用资源名称,而没有任何定义,这是一个不好的习惯,如果游戏资源不存在,缺少,或者修改名字,如此你需要在多出引用的地方一一修改。游戏开发中的变数总是无法预料,合理的“名字系统”可以节省很多人力。</p>
<p>我们设定一个文件,这里名为 “Resources.h” 的文件,在其中定义所有的资源名称,在游戏开发中,<strong>尽量只</strong> 使用此处的名称,如图片名称,字体名称,声音资源等。这样做有以下好处,只是简单说几点:</p>
<ul>
<li>如果对资源做出修改,我们可以修改此处定义,以保证同步,避免缺失,命名错误,错误引用等问题</li>
<li>在图片名定义修改时,编译器会编译出错,并自动帮助我们 “找” 出引用的地方,方便修改</li>
<li>由于有常量定义的缘故,我们的 IDE 会自动补全所有以定义变量名称,减少出错的可能,提高效率</li>
<li>这个文件列表显然可以写一个如 python 脚本自动生成</li>
</ul>
<p>使用脚本来自动生成文件常量定义显然是个行之有效的途径,这种机械式的操作交给脚本就行了,它总能出色的完成任务,首先来看看项目的 Resources 目录内容:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
</pre></td><td class='code'><pre><code class='bash'><span class='line'><span class="o">[</span>Resources<span class="o">]</span>~ ./tree
</span><span class='line'>├── CloseNormal.png
</span><span class='line'>├── CloseSelected.png
</span><span class='line'>├── HelloWorld.png
</span><span class='line'>├── file_list.json
</span><span class='line'>├── fonts
</span><span class='line'>│ └── Marker<span class="se">\ </span>Felt.ttf
</span><span class='line'>└── images
</span><span class='line'> ├── JungleLeft.png
</span><span class='line'> ├── ghosts.plist
</span><span class='line'> ├── ghosts.png
</span><span class='line'> ├── grossini_family.plist
</span><span class='line'> └── grossini_family.png
</span></code></pre></td></tr></table></div></figure>
<p>以上是资源文件,那么通过脚本所生成的 “Resources.h” 文件又是什么样子的呢,脚本在 Github 仓库中可以找到(<strong>注意:资源名中最好不要有空格,以免留下“隐患”</strong>):</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="cp">#ifndef _AUTO_RESOURCES_H_</span>
</span><span class='line'><span class="cp">#define _AUTO_RESOURCES_H_</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// search paths</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">vector</span><span class="o"><</span><span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">></span> <span class="n">searchPaths</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'> <span class="s">"fonts"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"images"</span><span class="p">,</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// files</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_CloseNormal</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"CloseNormal.png"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_CloseSelected</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"CloseSelected.png"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">sjs_file_list</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"file_list.json"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_HelloWorld</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"HelloWorld.png"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">st_MarkerFelt</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"Marker Felt.ttf"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">sp_ghosts</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"ghosts.plist"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_ghosts</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"ghosts.png"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">sp_grossini_family</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"grossini_family.plist"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_grossini_family</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"grossini_family.png"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_JungleLeft</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"JungleLeft.png"</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#endif </span><span class="c1">// _AUTO_RESOURCES_H_</span>
</span></code></pre></td></tr></table></div></figure>
<p>看到通过脚本,我们生成了所有文件的常量定义,这让得我们可以在游戏中任意使用,但是请注意,这里生成的文件名称是没有包含路径的,所以在定义文件之前,也自动生成了目录列表 <strong>searchPaths</strong>,顾名思义,设定了一个目录列表,以便找寻资源,我们可以在程序的开始处使用 <code>FileUtils::getInstance()->setSearchPaths(searchPaths);</code> 来设定游戏的资源目录列表,这样我们就可以不用关心资源所在的目录了,你甚至可以根据需要合理的调整资源目录。</p>
<p><strong>注意</strong>:通过设置 searchPaths 可以让我们不用关系资源的路径所在,那么意味着资源名称必须唯一,否则可能会出现引用问题。其次,是如果使用了多套资源方案,请注意 searchPaths 的先后顺序关系。本文暂不考虑多套资源。关于忽略资源目录的做法,如果有不同看法者,欢迎留言讨论,对我来说,忽略路径是利大于弊的 ~</p>
<p>以上通过脚本自动生成了文件列表,但是这显然不够,我们看到资源当中有两张 <strong>打包</strong> 资源图片(可以使用 TexturePacker 对图片资源进行打包,具有占用更小空间,优化运行效率等诸多好处,后面还会介绍此点) plist 文件。我们当然也是需要使用打包中资源的,所以脚本需要能够自动解析 plist 文件,并提取出 TexturePacker 打包的资源名称,请看如下定义,同样是自动生成在 “Resources.h” 文件之中:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">////// texture //////</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// ghosts.plist</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_child1</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"child1.gif"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_father</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"father.gif"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_sister1</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"sister1.gif"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_sister2</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"sister2.gif"</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// grossini_family.plist</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_grossini</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"grossini.png"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_grossinis_sister1</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"grossinis_sister1.png"</span><span class="p">;</span>
</span><span class='line'><span class="k">static</span> <span class="k">const</span> <span class="kt">char</span> <span class="n">si_grossinis_sister2</span><span class="p">[]</span> <span class="o">=</span> <span class="s">"grossinis_sister2.png"</span><span class="p">;</span>
</span></code></pre></td></tr></table></div></figure>
<p>此时我们就能用以下代码来创建精灵了,都引用了资源名称定义,并且使用两种方式创建了精灵:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// 直接由图片创建精灵</span>
</span><span class='line'><span class="k">auto</span> <span class="n">hello</span> <span class="o">=</span> <span class="n">Sprite</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">si_HelloWorld</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// 从打包资源创建精灵</span>
</span><span class='line'><span class="n">SpriteFrameCache</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">addSpriteFramesWithFile</span><span class="p">(</span><span class="n">sp_grossini_family</span><span class="p">,</span> <span class="n">si_grossini_family</span><span class="p">);</span>
</span><span class='line'><span class="k">auto</span> <span class="n">sister</span> <span class="o">=</span> <span class="n">Sprite</span><span class="o">::</span><span class="n">createWithSpriteFrameName</span><span class="p">(</span><span class="n">si_grossinis_sister1</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>上面我们使用两种方式创建精灵,为什么会有两种方式?也许你可以看看 <a href="http://blog.zilongshanren.com/">『子龙山人』</a> 翻译的文章 <a href="http://www.cnblogs.com/zilongshanren/archive/2011/03/18/1988097.html">『在cocos2d里面如何使用Texture Packer和像素格式来优化spritesheet』</a>
其中详细的介绍了图片资源打包优化的相关细节问题,一个游戏最多的就是图片资源,优化空间最大的也是图片资源,里面详细的介绍了优化图片资源占用空间 50% 以上,如何使游戏运行内存占用优化近 50%,以 cocos2d 为例,但 cocos2d-x 同样能够适用,而且能通过脚本自动打包。 所以合理的对图片资源进行打包优化是非常有必要的。但如何处理这个流程确实不好定夺,<strong>因为不同资源的使用方式不同,因为这两种方式的存在,导致我们编写代码的逻辑不同,这需要提前预定好,</strong>所以我们考虑如下开发流程:</p>
<p>在游戏开发前,对所有资源打包后提供给 编写游戏人员,也就是说在写程序之前,游戏资源就已确定,那些以打包,哪些未打包都已经知道,如前面一样,通过两种方式创建精灵。但是这样的结果是,前期规定好了的,后期就无法改动,或者说很难改动,牵一发而动全身啊 ~ 这就需要加大 <strong>前期的规划</strong> 力度,以确保后期不会出现太大太多事与愿违的情形。这种情况下的 <strong>后期优化</strong> 将会非常蹩脚。况且加大前期规划的力度,可能会对整个项目的进程有所影响,如比编写人员的动工会稍缓,人力资源分配不合理。</p>
<h3>透明</h3>
<p>前文提到,我们使用了 searchPaths 变量,以用忽略资源的路径,一个存在的东西,看起来好像不存在一样,我们称之为 “透明”,”透明” 在软件领域中也是重要的概念,它也强调着封装的重要性,隐藏细节的必要性。这里的资源路径就是如此,我们可以说 <strong>对于资源的使用来说,它的路径是透明的,</strong> 有没有路径,路径为何?那不重要,重要的是你能通过资源名称获取想要的资源。</p>
<p>也许你已经发现了,我想说的不是路径问题,而是图片资源问题。<strong>对于图片资源的使用来说,它’是否是打包资源’ 应该是透明的。</strong>也既是在使用图片资源的时候,你不应该关心它是不是打包后的资源,是也好,不是也罢,这不应该影响你对资源的请求和使用。”打包” 这个过程对你来说,<strong>不存 ~</strong></p>
<h2>图片资源类型的 “透明化” 处理</h2>
<p>先来段代码,看看没有 “透明化” 处理时的一般使用方式:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// 方式一 文件资源</span>
</span><span class='line'><span class="k">auto</span> <span class="n">jungle</span> <span class="o">=</span> <span class="n">Sprite</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">si_JungleLeft</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// 方式二 打包资源</span>
</span><span class='line'><span class="n">SpriteFrameCache</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">addSpriteFramesWithFile</span><span class="p">(</span><span class="n">sp_grossini_family</span><span class="p">,</span> <span class="n">si_grossini_family</span><span class="p">);</span>
</span><span class='line'><span class="k">auto</span> <span class="n">sister</span> <span class="o">=</span> <span class="n">Sprite</span><span class="o">::</span><span class="n">createWithSpriteFrameName</span><span class="p">(</span><span class="n">si_grossinis_sister1</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>以上我们看到,同样是创建精灵, <code>si_JungleLeft</code> 是普通的 <strong>文件资源</strong>,而 <code>si_grossinis_sister1</code> 是 <strong>打包资源</strong>,这决定着两者的使用方式不同,那么怎么 “透明化” 处理呢:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// 不论图片属于 文件资源 还是 打包资源 使用方法相同</span>
</span><span class='line'><span class="k">auto</span> <span class="n">jungle</span> <span class="o">=</span> <span class="n">AssetLoader</span><span class="o">::</span><span class="n">createSprite</span><span class="p">(</span><span class="n">si_JungleLeft</span><span class="p">);</span>
</span><span class='line'><span class="k">auto</span> <span class="n">jungle</span> <span class="o">=</span> <span class="n">AssetLoader</span><span class="o">::</span><span class="n">createSprite</span><span class="p">(</span><span class="n">si_grossinis_sister1</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>我们提供了一个类 <code>AssetLoader</code>,它有一个方法 <code>createSprite(const std::string& name)</code>。不论我们是不是打包资源,我们都通过这个方法来创建精灵,显然它的内部工作原理是根据图片的实际类型,动态判断并创建,之后返回,要实现这样一个功能是可行的,并且没有多复杂,实现以后。我们在使用图片资源的使用就再也用关心它是什么类型的资源了。</p>
<p><strong>这也意味着你可以以一个理想的方式来管理开发流程</strong>。 图片资源可以和游戏编写同时进行,不停的添加图片资源,不停的编写游戏逻辑,而不用考虑图片是否已经优化的问题了,此时可以提供一些零散的图片,以供使用(图片命名最好还是固定),当然也可以提前把关联性比较强的图片提前打包处理,这并不影响使用,因为对程序来说,<strong>它是透明的</strong>,”不存在”的。在后期,我们可以集中的在后期对游戏资源优化,打包处理等(关于此点,文章后面也会给出相对合理的处理流程)。</p>
<h3>功能的实现方案与流程</h3>
<p>在开始之前,一叶通常会将其流程在心中演算一遍,使其不会出现太大的纰漏,对于不合理的所在,可以重新拟定方案。然后实现之 ~ 要使得 <strong>AssetLoader</strong> 的 <strong>createSprite</strong> 方法完成其功能,那么它需要知道,当前请求的 <strong>图片资源</strong> 是否是 <strong>文件资源</strong>(以 <strong>文件资源</strong> 和 <strong>打包资源</strong> 区分两者),如果是,直接由前文 <strong>方式一</strong> 创建精灵返回,如果不是,则从 打包资源 里面找寻,找到就通过 <strong>方式二</strong> 创建精灵并返回,如果还没找到,就返回空指针喽 ~ 由此我们知道 AssetLoader 它内部需要完成以下功能:</p>
<ul>
<li>能够判断一个资源是否是文件资源</li>
<li>能够根据打包资源图片名称返回实际的 plist 文件(打包资源描述文件)和 图片文件</li>
</ul>
<p>要完成以上功能,那就需要让 AssetLoader 知道有哪些文件资源,还要知道有哪些打包资源,我们可以在 AssetLoader 里面定义几个字典用以保存这些数据:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="k">class</span> <span class="nc">AssetLoader</span><span class="o">:</span> <span class="k">public</span> <span class="n">Object</span><span class="p">{</span>
</span><span class='line'><span class="k">public</span><span class="o">:</span>
</span><span class='line'> <span class="k">static</span> <span class="n">Sprite</span><span class="o">*</span> <span class="n">createSprite</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&</span> <span class="n">name</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="k">private</span><span class="o">:</span>
</span><span class='line'> <span class="k">static</span> <span class="n">AssetLoader</span><span class="o">*</span> <span class="n">getInstance</span><span class="p">();</span>
</span><span class='line'> <span class="kt">bool</span> <span class="n">init</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'> <span class="kt">bool</span> <span class="n">fileExists</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&</span> <span class="n">filename</span><span class="p">);</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">getTexturePlist</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&</span> <span class="n">name</span><span class="p">);</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">getTextureImage</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&</span> <span class="n">name</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="k">private</span><span class="o">:</span>
</span><span class='line'> <span class="n">Dictionary</span><span class="o">*</span> <span class="n">_fileDict</span><span class="p">;</span> <span class="c1">// 文件列表</span>
</span><span class='line'> <span class="n">Dictionary</span><span class="o">*</span> <span class="n">_texturePlistDict</span><span class="p">;</span> <span class="c1">// 打包资源到文件的映射</span>
</span><span class='line'> <span class="n">Dictionary</span><span class="o">*</span> <span class="n">_textureImageDict</span><span class="p">;</span> <span class="c1">// 打包资源plist 到图片的映射</span>
</span><span class='line'><span class="p">};</span>
</span></code></pre></td></tr></table></div></figure>
<p>如以上的定义实现,它有三个字典, <code>_fileDict</code> 的 <strong>key</strong> 保存着所有文件资源,<strong>value</strong> 保存文件资源的 编号 ,这样我们就能够随时判断一个图片是否是文件资源了。<code>_texturePlistDict</code> 的 key 保存着打包资源的名称,value 保存打包资源所在 Plist 文件的编号,通过它我们能通过打包资源获取到它 Plist 所在的文件。 <code>_textureImageDict</code> 也是类似,key 保存打包资源名称,value 保存打包资源所在的真实 图片文件的引用。</p>
<p>功能已经定义完毕,现在的问题是我们如何去为这几个字典填充数据?显然程序初始化手动填充不靠谱,前文的文件名等信息都已经是自动定义了,此处我们当然也希望有一个方案 <strong>自动填充</strong> 了。这里的做法是,在使用 <strong>python</strong> 生成资源定义的时候,同时生成一个 json 文件,这个文件里面包含了所有此处字典中所需要的数据,然后 <strong>AssetLoader</strong> 初始化的时候读取这个 json 文件,以完成自动填充数据的功能。先来看看自动生成的 json 文件长什么样纸:</p>
<p>题外话:使用 json 来存储这样一个中转的数据格式是最后定下来的方案,设计之初考虑过几种方案,比如想到可以用一个 sqlite 数据来保存各种数据,这样数据的操作就非常统一,对后期的数据统计分析也会非常方便,曾与朋友 子龙山人 讨论过这之间的详细细节,以及各种实现方案的利弊分析。使用 sqlite 的好处是更为灵活,后期扩展功能会非常方便,适合稍微大点的项目,但是如果一个项目本身没有使用 sqlite 数据库,如果为这里的方案而硬添加一个扩展库实现 sqlite,可能就会非常的不友好,不通用。</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="s">"file_name"</span><span class="o">:</span> <span class="p">[</span>
</span><span class='line'> <span class="s">"CloseNormal.png"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"CloseSelected.png"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"file_list.json"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"HelloWorld.png"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"Marker Felt.ttf"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"ghosts.plist"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"ghosts.png"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"grossini_family.plist"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"grossini_family.png"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"JungleLeft.png"</span>
</span><span class='line'> <span class="p">],</span>
</span><span class='line'> <span class="s">"file_index"</span><span class="o">:</span> <span class="p">[</span>
</span><span class='line'> <span class="s">"1"</span><span class="p">,</span> <span class="s">"2"</span><span class="p">,</span> <span class="s">"3"</span><span class="p">,</span> <span class="s">"4"</span><span class="p">,</span> <span class="s">"5"</span><span class="p">,</span> <span class="s">"6"</span><span class="p">,</span> <span class="s">"7"</span><span class="p">,</span> <span class="s">"8"</span><span class="p">,</span> <span class="s">"9"</span><span class="p">,</span> <span class="s">"10"</span>
</span><span class='line'> <span class="p">],</span>
</span><span class='line'> <span class="s">"texture_name"</span><span class="o">:</span> <span class="p">[</span>
</span><span class='line'> <span class="s">"child1.gif"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"father.gif"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"sister1.gif"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"sister2.gif"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"grossini.png"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"grossinis_sister1.png"</span><span class="p">,</span>
</span><span class='line'> <span class="s">"grossinis_sister2.png"</span>
</span><span class='line'> <span class="p">],</span>
</span><span class='line'> <span class="s">"texture_plist"</span><span class="o">:</span> <span class="p">[</span>
</span><span class='line'> <span class="s">"6"</span><span class="p">,</span> <span class="s">"6"</span><span class="p">,</span> <span class="s">"6"</span><span class="p">,</span> <span class="s">"6"</span><span class="p">,</span> <span class="s">"8"</span><span class="p">,</span> <span class="s">"8"</span><span class="p">,</span> <span class="s">"8"</span>
</span><span class='line'> <span class="p">],</span>
</span><span class='line'> <span class="s">"texture_image"</span><span class="o">:</span> <span class="p">[</span>
</span><span class='line'> <span class="s">"7"</span><span class="p">,</span> <span class="s">"7"</span><span class="p">,</span> <span class="s">"7"</span><span class="p">,</span> <span class="s">"7"</span><span class="p">,</span> <span class="s">"9"</span><span class="p">,</span> <span class="s">"9"</span><span class="p">,</span> <span class="s">"9"</span>
</span><span class='line'> <span class="p">]</span>
</span><span class='line'> <span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>以上是自动生成的 json 数据文件内容,为了在这里展示,做了点格式化和缩进,更为友好一点。通过 <strong>file_name</strong> 和 <strong>file_index</strong> 可以创建文件资源列表字典,通过 texture_name 和 texture_plist 可以创建打包资源和文件资源之间的映射, texture_image 也是同样。 file_name 包含了所有文件资源,file_index 为文件资源做了编号,这两个数据项的个数是相同的。 texture_name 定义了所有打包资源的定义,texture_plist 和 texture_image 则保存了 打包资源所在的 plist 文件和图片文件的引用,它们的数据项个数也是相同的。只要保证这里生成的内容没有错误,那么我们就正确的将其填充到 AssetLoader 的字典里面,以实现想要的功能。</p>
<p>为什么数据会长这个样子?一叶本来的设计 json 文件,多层嵌套更具描述性(各种对象,各种属性,一目了然),但是发现 解析的时候稍显麻烦,在 新版 cocos2d-x 的 gui 库中,已经封装好了一些常用的 json 解析功能,本着 拿来注意(尽可能的寻找可用的资源来简化自身的流程) 的思想,为使解析过程简单,所以数据格式就定义成那个样子了 - =。现在只是用了五个数组(更平面化的数据组织,像是数据库表),保存所有数据。只能说,这样做是为了迎合代码的编写,让本来复杂的 json 解析过程变得更为简单。现在看来,但到也简单清晰,看看填充字典的关键代码实现(如果有其它更好的方式,修改也不麻烦,修改生成的数据格式,再修改代码中数据的填充方法就行了):</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="n">JsonDictionary</span> <span class="o">*</span><span class="n">jsonDict</span> <span class="o">=</span> <span class="k">new</span> <span class="n">JsonDictionary</span><span class="p">();</span>
</span><span class='line'><span class="n">String</span><span class="o">*</span> <span class="n">fileContent</span> <span class="o">=</span> <span class="n">String</span><span class="o">::</span><span class="n">createWithContentsOfFile</span><span class="p">(</span><span class="n">sjs_file_list</span><span class="p">);</span>
</span><span class='line'><span class="n">jsonDict</span><span class="o">-></span><span class="n">initWithDescription</span><span class="p">(</span><span class="n">fileContent</span><span class="o">-></span><span class="n">getCString</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'><span class="n">DictionaryHelper</span><span class="o">*</span> <span class="n">dicHelper</span> <span class="o">=</span> <span class="n">DICTOOL</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'><span class="n">_fileDict</span> <span class="o">=</span> <span class="n">Dictionary</span><span class="o">::</span><span class="n">create</span><span class="p">();</span>
</span><span class='line'><span class="kt">int</span> <span class="n">file_idx</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getArrayCount_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">file_name</span><span class="p">);</span>
</span><span class='line'><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">file_idx</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getStringValueFromArray_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">file_name</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">index</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getStringValueFromArray_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">file_index</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span><span class='line'> <span class="n">_fileDict</span><span class="o">-></span><span class="n">setObject</span><span class="p">(</span><span class="n">String</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">index</span><span class="p">),</span> <span class="n">name</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="n">log</span><span class="p">(</span><span class="s">"file count: %d"</span><span class="p">,</span> <span class="n">file_idx</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">_texturePlistDict</span> <span class="o">=</span> <span class="n">Dictionary</span><span class="o">::</span><span class="n">create</span><span class="p">();</span>
</span><span class='line'><span class="kt">int</span> <span class="n">texture_idx</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getArrayCount_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">texture_name</span><span class="p">);</span>
</span><span class='line'><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">texture_idx</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getStringValueFromArray_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">texture_name</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">plist</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getStringValueFromArray_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">texture_plist</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span><span class='line'> <span class="n">_texturePlistDict</span><span class="o">-></span><span class="n">setObject</span><span class="p">(</span><span class="n">String</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">plist</span><span class="p">),</span> <span class="n">name</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="n">log</span><span class="p">(</span><span class="s">"texture count: %d"</span><span class="p">,</span> <span class="n">texture_idx</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">_textureImageDict</span> <span class="o">=</span> <span class="n">Dictionary</span><span class="o">::</span><span class="n">create</span><span class="p">();</span>
</span><span class='line'><span class="k">for</span> <span class="p">(</span><span class="kt">int</span> <span class="n">i</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="n">i</span> <span class="o"><</span> <span class="n">texture_idx</span><span class="p">;</span> <span class="n">i</span><span class="o">++</span><span class="p">){</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">name</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getStringValueFromArray_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">texture_name</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">image</span> <span class="o">=</span> <span class="n">dicHelper</span><span class="o">-></span><span class="n">getStringValueFromArray_json</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">,</span> <span class="n">texture_image</span><span class="p">,</span> <span class="n">i</span><span class="p">);</span>
</span><span class='line'> <span class="n">_textureImageDict</span><span class="o">-></span><span class="n">setObject</span><span class="p">(</span><span class="n">String</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">image</span><span class="p">),</span> <span class="n">name</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="n">CC_SAFE_DELETE</span><span class="p">(</span><span class="n">jsonDict</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>这里能看到一些陌生的内容 <code>JsonDictionary</code>、<code>DictionaryHelper</code> 类型和其操作方式,这里的使用方法不是本文的重点,有兴趣的朋友看看源码实现。以很简洁的方式,填充了我们需要的字典数据内容。有了这些字典数据,我们就很容易的判断一个图片是否是文件资源了,如果是打包资源,也能够很容易找出打包资源所在的 Plist 文件和 图片文件,最后看一下 <code>createSprite</code> 方法的实现:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="n">Sprite</span><span class="o">*</span> <span class="n">AssetLoader</span><span class="o">::</span><span class="n">createSprite</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&</span> <span class="n">name</span><span class="p">){</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">AssetLoader</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">fileExists</span><span class="p">(</span><span class="n">name</span><span class="p">)){</span>
</span><span class='line'> <span class="k">return</span> <span class="n">Sprite</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="n">log</span><span class="p">(</span><span class="s">"create sprite: %s"</span><span class="p">,</span> <span class="n">name</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">plistfile</span> <span class="o">=</span> <span class="n">AssetLoader</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">getTexturePlist</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">imagefile</span> <span class="o">=</span> <span class="n">AssetLoader</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">getTextureImage</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'> <span class="n">log</span><span class="p">(</span><span class="s">"plist: %s, image: %s"</span><span class="p">,</span> <span class="n">plistfile</span><span class="p">.</span><span class="n">c_str</span><span class="p">(),</span> <span class="n">imagefile</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">plistfile</span> <span class="o">!=</span> <span class="s">""</span> <span class="o">&&</span> <span class="n">imagefile</span> <span class="o">!=</span> <span class="s">""</span><span class="p">){</span>
</span><span class='line'> <span class="n">SpriteFrameCache</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">addSpriteFramesWithFile</span><span class="p">(</span><span class="n">plistfile</span><span class="p">,</span> <span class="n">imagefile</span><span class="p">);</span>
</span><span class='line'> <span class="k">return</span> <span class="n">Sprite</span><span class="o">::</span><span class="n">createWithSpriteFrameName</span><span class="p">(</span><span class="n">name</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'> <span class="k">return</span> <span class="n">nullptr</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>至此我们便完成了 <strong>图片资源类型的 “透明化” 处理</strong> 。这样一个解决方案,很好的解决了在开发过程中图片资源的管理过程,后期优化,都不冲突。能够通过此提供一个较为合理的开发流程。 本文所使用的源码,脚本等都可以在 Github 上面找到 <a href="https://github.com/leafsoar/resource-manager">『https://github.com/leafsoar/resource-manager』</a>,但是要清楚,我这里提供的只是按照我这种流程下来的一种实现而已,对于程序本身而言,也还有很多可以改进的所在 ~ 思路同样,每个人实现的具体细节可能不一样,不论你使用 C++ 还是脚本语言,都不影响你 “透明化” 图片资源类型。</p>
<h2>如何优雅的管理游戏资源</h2>
<p>我们解决了一些问题,提供了一些解决方案,但总有更多的问题等着我们去解决,更多的优秀解决方案,好的工作模式,处理流程。我们会把开发中一些 <strong>变动</strong> 的所在找寻出来,对它灵活的处理,使它能够适应各种不同的 <strong>险恶环境</strong>。哪些是不变的,哪些是容易变动的,尽量做到 <strong>以不变应万变</strong>。现在新的问题和需求又来了,哈 ~</p>
<p>继续前文内容,我们可以使用 AssetLoader 来加载图片资源,创建精灵,实现游戏玩法逻辑等。但是我们通常会在一个场景进入时就预先缓存所有图片资源(声音资源亦是同样),甚至在游戏开始时,预先加载所有的图片资源,以 <strong>保证游戏画面的流畅性</strong>。如果没有预先缓存图片资源,那么在游戏中用到的时候,实时加载可能 <strong>会使游戏画面卡顿</strong>,这不是我们想看到的结果。如果一个游戏不大,资源总和也没多少,那么可以直接在游戏开始时全部加载完毕,这种情况处理起来比较简单,直接把所有资源加载就可以了。但是如今的游戏动辄几十兆,几百兆,显然游戏资源一次性加载是不科学的,这时我们可以分场景,在加载一个场景的时候,清空前一个场景所使用的图片缓存资源,然后预先加载当前场景的游戏资源,以达到最优的内存占用。</p>
<p>通常我们都是人为的,定义了一个方法在开始场景前做一些准备工作,清空缓存,预加载游戏资源,如这里有一个需要预加载的资源列表,而前文我们提到,在游戏开发的过程中,我们的图片资源可能会有所改动,这就需要我们去 <strong>人为的同步去手动维护这个列表</strong>,而这样的工作费时费力,还容易出现很多错误,如果我们能够把这一步的操作自动化,根据实际情况生成其列表,并且 <strong>列表资源的加载顺序也是做过优化的</strong>(根据文件大小,或者分辨率大小,优先加载大的资源,使游戏减少因占用内存过多而崩溃的可能性),那将使我们能有 更多的精力花在更值得的地方。如果结合到本文之前的实现方案就是,在开始一个场景时,我们对 AssetLoader 做一个标记,在这个标记之后所请求的图片资源都是当前场景的资源,我们可以在内部将其记录下来,以任何方式都行,这样我们就能够非常容易的收集并生成当前场景所使用的图片资源了。如果我们将这个列表做成动态可维护的,自动记录以便下次运行时预先加载,这样一种实现从逻辑上来说时可行。如何优雅得管理游戏资源?但是实现比 优雅 更重要,在实现的过程中,尽量使开发变得简单,流程变得清晰,也是一叶努力的方向 ~</p>
<p>以上只是对预加载资源列表的动态维护,提供了一个简单的思路,其中还有很多细节值得推敲。但我想实现这样一种流程对游戏的开发是非常有帮助的,对于这个部分的内容,一叶还没有给出一个具体的实现方案,但将继续之前的流程往下实现,并分享在 Github 上面,同时你也可以参与进来。也算是在这里集思广益,如果你有什么好的想法,对本文实现有什么改进,都可以一起交流。如果你遇到了相同的问题,也可以说说你是怎么处理这些问题的,欢迎分享 ~</p>
<div class="footnotes">
<hr/>
<ol>
<li id="fn:1">
<p>本文源码 Github 仓库地址:<a href="https://github.com/leafsoar/resource-manager/tree/v1.0">https://github.com/leafsoar/resource-manager/tree/v1.0</a><a href="#fnref:1" rev="footnote">↩</a></p></li>
</ol>
</div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[玩转 Cocos2d-x 脚本引擎]]></title>
<link href="http://blog.leafsoar.com/archives/2013/11-10.html"/>
<updated>2013-11-10T20:56:00+08:00</updated>
<id>http://blog.leafsoar.com/archives/2013/script-engin</id>
<content type="html"><![CDATA[<p>在 Unix 文化中,有这样一种理念,Happy Hacking!使用 Cocos2d-x/C++ 写过一些游戏,其绑定的脚本语言,用的也不少,脚本语言的一个好处就是快速开发,你无需明白它之运行机理,便可容易的完成所想要的效果,三天上手,五天就能写出像样的程序来,C++ 则不然,其各种语言细节特性,各种开发技巧,内存管理等细枝末叶 ~</p>
<p>计算机不会魔法,在一叶看来其内容,只有 <strong>“知、或者不知”</strong> ,没有 <strong>“懂、或者不懂”</strong>,“知或者不知”来自于你的学习历程与经验,至于“不懂”么,我还没接触到的领域内容,我都不懂,哈 ~ Cocos2d-x 脚本引擎也用过一段时间了,但其运行机理还不明白,就使用而言也无需明白,不过于在意细节的实现,可能更好的从宏观角度把握整体。过去只是对其“存疑”(对于这里的“不懂”,一叶通常美其名曰:<strong>要学会存疑</strong> :p ),而现在想要对其运行机制多了解一些,那就只有一步步去探究喽,要了解到什么程度,那就随意了~</p>
<p>对 Cocos2d-x 的运行机制只是略懂一二,C++ 的场景由 C++ 运行,脚本呢,先开启脚本引擎,让后将控制权交由脚本代码执行,在这过程中发生了什么,由脚本所控制的元素和 C++ 有什么不同,或者说它的本质是什么!这之前一叶一直说的是脚本引擎,而非具体那种脚本引擎,lua 或者 js (jsvascript)的引擎实现!凭着对已有知识的了解和直觉,很多疑问和可能性随之而来,它所支持的脚本语言有两种,此两种的共同之处是什么,其使用了脚本绑定技术,<strong>什么是绑定</strong> ?各种对象在内存中如何分布,如何配合在一起工作。</p>
<p>为了增加探究过程的趣味性,所以一叶试想着能不能让 Cocos2d-x 现今所支持的<strong>两种脚本引擎同时运行</strong> (lua and js),然后确定是否能在三者之间(C++, js, lua)访问同一个内存元素,如果行,便弄出来,即便不能做到,那也无所谓,这其中的过程比结果更有意思,不是吗 ~</p>
<!-- more -->
<h2>两种脚本引擎同时运行</h2>
<p>这里使用了 cocos2d-x-3.0alpha0-pre 版本,原因有二。一者:这是最新版本,反正是折腾,顺便了解一下 3.0 的新特性和 代码 style ,其二:3.0 对 三大开发平台(windows, linux ,mac),两大运行平台(android, ios)的支持更好更全一些,比如,lua 可以跑在 mac 上面,这一点最新的 2.2 版本不行(lua )。这样的选择,可以让我在当前系统(Mac OS X) 系统下,直接运行看效果,而不用开模拟器或者虚拟机,使过程更为方便。(过去使用 Linux 作为开发环境,也很方便,一叶的博客也有其具体的开发环境搭建配置等)而 windows 系统,几年前就几乎不怎么用了,各种不顺手。</p>
<p>3.0 中去除了使用项目模板来构建项目,而改为使用脚本创建,支持的平台如下(这个脚本是 github 上最新的版本),观其关键代码:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='python'><span class='line'><span class="c"># [Cocos2d-x]/tools/project-creator/create_project.py</span>
</span><span class='line'><span class="n">PLATFORMS</span> <span class="o">=</span> <span class="p">{</span>
</span><span class='line'> <span class="s">"cpp"</span> <span class="p">:</span> <span class="p">[</span><span class="s">"ios_mac"</span><span class="p">,</span> <span class="s">"android"</span><span class="p">,</span> <span class="s">"win32"</span><span class="p">,</span> <span class="s">"linux"</span><span class="p">],</span>
</span><span class='line'> <span class="s">"lua"</span> <span class="p">:</span> <span class="p">[</span><span class="s">"ios_mac"</span><span class="p">,</span> <span class="s">"android"</span><span class="p">,</span> <span class="s">"win32"</span><span class="p">,</span> <span class="s">"linux"</span><span class="p">],</span>
</span><span class='line'> <span class="s">"javascript"</span> <span class="p">:</span> <span class="p">[</span><span class="s">"ios_mac"</span><span class="p">,</span> <span class="s">"android"</span><span class="p">,</span> <span class="s">"win32"</span><span class="p">]</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p></p>
<p>从这里脚本看出 cpp 和 lua ,对五个平台已经全面支持,javascript 对 linux 还没有支持(脚本上是这样),相比 -x 2.x 版本支持更好,更全面,其代码也经过重构,更模块化,还有很多 C++ 11 的新特性,这里同样也期待 3.0 早日成熟,达到实用阶段 :p</p>
<p>为了简化操作步骤,一叶尽量利用现有的环境内容,使用 XCode打开 samples 项目,这里包含了所有项目内容,起初一叶打算基于 HelloCpp 项目做扩展,添加脚本支持,来实现自己的功能,也许是我对 XCode 环境了解不够,通过手动配置,让它能够支持 lua 扩展,但是 js 扩展却没能跑起来(没理由 lua 可以 js 却不行,知道一定是哪里配置有误),此时看来,在已有的项目中添加 lua 比 js 成功几率要大,固转而使用 HelloLua 项目添加 js 扩展支持,以达到项目组织上能够独立运行 js 引擎 或者 lua 引擎。(注:使用 HelloCpp 作为扩展,主要想看看怎么配置方便,如果都好配置,就基于 Cpp ,如果其中一个配置难,或者没通过,就基于没有通过配置的已有实现,扩展它。比如,这里 lua 通过 js 却没有,那就基于已有的 HelloLua 扩展支持 js,更为节省精力,这是策略问题 :p)</p>
<p>以上只是让项目同时支持 js <strong>或者</strong> lua 的运行,比如只跑 lua,或者只跑 js,但是 两者却不能同时跑,如果在代码中,同时用到了 lua 和 js 的支持库,在编译时会报错。这是因为在绑定的时候,两种脚本引擎分别实现了自己的 GLNode 。</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="c1">// [Cocos2d-x]/scripting/javascript/bindings/js_bindings_opengl.h</span>
</span><span class='line'><span class="cp">#include "cocos2d.h"</span>
</span><span class='line'><span class="cp">#include "ScriptingCore.h"</span>
</span><span class='line'><span class="cp">#include "cocos2d_specifics.hpp"</span>
</span><span class='line'>
</span><span class='line'><span class="k">class</span> <span class="nc">GLNode</span> <span class="o">:</span> <span class="k">public</span> <span class="n">cocos2d</span><span class="o">::</span><span class="n">Node</span> <span class="p">{</span>
</span><span class='line'> <span class="k">public</span><span class="o">:</span>
</span><span class='line'> <span class="kt">void</span> <span class="n">draw</span><span class="p">();</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">js_register_cocos2dx_GLNode</span><span class="p">(</span><span class="n">JSContext</span> <span class="o">*</span><span class="n">cx</span><span class="p">,</span> <span class="n">JSObject</span> <span class="o">*</span><span class="n">global</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// [Cocos2d-x]/scripting/lua/cocos2dx_support/LuaOpengl.h</span>
</span><span class='line'><span class="cp">#ifndef __LUA_OPENGL_H__</span>
</span><span class='line'><span class="cp">#define __LUA_OPENGL_H__</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#ifdef __cplusplus</span>
</span><span class='line'><span class="k">extern</span> <span class="s">"C"</span> <span class="p">{</span>
</span><span class='line'><span class="cp">#endif</span>
</span><span class='line'><span class="cp">#include "tolua++.h"</span>
</span><span class='line'><span class="cp">#ifdef __cplusplus</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'><span class="cp">#endif</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#include "base_nodes/CCNode.h"</span>
</span><span class='line'><span class="k">class</span> <span class="nc">GLNode</span><span class="o">:</span><span class="k">public</span> <span class="n">cocos2d</span><span class="o">::</span><span class="n">Node</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="k">virtual</span> <span class="kt">void</span> <span class="n">draw</span><span class="p">();</span>
</span><span class='line'><span class="p">};</span>
</span><span class='line'>
</span><span class='line'><span class="n">TOLUA_API</span> <span class="kt">int</span> <span class="n">tolua_Cocos2d_CCDrawNode_drawPolygon00</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="n">TOLUA_API</span> <span class="kt">int</span> <span class="n">tolua_opengl_open</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="cp">#endif </span><span class="c1">//__LUA_OPENGL_H__</span>
</span></code></pre></td></tr></table></div></figure>
<p>同时使用两种引擎,就意味着同时用到两者的库依赖,而重复的类型定义导致编译通不过,所以只能根据需要 hack 源码了,如果修改,二者修改其一,看修改哪个方便,引用的地方少。如下是使用 Emacs 的 find-grep 命令,在 scripting 目录搜索 “GLNode” 关键字的结果。(Emacs 是一叶的必备工具,这里搜索出的结果可以快速定位代码位置)</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
<span class='line-number'>52</span>
<span class='line-number'>53</span>
<span class='line-number'>54</span>
<span class='line-number'>55</span>
<span class='line-number'>56</span>
<span class='line-number'>57</span>
<span class='line-number'>58</span>
<span class='line-number'>59</span>
<span class='line-number'>60</span>
<span class='line-number'>61</span>
<span class='line-number'>62</span>
<span class='line-number'>63</span>
<span class='line-number'>64</span>
<span class='line-number'>65</span>
<span class='line-number'>66</span>
<span class='line-number'>67</span>
<span class='line-number'>68</span>
<span class='line-number'>69</span>
<span class='line-number'>70</span>
<span class='line-number'>71</span>
<span class='line-number'>72</span>
<span class='line-number'>73</span>
<span class='line-number'>74</span>
<span class='line-number'>75</span>
<span class='line-number'>76</span>
<span class='line-number'>77</span>
<span class='line-number'>78</span>
<span class='line-number'>79</span>
<span class='line-number'>80</span>
<span class='line-number'>81</span>
<span class='line-number'>82</span>
<span class='line-number'>83</span>
<span class='line-number'>84</span>
<span class='line-number'>85</span>
<span class='line-number'>86</span>
<span class='line-number'>87</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="o">-*-</span> <span class="nl">mode:</span> <span class="n">grep</span><span class="p">;</span> <span class="k">default</span><span class="o">-</span><span class="nl">directory:</span> <span class="s">"~/Tools/cocos2d-x/cocos2d-x-3.0alpha0-pre/scripting/"</span> <span class="o">-*-</span>
</span><span class='line'><span class="n">Grep</span> <span class="n">started</span> <span class="n">at</span> <span class="n">Mon</span> <span class="n">Nov</span> <span class="mi">11</span> <span class="mi">13</span><span class="o">:</span><span class="mi">55</span><span class="o">:</span><span class="mo">04</span>
</span><span class='line'>
</span><span class='line'><span class="n">find</span> <span class="p">.</span> <span class="o">-</span><span class="n">type</span> <span class="n">f</span> <span class="o">-</span><span class="n">exec</span> <span class="n">grep</span> <span class="o">-</span><span class="n">nH</span> <span class="o">-</span><span class="n">e</span> <span class="n">GLNode</span> <span class="p">{}</span> <span class="o">+</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js</span><span class="o">/</span><span class="n">jsb_cocos2d_extension</span><span class="p">.</span><span class="nl">js:</span><span class="mi">167</span><span class="o">:</span><span class="n">cc</span><span class="p">.</span><span class="n">GLNode</span><span class="p">.</span><span class="n">extend</span> <span class="o">=</span> <span class="n">cc</span><span class="p">.</span><span class="n">Class</span><span class="p">.</span><span class="n">extend</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">3</span><span class="o">:</span><span class="kt">void</span> <span class="n">GLNode</span><span class="o">::</span><span class="n">draw</span><span class="p">()</span> <span class="p">{</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">27</span><span class="o">:</span><span class="n">JSClass</span> <span class="o">*</span><span class="n">js_cocos2dx_GLNode_class</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">28</span><span class="o">:</span><span class="n">JSObject</span> <span class="o">*</span><span class="n">js_cocos2dx_GLNode_prototype</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">30</span><span class="o">:</span><span class="n">JSBool</span> <span class="n">js_cocos2dx_GLNode_constructor</span><span class="p">(</span><span class="n">JSContext</span> <span class="o">*</span><span class="n">cx</span><span class="p">,</span> <span class="n">uint32_t</span> <span class="n">argc</span><span class="p">,</span> <span class="n">jsval</span> <span class="o">*</span><span class="n">vp</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">34</span><span class="o">:</span> <span class="n">GLNode</span><span class="o">*</span> <span class="n">cobj</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GLNode</span><span class="p">();</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">41</span><span class="o">:</span> <span class="n">TypeTest</span><span class="o"><</span><span class="n">GLNode</span><span class="o">></span> <span class="n">t</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">51</span><span class="o">:</span> <span class="n">JS_AddNamedObjectRoot</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="o">&</span><span class="n">p</span><span class="o">-></span><span class="n">obj</span><span class="p">,</span> <span class="s">"cocos2d::GLNode"</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">59</span><span class="o">:</span><span class="kt">void</span> <span class="n">js_cocos2dx_GLNode_finalize</span><span class="p">(</span><span class="n">JSFreeOp</span> <span class="o">*</span><span class="n">fop</span><span class="p">,</span> <span class="n">JSObject</span> <span class="o">*</span><span class="n">obj</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">62</span><span class="o">:</span><span class="k">static</span> <span class="n">JSBool</span> <span class="n">js_cocos2dx_GLNode_ctor</span><span class="p">(</span><span class="n">JSContext</span> <span class="o">*</span><span class="n">cx</span><span class="p">,</span> <span class="n">uint32_t</span> <span class="n">argc</span><span class="p">,</span> <span class="n">jsval</span> <span class="o">*</span><span class="n">vp</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">65</span><span class="o">:</span> <span class="n">GLNode</span> <span class="o">*</span><span class="n">nobj</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GLNode</span><span class="p">();</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">68</span><span class="o">:</span> <span class="n">JS_AddNamedObjectRoot</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="o">&</span><span class="n">p</span><span class="o">-></span><span class="n">obj</span><span class="p">,</span> <span class="s">"GLNode"</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">73</span><span class="o">:</span><span class="n">JSBool</span> <span class="n">js_cocos2dx_GLNode_create</span><span class="p">(</span><span class="n">JSContext</span> <span class="o">*</span><span class="n">cx</span><span class="p">,</span> <span class="n">uint32_t</span> <span class="n">argc</span><span class="p">,</span> <span class="n">jsval</span> <span class="o">*</span><span class="n">vp</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">75</span><span class="o">:</span> <span class="n">GLNode</span><span class="o">*</span> <span class="n">ret</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GLNode</span><span class="p">();</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">79</span><span class="o">:</span> <span class="n">js_proxy_t</span> <span class="o">*</span><span class="n">proxy</span> <span class="o">=</span> <span class="n">js_get_or_create_proxy</span><span class="o"><</span><span class="n">GLNode</span><span class="o">></span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="n">ret</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">91</span><span class="o">:</span><span class="kt">void</span> <span class="n">js_register_cocos2dx_GLNode</span><span class="p">(</span><span class="n">JSContext</span> <span class="o">*</span><span class="n">cx</span><span class="p">,</span> <span class="n">JSObject</span> <span class="o">*</span><span class="n">global</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">92</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span> <span class="o">=</span> <span class="p">(</span><span class="n">JSClass</span> <span class="o">*</span><span class="p">)</span><span class="n">calloc</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">JSClass</span><span class="p">));</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">93</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">name</span> <span class="o">=</span> <span class="s">"GLNode"</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">94</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">addProperty</span> <span class="o">=</span> <span class="n">JS_PropertyStub</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">95</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">delProperty</span> <span class="o">=</span> <span class="n">JS_PropertyStub</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">96</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">getProperty</span> <span class="o">=</span> <span class="n">JS_PropertyStub</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">97</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">setProperty</span> <span class="o">=</span> <span class="n">JS_StrictPropertyStub</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">98</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">enumerate</span> <span class="o">=</span> <span class="n">JS_EnumerateStub</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">99</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">resolve</span> <span class="o">=</span> <span class="n">JS_ResolveStub</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">100</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">convert</span> <span class="o">=</span> <span class="n">JS_ConvertStub</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">101</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">finalize</span> <span class="o">=</span> <span class="n">js_cocos2dx_GLNode_finalize</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">102</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="o">-></span><span class="n">flags</span> <span class="o">=</span> <span class="n">JSCLASS_HAS_RESERVED_SLOTS</span><span class="p">(</span><span class="mi">2</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">109</span><span class="o">:</span> <span class="n">JS_FN</span><span class="p">(</span><span class="s">"ctor"</span><span class="p">,</span> <span class="n">js_cocos2dx_GLNode_ctor</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">JSPROP_PERMANENT</span> <span class="o">|</span> <span class="n">JSPROP_ENUMERATE</span><span class="p">),</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">114</span><span class="o">:</span> <span class="n">JS_FN</span><span class="p">(</span><span class="s">"create"</span><span class="p">,</span> <span class="n">js_cocos2dx_GLNode_create</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">JSPROP_PERMANENT</span> <span class="o">|</span> <span class="n">JSPROP_ENUMERATE</span><span class="p">),</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">118</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_prototype</span> <span class="o">=</span> <span class="n">JS_InitClass</span><span class="p">(</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">121</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="p">,</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">122</span><span class="o">:</span> <span class="n">js_cocos2dx_GLNode_constructor</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// constructor</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">129</span><span class="o">:</span> <span class="n">JS_SetPropertyAttributes</span><span class="p">(</span><span class="n">cx</span><span class="p">,</span> <span class="n">global</span><span class="p">,</span> <span class="s">"GLNode"</span><span class="p">,</span> <span class="n">JSPROP_ENUMERATE</span> <span class="o">|</span> <span class="n">JSPROP_READONLY</span><span class="p">,</span> <span class="o">&</span><span class="n">found</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">132</span><span class="o">:</span> <span class="n">TypeTest</span><span class="o"><</span><span class="n">GLNode</span><span class="o">></span> <span class="n">t</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">139</span><span class="o">:</span> <span class="n">p</span><span class="o">-></span><span class="n">jsclass</span> <span class="o">=</span> <span class="n">js_cocos2dx_GLNode_class</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">140</span><span class="o">:</span> <span class="n">p</span><span class="o">-></span><span class="n">proto</span> <span class="o">=</span> <span class="n">js_cocos2dx_GLNode_prototype</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">h:</span><span class="mi">5</span><span class="o">:</span><span class="k">class</span> <span class="nc">GLNode</span> <span class="o">:</span> <span class="k">public</span> <span class="n">cocos2d</span><span class="o">::</span><span class="n">Node</span> <span class="p">{</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">js_bindings_opengl</span><span class="p">.</span><span class="nl">h:</span><span class="mi">10</span><span class="o">:</span><span class="kt">void</span> <span class="n">js_register_cocos2dx_GLNode</span><span class="p">(</span><span class="n">JSContext</span> <span class="o">*</span><span class="n">cx</span><span class="p">,</span> <span class="n">JSObject</span> <span class="o">*</span><span class="n">global</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">jsb_opengl_registration</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">56</span><span class="o">:</span> <span class="n">js_register_cocos2dx_GLNode</span><span class="p">(</span><span class="n">_cx</span><span class="p">,</span> <span class="n">ccns</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">javascript</span><span class="o">/</span><span class="n">bindings</span><span class="o">/</span><span class="n">obfuscate</span><span class="o">/</span><span class="n">obfuscate_exclude_cocos2d</span><span class="p">.</span><span class="nl">js:</span><span class="mi">3049</span><span class="o">:</span><span class="n">CSSProperties</span><span class="p">.</span><span class="n">prototype</span><span class="p">.</span><span class="n">GLNode</span><span class="p">;</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">CCLuaEngine</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">615</span><span class="o">:</span> <span class="n">extendGLNode</span><span class="p">(</span><span class="n">lua_S</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">CCLuaEngine</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">726</span><span class="o">:</span><span class="kt">void</span> <span class="n">LuaEngine</span><span class="o">::</span><span class="n">extendGLNode</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">lua_S</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">CCLuaEngine</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">731</span><span class="o">:</span> <span class="n">lua_pushstring</span><span class="p">(</span><span class="n">lua_S</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">CCLuaEngine</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">736</span><span class="o">:</span> <span class="n">lua_pushcfunction</span><span class="p">(</span><span class="n">lua_S</span><span class="p">,</span><span class="n">tolua_Cocos2d_GLNode_registerScriptDrawHandler00</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">CCLuaEngine</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">739</span><span class="o">:</span> <span class="n">lua_pushcfunction</span><span class="p">(</span><span class="n">lua_S</span><span class="p">,</span><span class="n">tolua_Cocos2d_GLNode_unregisterScriptDrawHandler00</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">CCLuaEngine</span><span class="p">.</span><span class="nl">h:</span><span class="mi">146</span><span class="o">:</span> <span class="kt">void</span> <span class="n">extendGLNode</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">lua_S</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">24</span><span class="o">:</span><span class="kt">void</span> <span class="n">GLNode</span><span class="o">::</span><span class="n">draw</span><span class="p">()</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">26</span><span class="o">:</span> <span class="kt">int</span> <span class="n">handler</span> <span class="o">=</span> <span class="n">ScriptHandlerMgr</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">getObjectHandler</span><span class="p">((</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="k">this</span><span class="p">,</span> <span class="n">ScriptHandlerMgr</span><span class="o">::</span><span class="n">kGLNodeDrawHandler</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">38</span><span class="o">:</span> <span class="n">tolua_usertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span> <span class="s">"GLNode"</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">42</span><span class="o">:</span><span class="k">static</span> <span class="kt">int</span> <span class="n">tolua_collect_GLNode</span> <span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">44</span><span class="o">:</span> <span class="n">GLNode</span> <span class="o">*</span><span class="n">self</span> <span class="o">=</span> <span class="p">(</span><span class="n">GLNode</span><span class="o">*</span><span class="p">)</span> <span class="n">tolua_tousertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">63</span><span class="o">:</span><span class="cm">/* method: create of class GLNode */</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">64</span><span class="o">:</span><span class="err">#</span><span class="n">ifndef</span> <span class="n">TOLUA_DISABLE_tolua_Cocos2d_GLNode_create00</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">65</span><span class="o">:</span><span class="k">static</span> <span class="kt">int</span> <span class="n">tolua_Cocos2d_GLNode_create00</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">70</span><span class="o">:</span> <span class="o">!</span><span class="n">tolua_isusertable</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">&</span><span class="n">tolua_err</span><span class="p">)</span> <span class="o">||</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">77</span><span class="o">:</span> <span class="n">GLNode</span> <span class="o">*</span><span class="n">glNode</span> <span class="o">=</span> <span class="k">new</span> <span class="n">GLNode</span><span class="p">();</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">83</span><span class="o">:</span> <span class="n">toluafix_pushusertype_ccobject</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span> <span class="n">nID</span><span class="p">,</span> <span class="n">pLuaID</span><span class="p">,</span> <span class="p">(</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">glNode</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">100</span><span class="o">:</span><span class="cm">/* method: setShaderProgram of class GLNode */</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">101</span><span class="o">:</span><span class="err">#</span><span class="n">ifndef</span> <span class="n">TOLUA_DISABLE_tolua_Cocos2d_GLNode_setShaderProgram00</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">102</span><span class="o">:</span><span class="k">static</span> <span class="kt">int</span> <span class="n">tolua_Cocos2d_GLNode_setShaderProgram00</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">107</span><span class="o">:</span> <span class="o">!</span><span class="n">tolua_isusertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">&</span><span class="n">tolua_err</span><span class="p">)</span> <span class="o">||</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">115</span><span class="o">:</span> <span class="n">GLNode</span><span class="o">*</span> <span class="n">self</span> <span class="o">=</span> <span class="p">(</span><span class="n">GLNode</span><span class="o">*</span><span class="p">)</span> <span class="n">tolua_tousertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">292</span><span class="o">:</span><span class="cm">/* method: glBindFramebuffer of class GLNode */</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">300</span><span class="o">:</span> <span class="o">!</span><span class="n">tolua_isusertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">&</span><span class="n">tolua_err</span><span class="p">)</span> <span class="o">||</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">6386</span><span class="o">:</span> <span class="n">tolua_cclass</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">,</span><span class="s">"CCNode"</span><span class="p">,</span><span class="n">tolua_collect_GLNode</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">6387</span><span class="o">:</span> <span class="n">tolua_beginmodule</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">6388</span><span class="o">:</span> <span class="n">tolua_function</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span> <span class="s">"create"</span><span class="p">,</span> <span class="n">tolua_Cocos2d_GLNode_create00</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">6389</span><span class="o">:</span> <span class="n">tolua_function</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span> <span class="s">"setShaderProgram"</span><span class="p">,</span> <span class="n">tolua_Cocos2d_GLNode_setShaderProgram00</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaOpengl</span><span class="p">.</span><span class="nl">h:</span><span class="mi">13</span><span class="o">:</span><span class="k">class</span> <span class="nc">GLNode</span><span class="o">:</span><span class="k">public</span> <span class="n">cocos2d</span><span class="o">::</span><span class="n">Node</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">584</span><span class="o">:</span><span class="kt">int</span> <span class="n">tolua_Cocos2d_GLNode_registerScriptDrawHandler00</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">588</span><span class="o">:</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">tolua_isusertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">&</span><span class="n">tolua_err</span><span class="p">)</span> <span class="o">||</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">595</span><span class="o">:</span> <span class="n">GLNode</span><span class="o">*</span> <span class="n">glNode</span> <span class="o">=</span> <span class="p">(</span><span class="n">GLNode</span><span class="o">*</span><span class="p">)</span> <span class="n">tolua_tousertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">597</span><span class="o">:</span> <span class="n">ScriptHandlerMgr</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">addObjectHandler</span><span class="p">((</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">glNode</span><span class="p">,</span> <span class="n">handler</span><span class="p">,</span> <span class="n">ScriptHandlerMgr</span><span class="o">::</span><span class="n">kGLNodeDrawHandler</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">608</span><span class="o">:</span><span class="kt">int</span> <span class="n">tolua_Cocos2d_GLNode_unregisterScriptDrawHandler00</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">)</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">612</span><span class="o">:</span> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">tolua_isusertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="s">"GLNode"</span><span class="p">,</span><span class="mi">0</span><span class="p">,</span><span class="o">&</span><span class="n">tolua_err</span><span class="p">)</span> <span class="o">||</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">618</span><span class="o">:</span> <span class="n">GLNode</span><span class="o">*</span> <span class="n">glNode</span> <span class="o">=</span> <span class="p">(</span><span class="n">GLNode</span><span class="o">*</span><span class="p">)</span><span class="n">tolua_tousertype</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="mi">1</span><span class="p">,</span><span class="mi">0</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">619</span><span class="o">:</span> <span class="n">ScriptHandlerMgr</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">removeObjectHandler</span><span class="p">((</span><span class="kt">void</span><span class="o">*</span><span class="p">)</span><span class="n">glNode</span><span class="p">,</span><span class="n">ScriptHandlerMgr</span><span class="o">::</span><span class="n">kGLNodeDrawHandler</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">cpp:</span><span class="mi">779</span><span class="o">:</span> <span class="n">tolua_constant</span><span class="p">(</span><span class="n">tolua_S</span><span class="p">,</span><span class="s">"kGLNodeDrawHandler"</span><span class="p">,</span><span class="n">ScriptHandlerMgr</span><span class="o">::</span><span class="n">kGLNodeDrawHandler</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">h:</span><span class="mi">99</span><span class="o">:</span> <span class="n">kGLNodeDrawHandler</span><span class="p">,</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">h:</span><span class="mi">137</span><span class="o">:</span><span class="n">TOLUA_API</span> <span class="kt">int</span> <span class="n">tolua_Cocos2d_GLNode_registerScriptDrawHandler00</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">cocos2dx_support</span><span class="o">/</span><span class="n">LuaScriptHandlerMgr</span><span class="p">.</span><span class="nl">h:</span><span class="mi">138</span><span class="o">:</span><span class="n">TOLUA_API</span> <span class="kt">int</span> <span class="n">tolua_Cocos2d_GLNode_unregisterScriptDrawHandler00</span><span class="p">(</span><span class="n">lua_State</span><span class="o">*</span> <span class="n">tolua_S</span><span class="p">);</span>
</span><span class='line'><span class="p">.</span><span class="o">/</span><span class="n">lua</span><span class="o">/</span><span class="n">script</span><span class="o">/</span><span class="n">Opengl</span><span class="p">.</span><span class="nl">lua:</span><span class="mi">297</span><span class="o">:</span> <span class="k">return</span> <span class="nl">GLNode:</span><span class="n">create</span><span class="p">()</span>
</span><span class='line'><span class="n">Grep</span> <span class="n">finished</span> <span class="p">(</span><span class="n">matches</span> <span class="n">found</span><span class="p">)</span> <span class="n">at</span> <span class="n">Mon</span> <span class="n">Nov</span> <span class="mi">11</span> <span class="mi">13</span><span class="o">:</span><span class="mi">55</span><span class="o">:</span><span class="mo">07</span>
</span></code></pre></td></tr></table></div></figure>
<p>目测感觉两者差不多,而且代码量也不多,所以修改其中之一的 GLNode 类名称是可行的,总共八十多行结果,修改一种就四十行左右,而且其中出现的 “GLNode” 关键字,并不是都需要修改,有的是绑定到脚本引擎内部的,我们只需要修改其 C++ 端绑定的类型就 OK 了,一叶修改了 lua 绑定中的 GLNode 名字为 LuaGLNode,然后定位到 LuaOpengl 和相关文件(两个文件左右),查找并替换其中一部分 “GLNode” 关键字代码,这里借助 Emacs ,递进式的关键字查询替换,通过匹配规则,一个个过滤,手动选择是替换还是不替换,最后替换了所有 C++ 中 Lua 端的 GLNode 类名实现(替换的内容很少,比我想象中要少)。</p>
<p>到这里就已经完成能够让两种脚本引擎同时运行的方法。并且一叶修改了入口函数,在 AppDelegate 入口处,添加修改:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
<span class='line-number'>23</span>
<span class='line-number'>24</span>
<span class='line-number'>25</span>
<span class='line-number'>26</span>
<span class='line-number'>27</span>
<span class='line-number'>28</span>
<span class='line-number'>29</span>
<span class='line-number'>30</span>
<span class='line-number'>31</span>
<span class='line-number'>32</span>
<span class='line-number'>33</span>
<span class='line-number'>34</span>
<span class='line-number'>35</span>
<span class='line-number'>36</span>
<span class='line-number'>37</span>
<span class='line-number'>38</span>
<span class='line-number'>39</span>
<span class='line-number'>40</span>
<span class='line-number'>41</span>
<span class='line-number'>42</span>
<span class='line-number'>43</span>
<span class='line-number'>44</span>
<span class='line-number'>45</span>
<span class='line-number'>46</span>
<span class='line-number'>47</span>
<span class='line-number'>48</span>
<span class='line-number'>49</span>
<span class='line-number'>50</span>
<span class='line-number'>51</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">bool</span> <span class="n">AppDelegate</span><span class="o">::</span><span class="n">applicationDidFinishLaunching</span><span class="p">()</span>
</span><span class='line'><span class="p">{</span>
</span><span class='line'> <span class="c1">// initialize director</span>
</span><span class='line'> <span class="n">Director</span> <span class="o">*</span><span class="n">pDirector</span> <span class="o">=</span> <span class="n">Director</span><span class="o">::</span><span class="n">getInstance</span><span class="p">();</span>
</span><span class='line'> <span class="n">pDirector</span><span class="o">-></span><span class="n">setOpenGLView</span><span class="p">(</span><span class="n">EGLView</span><span class="o">::</span><span class="n">getInstance</span><span class="p">());</span>
</span><span class='line'>
</span><span class='line'> <span class="n">EGLView</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">setDesignResolutionSize</span><span class="p">(</span><span class="mi">480</span><span class="p">,</span> <span class="mi">320</span><span class="p">,</span> <span class="n">ResolutionPolicy</span><span class="o">::</span><span class="n">NO_BORDER</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// turn on display FPS</span>
</span><span class='line'> <span class="n">pDirector</span><span class="o">-></span><span class="n">setDisplayStats</span><span class="p">(</span><span class="kc">true</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="c1">// set FPS. the default value is 1.0/60 if you don't call this</span>
</span><span class='line'> <span class="n">pDirector</span><span class="o">-></span><span class="n">setAnimationInterval</span><span class="p">(</span><span class="mf">1.0</span> <span class="o">/</span> <span class="mi">60</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="c1">// runLua();</span>
</span><span class='line'> <span class="n">runCpp</span><span class="p">();</span>
</span><span class='line'><span class="c1">// runJsb();</span>
</span><span class='line'>
</span><span class='line'> <span class="k">return</span> <span class="kc">true</span><span class="p">;</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">AppDelegate</span><span class="o">::</span><span class="n">runCpp</span><span class="p">(){</span>
</span><span class='line'> <span class="k">auto</span> <span class="n">scene</span> <span class="o">=</span> <span class="n">HelloLeafsoar</span><span class="o">::</span><span class="n">scene</span><span class="p">();</span>
</span><span class='line'> <span class="n">Director</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">runWithScene</span><span class="p">(</span><span class="n">scene</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">AppDelegate</span><span class="o">::</span><span class="n">runJsb</span><span class="p">(){</span>
</span><span class='line'> <span class="n">ScriptingCore</span><span class="o">*</span> <span class="n">sc</span> <span class="o">=</span> <span class="n">ScriptingCore</span><span class="o">::</span><span class="n">getInstance</span><span class="p">();</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">register_all_cocos2dx</span><span class="p">);</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">register_all_cocos2dx_extension</span><span class="p">);</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">register_cocos2dx_js_extensions</span><span class="p">);</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">jsb_register_chipmunk</span><span class="p">);</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">register_all_cocos2dx_extension_manual</span><span class="p">);</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">register_CCBuilderReader</span><span class="p">);</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">jsb_register_system</span><span class="p">);</span>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">addRegisterCallback</span><span class="p">(</span><span class="n">JSB_register_opengl</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="n">sc</span><span class="o">-></span><span class="n">start</span><span class="p">();</span>
</span><span class='line'>
</span><span class='line'> <span class="n">ScriptEngineProtocol</span> <span class="o">*</span><span class="n">pEngine</span> <span class="o">=</span> <span class="n">ScriptingCore</span><span class="o">::</span><span class="n">getInstance</span><span class="p">();</span>
</span><span class='line'> <span class="n">ScriptEngineManager</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">setScriptEngine</span><span class="p">(</span><span class="n">pEngine</span><span class="p">);</span>
</span><span class='line'> <span class="n">ScriptingCore</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">runScript</span><span class="p">(</span><span class="s">"main.js"</span><span class="p">);</span>
</span><span class='line'><span class="p">}</span>
</span><span class='line'>
</span><span class='line'><span class="kt">void</span> <span class="n">AppDelegate</span><span class="o">::</span><span class="n">runLua</span><span class="p">(){</span>
</span><span class='line'> <span class="n">LuaEngine</span><span class="o">*</span> <span class="n">luaEngine</span> <span class="o">=</span> <span class="n">LuaEngine</span><span class="o">::</span><span class="n">getInstance</span><span class="p">();</span>
</span><span class='line'> <span class="n">ScriptEngineManager</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">setScriptEngine</span><span class="p">(</span><span class="n">luaEngine</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">path</span> <span class="o">=</span> <span class="n">FileUtils</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">fullPathForFilename</span><span class="p">(</span><span class="s">"hello.lua"</span><span class="p">);</span>
</span><span class='line'> <span class="n">luaEngine</span><span class="o">-></span><span class="n">executeScriptFile</span><span class="p">(</span><span class="n">path</span><span class="p">.</span><span class="n">c_str</span><span class="p">());</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>可以看到这里有三个方法,runCpp 、runLua 和 runJsb,这三者可单独独立运行,也可同时运行,在脚本实现不同的 log 打印,便能知晓,但如如果你在这三处同时运行了一个场景的话,那么根据场景的运行规则,后面运行的场景会入栈,替换之前场景的运行,三者的运行顺序,可以随意修改,并观其运行结果。为了测试这一点,我们同时运行 runLua、runCpp 和 runJsb ,然后使用一个全局定时器(请看 实现 <a href="http://blog.leafsoar.com/archives/2013/05-08.html">『Cocos2d-x 全局定时器』</a> 一文),每三秒钟弹出一个场景。而每一个场景的内部不同,这样我们便能看见首先运行了 runJsb 场景,三秒后 runLua ,之后 runCpp 场景,最终三秒后,所有场景弹出,Game Over 了。</p>
<h2>脚本绑定技术的特性</h2>
<p>以上通过对源代码的修改,一个例子,让 lua 和 js 两种脚本引擎同时运行,由于在任何时候只能有一个场景运行,所以,无论由 C++、lua 还是 js 来启动游戏,另外两种语言将会得不倒执行的权利,但是从另一个侧面,全局定时器它得的运行并不依赖场景的运行,这对我们研究程序执行过程中对象的特性提供了方便,前文通过一个 C++ 端实现的全局定时器,不论你运行的是不是脚本,是什么脚本,都不影响它之运行,那么我们就能能用这个定时器去定期的调用各种脚本,以让这三种脚本语言同时运行,在这样一个过程中,去验证对它们的内存分布,操作机制的的情况等 ~</p>
<p>一叶在 C++ 端开启了一个定时器,且由 C++ 运行了第一个场景,然后修改全局定时器的定时调用实现,添加对 lua 和 js 的脚本调用:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
<span class='line-number'>11</span>
<span class='line-number'>12</span>
<span class='line-number'>13</span>
<span class='line-number'>14</span>
<span class='line-number'>15</span>
<span class='line-number'>16</span>
<span class='line-number'>17</span>
<span class='line-number'>18</span>
<span class='line-number'>19</span>
<span class='line-number'>20</span>
<span class='line-number'>21</span>
<span class='line-number'>22</span>
</pre></td><td class='code'><pre><code class='c++'><span class='line'><span class="kt">void</span> <span class="n">GlobalSchedule</span><span class="o">::</span><span class="n">globalUpdate</span><span class="p">(</span><span class="kt">float</span> <span class="n">dt</span><span class="p">)</span> <span class="p">{</span>
</span><span class='line'> <span class="c1">// 这里写全局定时器的逻辑处理代码</span>
</span><span class='line'> <span class="n">CCLOG</span><span class="p">(</span><span class="s">"global update"</span><span class="p">);</span>
</span><span class='line'><span class="c1">// Director::getInstance()->popScene();</span>
</span><span class='line'> <span class="n">count</span> <span class="o">++</span><span class="p">;</span>
</span><span class='line'>
</span><span class='line'> <span class="k">auto</span> <span class="n">scene</span> <span class="o">=</span> <span class="n">Director</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">getRunningScene</span><span class="p">();</span>
</span><span class='line'> <span class="n">LabelTTF</span><span class="o">*</span> <span class="n">label</span> <span class="o">=</span> <span class="p">(</span><span class="n">LabelTTF</span><span class="o">*</span><span class="p">)</span><span class="n">scene</span><span class="o">-></span><span class="n">getChildByTag</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="n">label</span><span class="p">){</span>
</span><span class='line'> <span class="n">label</span> <span class="o">=</span> <span class="n">LabelTTF</span><span class="o">::</span><span class="n">create</span><span class="p">(</span><span class="s">"一叶 v 5~"</span><span class="p">,</span> <span class="s">""</span><span class="p">,</span> <span class="mi">24</span><span class="p">);</span>
</span><span class='line'> <span class="n">label</span><span class="o">-></span><span class="n">setPosition</span><span class="p">(</span><span class="n">Point</span><span class="p">(</span><span class="mi">250</span><span class="p">,</span> <span class="mi">300</span><span class="p">));</span>
</span><span class='line'> <span class="n">label</span><span class="o">-></span><span class="n">setColor</span><span class="p">(</span><span class="n">Color3B</span><span class="o">::</span><span class="n">BLACK</span><span class="p">);</span>
</span><span class='line'> <span class="n">scene</span><span class="o">-></span><span class="n">addChild</span><span class="p">(</span><span class="n">label</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="mi">100</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span><span class='line'> <span class="k">if</span> <span class="p">(</span><span class="n">count</span> <span class="o">%</span> <span class="mi">3</span> <span class="o">==</span> <span class="mi">0</span><span class="p">)</span>
</span><span class='line'> <span class="n">label</span><span class="o">-></span><span class="n">setScale</span><span class="p">(</span><span class="mi">1</span><span class="p">);</span>
</span><span class='line'> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">count</span> <span class="o">%</span> <span class="mi">3</span> <span class="o">==</span> <span class="mi">1</span><span class="p">)</span>
</span><span class='line'> <span class="n">ScriptingCore</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">runScript</span><span class="p">(</span><span class="s">"jsbMethod.js"</span><span class="p">);</span>
</span><span class='line'> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="n">count</span> <span class="o">%</span><span class="mi">3</span> <span class="o">==</span> <span class="mi">2</span><span class="p">)</span>
</span><span class='line'> <span class="n">LuaEngine</span><span class="o">::</span><span class="n">getInstance</span><span class="p">()</span><span class="o">-></span><span class="n">executeScriptFile</span><span class="p">(</span><span class="s">"luaMethod.lua"</span><span class="p">);</span>
</span><span class='line'> <span class="p">}</span>
</span><span class='line'><span class="p">}</span>
</span></code></pre></td></tr></table></div></figure>
<p>这是全局定时器的实现,它在当前运行的场景中添加了一个 Label ,label 的内容 “<strong>一叶 v 5~</strong>“,并且通过一个执行技术 <strong>count</strong> 来决定当前执行的是 C++ 还是 lua 或者 js,在不同的语言中,修改同一个元素的大小 <strong>Scale</strong>,看看 js 和 lua 的 method 文件实现:</p>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
<span class='line-number'>7</span>
<span class='line-number'>8</span>
<span class='line-number'>9</span>
<span class='line-number'>10</span>
</pre></td><td class='code'><pre><code class='lua'><span class='line'><span class="c1">-- luaMethod.lua 具体实现</span>
</span><span class='line'><span class="n">cclog</span> <span class="o">=</span> <span class="k">function</span><span class="p">(</span><span class="o">...</span><span class="p">)</span>
</span><span class='line'> <span class="nb">print</span><span class="p">(</span><span class="nb">string.format</span><span class="p">(</span><span class="o">...</span><span class="p">))</span>
</span><span class='line'><span class="k">end</span>
</span><span class='line'>
</span><span class='line'><span class="n">cclog</span><span class="p">(</span><span class="s2">"</span><span class="s">lua method ."</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">local</span> <span class="n">scene</span> <span class="o">=</span> <span class="n">CCDirector</span><span class="p">:</span><span class="n">getInstance</span><span class="p">():</span><span class="n">getRunningScene</span><span class="p">()</span>
</span><span class='line'><span class="kd">local</span> <span class="n">label</span> <span class="o">=</span> <span class="n">scene</span><span class="p">:</span><span class="n">getChildByTag</span><span class="p">(</span><span class="mi">100</span><span class="p">)</span>
</span><span class='line'><span class="n">label</span><span class="p">:</span><span class="n">setScale</span><span class="p">(</span><span class="mf">0.8</span><span class="p">)</span>
</span></code></pre></td></tr></table></div></figure>
<figure class='code'><figcaption><span></span></figcaption><div class="highlight"><table><tr><td class="gutter"><pre class="line-numbers"><span class='line-number'>1</span>
<span class='line-number'>2</span>
<span class='line-number'>3</span>
<span class='line-number'>4</span>
<span class='line-number'>5</span>
<span class='line-number'>6</span>
</pre></td><td class='code'><pre><code class='javascript'><span class='line'><span class="c1">// jsbMethod.js 具体实现</span>
</span><span class='line'><span class="nx">cc</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s2">" jsb method ."</span><span class="p">);</span>
</span><span class='line'>
</span><span class='line'><span class="kd">var</span> <span class="nx">scene</span> <span class="o">=</span> <span class="nx">cc</span><span class="p">.</span><span class="nx">Director</span><span class="p">.</span><span class="nx">getInstance</span><span class="p">().</span><span class="nx">getRunningScene</span><span class="p">();</span>
</span><span class='line'><span class="kd">var</span> <span class="nx">label</span> <span class="o">=</span> <span class="nx">scene</span><span class="p">.</span><span class="nx">getChildByTag</span><span class="p">(</span><span class="mi">100</span><span class="p">);</span>
</span><span class='line'><span class="nx">label</span><span class="p">.</span><span class="nx">setScale</span><span class="p">(</span><span class="mf">1.2</span><span class="p">);</span>
</span></code></pre></td></tr></table></div></figure>
<p>以上的代码都很简单,各种语言的逻辑一样,首先或者当前运行着的场景,然后通过 tag 获取场景中的元素 Label,再之修改它的大小,这样将程序运行,便能看见此 Label 定时改变大小,而且是三种大小状态不停的切换,可见已经完成了我们之前的目标,双开脚本引擎,用不语言控制同一个元素(文章最后给出所有代码)。</p>
<h3>绑定技术的特性浅析</h3>
<p>说道脚本绑定技术,这里可以插入一个新的内容来说,Cocos2d-html5 版本!作为对比,更为明了,h5 的实现和 jsb 的实现显然不同,h5 是跑在浏览器上的,jsb 是跑在移动终端上的。但是它们都用统一的接口实现,即用 js 写的游戏(同一套代码)即能够跑在浏览器上,又能够能跑在手机的 js 引擎上,这两者之间 <strong>表面相同,本质不同 </strong>,也是隐藏了内部实现,提供统一的接口让写程序更为简单。有兴趣的朋友可以去了解一下。在 Emacs 内置的 lisp 语言函数中有很多性能要求比较高的是使用 c 语言实现的,但在调用的时候全然不知(不知道就对了)。</p>
<p>而 jsb 和 lua 之间:知其不同,是见其表,知其皆同,是知其本,舍不同而观其同,可游心于物之初,哈。 在脚本引擎库中,以 C++ 实现的类型为基本,通过动态往虚拟机(引擎环境,或者上下文对象)里添加类型定义并绑定,每钟脚本类型都有其对应的 C++ 类型作为依据,通过脚本创建的对象最终被映射为调用 C++ 创建对象,而在 C++ 中创建的对象,也可以在脚本中随时获取,并修改其属性,当然其内部还有复杂的内存管理解决方案 (特别是本文中这样混合形的运行时环境,其对象生命周期就更复杂了,关系到引擎内部实现的细节,由不同语言创建的对象,由谁管理,由谁释放等等),在需要之时可以深究,而这里显然没有必要(这里引擎双开仅作学习之用),宏观角度考量,内存管理无非是定义一套规则,或是规范,这样能保证出错误的最小可能性(在 <a href="http://blog.leafsoar.com/archives/2013/05-22.html">『Cocos2d-x 内存管理浅说』</a> , <a href="http://blog.leafsoar.com/archives/2013/05-29.html">『Cocos2d-x 内存管理的一种实现』</a>, <a href="http://blog.leafsoar.com/archives/2013/06-04.html">『深入理解 Cocos2d-x 内存管理』</a>) 几篇文章有怎样通过编程规范来尽量避免内存出现的问题)。</p>
<p>如果我们需要添加一种新脚本绑定实现,比如使用 lisp 语言作为绑定 (Emacs 用户首先想到的就是 lisp 了),那么我们需要一个 lisp 运行时环境的实现,然后通过函数绑定,javascript 和 lua 的第一类型是 函数(First-class Function),它们都有很强的函数式语言特性,其封装的 Cocos2d-x 调用方式不过是语法糖衣,看起来像面相对象而已,此点 js 表现更甚。所以对于 lisp 实现来说,是可行的,至于最后写起来是否顺手不得而知,目测如果实现,写法更像 lua 对 Cocos2d-x 的 style,可能很好使,可能很糟糕 :P 也许使用对象形的脚本语言更加合宜。</p>
<h2>非吾小天下 宏观而已</h2>
<p>想要玩转这里脚本引擎,那么你至少会绑定,知道怎么绑定,其具体步骤 ?jsb 怎么手动绑定,lua 怎么手动绑定,而且还有自动绑定脚本,jsb 的内部使用了 spidermonkey 开源的 js 引擎,lua 还可以开 jit,其运行环境有很多复杂的上下文参数,各种错综复杂,提出各种专有的概念,有着各自不同的游戏规则,其内部的细枝末叶是对具体问题的解决方案,然而有的时候我们并不知道需要解决的问题由来,一环套着一环,我在这里却避而不谈,一方面是因为我也不知 :p ,另一方面是因为不想让我或者别人陷入这样那样的泥沼中去,从宏观的角度去看问题,或者抽象,在 lua 和 js 这两种脚本引擎中,其特点为何,能达到什么样的效果,在本文的操作过程,并没有什么复杂的步骤,修改了一处编译报错问题,引擎双开,操作同一对象。避开了很多各脚本的内部实现细节内容。把复杂的问题简单化 ~</p>
<p>关于本文的内容,一叶会将代码项目提交到 github 以供参考(在文章最后给出<sup id="fnref:1"><a href="#fn:1" rel="footnote">1</a></sup>),内容不多,组织凌乱(时不时想修改,临时添加以看不同的测试效果),所以就将就着看了,哈,我的博文从不倾向给出一个完整的解决方案,以思路为重,其过程比结果更为重要。</p>
<div class="footnotes">
<hr/>
<ol>
<li id="fn:1">
<p>本文环境及其代码:<a href="https://github.com/leafsoar/cocos2d-x-script-engine">https://github.com/leafsoar/cocos2d-x-script-engine</a><a href="#fnref:1" rev="footnote">↩</a></p></li>
</ol>
</div>
]]></content>
</entry>
<entry>
<title type="html"><![CDATA[CCScrollView 实现帮助界面、关卡选择]]></title>
<link href="http://blog.leafsoar.com/archives/2013/07-27.html"/>
<updated>2013-07-27T17:30:00+08:00</updated>
<id>http://blog.leafsoar.com/archives/2013/ccscrollview-level</id>
<content type="html"><![CDATA[<p>本文介绍了 CCScrollView 来编写帮助界面和关卡选择界面的方法,在编写这样一个功能之时,大多会遇到一些困难,这里也是同样,最后提供了一个相应且合理的解决方案,并解说了其它实现方案的优缺点,这里的内容,你可以直接拿去用,或者可以作为实现的参考。总能找到你需要的东西,或多~或少~。文章大致内容如下:</p>