root/lang/d/koke/trunk/character.d @ 7081

Revision 7081, 19.3 kB (checked in by omega, 5 years ago)

運営レーザーを実装

Line 
1/********************************************************************************/
2/*      character.d                                                                                                                                     */
3/*------------------------------------------------------------------------------*/
4/*      製作              ( ゜ワ゜)ノ / 松久貫太                                                                  */
5/*      製作開始    2008/01/03                                                                                                              */
6/*      MAIL            omega@personal.email.ne.jp                                                                              */
7/*      URL             http://nagoya.cool.ne.jp/o_mega                                                                         */
8/*                                                                                                                                                              */
9/*      このソースは「やわらかライセンス」の元で配布されています。                                   */
10/*-更新履歴---------------------------------------------------------------------*/
11/*      2008/01/04                                                                                                                                      */
12/*-その他-----------------------------------------------------------------------*/
13/*      なし                                                                                                                                              */
14/********************************************************************************/
15
16private import gamecore;
17private import hell2;
18private import boot;
19private import actor;
20private import vector;
21private import keypad;
22private import map;
23
24//********************************************************************************
25// キャラクタ
26//********************************************************************************
27
28class Character : Actor{
29        enum TYPE{
30                NONE = 0,
31                SHADOW = 0,
32                NICOCHU,
33                VC_MK,
34                RAINBOW_RAY,
35                EXPLODE,
36                UP_NUSHI,
37                ARASHI,
38                MAX,
39        }
40        // 名称
41        static string type_name[] =
42                ["SHADOW" , "NICOCHU" , "SOWAKA" , "RAINBOW_RAY" , "EXPLODE" , "UP_NUSHI" , "ARASHI" , "MAX"];
43        static const double type_movespeed[] =
44                [   0.0 ,  0.03 ,   0.1 ,   0.5 ,     0 ,  0.03  ,  0.04 ];             // 移動速度
45        static const bool type_shadow[] =
46                [ false ,  true ,  true , false , false ,  true  ,  true ];             // 影の有無
47        static const bool type_shake[] =
48                [ false ,  true ,  true , false , false ,  true  ,  true ];             // 揺れの有無
49        static const int type_life_max[] =
50                [     0 ,    20 ,  9999 ,     0 ,     0 ,    20  ,    20 ];             // ライフ上限値
51        static const bool type_blocking[] =     
52                [ false ,  true ,  true , false , false ,  true  ,  true ];             // 衝突判定の有無
53        static const int type_life_dec[] =
54                [         0 ,    40 ,     0 ,     0 ,     0 ,    40  ,    40 ];         // ライフ減少時間(フレーム)
55       
56        // 方向
57        enum DIRECTION{
58                DOWN = 0,
59                RIGHT,
60                LEFT,
61                UP,
62                MAX,
63        }
64        double vecx[] = [  0 ,  1 , -1 ,  0 ];  // ベクトル
65        double vecy[] = [  1 ,  0 ,  0 , -1 ];
66       
67        // 行動
68        enum MOTION{
69                NORMAL = 0,             // 通常
70                WALK,                   // 移動
71                DAMAGED,                // 非ダメージ
72                SHOOTING,               // 射撃中(ソワカちゃん向け)
73                VANISH,                 // 消失(爆発エフェクト向け)
74                DYING,                  // 死亡中
75                EATING,                 // もぐもぐ中(ニコ厨の芝)
76                EATING2,                // もぐもぐ中2(あらしの動画)
77        }
78        static const int motion_interval[] = [ 0 , 999 , 20 , 2 , 24 , 40 , 20 , 80];
79       
80        DIRECTION direction;    // 方向
81        MOTION motion;                  // モーション
82        int motion_wait;                // モーション待ち時間(フレーム)
83        double move_fraction;   // 移動時の端数(0~1)
84        TYPE type;
85        int timer;
86        Keypad keypad;
87       
88        int life;
89       
90        GameMain gamemain;
91       
92        this(){
93                position = new Vec3();
94                type = TYPE.NICOCHU;
95                move_fraction = 0;
96                timer = 0;
97                direction = DIRECTION.DOWN;
98                motion = MOTION.NORMAL;
99                life = 0;
100        }
101       
102        void init(GameMain gamemain , Vec3 pos , TYPE type){
103                this.gamemain = gamemain;
104                this.position = pos;
105                this.type = type;
106                this.exist = true;
107                this.motion = MOTION.NORMAL;
108                this.move_fraction = 0;
109                this.keypad = null;
110                this.timer = 0;
111               
112                if(type == TYPE.VC_MK) this.keypad = new Keypad();
113                this.life = type_life_max[type];
114        }
115       
116        Vec3 getPosition(){return position;}
117        Vec3 getDestination(){
118                if(motion != MOTION.WALK) return position;
119                return new Vec3(position.x + vecx[direction] , position.y + vecy[direction] , 0);
120        }
121       
122        void move(){
123                timer++;
124               
125                Map map = gamemain.map;
126                int x = cast(int)position.x , y = cast(int)position.y;
127               
128                // 画面外
129                if(x < 0 || y < 0 || x >= map.width || y >= map.height){
130                        exist = false;
131                }
132               
133                // ライフ減少
134                if(type_life_dec[type] > 0 && timer % type_life_dec[type] == 0){
135                        life--;
136                }
137               
138                // モーション管理
139                motion_wait--;
140                if(motion_wait < 1){
141                        motion_wait = 0;
142                        if(motion == MOTION.VANISH || motion == MOTION.DYING) exist = false;
143                        if(motion == MOTION.DYING){
144                                if(map.getGrassLevel(x,y) < 2) map.setGrass(x,y,20);
145                        }
146                        motion = MOTION.NORMAL;
147                }
148               
149                // 死亡モーション遷移
150                if(life < 0  && motion != MOTION.VANISH && motion != MOTION.DYING && type_life_max[type] > 0){
151                        setMotion(MOTION.DYING);
152                        life = 0;
153                }
154                if(motion == MOTION.DYING) return;
155               
156                // キャラクタ固有行動
157                switch(type){
158               
159                        // ニコ厨
160                        case TYPE.NICOCHU:
161                                if(motion == MOTION.NORMAL && Hell_randInt(0,10) < 5){
162                                        if(eatGrass()){
163                                                setMotion(MOTION.EATING);
164                                                selectNewDirection();
165                                        }
166                                }
167                                if(motion == MOTION.EATING) map.setGrass(x,y,0);
168                                if(motion == MOTION.NORMAL){
169                                        int t = Hell_randInt(0,100);
170                                        if(t < configparser.getint("NICOCHU_TURN_RATIO")){
171                                                int gl = cast(int)map.getGrassLevel(x-1,y);
172                                                int gr = cast(int)map.getGrassLevel(x+1,y);
173                                                int gu = cast(int)map.getGrassLevel(x,y-1);
174                                                int gd = cast(int)map.getGrassLevel(x,y+1);
175                                               
176                                                if(gl+gr+gu+gd == 0){
177                                                        selectNewDirection();
178                                                }else{
179                                                        int r = Hell_randInt(0,gl+gr+gu+gd);
180                                                        if(r < gl){
181                                                                direction = DIRECTION.LEFT;
182                                                        }else if(r < gl + gr){
183                                                                direction = DIRECTION.RIGHT;
184                                                        }else if(r < gl + gr + gu){
185                                                                direction = DIRECTION.UP;
186                                                        }else{
187                                                                direction = DIRECTION.DOWN;
188                                                        }
189                                                }
190                                        }
191                                        setMotion(MOTION.WALK);
192                                       
193                                }
194                               
195                                if(timer % (configparser.getint("UPNUSHI_TRANSFORM_INTERVAL") * 40) == 0
196                                        && Hell_randInt(0,100) < configparser.getint("UPNUSHI_TRANSFORM_RATIO") )
197                                {
198                                        exist = false;
199                                       
200                                        Character c = gamemain.charpool.set( new Vec3(position) , TYPE.UP_NUSHI , direction );
201                                }
202                                break;
203                       
204                        // ソワカちゃん
205                        case TYPE.VC_MK:
206                                controlCharacter();
207                                life = type_life_max[type];     // 常時初期ライフ
208                                break;
209                               
210                        // びーむ
211                        case TYPE.RAINBOW_RAY:
212                                if(motion == MOTION.NORMAL) setMotion(MOTION.WALK);
213                                destroyNeighbor();
214                                break;
215                       
216                        // 爆風
217                        case TYPE.EXPLODE:
218                                break;
219                       
220                        // うp主
221                        case TYPE.UP_NUSHI:
222                                if(motion == MOTION.NORMAL){
223                                        if(Hell_randInt(0,10) < 3){
224                                                selectNewDirection();
225                                        }
226                                        setMotion(MOTION.WALK);
227                                }
228                               
229                                if(life < 1){
230                                        map.set(cast(int)position.x , cast(int)position.y , MapChip.TYPE.MOVIE);
231                                        setMotion(MOTION.DYING);
232                                }
233                               
234                                break;
235                       
236                        // あらし
237                        case TYPE.ARASHI:
238                                if(motion == MOTION.NORMAL){
239                                        if(eatMovie()){
240                                                setMotion(MOTION.EATING2);
241                                        }else{
242                                                if(Hell_randInt(0,10) < 3){
243                                                        selectNewDirection();
244                                                }
245                                                setMotion(MOTION.WALK);
246                                        }
247                                }
248                                map.setGrass(x,y,0);
249                               
250                                break;
251                               
252                        default:
253                                break;
254                }
255                actCharacter();
256        }
257       
258        // 移動とか汎用処理
259        void actCharacter(){
260                if(motion == MOTION.WALK){
261                        // 移動
262                        move_fraction += type_movespeed[cast(int)type];
263                        if(move_fraction >= 1.0){
264                                move_fraction = 1.0;
265                                position.x = cast(int)toMapXf();
266                                position.y = cast(int)toMapYf();
267                               
268                                move_fraction = 0;
269                                setMotion(MOTION.NORMAL);
270                        }
271                       
272                        // 移動先の確認
273                        int x = cast(int)(position.x + vecx[cast(int)direction]);
274                        int y = cast(int)(position.y + vecy[cast(int)direction]);
275                        if( !gamemain.map.isMovable(x,y) && isBlocking() ){
276                                move_fraction = 0;
277                                setMotion(MOTION.NORMAL);
278                        }
279                }
280        }
281       
282        bool isBlocking(){
283                return type_blocking[type];
284        }
285       
286        // 移動方向をランダム決定する(障害物のない方向を向く)
287        void selectNewDirection(){
288                bool chk;
289                int t = 0;
290                do{
291                        t++;
292                        direction = cast(DIRECTION) Hell_randInt(0,DIRECTION.MAX);
293                        int x = cast(int)(position.x + vecx[direction]);
294                        int y = cast(int)(position.y + vecy[direction]);
295                        chk = gamemain.map.isMovable(x,y);
296                }while(!chk && t < 32);
297        }
298       
299        // ソワカちゃん専用処理(プレーヤー操作)
300        void controlCharacter(){
301                // 七色レーザー発射
302                if(keypad.isPressEnter() && motion != MOTION.SHOOTING){
303                        Character c = gamemain.charpool.set( new Vec3(position) , TYPE.RAINBOW_RAY , direction );
304                        if(c){
305                                c.move_fraction = move_fraction;
306                                setMotion(MOTION.SHOOTING);
307                        }
308                }
309               
310                // パッド操作
311                if(motion == MOTION.NORMAL){
312                        if(move_fraction != 0){
313                                setMotion(MOTION.WALK);
314                                return;
315                        }
316                       
317                        // 移動方向決定
318                        if(keypad.isPressDown()){
319                                direction = DIRECTION.DOWN;
320                                setMotion(MOTION.WALK);
321                        }
322                       
323                        if(keypad.isPressRight()){
324                                direction = DIRECTION.RIGHT;
325                                setMotion(MOTION.WALK);
326                        }
327                       
328                        if(keypad.isPressUp()){
329                                direction = DIRECTION.UP;
330                                setMotion(MOTION.WALK);
331                        }
332                       
333                        if(keypad.isPressLeft()){
334                                direction = DIRECTION.LEFT;
335                                setMotion(MOTION.WALK);
336                        }
337                }
338        }
339       
340        // 芝を食うの図
341        bool eatGrass(){
342                int x = cast(int)position.x , y = cast(int)position.y;
343               
344                if(move_fraction != 0) return false;
345                if(gamemain.map.getGrassLevel(x,y) < 1) return false;   // レベル1以上の芝しか食べない
346               
347                // 芝を食う
348                life += gamemain.map.getGrassLevel(x,y) * 2;
349                if(life >= type_life_max[type]) {
350                        // ライフ上限を超えたらライフを半分にして増殖
351                        life /= 2;
352                       
353                        TYPE ty = TYPE.NICOCHU;
354                        // 一定率で"あらし"になる
355                        if(Hell_randInt(0,100) < configparser.getint("ARASHI_TRANSFORM_RATIO")){
356                                ty = TYPE.ARASHI;
357                        }
358                       
359                        Character c = gamemain.charpool.set( new Vec3(position.x , position.y , 0) , ty);
360                        if(c){
361                                c.life = life;
362                                while(c.direction == direction){
363                                        c.direction = cast(DIRECTION) Hell_randInt( 0 , DIRECTION.MAX );
364                                }
365                               
366                        }
367                }
368                gamemain.map.setGrass(x,y,0);
369                return true;
370        }
371       
372        // 動画を食べる
373        bool eatMovie(){
374                int x = cast(int)position.x , y = cast(int)position.y;
375               
376                if(move_fraction != 0) return false;
377                for(int t = 0 ; t < cast(int)DIRECTION.MAX ; t++){
378                        int px = x + cast(int)vecx[t];
379                        int py = y + cast(int)vecy[t];
380                        if(gamemain.map.isMap(px,py, MapChip.TYPE.MOVIE)){
381                                // 動画を食べる
382                                direction = cast(DIRECTION)t;
383                                life += configparser.getint("ARASHI_EAT_MOVIE_LIFE_GAIN");
384                               
385                                gamemain.map.set(px,py,MapChip.TYPE.NONE);
386                               
387                                Character c = gamemain.charpool.set( new Vec3(px , py , 0) , TYPE.EXPLODE);
388                                if(c){
389                                        c.setMotion(MOTION.VANISH);
390                                }
391                               
392                                return true;
393                        }
394                }
395                return false;
396        }
397       
398        void destroyNeighbor(){
399                destroyMap(cast(int)position.x , cast(int)position.y);
400        }
401        // ぶっとばすぞー
402        void destroyMap(int xx,int yy,int size = 1, bool all = false){
403                for(int x=-size;x<=size;x++){
404                        for(int y=-size;y<=size;y++){
405                                int px = xx + x;
406                                int py = yy + y;
407                               
408                                if(gamemain.map.isMap( px , py , MapChip.TYPE.MOVIE) || (all && !gamemain.map.isMap( px , py , MapChip.TYPE.NONE))){
409                                        gamemain.map.set( px , py , MapChip.TYPE.NONE);
410                                        Character c = gamemain.charpool.set( new Vec3(px , py , 0) , TYPE.EXPLODE);
411                                        if(c){
412                                                c.setMotion(MOTION.VANISH);
413                                        }
414                                }
415                                gamemain.map.setGrass( px , py , 0 );
416                               
417                                Character ch[] = gamemain.charpool.getCharacterAtMap(px,py);
418                               
419                                foreach(inout c;ch){
420                                        // VC_MKでなく、ライフがあるキャラば爆発しろ!
421                                        if(c && c.exist && c.type != TYPE.VC_MK && type_life_max[c.type] > 0){
422                                                c.destroy();
423                                        }
424                                }
425                        }
426                }
427        }
428       
429        // 爆発しろ
430        void destroy(){
431                exist = false;
432               
433                Character c = gamemain.charpool.set( new Vec3(position) , TYPE.EXPLODE , direction );
434                if(c){
435                        c.move_fraction = move_fraction;
436                        c.setMotion(MOTION.VANISH);
437                }
438        }
439       
440        // モーションセット
441        void setMotion(MOTION m){
442                this.motion = m;
443                this.motion_wait = motion_interval[m];
444        }
445       
446        // 作画
447        void draw(DRAW_PRIORITY dp = DRAW_PRIORITY.NORMAL){
448                if(dp == DRAW_PRIORITY.NORMAL){
449                        Map map = gamemain.map;
450                        double mx = toMapXf() , my = toMapYf();
451                        // アルファブレンド
452                        int alpha = 255;
453                        if(motion == MOTION.DYING) alpha = 255 * motion_wait / motion_interval[motion];
454                       
455                        // 影
456                        if(type_shadow[cast(int)type]){
457                                /* 速度を稼ぐため、下半分だけコピーする */
458                                Hell_drawTexture("char" , map.toViewX(mx,my) , map.toViewY(mx,my) + CHIP_SIZE / 2
459                                        ,CHIP_SIZE * 0 + CHIP_SIZE * 5
460                                        ,CHIP_SIZE * TYPE.SHADOW + CHIP_SIZE / 2
461                                        ,CHIP_SIZE , CHIP_SIZE / 2 , 1 , 1
462                                        ,0,255,255,255,alpha);
463                                /* 本来のコード
464                                Hell_drawTexture("char" , map.toViewX(mx,my) , map.toViewY(mx,my)
465                                        ,CHIP_SIZE * 0 + CHIP_SIZE * 5
466                                        ,CHIP_SIZE * TYPE.SHADOW
467                                        ,CHIP_SIZE , CHIP_SIZE , 1 , 1
468                                        ,0,255,255,255,alpha);
469                                */
470                        }
471                       
472                        int shake = type_shake[cast(int)type] ? ((timer / 8) % 2) : 0 ;
473                        int reverse = (direction == DIRECTION.RIGHT || direction == DIRECTION.UP) ? -1 : 1;
474                        if(motion == MOTION.NORMAL || motion == MOTION.WALK){
475                                // 通常
476                                Hell_drawTexture("char"
477                                        , map.toViewX(mx,my) + (1 - reverse) * CHIP_SIZE / 2 , map.toViewY(mx,my) + shake
478                                        ,CHIP_SIZE * (cast(int)direction / 2) + CHIP_SIZE * 5
479                                        ,CHIP_SIZE * type
480                                        ,CHIP_SIZE , CHIP_SIZE , reverse , 1.0);
481                        }else if(motion == MOTION.DAMAGED){
482                                // ダメージ
483                                if(timer % 4 < 2)
484                                Hell_drawTexture("char"
485                                        , map.toViewX(mx,my) + (1 - reverse) * CHIP_SIZE / 2 , map.toViewY(mx,my)
486                                        ,CHIP_SIZE * (cast(int)direction / 2) + CHIP_SIZE * 5
487                                        ,CHIP_SIZE * type
488                                        ,CHIP_SIZE , CHIP_SIZE , reverse , 1.0);
489                        }else if(motion == MOTION.SHOOTING){
490                                // 射撃
491                                Hell_drawTexture("char"
492                                        , map.toViewX(mx,my) + (1 - reverse) * CHIP_SIZE / 2 , map.toViewY(mx,my)
493                                        ,CHIP_SIZE * (cast(int)direction / 2 + 2) + CHIP_SIZE * 5
494                                        ,CHIP_SIZE * type
495                                        ,CHIP_SIZE , CHIP_SIZE , reverse , 1.0);
496                        }else if(motion == MOTION.VANISH){
497                                // 消失
498                                Hell_drawTexture("char"
499                                        , map.toViewX(mx,my) , map.toViewY(mx,my)
500                                        ,CHIP_SIZE * (timer / 6) + CHIP_SIZE * 5
501                                        ,CHIP_SIZE * type
502                                        ,CHIP_SIZE , CHIP_SIZE);
503                        }else if(motion == MOTION.DYING){
504                                // 死亡
505                                int fly_y = (motion_interval[MOTION.DYING] - motion_wait);
506                                Hell_drawTexture("char"
507                                        , map.toViewX(mx,my) , map.toViewY(mx,my) - CHIP_SIZE / 4 - fly_y
508                                        ,CHIP_SIZE * 6
509                                        ,CHIP_SIZE * 0
510                                        ,CHIP_SIZE , CHIP_SIZE , 1 , 1
511                                        ,0,255,255,255,alpha);
512                                Hell_drawTexture("char"
513                                        , map.toViewX(mx,my) + (1 - reverse) * CHIP_SIZE / 2 , map.toViewY(mx,my) - fly_y
514                                        ,CHIP_SIZE * (cast(int)direction / 2) + CHIP_SIZE * 5
515                                        ,CHIP_SIZE * type
516                                        ,CHIP_SIZE , CHIP_SIZE , reverse , 1
517                                        ,0,255,255,255,alpha);
518                        }else if(motion == MOTION.EATING){
519                                // 食事中(ニコ厨が芝を食べる)
520                                Hell_drawTexture("char"
521                                        , map.toViewX(mx,my) + (1 - reverse) * CHIP_SIZE / 2 , map.toViewY(mx,my) - ((timer / 3) % 2) * 2
522                                        ,CHIP_SIZE * (cast(int)direction / 2) + CHIP_SIZE * 5
523                                        ,CHIP_SIZE * type
524                                        ,CHIP_SIZE , CHIP_SIZE , reverse , 1.0);
525                        }else if(motion == MOTION.EATING2){
526                                // 食事中2(あらしが動画を食べる)
527                                Hell_drawTexture("char"
528                                        , map.toViewX(mx,my) + (1 - reverse) * CHIP_SIZE / 2 , map.toViewY(mx,my) + shake
529                                        ,CHIP_SIZE * (cast(int)direction / 2 + ((timer / 8) % 2) * 2) + CHIP_SIZE * 5
530                                        ,CHIP_SIZE * type
531                                        ,CHIP_SIZE , CHIP_SIZE , reverse , 1.0);
532                                }
533                }else{
534                }
535        }
536       
537        // ステータス
538        void drawStatus(){
539                Map map = gamemain.map;
540                double mx = toMapXf() , my = toMapYf();
541                int vx = cast(int)map.toViewX(mx,my);
542                int vy = cast(int)map.toViewY(mx,my);
543               
544                Hell_drawRect(vx - 8 * 11  , vy - 16 , 8 * 12 , 8 * 6 , 0,0, 255,255,255,192);
545                Hell_drawFont(type_name[cast(int)type] , vx - 8 * 10  , vy - 8);
546                Hell_drawFont("LIFE:" ~ std.string.toString(life) , vx - 8 * 10 , vy + 2);
547                Hell_drawFont("TIME:" ~ std.string.toString(timer / 40) , vx - 8 * 10 , vy + 10);
548                //Hell_drawFont("MOT:" ~ std.string.toString(cast(int)motion) , vx - 8 * 10 , vy + 10);
549                //Hell_drawFont("MOW:" ~ std.string.toString(cast(int)motion_wait) , vx - 8 * 10 , vy + 18);
550        }
551       
552        double toMapXf(){
553                return position.x + move_fraction * vecx[cast(int)direction];
554        }
555        double toMapYf(){
556                return position.y + move_fraction * vecy[cast(int)direction];
557        }
558}
559
560
561//********************************************************************************
562// キャラクタプール
563//********************************************************************************
564
565class CharacterPool : ActorPool ! (Character){
566        GameMain gamemain;
567        int width;
568        int height;
569       
570        // キャラクタのバケットソート用クラス
571        class CharacterBacket{
572                const static int BACKET_MAX = 4;
573                Character char_ptr[];
574               
575                this(){
576                        char_ptr = new Character[BACKET_MAX];
577                        init();
578                }
579               
580                void init(){
581                        for(int t=0;t<BACKET_MAX;t++) char_ptr[t] = null;
582                }
583               
584                void entry(inout Character ch){
585                        for(int t=0;t<BACKET_MAX;t++){
586                                if(char_ptr[t] is null){
587                                        char_ptr[t] = ch;
588                                        return;
589                                }
590                        }
591                }
592               
593                // バケット内のキャラを描く
594                void draw(){
595                        for(int t=0;t<BACKET_MAX;t++){
596                                if(char_ptr[t]) char_ptr[t].draw();
597                        }
598                }
599        }
600        CharacterBacket charbacket[];
601       
602        this(GameMain gamemain , int n , int width , int height){
603                this.gamemain = gamemain;
604               
605                this.width = width;
606                this.height = height;
607                this.charbacket = new CharacterBacket[width * height];
608                foreach(inout c;this.charbacket) c = new CharacterBacket();
609               
610                super(n);
611        }
612       
613        // キャラクタ出現
614        Character set(Vec3 pos , Character.TYPE type , Character.DIRECTION direction = Character.DIRECTION.DOWN){
615                Character c = getInstance();
616                if(c){
617                        c.init(gamemain , pos , type);
618                        c.direction = direction;
619                        return c;
620                }else{
621                        return null;
622                }
623        }
624       
625        // キャラクタ数を数える
626        int count(Character.TYPE type = Character.TYPE.NONE){
627                int result = 0;
628                foreach(c;actors){
629                        if(c.exist == true &&(type == Character.TYPE.NONE || c.type == type)) result++;
630                }
631                return result;
632        }
633       
634        void move(){
635                // 動かす
636                super.move();
637                updateBacket();
638        }
639       
640        // バケットソートを更新する
641        void updateBacket(){
642                // バケット初期化
643                foreach(inout c;charbacket) c.init();
644               
645                // バケットソート
646                foreach(inout c;actors){
647                        if(c.exist){
648                                int x = cast(int)(c.toMapXf());
649                                int y = cast(int)(c.toMapYf());
650                                if(!inRange(x,y)) continue;
651                               
652                                charbacket[x + y * width].entry(c);
653                        }
654                }
655        }
656       
657        // ステータス作画(フラグが立っているもののみ)
658        void drawStatus(){
659                foreach(inout c;actors){
660                        if(c.exist) c.drawStatus();
661                }
662        }
663       
664        // 作画(with バケットソート)
665        void drawAtMap(int x,int y){
666                if(!inRange(x,y)) return;
667                charbacket[x + y * width].draw();
668        }
669       
670        // キャラ取得(with バケットソート)
671        Character[] getCharacterAtMap(int x,int y){
672                if(!inRange(x,y)) return null;
673                return charbacket[x + y * width].char_ptr;
674        }
675       
676        // マップ端からランダム進入
677        void entryFromMapBorder(Character.TYPE type){
678                int x,y;
679                int rndkey = Hell_randInt(0 , (width + height));
680               
681                Character c = set( new Vec3() , type);
682                if(!c) return;
683               
684                if(rndkey > width){
685                        // y軸方面から進入
686                        c.position.y = rndkey - width;
687                        if(Hell_randInt(0,10) < 5){
688                                // 左から
689                                c.position.x = 0;
690                                c.direction = Character.DIRECTION.RIGHT;
691                        }else{
692                                // 右から
693                                c.position.x = width - 1;
694                                c.direction = Character.DIRECTION.LEFT;
695                        }
696                }else{
697                        // x軸方向から進入
698                        c.position.x = rndkey;
699                        if(Hell_randInt(0,10) < 5){
700                                // 上から
701                                c.position.y = 0;
702                                c.direction = Character.DIRECTION.DOWN;
703                        }else{
704                                // 下から
705                                c.position.y = height - 1;
706                                c.direction = Character.DIRECTION.UP;
707                        }
708                }
709        }
710       
711        // キャラクタを取り除く
712        void removeCharacter(Character.TYPE type){
713                foreach(inout c;actors){
714                        if(c.exist && c.type == type) c.exist = false;
715                }
716        }
717       
718        bool inRange(int x,int y){
719                if(x < 0 || y < 0 || x >= width || y >= height) return false;
720                return true;
721        }
722}
Note: See TracBrowser for help on using the browser.