プログラムのご協力

フォーラム(掲示板)ルール
フォーラム(掲示板)ルールはこちら  ※コードを貼り付ける場合は [code][/code] で囲って下さい。詳しくはこちら
電気屋

プログラムのご協力

#1

投稿記事 by 電気屋 » 14年前

久しぶりの書き込みです。よろしくお願いします。
今回、マウスの座標をトレースしてキャラクタを移動するプログラムを作っているのですが、なかなかうまく動きません。
その訳が、キャラクタのみを移動させるプログラムは何の問題もなく作れるのですが、
今回は、キャラクタの後に”尾”(キャラクタの後をついてくるオブジェクト)がありその”尾”も移動速度が変化してもしっかり付いてくる用にプログラムを書き換えたいのですがうまくいきません。
どうかアドバイスがあればお願いします。

コード:

#include "DxLib.h"
#include <math.h>
///////////////////////////////////////////////////////////////////////////////
//宣言
///////////////////////////////////////////////////////////////////////////////
#define SPEED 2.00
#define TAMA_MAX 10
#define LONG_W 100
#define LONG_K 10
#define H 30.00
#define W 30.00
#define R 30.00
#define PI 3.1415926535897932384626433832795

////////////////////////////////////////////////////////////////////////////////
//グローバル変数
////////////////////////////////////////////////////////////////////////////////

char Key[256];
int time;
int i;
int bufhead;

double xdelay[784];
double ydelay[784];
double speed=3.0;
double curx;
double cury;
/*
int xdelay[784];
int ydelay[784];
int speed;
int curx;
int cury;
*/
/////////////////////////////////////////////////////////////////////////////////
//構造体
/////////////////////////////////////////////////////////////////////////////////

struct CharData{
	double x;
	double y;
	int life;
};
struct CharData ch_1;
struct CharData jitama[TAMA_MAX];
struct CharData tekidata[LONG_W];


typedef struct{
    int x;
    int y;          //座標
}Mouse_t;
Mouse_t Mouse;
///////////////////////////////////////////////////////////////////////////////////
//プロトタイプ宣言
///////////////////////////////////////////////////////////////////////////////////
void WindowMode();
void TekiInit();
void KEY();
void Move();
void JitamaMove();



int GetHitMouseStateAll_2(Mouse_t *Nezumi){
    if(GetMousePoint( &Nezumi->x, &Nezumi->y ) == -1){ //マウスの位置取得
        return -1;
    }
}
////////////////////////////////////////////////////////////////////////////////////
//メインループ
////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP,LPSTR lpC, int nC ){

	TekiInit();

	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; //ウィンドウ化と初期化処理
		
	
		SetDrawScreen(DX_SCREEN_BACK);
		SetMouseDispFlag( TRUE ) ;//マウス表示オン



		int White = GetColor(255,255,255);
	while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
            //↑メッセージ処理        ↑画面をクリア         ↑キーボード入力状態取得       ↑ESCが押されると終了
        GetHitMouseStateAll_2(&Mouse);  //マウスの入力状態取得
///////////////////////////////////////////////////////////////////////////////////////////////
//プログラム
///////////////////////////////////////////////////////////////////////////////////////////////
		KEY();
		Move();
		DrawCircle( ch_1.x, ch_1.y, R , GetColor(255,255,255) , TRUE) ;
		JitamaMove();

        DrawFormatString(0,0,White,"座標[%d,%d]",Mouse.x,Mouse.y);

		WindowMode();
		ScreenFlip();


///////////////////////////////////////////////////////////////////////////////////////////////
	}
	DxLib_End() ;				// DXライブラリ使用の終了処理
	return 0 ;					// ソフトの終了
}




////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
//プログラム的処理
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ウインドウモード切替
////////////////////////////////////////////////////////////////////////////////////////////////////////////

void WindowMode(){
	if     (Key[KEY_INPUT_F1]==1)ChangeWindowMode(TRUE);
	else if(Key[KEY_INPUT_F2]==1)ChangeWindowMode(FALSE);
}

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//初期化
////////////////////////////////////////////////////////////////////////////////////////////////////////////


void TekiInit(){		
	ch_1.x =0.00;
	ch_1.y =0.00;
	time   =0;
	bufhead=0;
	for(i=0;i<LONG_W;i++){
		xdelay[i]=ch_1.x;
		ydelay[i]=ch_1.y;
	}
}


////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////
//ゲーム操作
////////////////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////
//キー操作
////////////////////////////////////////////////////////////////////////////////////////////////////////////


