- 20091223:更新があったらこのエントリに追加・修正していきたいと思います。
- d3dung.h
#ifndef _D3DUNG_H_INCLUDED_
#define _D3DUNG_H_INCLUDED_
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "DxLib.h"
#define D3DMAPH 64
#define D3DMAPW 64
#define N_TILETYPES 4
enum eD3DIRs {
D3DIR_L,
D3DIR_U,
D3DIR_R,
D3DIR_D,
};
enum eDUNGWALLS {
DWA_NONE,
DWA_STD,
DWA_STONE,
DWA_DOOR_O,
DWA_DOOR_C,
};
typedef struct tag_masu_type {
int is_wall;
} masu_t;
class D3DungDrawer
{
private:
masu_t map[D3DMAPH][D3DMAPW];
int dir, posx, posy;
int maph, mapw;
int loop_flag;
int hpictbase;
int hpict[N_TILETYPES][15];
int hpictdungbase;
int iswtmp[3][3];
int drawing_size;
int drawingx, drawingy;
int bmp_wid, bmp_hgt;
int colorkey[3];
int loadposx[N_TILETYPES], loadposy[N_TILETYPES];
int loadposbx, loadposby;
void D3DungDrawer::DrawWallPict(int i, int j);
public:
char pictfilename[256];
D3DungDrawer()
{
loop_flag = 1;
maph = 20; mapw = 20;
hpictbase = -1;
for(int i = 0;i<N_TILETYPES;i++)
{
for(int j = 0;j<15;j++)
{
hpict[i][j] = -1;
}
}
strcpy(pictfilename, "3DDung4832.bmp");
hpictdungbase = -1;
posx = 0;
posy = 0;
dir = D3DIR_D;
drawing_size = 3;
bmp_wid = 48;
bmp_hgt = 32;
loadposx[0] = 144;
loadposy[0] = 16;
loadposbx = 16;
loadposby = 112;
colorkey[0] = 71;
colorkey[1] = 108;
colorkey[2] = 108;
memset(map,0,sizeof(map));
}
void SetD3DMapSize(int h, int w)
{
maph = h; mapw = w;
}
void LoadSettingFIle(char *fname);
void DrawDungeon(int dx, int dy);
void D3DungDrawer::DrawDungeon3D(int dx, int dy);
int D3DungDrawer::LoadBitmap(char *filename);
void D3DungDrawer::MakeMazeByTextFile(char *fname);
void D3DungDrawer::PosTurning(int xxx);
void D3DungDrawer::PosSusumu(int flag);
};
#endif
#include "d3dung.h"
static int adxx[4] = {-1, 0, 1, 0};
static int adyy[4] = { 0,-1, 0, 1};
int D3DungDrawer::LoadBitmap(char *filename)
{
const int bmpw = bmp_wid, bmph = bmp_hgt, bmppad = bmp_wid;
SetTransColor(colorkey[0], colorkey[1], colorkey[2]);
hpictbase = LoadGraph(filename);
if (hpictbase == -1)
{
return 0;
}
hpictdungbase = DerivationGraph(loadposbx, loadposby, bmpw, bmph, hpictbase);
for(int i=0; i<4; i++)
{
for(int j=0; j<9; j++)
{
hpict[i][j] = DerivationGraph(
loadposx[i] + (j%3)*bmppad,
loadposy[i] + (j/3)*bmph, bmpw, bmph, hpictbase);
}
}
return 1;
}
void D3DungDrawer::DrawWallPict(int i, int j)
{
int wtp[3][3] = {
{6,7,8},
{3,4,5},
{0,1,2},
};
if (iswtmp[i][j])
{
int pidx, picthandle;
pidx = wtp[i][j];
switch(iswtmp[i][j])
{
case DWA_STONE:
picthandle = hpict[1][pidx];
break;
default:
picthandle = hpict[0][pidx];
break;
}
if (picthandle == -1) return;
if (pidx == 7)
{
;
}
else
{
DrawExtendGraph(drawingx, drawingy,
drawingx + bmp_wid*drawing_size, drawingy + bmp_hgt*drawing_size,
picthandle, TRUE);
}
switch(iswtmp[i][j])
{
case DWA_DOOR_O:
picthandle = hpict[2][pidx];
break;
case DWA_DOOR_C:
picthandle = hpict[3][pidx];
break;
default:
picthandle = -1;
break;
}
if (picthandle == -1) return;
DrawExtendGraph(drawingx, drawingy,
drawingx + bmp_wid*drawing_size, drawingy + bmp_hgt*drawing_size,
picthandle, TRUE);
}
}
void D3DungDrawer::DrawDungeon3D(int dx, int dy)
{
int ddir;
this->drawingx = dx;
this->drawingy = dy;
ddir = this->dir;
memset(iswtmp,0,sizeof(iswtmp));
DrawBox(dx-1,dy-1,
dx+bmp_wid*drawing_size+1,dy+bmp_hgt*drawing_size+1,
GetColor(40,40,255), FALSE);
for(int i=0;i<3;i++)
{
for(int j=-1; j<2;j++)
{
int wset = 0;
int dx = posx, dy = posy;
switch(ddir)
{
case D3DIR_L:
dx += i*-1;
dy += j*-1;
break;
case D3DIR_R:
dx += i*1;
dy += j*1;
break;
case D3DIR_U:
dx += j*1;
dy += i*-1;
break;
case D3DIR_D:
dx += j*-1;
dy += i*1;
break;
}
if (dy < 0 || dy >= maph ||
dx < 0 || dx >= mapw)
{
if (!loop_flag)
{
wset = 1;
}
else
{
if (dx >= mapw)
{
dx = dx % mapw;
}
if (dy >= maph)
{
dy = dy % maph;
}
while (dx < 0) {dx += mapw;}
while (dy < 0) {dy += maph;}
if (map[dy][dx].is_wall)
{
wset = map[dy][dx].is_wall;
}
}
}
else if (map[dy][dx].is_wall)
{
wset = map[dy][dx].is_wall;
}
iswtmp[i][j+1] = wset;
}
}
DrawExtendGraph(dx, dy,
drawingx + bmp_wid*drawing_size, drawingy + bmp_hgt*drawing_size,
hpictdungbase, TRUE);
DrawWallPict(2, 0);
DrawWallPict(2, 2);
DrawWallPict(2, 1);
DrawWallPict(1, 0);
DrawWallPict(1, 2);
DrawWallPict(1, 1);
DrawWallPict(0, 0);
DrawWallPict(0, 2);
DrawWallPict(0, 1);
}
void D3DungDrawer::DrawDungeon(int dx, int dy)
{
int i, j;
DrawDungeon3D(dx, dy);
SetDrawBlendMode(DX_BLENDMODE_ALPHA, 128);
for(i=0;i<maph;i++)
{
for(j=0;j<mapw;j++)
{
char buf[2];
char ch = '.';
switch(map[i][j].is_wall)
{
case DWA_STD:
case DWA_STONE:
ch = '#';
break;
case DWA_DOOR_C:
ch = '+';
break;
case DWA_DOOR_O:
ch = '`';
break;
}
if (posx == j && posy == i) ch = '@';
buf[0] = ch;
buf[1] = 0;
DrawString(dx + 320 + j*9, dy + i*16, buf, GetColor(255,255,255));
}
}
SetDrawBlendMode(DX_BLENDMODE_NOBLEND, 0);
{
char buf[100];
char *dirch[4] = {"←","↑","→","↓"};
sprintf(buf, "dir:%s x:%d y:%d", dirch[dir], posx, posy);
DrawString(dx, dy + 200, buf, GetColor(255,255,255));
sprintf(buf, "Loop:%d mapw:%d maph:%d", loop_flag, mapw, maph);
DrawString(dx, dy + 200 + 16, buf, GetColor(255,255,255));
sprintf(buf, "pic:%s loadposbx:%d loadposby:%d", pictfilename, loadposbx, loadposby);
DrawString(dx, dy + 200 + 16*2, buf, GetColor(255,255,255));
}
DrawGraph(200,200,hpictbase, TRUE);
}
void D3DungDrawer::LoadSettingFIle(char *fname)
{
char buf[1024];
FILE *f;
f = fopen(fname, "rt");
if (f == 0) return;
while(fgets(buf, 1024, f))
{
if (buf[0] == '#') continue;
if (buf[0] == '\n' || buf[0] == '\r' || buf[0] == 0) continue;
if (buf[1] == ':')
{
switch(buf[0])
{
case 'F':
{
char *str = &buf[2], *tmp;
tmp = str;
while(1)
{
if (*tmp == 0) break;
if (*tmp == '\n' || *tmp == '\r')
{
*tmp = 0;
break;
}
tmp++;
}
strcpy(pictfilename, str);
}
break;
case 'S':
{
char *str = &buf[2], *tok;
tok = strtok(str, ":");
bmp_wid = atoi(tok);
tok = strtok(0, ":");
bmp_hgt = atoi(tok);
}
break;
case 'C':
{
char *str = &buf[2], *tok;
tok = strtok(str, ":");
colorkey[0] = atoi(tok);
tok = strtok(0, ":");
colorkey[1] = atoi(tok);
tok = strtok(0, ":");
colorkey[2] = atoi(tok);
}
break;
case 'T':
{
char *str = &buf[2], *tok;
tok = strtok(str, ":");
if (*tok == 'B')
{
tok = strtok(0, ":");
loadposbx = atoi(tok);
tok = strtok(0, ":");
loadposby = atoi(tok);
}
else
{
int tidx = atoi(tok);
tok = strtok(0, ":");
loadposx[tidx] = atoi(tok);
tok = strtok(0, ":");
loadposy[tidx] = atoi(tok);
}
}
break;
}
}
}
fclose(f);
}
void D3DungDrawer::MakeMazeByTextFile(char *fname)
{
FILE *f;
int yy = 0;
char buf[1024];
f = fopen(fname, "rt");
if (f == 0) return;
maph = 10;
mapw = 10;
while(fgets(buf, 1024, f))
{
if (buf[0] == 'R') continue;
if (buf[0] == 'L' && buf[1] == ':')
{
loop_flag = atoi(&buf[2]);
continue;
}
else if (buf[0] == 'S' && buf[1] == ':')
{
char *str = &buf[2];
char *tok;
tok = strtok(str, ":");
mapw = atoi(tok);
tok = strtok(0, ":");
maph = atoi(tok);
continue;
}
for(int j=0;j<mapw;j++)
{
if (!buf[j] || buf[j] == '\n' || buf[j] == '\r')
{
break;
}
switch(buf[j])
{
case '#':
map[yy][j].is_wall = DWA_STD;
break;
case '%':
map[yy][j].is_wall = DWA_STONE;
break;
case '+':
map[yy][j].is_wall = DWA_DOOR_C;
break;
case 'o':
map[yy][j].is_wall = DWA_DOOR_O;
break;
case '@':
map[yy][j].is_wall = 0;
posx = j;
posy = yy;
break;
case '.':
default:
map[yy][j].is_wall = 0;
break;
}
}
yy++;
if (yy >= maph) break;
}
fclose(f);
}
void D3DungDrawer::PosTurning(int xxx)
{
if (map[posy][posx].is_wall == DWA_DOOR_O)
{
if (xxx != 2) return;
}
dir += xxx;
if (dir < 0) dir = dir + 4;
if (dir >= 4) dir = dir % 4;
}
void D3DungDrawer::PosSusumu(int flag)
{
int nposx, nposy;
nposx = posx + adxx[dir];
nposy = posy + adyy[dir];
if (!loop_flag)
{
if (nposx < 0) nposx = 0;
if (nposy < 0) nposy = 0;
if (nposx > mapw-1) nposx = mapw-1;
if (nposy > maph-1) nposy = maph-1;
}
else
{
if (nposx < 0) nposx += mapw;
if (nposy < 0) nposy += maph;
if (nposx > mapw-1) nposx = nposx % mapw;
if (nposy > maph-1) nposy = nposy % maph;
}
if (!flag && map[nposy][nposx].is_wall)
{
if (map[nposy][nposx].is_wall == DWA_DOOR_C)
{
map[nposy][nposx].is_wall = DWA_DOOR_O;
return;
}
else if (map[nposy][nposx].is_wall == DWA_DOOR_O)
{
;
}
else
{
return;
}
}
posx = nposx;
posy = nposy;
}
keykode_type keykode[7] = {
{CTRL_CODE_LEFT, 'h'},
{CTRL_CODE_RIGHT, 'l'},
{CTRL_CODE_DOWN, 'j'},
{CTRL_CODE_UP, 'k'},
{CTRL_CODE_ESC, ESCAPE},
{CTRL_CODE_CR, '\n'},
{0, 0},
};
char getcommand()
{
char rval;
ClearInputCharBuf();
while(1)
{
int i;
char ch = GetInputCharWait(TRUE);
for(i=0;i<6;i++)
{
if (keykode[i].kode == 0) break;
if (ch == keykode[i].kode)
{
ch = keykode[i].changeto;
break;
}
}
rval = ch;
break;
}
return rval;
}
D3DungDrawer dung;
...
dung.LoadSettingFIle("0tiledef.txt");
if (!dung.LoadBitmap(dung.pictfilename))
{
return;
}
dung.MakeMazeByTextFile("Maze.txt");
while(1)
{
int cmd;
clear_s();
dung.DrawDungeon(10, 10);
refresh_s();
cmd = getcommand();
switch(cmd)
{
case 'h':
dung.PosTurning(-1);
break;
case 'l':
dung.PosTurning( 1);
break;
case 'j':
dung.PosTurning( 2);
break;
case 'k':
dung.PosSusumu(0);
break;
case ESCAPE:
return;
}
}