root/lang/d/koke/trunk/src/map.d @ 12011

Revision 12011, 10.6 kB (checked in by omega, 5 years ago)

ディリクトリ構成変更・チャートバグ対処

Line 
1/********************************************************************************/
2/*      map.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;
22
23private import character;
24
25
26//********************************************************************************
27// マップちっぷ
28//********************************************************************************
29
30const static int CHIP_SIZE = 32;
31
32class MapChip{
33        enum TYPE{
34                NONE = 0,
35                CURSOR = 0,
36                MOVIE = 1,
37                FENCE,
38                WATER,
39                DARK,
40        }
41        const static string name[] = ["NONE" , "MOVIE" , "FENCE" , "WATER" , "DARK" ];
42       
43        const static int TYPEDRAW_LOOP = 16;
44        static int GRASS_COLOR_R = 128;
45        static int GRASS_COLOR_G = 128;
46        static int GRASS_COLOR_B = 128;
47       
48        double grass;
49       
50        TYPE type;
51       
52        this(){
53                init();
54        }
55       
56        void init(){
57                grass = 0;
58                type = TYPE.NONE;
59        }
60       
61        void drawBase(double x,double y){
62                /* 本来はCHIP_SIZE * CHIP_SIZE分コピーすべきだが、高速化のため下半分だけコピーする */
63                Hell_drawTexture("char" , x , y + CHIP_SIZE / 2
64                        ,0
65                        ,CHIP_SIZE / 2
66                        ,CHIP_SIZE
67                        ,CHIP_SIZE / 2);
68               
69                /* 本来のコード
70                Hell_drawTexture("char" , x , y
71                        ,0
72                        ,0
73                        ,CHIP_SIZE
74                        ,CHIP_SIZE);
75                */
76        }
77        void draw(double x , double y,int anime = 0){
78                if(type == TYPE.NONE){
79                        // 芝
80                        if(getGrassLevel() < 1) return;
81                        Hell_drawTexture("char" , x , y
82                                ,0
83                                ,CHIP_SIZE * getGrassLevel()
84                                ,CHIP_SIZE
85                                ,CHIP_SIZE,1,1,0, GRASS_COLOR_R,GRASS_COLOR_G,GRASS_COLOR_B);
86                }else{
87                        // オブジェクト
88                        Hell_drawTexture("char" , x , y
89                                ,CHIP_SIZE * anime + CHIP_SIZE
90                                ,CHIP_SIZE * (type % TYPEDRAW_LOOP)
91                                ,CHIP_SIZE
92                                ,CHIP_SIZE);
93                }
94        }
95       
96        static void drawCursor(double x,double y,int anime = 0){
97                Hell_drawTexture("char" , x , y ,CHIP_SIZE * anime + CHIP_SIZE ,0
98                        ,CHIP_SIZE
99                        ,CHIP_SIZE);
100        }
101       
102        int getGrassLevel(){
103                if(grass < 10){
104                        return 0;
105                }else if(grass < 20){
106                        return 1;
107                }else if(grass < 40){
108                        return 2;
109                }else if(grass < 80){
110                        return 3;
111                }else{
112                        return 4;
113                }
114        }
115       
116        char toSerializedChar(){
117                if( type == TYPE.NONE )         return ' ';
118                if( type == TYPE.MOVIE )        return 'W';
119                if( type == TYPE.FENCE )        return 'F';
120                if( type == TYPE.WATER )        return 'M';
121                if( type == TYPE.DARK )         return 'D';
122                Hell_write("Undefined mapdata serialize to char.");
123                return ' ';
124        }
125       
126        bool setSerializedChar( char ch ){
127                if( ch == ' ' )         return set( TYPE.NONE , 0 );
128                if( ch == 'W' )         return set( TYPE.MOVIE , 0 );
129                if( ch == 'F' )         return set( TYPE.FENCE , 0 );
130                if( ch == 'M' )         return set( TYPE.WATER , 0 );
131                if( ch == 'D' )         return set( TYPE.DARK , 0 );
132                Hell_write("Undefine mapdata restore from char");
133                return false;
134        }
135       
136        bool set( TYPE type , double grass ){
137                this.type = type;
138                this.grass = grass;
139                return true;
140        }
141}
142
143//********************************************************************************
144// マップ
145//********************************************************************************
146
147class Map{
148        const static double DRAW_CHIP_W = 12.0;
149        const static double DRAW_CHIP_H = 6.0;
150        const static double MOUSE_OFS_X = 16.0;
151        const static double MOUSE_OFS_Y = 18.0;
152       
153        static double MAP_GRASS_AFFECT = 0.90;
154        static double MAP_GRASS_AFFECT_LIMIT = 0.3;
155       
156        static int MAP_REFRESH_INTERVAL = 10;
157       
158        static double MOVIE_GRASS_FEED = 200;
159       
160        static bool MAP_BORDER_IS_WALL = false;
161       
162        GameMain gamemain;
163        MapChip[] map;
164        bool[] movable_map;
165       
166        int width;
167        int height;
168        int timer;
169       
170        double draw_ofs_x;
171        double draw_ofs_y;
172       
173        this(GameMain gamemain , int width , int height){
174                this.gamemain = gamemain;
175                this.width = width;
176                this.height = height;
177               
178                this.map = new MapChip[width * height];
179                foreach(inout m;map) m = new MapChip();
180               
181                this.movable_map = new bool[width * height];
182                foreach(inout mm;movable_map) mm = true;
183               
184                this.draw_ofs_x = 0;
185                this.draw_ofs_y = 0;
186               
187                timer = 0;
188        }
189       
190        void update(){
191                timer++;
192               
193                // 各種ゲームパラメタ
194                MAP_GRASS_AFFECT = configparser.getfloat("MAP_GRASS_AFFECT");
195                MAP_REFRESH_INTERVAL = configparser.getint("MAP_REFRESH_INTERVAL");
196                MOVIE_GRASS_FEED = configparser.getfloat("MAP_MOVIE_GRASS_FEED");
197                MAP_GRASS_AFFECT_LIMIT = configparser.getfloat("MAP_GRASS_AFFECT_LIMIT");
198               
199                MAP_BORDER_IS_WALL = configparser.getboolean("MAP_BORDER_IS_WALL");
200               
201                int[] vecx = [ -1 ,  0 ,  1 ,  0 ];
202                int[] vecy = [  0 , -1 ,  0 ,  1 ];
203               
204                for(int x = 0;x < width;x++){
205                        // 適当に負荷分散してみる
206                        if(timer % MAP_REFRESH_INTERVAL != x % MAP_REFRESH_INTERVAL) continue;
207                       
208                        for(int y=0;y < height;y++){
209                                MapChip here = toMap(x,y);
210                                if(isMap(x,y, MapChip.TYPE.NONE)){
211                                        // 何もない場合は隣接マスから芝えねるぎーを算出する
212                                        int grass_density = 0;
213                                       
214                                        // 周りの芝濃度を算出する
215                                        for(int v=0;v < vecx.length ; v++){
216                                                int px = x + vecx[v];
217                                                int py = y + vecy[v];
218                                               
219                                                if(inRange(px,py)){
220                                                        MapChip m = toMap(px,py);
221                                                        grass_density += m.grass;
222                                                }
223                                        }
224                                        // 濃度にあわせようとする
225                                        grass_density /= vecx.length;//grass_cnt;
226                                       
227                                        if(here.grass < grass_density){
228                                                double a = grass_density - here.grass;
229                                                if(a > MAP_GRASS_AFFECT_LIMIT) a = MAP_GRASS_AFFECT_LIMIT;
230                                                here.grass += a;
231                                        }                               
232                                }else if(isMap(x,y, MapChip.TYPE.MOVIE)){
233                                        // 動画がある場合は無条件に濃度上昇
234                                        here.grass = MOVIE_GRASS_FEED;
235                                }
236                        }
237                }
238               
239                updateMovableMap();
240        }
241       
242        // キャラクタ判定用・移動可能マップを更新する
243        void updateMovableMap(){
244                for(int x = 0;x < width;x++){
245                        for(int y=0;y < height;y++){
246                                bool res = true;
247                               
248                                if(map[x + y * width].type != MapChip.TYPE.NONE) res = false;
249                               
250                                movable_map[x + y * width] = res;
251                        }
252                }
253               
254                CharacterPool cp = gamemain.charpool;
255                foreach(c;cp.actors){
256                        if(c.exist){
257                                Vec3 p = c.getPosition();
258                                if(inRange(cast(int)p.x , cast(int)p.y) && c.isBlocking())
259                                        movable_map[cast(int)p.x + cast(int)p.y * width] = false;
260                        }
261                }
262        }
263       
264        // 作画
265        // 参照・キャラクタバケットソート
266        void draw(){
267                // 芝色
268                MapChip.GRASS_COLOR_R = configparser.getint("MAP_GRASS_COLOR_R");
269                MapChip.GRASS_COLOR_G = configparser.getint("MAP_GRASS_COLOR_G");
270                MapChip.GRASS_COLOR_B = configparser.getint("MAP_GRASS_COLOR_B");
271               
272                // Map座標系で作画範囲をクリップ
273                int x_st = toRoundMapX(toMapX(0,0));
274                int y_st = toRoundMapY(toMapY(gamemain.getScreenWidth(),0));
275                int x_ed = toRoundMapX(toMapX(gamemain.getScreenWidth() , gamemain.getScreenHeight()) + 2);
276                int y_ed = toRoundMapY(toMapY(0 , gamemain.getScreenHeight()) + 2);
277               
278                for(int x = x_st;x < x_ed;x++){
279                        for(int y = y_st;y < y_ed;y++){
280                                double dx = toViewX(x,y);
281                                double dy = toViewY(x,y);
282                               
283                                if(dx < -32 || dy < -32 || dx > gamemain.getScreenWidth() + 32
284                                        || dy > gamemain.getScreenHeight() + 32) continue;
285                               
286                                toMap(x,y).drawBase(dx , dy);
287                                if(isMap(x,y, MapChip.TYPE.NONE)) toMap(x,y).draw(dx , dy , (timer / 5) % 4);
288                        }
289                }
290               
291                for(int x = x_st;x < x_ed;x++){
292                        for(int y = y_st;y < y_ed;y++){
293                                double dx = toViewX(x,y);
294                                double dy = toViewY(x,y);
295                               
296                                if(dx < -32 || dy < -32 || dx > gamemain.getScreenWidth() + 32
297                                        || dy > gamemain.getScreenHeight() + 32) continue;
298                               
299                                if(!isMap(x,y, MapChip.TYPE.NONE)) toMap(x,y).draw(dx , dy , (timer / 5) % 4);
300                                gamemain.charpool.drawAtMap(x,y);
301                        }
302                }
303        }
304       
305        // ロード
306        bool loadFile( string filename ){
307                string[] buffer;
308                try{
309                        buffer = std.string.split( cast(string) std.file.read(filename) , "\n" );
310                }catch(Exception e){
311                        Hell_write(e);
312                        return false;
313                }
314               
315                for(int y = 0 ; y < buffer.length ; y++ ){
316                        string line = buffer[y];
317                        for(int x = 0 ; x < line.length ; x++ ){
318                                char ch = line[x];
319                                MapChip m = toMap( x , y );
320                                if(m) m.setSerializedChar( ch );
321                        }
322                }
323                return true;
324        }
325        // セーブ
326        bool saveFile( string filename ){
327                string buffer = "";
328                for(int y = 0; y < height ; y++ ){
329                        for(int x = 0 ; x <width ; x++ ){
330                                MapChip m = toMap(x,y);
331                                buffer ~= m.toSerializedChar();
332                        }
333                        buffer ~= "\n";
334                }
335               
336                try{
337                        std.file.write( filename , buffer );
338                }catch(Exception e){
339                        Hell_write(e);
340                        return false;
341                }
342                return true;
343        }
344       
345        // マップチップを配置
346        bool set(int x,int y,MapChip.TYPE type){
347                if(!inRange(x,y)) return false;
348               
349                MapChip m = toMap(x,y);
350                return m.set( type , 0 );
351        }
352       
353        // 芝えねるぎーを配置
354        bool setGrass(int x,int y,double grass){
355                if(!inRange(x,y)) return false;
356               
357                MapChip m = toMap(x,y);
358                m.grass = grass;
359                return true;
360        }
361       
362        // 芝エネルギー値をえる
363        double getGrass(int x,int y){
364                if(!inRange(x,y)) return 0;
365               
366                MapChip m = toMap(x,y);
367                return m.grass;
368        }
369       
370        int getGrassLevel(int x,int y){
371                if(!inRange(x,y)) return 0;
372               
373                MapChip m = toMap(x,y);
374                return m.getGrassLevel();
375        }
376       
377        bool isMap(int x,int y,MapChip.TYPE type){
378                if(!inRange(x,y)) return false;
379               
380                MapChip m = toMap(x,y);
381                return m.type == type;
382        }
383       
384        // 座標変換
385        double toViewX(double x,double y){return (x - y) * DRAW_CHIP_W + draw_ofs_x;}
386        double toViewY(double x,double y){return (x + y) * DRAW_CHIP_H + draw_ofs_y;}
387        int toMapX(int x,int y){
388                return cast(int)(((x - draw_ofs_x - MOUSE_OFS_X) / DRAW_CHIP_W + (y - draw_ofs_y - MOUSE_OFS_Y) / DRAW_CHIP_H) / 2);
389        }
390        int toMapY(int x,int y){
391                return cast(int)(((y - draw_ofs_y - MOUSE_OFS_Y) / DRAW_CHIP_H - (x - draw_ofs_x - MOUSE_OFS_X) / DRAW_CHIP_W) / 2);
392        }
393       
394        int toRoundMapX(int x){
395                if(x < 0) return 0;
396                if(x >= width) return width;
397                return x;
398        }
399        int toRoundMapY(int y){
400                if(y < 0) return 0;
401                if(y >= height) return height;
402                return y;
403        }
404       
405        bool inRange(int x,int y){
406                return x >= 0 && y >= 0 && x < width && y < height;
407        }
408       
409        MapChip toMap(int x,int y){return map[x + y * width];}
410        bool isMovable(int x,int y){
411                if(inRange(x,y)) return movable_map[x + y * width];
412                return !MAP_BORDER_IS_WALL;
413        }
414       
415        int count(MapChip.TYPE type){
416                int result = 0;
417                foreach(m;map){
418                        if(m.type == type) result++;
419                }
420                return result;
421        }
422}
423
Note: See TracBrowser for help on using the browser.