花火の始点が5つ連なってしまって上手くばらけさせて綺麗な花火が作れません。C言語のMsTimer型です。

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

花火の始点が5つ連なってしまって上手くばらけさせて綺麗な花火が作れません。C言語のMsTimer型です。

#1

投稿記事 by wasabi » 14年前

コード:

/**
 *	最終課題 : 打ち上げ花火
 *	注意: 描画領域の大きさは,Width, Height である。
 *		   πの値はPAIで定義されている。(ラジアン値=PAI/360.0×度)
 */
#include	<stdio.h>				// 基本関数など(標準)
#include 	<string.h>				// 文字操作用(標準)
#include	<math.h>				// 数学関数用(標準)
#include 	"WinBase4.h"			// C言語グラフィックス教材専用

/* 花火構造体の型宣言 */
typedef struct _HANABI {
	double		xpos;	// 花火の位置(X座標)
	double		ypos;	// 花火の位置(Y座標)
	double		radius;	// 花火の半径
	COLORREF	color;	// 花火の色
} HANABI;

/* プロトタイプの宣言 */
void drawHanabi( HDC gDC, HANABI hanabi );

/* 広域変数の定義 */
//HANABI	blueHanabi;		// 花火変数を宣言する

HANABI	abcHanabi[5];		// 花火変数を宣言する

char	Str1[] = "  打ち上げ花火";

/**
 *	機能 : 初期設定用(プログラムの実行で最初に1回呼ばれる)
 *	HWND   hWind : ウィンドウのハンドル
 *	戻り値       : なし
 */
void  MsInit( HWND  hWind )
{
	MsWinReal( FALSE );	// gDCを仮想画面にする
	// 花火に初期値を設定する
	abcHanabi[0].xpos = 300;		// 位置
	abcHanabi[0].ypos = 150;		// 位置
	abcHanabi[0].radius = 100;		// 半径
	abcHanabi[0].color = RGB( 0, 0, 255);		
	// 花火に初期値を設定する
	abcHanabi[1].xpos = 400;		// 位置
	abcHanabi[1].ypos = 200;		// 位置
	abcHanabi[1].radius = 100;		// 半径
	abcHanabi[1].color = RGB( 0,255 , 0);		
	// 花火に初期値を設定する
	abcHanabi[2].xpos = 300;		// 位置
	abcHanabi[2].ypos = 300;		// 位置
	abcHanabi[2].radius = 100;		// 半径
	abcHanabi[2].color = RGB( 255,0 , 0);		
	// 花火に初期値を設定する
	abcHanabi[3].xpos = 450;		// 位置
	abcHanabi[3].ypos = 150;		// 位置
	abcHanabi[3].radius = 100;		// 半径
	abcHanabi[3].color = RGB( 255,0 ,255);		
	// 花火に初期値を設定する
	abcHanabi[4].xpos = 250;		// 位置
	abcHanabi[4].ypos = 350;		// 位置
	abcHanabi[4].radius = 100;		// 半径
	abcHanabi[4].color = RGB( 0,255 ,255 );		
}
/**
 *	機能: 1/100秒(10ms)ごとに実行される
 *	HWND   hWind : ウィンドウのハンドル
 *	戻り値       : なし
 */
void MsTimer( HWND hWind, UINT TimerID )
{
	static int	count = 0;
	double		dd, x0, y0;
	int i;
	//
	
	MsClear( 0 );	// 仮想画面をクリアーする

	/*
		abcHanabi[i].xpos += abcHanabi[i].delta*cos(abcHanabi[i].dir);
		if((Width-abcHanabi[i].radius)<abcHanabi[i].xpos) abcHanabi[i].dir = PAI - abcHanabi[i].dir;
		if((0.0+abcHanabi[i].radius)>abcHanabi[i].xpos) abcHanabi[i].dir = PAI - abcHanabi[i].dir;
		abcHanabi[i].ypos += abcHanabi[i].delta*sin(abcHanabi[i].dir);
		if((Height-abcHanabi[i].radius)<abcHanabi[i].ypos) abcHanabi[i].dir = 0.0 - abcHanabi[i].dir;
		if((0.0+abcHanabi[i].radius)>abcHanabi[i].ypos) abcHanabi[i].dir = 0.0 - abcHanabi[i].dir;
	*/	
		
	

	
	
	for(i=0;i<5;i++)
	{	
		// 新しい位置を計算する

		// 花火を表示する
		drawHanabi( gDC, abcHanabi[i] );

	}	
		//
	TextOut( gDC, 20, 10, Str1, (int)strlen(Str1) );	// 見出しを表示
	MsShow(); 		// 実画面への表示
	count++;
}
// WM_DESTROY(X)で起動される
void MsClose( HWND  hWind )	
{
	// プログラムの後処理を記述する
}
/**
 *	関数名: drawHanabi  
 *	機能  : 花火を(xpos,ypos)座標に描く
 */
