/**
* 最終課題 : 打ち上げ花火
* 注意: 描画領域の大きさは,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つの始点をうまくばらけさせるにはどうすればいいのでしょうか。
またゆくゆくはランダムに座標を指定して花火を作りたいと思っています。
ご指摘の方よろしくおねがいします。