void KEY(){
		if(Key[KEY_INPUT_UP   ]==1)ch_1.y-=SPEED;
		if(Key[KEY_INPUT_DOWN ]==1)ch_1.y+=SPEED;
		if(Key[KEY_INPUT_LEFT ]==1)ch_1.x-=SPEED;
		if(Key[KEY_INPUT_RIGHT]==1)ch_1.x+=SPEED;
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//弾move
////////////////////////////////////////////////////////////////////////////////////////////////////////////


void JitamaMove(){
	if(Key[KEY_INPUT_Z]&&time==0){
		for(int i=0;i<TAMA_MAX;i++){
			if(jitama[i].life==0){
				jitama[i].life=1;
				jitama[i].x   =ch_1.x;
				jitama[i].y   =ch_1.y;
				break;
			}
		}
		time=10;
	}
	if(time>0)time-=1;
	for(i=0;i<TAMA_MAX;i++){
		if(jitama[i].life>0){
			jitama[i].x+=10.00;
			DrawCircle( jitama[i].x, jitama[i].y, R , GetColor(255,0,0) , TRUE) ;
			if(jitama[i].x>640)jitama[i].life=0;
		}
	}
}



////////////////////////////////////////////////////////////////////////////////////////////////////////////
//行動パターン
////////////////////////////////////////////////////////////////////////////////////////////////////////////


void Move(){

	for(i=0;i<LONG_K;i++){
		tekidata[i].x=xdelay[(bufhead+i*LONG_W/LONG_K+LONG_W)%LONG_W];
		tekidata[i].y=ydelay[(bufhead+i*LONG_W/LONG_K+LONG_W)%LONG_W];
		SetDrawBlendMode( DX_BLENDMODE_ALPHA , 128 ) ;
		DrawCircle( tekidata[i].x, tekidata[i].y, R , GetColor(255,0,0) , TRUE) ;
		SetDrawBlendMode( DX_BLENDMODE_ALPHA , 255 ) ;
		
	}
	curx=xdelay[bufhead];
	cury=ydelay[bufhead];
	bufhead=(bufhead-1+LONG_W)%LONG_W;

	if(ch_1.x<=curx)xdelay[bufhead]=curx-SPEED;
	else            xdelay[bufhead]=curx+SPEED;
	if(ch_1.y<=cury)ydelay[bufhead]=cury-SPEED;
	else            ydelay[bufhead]=cury+SPEED;
}
今回は、自分なりの書き方が多いので読みにくいかもしれませんがお願いします。
また、現在自分なりに作っているのでもっと効率によい書き方がある場合は今回の要望以外でもお願いします。
技術向上にご協力お願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: プログラムのご協力

#2

投稿記事 by h2so5 » 14年前

電気屋 さんが書きました: 今回、マウスの座標をトレースしてキャラクタを移動するプログラムを作っているのですが、なかなかうまく動きません。
マウス座標を使ったソースを見せてください。
このソースだとキー入力しかできません。
電気屋 さんが書きました: 今回は、キャラクタの後に”尾”(キャラクタの後をついてくるオブジェクト)がありその”尾”も移動速度が変化してもしっかり付いてくる用にプログラムを書き換えたいのですがうまくいきません。
どううまくいかないのかも書いてください。
常にキャラの座標に向かって移動すれようにすれば移動速度しても問題ないと思います。

電気屋

Re: プログラムのご協力

#3

投稿記事 by 電気屋 » 14年前

コメントありがとうございました。
まず、わかりづらい書き方を乗せたことを深くお詫び申します。
現在の状況は下記です

コード:

 
#include "DxLib.h"
#include <math.h>
///////////////////////////////////////////////////////////////////////////////
//宣言
///////////////////////////////////////////////////////////////////////////////
#define SPEED 2.00
#define LONG_W 100
#define LONG_K 10
#define H 30.00
#define W 30.00
#define R 30.00
#define PI 3.1415926535897932384626433832795
////////////////////////////////////////////////////////////////////////////////
//グローバル変数
////////////////////////////////////////////////////////////////////////////////
char Key[256];
int time;
int i;
int bufhead;

double xdelay[784];
double ydelay[784];
double speed=3.0;
double curx;
double cury;
/////////////////////////////////////////////////////////////////////////////////
//構造体
/////////////////////////////////////////////////////////////////////////////////
struct CharData{
	double x;
	double y;
	int life;
};
struct CharData ch_1;
struct CharData tekidata[LONG_W];

typedef struct{
    int x;
    int y;
}Mouse_t;
Mouse_t Mouse;
///////////////////////////////////////////////////////////////////////////////////
//プロトタイプ宣言
///////////////////////////////////////////////////////////////////////////////////
void WindowMode();
void TekiInit();
void KEY();
void Move();
void JitamaMove();

int GetHitMouseStateAll_2(Mouse_t *Nezumi){
    if(GetMousePoint( &Nezumi->x, &Nezumi->y ) == -1){ //マウスの位置取得
        return -1;
    }
}
////////////////////////////////////////////////////////////////////////////////////
//メインループ
////////////////////////////////////////////////////////////////////////////////////
int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP,LPSTR lpC, int nC ){

	TekiInit();

	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; 

	SetDrawScreen(DX_SCREEN_BACK);
	SetMouseDispFlag( TRUE ) ;//マウス表示オン
	int White = GetColor(255,255,255);
	
	while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && !Key[KEY_INPUT_ESCAPE]){
        GetHitMouseStateAll_2(&Mouse);  //マウスの入力状態取得
///////////////////////////////////////////////////////////////////////////////////////////////
//プログラム
///////////////////////////////////////////////////////////////////////////////////////////////
		Move();
		DrawCircle( Mouse.x, Mouse.y, R , GetColor(255,255,255) , TRUE) ;
        DrawFormatString(0,0,White,"座標[%d,%d]",Mouse.x,Mouse.y);

		WindowMode();
		ScreenFlip();
///////////////////////////////////////////////////////////////////////////////////////////////
	}
	DxLib_End() ;				// DXライブラリ使用の終了処理
	return 0 ;					// ソフトの終了
}