void drawHanabi( HDC gDC, HANABI hanabi )
{
	double		x1, y1, x0, y0;			// 左上隅と右下隅
	double		rr;
	int i;
	double nHdo;
	
	for(i=0;i<=5;i++){
	// === 描画のための準備 ===
	
	HPEN		hPen0 , hPen ; 			// ペンのハンドル
	HBRUSH		hBrush0 , hBrush ;		// ブラシのハンドル
	COLORREF	Color ;					// 色指定コード





	//ans = 0;
	//ans = 20 + MsRandom(200); 
	//nLeng = ans;

	
	Color = hanabi.color;						// 色を取り出す
	hBrush =  CreateSolidBrush( Color );	// ブラシを作成する。
	hBrush0 = SelectObject( gDC , hBrush );	// ブラシをDCに持たせる
	hPen  = CreatePen( PS_SOLID , 0 , Color );	// ペンを作成する
	hPen0 = SelectObject( gDC , hPen );	   	// ペンをDCに持たせる
//-------------------------------------------------------------------------------------------
		nHdo=0;
		rr = hanabi.radius; //花火の半径
		// === 花火を描く ===
		x0=300;
		y0=150;
		x0 = abcHanabi[i].xpos;
		y0 = abcHanabi[i].ypos;
		while( nHdo<360 )
		{
			x1 = hanabi.xpos+rr*cos(nHdo*(PAI/180.0));
			y1 = hanabi.ypos+rr*sin(nHdo*(PAI/180.0));		
			MoveToEx(gDC,(int)(x0+0.5),(int)(y0+0.5),NULL); 
			LineTo(gDC,(int)(x1+0.5),(int)(y1+0.5));
			nHdo += 10;
		}
//----------------------------------------------------------------------------------------------------
	SelectObject( gDC , hPen0 ) ;	// 元のペンを持たせる
	DeleteObject( hPen  );			// ペンを消去する
	SelectObject( gDC , hBrush0 ) ;	// 元のブラシを持たせる
	DeleteObject( hBrush );			// ブラシを消去する

		
	
	
	}

		

	
	  
	// === 描画関係の後処理 ===
		

}

学校の課題で花火の製作をすることにしたのですが、始点が上手く定まらずそれぞれの花火のペン色がほかのすべての
花火の始点に連らなって移ってしまう処理がされてしまいます。
それぞれの花火の5つの始点をうまくばらけさせるにはどうすればいいのでしょうか。
またゆくゆくはランダムに座標を指定して花火を作りたいと思っています。
ご指摘の方よろしくおねがいします。
最後に編集したユーザー Justy on 2011年1月07日(金) 02:19 [ 編集 2 回目 ]
理由: Code タグを修正させていただきました:個人情報を削除しました

アバター
kimuchi
記事: 163
登録日時: 14年前
住所: 東京

Re: 花火の始点が5つ連なってしまって上手くばらけさせて綺麗な花火が作れません。C言語のMsTimer型です。

#2

投稿記事 by kimuchi » 14年前

wasabiさんの書かれた花火の各点の移動処理はコメントアウト部分でしょうか?

とりあえず今疑問に思った事を書きます。
144~147行目で、x0,y0の代入が連続している、
また此処だけhanabiではなくabcHanabiが使われているのはなぜでしょうか?

wasabi

Re: 花火の始点が5つ連なってしまって上手くばらけさせて綺麗な花火が作れません。C言語のMsTimer型です。

#3

投稿記事 by wasabi » 14年前

kimuch様ご指摘ありがとうございます。
ご指摘された通り直したところ上手く処理することができました。
ありがとうございます。
動きは10個ほど花火をランダムで座標にあげたあとに一回画面をクリアし、もう一度花火を打ち上げるの繰り返しをしようと考えています。
コメント部分は無視してください。

コード:

/**
 *	最終課題 : 打ち上げ花火
 *	注意: 描画領域の大きさは,Width, Height である。
 *		   πの値はPAIで定義されている。(ラジアン値=PAI/360.0×度)
 */
#include	<stdio.h>				// 基本関数など(標準)
#include 	<string.h>				// 文字操作用(標準)
#include	<math.h>				// 数学関数用(標準)
#include 	"WinBase4.h"			// C言語グラフィックス教材専用

/* 花火構造体の型宣言 */
typedef struct _HANABI {
	double		xpos;	// 花火の位置(X座標)
	double		ypos;	// 花火の位置(Y座標)
	double		radius;	// 花火の半径
	COLORREF	color;	// 花火の色
} HANABI;

/* プロトタイプの宣言 */
void drawHanabi( HDC gDC, HANABI hanabi );

/* 広域変数の定義 */
//HANABI	blueHanabi;		// 花火変数を宣言する

HANABI	abcHanabi[5];		// 花火変数を宣言する

char	Str1[] = "  打ち上げ花火";

/**
 *	機能 : 初期設定用(プログラムの実行で最初に1回呼ばれる)
 *	HWND   hWind : ウィンドウのハンドル
 *	戻り値       : なし
 */
void  MsInit( HWND  hWind )
{
	MsWinReal( FALSE );	// gDCを仮想画面にする
	// 花火に初期値を設定する
	abcHanabi[0].xpos = 300;		// 位置
	abcHanabi[0].ypos = 150;		// 位置
	abcHanabi[0].radius = 100;		// 半径
	abcHanabi[0].color = RGB( 0, 0, 255);		
	// 花火に初期値を設定する
	abcHanabi[1].xpos = 400;		// 位置
	abcHanabi[1].ypos = 200;		// 位置
	abcHanabi[1].radius = 100;		// 半径
	abcHanabi[1].color = RGB( 0,255 , 0);		
	// 花火に初期値を設定する
	abcHanabi[2].xpos = 300;		// 位置
	abcHanabi[2].ypos = 300;		// 位置
	abcHanabi[2].radius = 100;		// 半径
	abcHanabi[2].color = RGB( 255,0 , 0);		
	// 花火に初期値を設定する
	abcHanabi[3].xpos = 450;		// 位置
	abcHanabi[3].ypos = 150;		// 位置
	abcHanabi[3].radius = 100;		// 半径
	abcHanabi[3].color = RGB( 255,0 ,255);		
	// 花火に初期値を設定する
	abcHanabi[4].xpos = 250;		// 位置
	abcHanabi[4].ypos = 350;		// 位置
	abcHanabi[4].radius = 100;		// 半径
	abcHanabi[4].color = RGB( 0,255 ,255 );		
}
/**
 *	機能: 1/100秒(10ms)ごとに実行される
 *	HWND   hWind : ウィンドウのハンドル
 *	戻り値       : なし
 */
void MsTimer( HWND hWind, UINT TimerID )
{
	static int	count = 0;
	double		dd, x0, y0;
	int i;
	//
	
	MsClear( 0 );	// 仮想画面をクリアーする


	

	
	
	for(i=0;i<5;i++)
	{	
		// 花火を表示する
		drawHanabi( gDC, abcHanabi[i] );

	}	
		//
	TextOut( gDC, 20, 10, Str1, (int)strlen(Str1) );	// 見出しを表示
	MsShow(); 		// 実画面への表示
	count++;
}
// WM_DESTROY(X)で起動される
void MsClose( HWND  hWind )	
{
	// プログラムの後処理を記述する
}
/**
 *	関数名: drawHanabi  
 *	機能  : 花火を(xpos,ypos)座標に描く
 */
