ネット対戦を実装してみたのですが、なかなかうまくいかなくて困っています。
一応つながることはつながるんですが・・・クライアント側には正常に描画されるんですが、ホスト側には、自分の機体のみが表示され、いろいろと荒ぶります。 ←これは事故解決しました、もう一つのクライアントに渡しているexeファイルをReleaseでビルドされたものを渡していたつもりなのですが、何かの間違いでDebugのexeファイルをを渡していたみたいです。
なんですが。通信は上手くいったんですが、かなりタイムラグがひどいです。クライアントでキーを押してから、ホストに反映されるまでにおよそ3秒くらいかかります。何故なんでしょうか・・・・なにか良い対処法はないんですかね・・・・
クライアントのコード
void Link_S_Init(){ //クライアントの初期化
DeleteUDPSocket( NetUDPHandle ) ;
NetUDPHandle = MakeUDPSocket( 25953 ) ;
state=0;
Game_Init();
mynum=1;
}
void Link_S_Update(){ //クライアントの更新
if(state==0){
DrawFormatString(50,0,GetColor(255,255,255),"IPアドレスを入力してね");
ScreenFlip(); //裏画面情報を表画面に描画
char StrBuf[ 81 ] , StrBuf2[ 81 ] ;
// IPの入力を行う
KeyInputSingleCharString( 0 , 300 , 80 , StrBuf , FALSE ) ;
// ピリオドが3つあるか調べる
j = 0 ;
for( i = 0 ; i < 80 ; i ++ )
{
if( StrBuf[ i ] == '.' ) j ++ ;
}
// もし3つピリオドがなかった場合は入力のし直し
if( j == 3 )
{
// 文字列からIPを抜き出す
j = 0 ;
k = 0 ;
i = 0 ;
while( !ProcessMessage() )
{
if( StrBuf[ i ] == '.' || StrBuf[ i ] == '\0' )
{
StrBuf2[ j ] = '\0' ;
switch( k )
{
case 0 :IP.d1 = atoi( StrBuf2 ) ; break ;
case 1 :IP.d2 = atoi( StrBuf2 ) ; break ;
case 2 :IP.d3 = atoi( StrBuf2 ) ; break ;
case 3 :IP.d4 = atoi( StrBuf2 ) ; break ;
}
k ++ ;
if( k == 4 ) break ;
j = 0 ;
}
else
{
StrBuf2[ j ] = StrBuf[ i ] ;
j ++ ;
}
i ++ ;
}
state=1;
}
}
if(state==1){
NetWorkSendUDP( NetUDPHandle,IP,25953,&netS, sizeof(netS) ) ;
// 新しい接続があった場合はループを出る
if( CheckNetWorkRecvUDP( NetUDPHandle ) == TRUE ) {
state=2;
}
}
if(state==2){
if(Key(KEY_INPUT_ESCAPE)==1){
Next_Scene(eScene_Menu);
}
NetWorkRecvUDP( NetUDPHandle, NULL, NULL, &netJ, sizeof(netJ), FALSE ) ;
for(int i=0;i<COF_NUM_KEY;i++){
netS.COF[i]=Cof(pl[0].Profile,i);
netS.COFDown[i]=CofDown(pl[0].Profile,i);
}
NetWorkSendUDP( NetUDPHandle,IP,25953,&netS, sizeof(netS)) ;
allcount++;
for(int i=0;i<4;i++){
if(pl[i].frag==true){
if(i==mynum){
Player_Update( i);
/*
pl[i].x=netJ.pl[i].x;
pl[i].y=netJ.pl[i].y;
pl[i].num=netJ.pl[i].num;
pl[i].Dash=netJ.pl[i].Dash;
pl[i].Fx=netJ.pl[i].Fx;
pl[i].Fy=netJ.pl[i].Fy;
pl[i].TargetAngle=netJ.pl[i].TargetAngle;
pl[i].stoptime=netJ.pl[i].stoptime;
pl[i].Gard=netJ.pl[i].Gard;
pl[i].GardP=netJ.pl[i].GardP;
pl[i].Jump=netJ.pl[i].Jump;
pl[i].AttackStatus=netJ.pl[i].AttackStatus;
pl[i].GardP=netJ.pl[i].GardP;
pl[i].Draw=netJ.pl[i].Draw;
pl[i].vx=netJ.pl[i].vx;
pl[i].vy=netJ.pl[i].vy;
pl[i].frag=netJ.pl[i].frag;
*/
}else{
Player_Update_Net( i,netJ.COF,netJ.COFDown);
/*
pl[i].x=netJ.pl[i].x;
pl[i].y=netJ.pl[i].y;
pl[i].num=netJ.pl[i].num;
pl[i].Dash=netJ.pl[i].Dash;
pl[i].Fx=netJ.pl[i].Fx;
pl[i].Fy=netJ.pl[i].Fy;
pl[i].TargetAngle=netJ.pl[i].TargetAngle;
pl[i].stoptime=netJ.pl[i].stoptime;
pl[i].Gard=netJ.pl[i].Gard;
pl[i].GardP=netJ.pl[i].GardP;
pl[i].Jump=netJ.pl[i].Jump;
pl[i].AttackStatus=netJ.pl[i].AttackStatus;
pl[i].GardP=netJ.pl[i].GardP;
pl[i].Draw=netJ.pl[i].Draw;
pl[i].vx=netJ.pl[i].vx;
pl[i].vy=netJ.pl[i].vy;
pl[i].frag=netJ.pl[i].frag;
*/
}
if(pl[i].num<=0){
pl[i].frag=0;
}
}
}
allcount++;
Shot_Update();
Effect_Update();
ChangeLightTypeDir( VGet( 0 ,-2600 , 3400 ) ) ;
float x,z,y;
x=(pl[0].x-pl[1].x);
y=(pl[0].y-pl[1].y);
if(x>0){
x=-x;
}
if(y>0){
y=-y;
}
z=x+y;
if(z>0){
z=-z;
}
SetCameraPositionAndTarget_UpVecY( VGet( (pl[0].x+pl[1].x)/2, ((pl[0].y+pl[1].y)/2)+20, z-30 ), VGet( (pl[0].x+pl[1].x)/2, ((pl[0].y+pl[1].y)/2)+10, 0.0f ) ) ;
// SetCameraPositionAndTarget_UpVecY( VGet( (pl[0].x+pl[1].x)/2, ((pl[0].y+pl[1].y)/2)+20, -120 ), VGet( (pl[0].x+pl[1].x)/2, ((pl[0].y+pl[1].y)/2)+10, 0.0f ) ) ;
// SetCameraPositionAndTarget_UpVecY( VGet( 0, 20, -120 ), VGet( 50, 20, 0.0f ) ) ;
}
}
void Link_S_Draw(){ //クライアントの描画
if(state==0){
DrawFormatString(50,0,GetColor(255,255,255),"IPアドレスを入力してね");
}
if(state==1){
DrawFormatString(50,0,GetColor(255,255,255),"接続まちなう~");
}
if(state==2){
// 3Dモデルのスケールをx軸方向に2倍にする
MV1SetScale( stg.ModelHandleA, VGet( 1.5f, 1.5f, 1.5f ) ) ;
MV1SetPosition( stg.ModelHandleA, VGet(0,-185,-420) ) ;
MV1SetRotationXYZ( stg.ModelHandleA, VGet( 0.0f,0.0f, 0.0f ) ) ;
// ステージモデルの描画
MV1DrawModel( stg.ModelHandleB ) ;
// ステージモデルの描画
MV1DrawModel( stg.ModelHandleA ) ;
for(int i=0; i<4;i++){
// 指定位置にモデルを配置
MV1SetPosition( pl[i].ModelHandle, VGet( pl[i].x, pl[i].y, 0 ) ) ;
if(pl[i].frag==true&&pl[i].Draw==true){
// 3Dモデルの描画
MV1DrawModel( pl[i].ModelHandle ) ;
if(pl[i].status==4&&pl[i].Gard==0){
SetDrawBlendMode( DX_BLENDMODE_ADD , 255 ) ;
DrawBillboard3D( VGet( pl[i].x, pl[i].y+10,0 ), 0.5f, 0.5f, pl[i].GardP/8, 0, imgrs[0], true ) ;
SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
}
SetDrawBlendMode( DX_BLENDMODE_ALPHA, 160 );
VECTOR Screen = ConvWorldPosToScreenPos( VGet(pl[i].x,pl[i].y+25,0) ) ;
DrawBox(Screen.x-15,Screen.y-5,Screen.x+120,Screen.y+30,GetColor(0,0,0),true);
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 );
DrawFormatString(Screen.x-10,Screen.y,GetColor(255,255,255),profile[pl[i].Profile].name);
}
}
Shot_Draw();
Effect_Draw();
DrawBox(0,0,300,100,GetColor(255,255,255),true);
DrawFormatString(0,0,0,"pl1,x:%f,y:%f",pl[0].x,pl[0].y);
DrawFormatString(0,20,0,"pl2,x:%f,y:%f",pl[1].x,pl[1].y);
DrawFormatString(0,40,0,"pl1 vy%f,y%f,",pl[0].vy,pl[0].y);
DrawFormatString(0,60,0,"pl1 vy%f,y%f,",pl[1].vy,pl[1].y);
DrawBox(150,300,300,400,GetColor(255,255,255),true);
DrawBox(350,300,500,400,GetColor(255,255,255),true);
DrawFormatString(150,300,0,"%d%",pl[0].Percentage);
DrawFormatString(350,300,0,"%d%",pl[1].Percentage);
DrawFormatString(150,325,0,"残機:%d",pl[0].num);
DrawFormatString(350,325,0,"残機:%d",pl[1].num);
DrawFormatString(150,350,0,profile[pl[0].Profile].name);
DrawFormatString(350,350,0,profile[pl[1].Profile].name);
if(ba<=1&&allcount<127){
SetDrawBlendMode( DX_BLENDMODE_ALPHA, allcount*2 );
DrawBox(0,0,640,480,GetColor(0,0,0),true);
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 );
}
if( CheckNetWorkRecvUDP( NetUDPHandle ) == FALSE ) {
DrawBox(50,50,100,200,GetColor(255,255,255),true);
DrawFormatString(80,80,0,"相手からのデータ応答がありません",pl[1].num);
}
}
}[\code]
ホストのコード
[code]
void Link_J_Init(){ //ホストの初期化
DeleteUDPSocket( NetUDPHandle ) ;
NetUDPHandle = MakeUDPSocket( 25953 ) ;
state=0;
Game_Init();
mynum=0;
}
int winpl;
int ba;
int iroha;
void Link_J_Update(){ //ホスト側の通信
if(state==0){
// 新しい接続があった場合はループを出る
if( CheckNetWorkRecvUDP( NetUDPHandle ) == TRUE ) {
state=1;
NetWorkRecvUDP( NetUDPHandle, &IP, NULL, &netS, sizeof(netS), FALSE ) ;
NetWorkSendUDP( NetUDPHandle,IP,25953,&netJ, sizeof(netJ)) ;
}
}
if(state==1){
if(Key(KEY_INPUT_ESCAPE)==1){
Next_Scene(eScene_Menu);
}
NetWorkRecvUDP( NetUDPHandle, NULL, NULL, &netS, sizeof(netS), FALSE ) ;
for(int i=0;i<4;i++){
if(pl[i].frag==true){
if(i==mynum){
Player_Update( i);
}else{
Player_Update_Net( i,netS.COF,netS.COFDown);
}
if(pl[i].num<=0){
pl[i].frag=0;
}
}
netJ.pl[i]=pl[i];
}
for(int i=0;i<COF_NUM_KEY;i++){
netJ.COF[i]=Cof(pl[0].Profile,i);
netJ.COFDown[i]=CofDown(pl[0].Profile,i);
}
NetWorkSendUDP( NetUDPHandle,IP,25953,&netJ, sizeof(netJ)) ;
allcount++;
Shot_Update();
Effect_Update();
ChangeLightTypeDir( VGet( 0 ,-2600 , 3400 ) ) ;
}
}
void Link_J_Draw(){ //ホストの描画
if(state==0){
DrawFormatString(50,0,GetColor(255,255,255),"接続待ちをしています。");
}
if(state==1){
MV1SetScale( stg.ModelHandleA, VGet( 1.5f, 1.5f, 1.5f ) ) ;
MV1SetPosition( stg.ModelHandleA, VGet(0,-185,-420) ) ;
MV1SetRotationXYZ( stg.ModelHandleA, VGet( 0.0f,0.0f, 0.0f ) ) ;
// ステージモデルの描画
MV1DrawModel( stg.ModelHandleB ) ;
// ステージモデルの描画
MV1DrawModel( stg.ModelHandleA ) ;
for(int i=0; i<4;i++){
// 指定位置にモデルを配置
MV1SetPosition( pl[i].ModelHandle, VGet( pl[i].x, pl[i].y, 0 ) ) ;
if(pl[i].frag==true&&pl[i].Draw==true){
// 3Dモデルの描画
MV1DrawModel( pl[i].ModelHandle ) ;
if(pl[i].status==4&&pl[i].Gard==0){
SetDrawBlendMode( DX_BLENDMODE_ADD , 255 ) ;
DrawBillboard3D( VGet( pl[i].x, pl[i].y+10,0 ), 0.5f, 0.5f, pl[i].GardP/8, 0, imgrs[0], true ) ;
SetDrawBlendMode( DX_BLENDMODE_NOBLEND , 0 ) ;
}
SetDrawBlendMode( DX_BLENDMODE_ALPHA, 160 );
VECTOR Screen = ConvWorldPosToScreenPos( VGet(pl[i].x,pl[i].y+25,0) ) ;
DrawBox(Screen.x-15,Screen.y-5,Screen.x+120,Screen.y+30,GetColor(0,0,0),true);
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 );
DrawFormatString(Screen.x-10,Screen.y,GetColor(255,255,255),profile[pl[i].Profile].name);
}
}
Shot_Draw();
Effect_Draw();
DrawBox(0,0,300,100,GetColor(255,255,255),true);
DrawFormatString(0,0,0,"pl1,x:%f,y:%f",pl[0].x,pl[0].y);
DrawFormatString(0,20,0,"pl2,x:%f,y:%f",pl[1].x,pl[1].y);
DrawFormatString(0,40,0,"pl1 vy%f,y%f,",pl[0].vy,pl[0].y);
DrawFormatString(0,60,0,"pl1 vy%f,y%f,",pl[1].vy,pl[1].y);
DrawBox(150,300,300,400,GetColor(255,255,255),true);
DrawBox(350,300,500,400,GetColor(255,255,255),true);
DrawFormatString(150,300,0,"%d%",pl[0].Percentage);
DrawFormatString(350,300,0,"%d%",pl[1].Percentage);
DrawFormatString(150,325,0,"残機:%d",pl[0].num);
DrawFormatString(350,325,0,"残機:%d",pl[1].num);
DrawFormatString(150,350,0,profile[pl[0].Profile].name);
DrawFormatString(350,350,0,profile[pl[1].Profile].name);
if(ba<=1&&allcount<127){
SetDrawBlendMode( DX_BLENDMODE_ALPHA, allcount*2 );
DrawBox(0,0,640,480,GetColor(0,0,0),true);
SetDrawBlendMode( DX_BLENDMODE_NOBLEND, 0 );
}
if( CheckNetWorkRecvUDP( NetUDPHandle ) == FALSE ) {
DrawBox(50,50,100,200,GetColor(255,255,255),true);
DrawFormatString(80,80,0,"相手からのデータ応答がありません",pl[1].num);
}
}
}
//プレイヤーに関する構造体
typedef struct{
int COF[COF_NUM_KEY];
int COFDown[COF_NUM_KEY];
pl_st pl[4];
}net_J_st;
//プレイヤーに関する構造体
typedef struct{
int COF[COF_NUM_KEY];
int COFDown[COF_NUM_KEY];
}net_S_st;
int state;
int NetUDPHandle ; // 接続相手のネットワークハンドル
int i,j,k;
IPDATA IP; // 送信用IPアドレスデータ
//net_J_st netJ_test;
net_S_st netS;
net_J_st netJ;