////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////
//プログラム的処理
////////////////////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////
//ウインドウモード切替
////////////////////////////////////////////////////////////////////////////////////////////////

void WindowMode(){
	if     (Key[KEY_INPUT_F1]==1)ChangeWindowMode(TRUE);
	else if(Key[KEY_INPUT_F2]==1)ChangeWindowMode(FALSE);
}

///////////////////////////////////////////////////////////////////////////////////////////////
//初期化
///////////////////////////////////////////////////////////////////////////////////////////////
void TekiInit(){		
	ch_1.x =0.00;
	ch_1.y =0.00;
	time   =0;
	bufhead=0;
	for(i=0;i<LONG_W;i++){
		xdelay[i]=Mouse.x;
		ydelay[i]=Mouse.y;
	}
}
//////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////
//ゲーム操作
/////////////////////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////////////////////

/////////////////////////////////////////////////////////////////////////////////////////////
//行動パターン(尾)
/////////////////////////////////////////////////////////////////////////////////////////////
void Move(){
	for(i=0;i<LONG_K;i++){
		tekidata[i].x=xdelay[(bufhead+i*LONG_W/LONG_K+LONG_W)%LONG_W];
		tekidata[i].y=ydelay[(bufhead+i*LONG_W/LONG_K+LONG_W)%LONG_W];
		SetDrawBlendMode( DX_BLENDMODE_ALPHA , 128 ) ;
		DrawCircle( tekidata[i].x, tekidata[i].y, R , GetColor(255,0,0) , TRUE) ;
		SetDrawBlendMode( DX_BLENDMODE_ALPHA , 255 ) ;
	}
	curx=xdelay[bufhead];
	cury=ydelay[bufhead];
	bufhead=(bufhead-1+LONG_W)%LONG_W;
///////////////////////////////////////////////////////////////////////////
//今回、メインで見てもらいたい場所
///////////////////////////////////////////////////////////////////////////
	if(Mouse.x<=curx)xdelay[bufhead]=curx-SPEED;
	else                xdelay[bufhead]=curx+SPEED;
	if(Mouse.y<=cury)ydelay[bufhead]=cury-SPEED;
	else                ydelay[bufhead]=cury+SPEED;
}
 
今回は、尾(付いてくるオブジェクト)に付いての質問です。
現在は”SPEED”で尾(付いてくるオブジェクト)の移動量を定義していますが、今回はマウスの座標の移動なので移動量が不規則でマウスの移動が早いと尾(付いてくるオブジェクト)が遅れてしまいます。また”SPEED”の値を大きくすると、尾(付いてくるオブジェクト)が変な動きをします。どうすれば綺麗に尾(付いてくるオブジェクト)を作れるか教えてください。
また、今 DrawCircleで円を描画していますが、値がどうしても0にならないのか尾(付いてくるオブジェクト)がずれてしまいます。どうすればいいのか教えてください。お願いします。

アバター
h2so5
副管理人
記事: 2212
登録日時: 15年前
住所: 東京
連絡を取る:

Re: プログラムのご協力

#4

投稿記事 by h2so5 » 14年前

電気屋 さんが書きました: 現在は”SPEED”で尾(付いてくるオブジェクト)の移動量を定義していますが、今回はマウスの座標の移動なので移動量が不規則でマウスの移動が早いと尾(付いてくるオブジェクト)が遅れてしまいます。また”SPEED”の値を大きくすると、尾(付いてくるオブジェクト)が変な動きをします。どうすれば綺麗に尾(付いてくるオブジェクト)を作れるか教えてください。
尾の移動スピードを、尾とマウス座標の距離に比例するようにすればいいんじゃないでしょうか。
電気屋 さんが書きました: また、今 DrawCircleで円を描画していますが、値がどうしても0にならないのか尾(付いてくるオブジェクト)がずれてしまいます。どうすればいいのか教えてください。お願いします。
尾とマウス座標の距離がSPEEDより小さかった場合、マウス座標を通り越してしまうので、
その場合は条件分岐して尾とマウス座標を一致させるなどの工夫が必要です。

しひ

Re: プログラムのご協力

#5

投稿記事 by しひ » 14年前

移動量云々などわざわざ考えなくとも、単純に過去のマウスの座標を尾の座標とするだけで良いのではないでしょうか。

電気屋

Re: プログラムのご協力

#6

投稿記事 by 電気屋 » 14年前

しひ、ありがとうございました。
:移動量云々などわざわざ考えなくとも、単純に過去のマウスの座標を尾の座標とするだけで良いのではないでしょうか
これなのですが、過去のマウスの座標を尾の座標にしても移動速度の変更をしないといけないのでずれます。

しひ

Re: プログラムのご協力

#7

投稿記事 by しひ » 14年前

移動量云々などわざわざ考えなくとも、というのは移動量なんて変数は使う必要が無いって意味です。

コード:

#include "dxlib.h"

// 座標用の構造体
typedef struct{
	int x; // キャストとかが面倒なので取り敢えず整数で
	int y;
} Position;

// 定数
static const int CHARA_SIZE = 30; // キャラクタの大きさ
static const int TAIL_MAX = 30; // 尾の数

// グローバル変数
static Position mouse; // マウスの座標兼自機の座標
static Position tails[TAIL_MAX]; // 尾の座標

int WINAPI WinMain( HINSTANCE hI, HINSTANCE hP,LPSTR lpC, int nC )
{
	// 初期化云々
	if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; 
	SetDrawScreen(DX_SCREEN_BACK);
	SetMouseDispFlag( TRUE );
	
	// 尾の初期化
	{
		int i = 0;
		for( ; i < TAIL_MAX; ++i )
		{
			tails[i].x = mouse.x;
			tails[i].y = mouse.y;
		}
	}

	// メインループ
	while( !ProcessMessage() && !CheckHitKey( KEY_INPUT_ESCAPE ) ) // Escで終了
	{
		ClearDrawScreen();
		
        // 尾の更新
        {
        	// 尾の座標を一つづつづらしていく
        	int i = TAIL_MAX - 1;
			for( ; 0 < i; --i )
			{
				tails[i].x = tails[i-1].x;
				tails[i].y = tails[i-1].y;
			}

			// 最後、tails[0]に前フレームのマウスの座標を入れる
			tails[0].x = mouse.x;
			tails[0].y = mouse.y;
        }

		// 自機の更新
		GetMousePoint( &mouse.x, &mouse.y ); // マウスの位置取得

		// 尾の描画
		{
			int i = 0;
			for( ; i < TAIL_MAX; ++i )
			{
				const int red = i * 255 / TAIL_MAX;
				DrawCircle( tails[TAIL_MAX-i].x, tails[TAIL_MAX-i].y, CHARA_SIZE, GetColor( red, 0, 0 ), TRUE );
			}
		}

		// 自機(マウス)の描画
		DrawCircle( mouse.x, mouse.y, CHARA_SIZE, GetColor( 255,255,255 ), TRUE );
		
		ScreenFlip();
	}
	DxLib_End();
	return 0;
}
C言語に準拠してるか微妙ですが、こういう感じです。

閉鎖

“C言語何でも質問掲示板” へ戻る