void drawHanabi( HDC gDC, HANABI hanabi )
{
	double		x1, y1, x0, y0;			// 左上隅と右下隅
	double		rr;
	int i;
	double nHdo;
	
	for(i=0;i<=5;i++){
	// === 描画のための準備 ===
	
	HPEN		hPen0 , hPen ; 			// ペンのハンドル
	HBRUSH		hBrush0 , hBrush ;		// ブラシのハンドル
	COLORREF	Color ;					// 色指定コード





	//ans = 0;
	//ans = 20 + MsRandom(200); 
	//nLeng = ans;

	
	Color = hanabi.color;						// 色を取り出す
	hBrush =  CreateSolidBrush( Color );	// ブラシを作成する。
	hBrush0 = SelectObject( gDC , hBrush );	// ブラシをDCに持たせる
	hPen  = CreatePen( PS_SOLID , 0 , Color );	// ペンを作成する
	hPen0 = SelectObject( gDC , hPen );	   	// ペンをDCに持たせる
//-------------------------------------------------------------------------------------------
		nHdo=0;
		rr = hanabi.radius; //花火の半径
		// === 花火を描く ===

		x0 = hanabi.xpos;
		y0 = hanabi.ypos;
		while( nHdo<360 )
		{
			x1 = hanabi.xpos+rr*cos(nHdo*(PAI/180.0));
			y1 = hanabi.ypos+rr*sin(nHdo*(PAI/180.0));		
			MoveToEx(gDC,(int)(x0+0.5),(int)(y0+0.5),NULL); 
			LineTo(gDC,(int)(x1+0.5),(int)(y1+0.5));
			nHdo += 10;
		}
//----------------------------------------------------------------------------------------------------
	SelectObject( gDC , hPen0 ) ;	// 元のペンを持たせる
	DeleteObject( hPen  );			// ペンを消去する
	SelectObject( gDC , hBrush0 ) ;	// 元のブラシを持たせる
	DeleteObject( hBrush );			// ブラシを消去する

		
	
	
	}

		

	
	  
	// === 描画関係の後処理 ===
		

}
最後に編集したユーザー Justy on 2011年1月07日(金) 02:17 [ 編集 1 回目 ]
理由: 個人情報を削除しました

アバター
bitter_fox
記事: 607
登録日時: 14年前
住所: 大阪府

Re: 花火の始点が5つ連なってしまって上手くばらけさせて綺麗な花火が作れません。C言語のMsTimer型です。

#4

投稿記事 by bitter_fox » 14年前

直接の回答と関係ないですが、質問文のコードに質問者さんのお名前と思われるものが表示されてしまってますが、大丈夫でしょうか??
char str[]のところです。

wasabi.1

Re: 花火の始点が5つ連なってしまって上手くばらけさせて綺麗な花火が作れません。C言語のMsTimer型です。

#5

投稿記事 by wasabi.1 » 14年前

名前・・・。
投稿した後は名前の部分だけ消せないですよね?
消せるのであれば消していただくとありがたいです・・・。

アバター
kimuchi
記事: 163
登録日時: 14年前
住所: 東京

Re: 花火の始点が5つ連なってしまって上手くばらけさせて綺麗な花火が作れません。C言語のMsTimer型です。

#6

投稿記事 by kimuchi » 14年前

ランダムな座標というのはxposやyposをランダムにしたいということでしょうか?
MsInit関数が何度でも呼べるのであれば、この中でランダムな値を設定し、
あとはcountを管理されているようなので、以下のような感じでどうでしょう?

コード:

void  MsInit( HWND  hWind )
{
    MsWinReal( FALSE ); // gDCを仮想画面にする
    // 花火に初期値を設定する
    abcHanabi[0].xpos = ランダムで有効な値;        // 位置
    abcHanabi[0].ypos = ランダムで有効な値;        // 位置
以下略

void MsTimer( HWND hWind, UINT TimerID )
{
    static int  count = 0;
    double      dd, x0, y0;
    int i;
    //
    
    if(count%1000==999)  //10秒ごとにリセット
    {
        MsClear( 0 );   // 仮想画面をクリアーする
        MsInit( hWind );  //花火の情報をリセットする
    }
以下略
MsInit関数が二回以上使えなくても代わりは立てられると思います。
当方プログラムの仕様をあまりよく知らないので、でたらめかもしれませんがお許し下さい。


閉鎖

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