?? game_尋路.cpp
字號:
/*********************************
[學VC編游戲]
編著、程序設計:唐明理 2004.7
E-mail: cqtml@163.com
**********************************/
#include "stdafx.h"
#include "game_尋路.h"
extern unsigned short dw[7][6];
gamepro:: gamepro(){} //構造函數
gamepro::~gamepro(){} //析構函數
//VVVVVVVVVVVVVVVVVV碰撞檢測VVVVVVVVVVVVVVVVVV
//**************************************************
// lookit(int i)//角色碰撞
// 只判斷人是否與獸相遇;若相遇,獸停下來。
// 由位置差使雙方面對面,打斗。
//**************************************************
void gamepro::lookit(int i)//角色碰撞
{ if(man[i].lb==2) return;
{for(int q=0;q<rs;q++)
{if(q==i) continue; //是自己
if(man[q].lb==2) continue; //是景
int x=man[i].xix-man[q].xix; //取q,i對象的位置差
int y=man[i].xiy-man[q].xiy; //
if(abs(x)<man[q].w*4/3 && abs(y)<man[q].h*4/3)//相遇
{int x0=man[q].xix-scrx-man[q].w/2;//q對象當前位置x
int y0=man[q].xiy-scry-man[q].h/2;//q對象當前位置y
if(man[i].lb!=man[q].lb) //不同類
{if(man[q].lb==1) continue;//是獸看見人
man[i].x0=man[i].fx=man[i].xix;//
man[i].y0=man[i].fy=man[i].xiy;//
man[i].fid=man[i].pk;//獸停下來
//雙方面對面
if(x==0&&y<0) {man[i].fw=0;man[q].fw=4;}//北
if(x>0&&y< 0) {man[i].fw=1;man[q].fw=5;}//東北
if(x>0&&y==0) {man[i].fw=2;man[q].fw=6;}//東
if(x>0&&y> 0) {man[i].fw=3;man[q].fw=7;}//東南
if(x==0&&y>0) {man[i].fw=4;man[q].fw=0;}//南
if(x<0&&y> 0) {man[i].fw=5;man[q].fw=1;}//西南
if(x<0&&y==0) {man[i].fw=6;man[q].fw=2;}//西
if(x<0&&y< 0) {man[i].fw=7;man[q].fw=3;}//西北
man[i].zs=dw[man[i].js][3];man[i].zd=1;//開打
man[q].zs=3; man[q].zd=1;//開打
if(man[q].p==man[q].m1-2) sndPlaySound("砍1.wav",SND_ASYNC);//聲音
if(man[q].p==man[q].m1-8) sndPlaySound("羊.wav",SND_ASYNC);//聲音
break;
}
/*else//是同類,隨機移動
{if(man[q].fid<man[q].pk||fidf==TRUE) continue;//正在移動或搜索忙
int x=man[q].x0+(100-rand()%200);//x隨機位移
int y=man[q].y0+(100-rand()%200);//y隨機位移
FindPath(q,x,y); //同類,隨機產生局部位移
//man[i].zs=0;
}*/
}
}
}
}
//**************************************************
// randxy()//隨機產生獸的移動目標
//
//**************************************************
void gamepro::randxy()//隨機產生獸的移動目標
{ for(int q=0;q<rs;q++)
{if(fidf==TRUE) return; //搜索路徑正忙
if(rand()%20>0) continue; //20次跳過19次,不要移動太頻繁。
if(man[q].lb!=1||man[q].fid<man[q].pk)//不是獸或正在移動
continue; //跳過
if(man[q].zd==1) continue; //正在打,跳過
int x=man[q].x0+WIDTH/2-rand()%WIDTH; //隨機產生獸的x位移
int y=man[q].y0+HEIGHT/2-rand()%HEIGHT;//隨機產生獸的y位移
//邊界檢測
if(x<GX) x=GX;
if(y<GY) y=GY;
if(x>WIDTH *SCRP0-GX) x=WIDTH *SCRP0-GX;
if(y>HEIGHT*SCRP0-GY) y=HEIGHT*SCRP0-GY;
if(FindPath(q,x,y)<0) continue;//A*算法尋路,搜索路徑在man[i].ph中
man[q].p=man[q].m1-1; //中止當前動作
}
}
// int FindPath(int i,int x,int y) A*算法尋路
// A、由(x,y)目標點先濾出無效點。
// B、設置起點、目標點調A*算法尋路
// C、將尋得路徑裝入對象的路徑中
// D、取尋得路徑的第一個點,作為對象移動的目標。
// 返回尋路時間
//**************************************************
int gamepro::FindPath(int i,int x,int y)//A*算法尋路
{ if(find_p==0) return 0;
if(fidf==TRUE) return -4;//搜索路徑正忙
// A、由(x,y)目標點先濾出無效點。
if(x<=0||y<=0) return -3;//無路
int x0=x/GX,y0=y/GY;
if(m_fid.map[x0][y0]=='1')
{fidf=FALSE;return -1;} //目標點是障礙點
if(x0==man[i].xix/GX&&y0==man[i].xiy/GY)
{fidf=FALSE;return -2;} //目標點是起始點
if(x0<1||y0<1)
{fidf=FALSE;return -10;}//左上邊界
if((x0+1)>=WIDTH*SCRP0/GX||(y0+1)>=HEIGHT*SCRP0/GY)
{fidf=FALSE;return -20;}//右下邊界
// B、設置起點、目標點調A*算法尋路
fidf=TRUE;//置搜索路徑正忙
int tim=timeGetTime(); //進入時間
m_fid.end_y =man[i].xix/GX;//目標點
m_fid.end_x =man[i].xiy/GY;//
m_fid.start_y=x0; //起始點
m_fid.start_x=y0;
if(m_fid.findpath()==-1) //A*算法尋路,
{fidf=FALSE;
return-1; //無路返回-1
}
man[i].pk=zlpath(); //重組路徑
if(man[i].pk<0)
{fidf=FALSE;return -3;} //無路返回
if(man[i].pk>250) {man[i].pk=0;fidf=FALSE;return -5;}
// C、將尋得路徑裝入對象的路徑中
for(int j=0;j<man[i].pk;j++)
man[i].ph[j]=pathn[j];//路徑保存到對應的對象(i)
man[i].fx=x;man[i].fy=y; //保留目標點
// D、取尋得路徑的第一個點,作為對象移動的目標。
man[i].fid=1; //取路徑計數
if(man[i].pk>1) //取路徑初值
{man[i].x0=man[i].ph[man[i].fid].x*GX+man[i].w/2;
man[i].y0=man[i].ph[man[i].fid].y*GY+man[i].h/2;
man[i].fid++;
}
fidf=FALSE;//取消搜索路徑正忙
return timeGetTime()-tim; //返回尋路時間
}
//**************************************************
//int zlpath() 重組路徑,合并有效點,使行走平滑。
//**************************************************
int gamepro::zlpath()//重組路徑
{ int k=1;
int yy0;
int xx=m_fid.path[0]/m_fid.map_w;
int yy=m_fid.path[0]%m_fid.map_w;
pathn[0].x=xx;pathn[0].y=yy;
for(int j=1;m_fid.path[j]>0;j++)
{xx= m_fid.path[j]/m_fid.map_w;
yy= m_fid.path[j]%m_fid.map_w;
yy0=m_fid.path[j+1]%m_fid.map_w;
pathn[k].x=xx;pathn[k].y=yy;
if(yy!=yy0) k++;
if(k>500) return -1;
}
// if(stackmax<j) stackmax=j;
int p=1;
for(j=1;j<k;j++)
{pathn[p].x=pathn[j].x;pathn[p].y=pathn[j].y;
if(pathn[j].x!=pathn[j+1].x) p++;
}
return p;
}
//*********************************************
// loadza(CString name)//調入障礙表
// 調入障礙表(.map),障礙表的格式:
// 第1行,障礙表的行列值,以后1 行就是障礙表1行的數據。
//*********************************************
void gamepro::loadza(CString name)//調入障礙表
{// B、調入障礙表(.map)
char cc[256];
FILE *f;
int i,j;
strcpy(cc,name);cc[lstrlen(name)-3]=0;//變換文件名
strcat(cc,"map");
f=fopen(cc,"r");
if(f==NULL) goto aa; //如果沒有障礙文件
fscanf(f,"%d,%d\n",&w,&h);
SCRP0=w/16; //換成地圖倍數
m_fid.map_w=WIDTH*SCRP0/GX;
m_fid.map_h=HEIGHT*SCRP0/GY;
if(w>WIDTH*SCRP/GX||h>HEIGHT*SCRP/GY)
{SetCurrentDirectory(appdir);//置當前目錄
return;
}
for(i=0;i<h;i++)
fgets(&m_fid.map[i][0],w+2,f);
fclose(f);
aa:for(i=0;i<m_fid.map_w;i++)
for(j=0;j<m_fid.map_h;j++)
if(m_fid.map[i][j]!='1') m_fid.map[i][j]='0';
find_p=1; //無搜索0有搜索1
SetCurrentDirectory(appdir);//置當前目錄
}
//**************************************************
// BOOL pongcung(int i)//與障礙碰撞檢測
//
//**************************************************
/*BOOL game::pongcung(int i)//與障礙碰撞檢測
{ int xl=(man[i].xix )/GX;//左邊所在格
int yl=(man[i].xiy-man[i].h/2)/GY;//
int xr=(man[i].xix+man[i].w )/GX;//右邊所在格
int yr=(man[i].xiy-man[i].h/2)/GY;//
if(m_fid.map[xl][yl]=='1'|| //左邊在障礙格
m_fid.map[xr][yr]=='1' ) //右邊在障礙格
return TRUE; //有碰撞
else return FALSE; //無碰撞
}*/
//^^^^^^^^^^^^^^^^^^^碰撞檢測^^^^^^^^^^^^^^^^^^^
//**************************************************
// game::loaddata()//調壓縮資源包
// A、分別調入景j、獸s、人r的圖形壓縮包指針
// 和位置偏移量(.dat)到相應數組
// Xbufadd ,圖形壓縮包指針
// Xsbufx ,x位置偏移量
// Xsbufy ,y位置偏移量
// B、分別調入景j、獸s、人r的圖形壓縮包數據到
// 內存jtmp、stmp、rtmp中
//**************************************************
void gamepro::loaddata()//調壓縮資源包
{// A、......
FILE *f;
int len,i,j;
CString cc;
cc=dir+"景.dar";
f=fopen(cc,"r");
if(f==NULL) return;
fscanf(f,"%d",&len);
for(i=0;i<len;i++)
fscanf(f,"%d,%d,%d",&jbufadd[i],&j,&j);//角色的偏移位置
fclose(f);
cc=dir+"獸.dar";
f=fopen(cc,"r");
if(f==NULL) return;
fscanf(f,"%d",&len);
for(i=0;i<len;i++)
fscanf(f,"%d,%d,%d",&sbufadd[i],&sbufx[i],&sbufy[i]);//角色的偏移位置
fclose(f);
cc=dir+"人.dar";
f=fopen(cc,"r");
if(f==NULL) return;
fscanf(f,"%d",&len);
for(i=0;i<len;i++)
fscanf(f,"%d,%d,%d",&rbufadd[i],&rbufx[i],&rbufy[i]);//角色的偏移位置
fclose(f);
// B、......
cc=dir+"獸.gam";
if( !sfile.Open(cc, CFile::modeRead, NULL ) ) return;
cc=dir+"人.gam";
if( !rfile.Open(cc, CFile::modeRead, NULL ) ) return;
cc=dir+"景.gam";
if( !jfile.Open(cc, CFile::modeRead, NULL ) ) return;
UINT len0=sfile.GetLength();
stmp=(BYTE *)new BYTE[len0];//獸
sfile.Read( stmp, len0);
sfile.Close();
len0=rfile.GetLength();
rtmp=(BYTE *)new BYTE[len0];//人
rfile.Read( rtmp, len0);
rfile.Close();
len0=jfile.GetLength();
jtmp=(BYTE *)new BYTE[len0];//景
jfile.Read( jtmp, len0);
jfile.Close();
}
//**************************************************
// int leftdown(HDC hdc,int x,int y)//按左鍵
// 這是由按鼠標左鍵調用的。
// A、在顯示區按鍵,給出主角的目標位置,調A*算法尋路
// B、在小地圖區按鍵,調定位地圖。
// 若是尋路,返回尋路的時間。
//**************************************************
int gamepro::leftdown(HDC hdc,int x,int y)//按左鍵
{ int fidtim=0;
if(find_p==0) //無搜索0有搜索1
{gamemap::leftdown(hdc,x,y);
return fidtim;
}
if(x>0&&x<WIDTH&&y>0&&y<HEIGHT&&edi==0) //在顯示區,非編輯態
{int i=mann; //只對主角取目標點
fidtim=FindPath(i,x-2+scrx,y-10+scry);//A*算法尋路,得尋路時間
man[i].p=man[i].m1-1;//中止當前動作
}
if(dingweimap(x,y)==TRUE) //在小地圖上點左鍵,調定位地圖
smlmap(hdc); //顯示小地圖
return fidtim;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -