//----------[インクルードファイル ]----------------------------------------
#include "DxLib.h"
#include <math.h>
//----------[マクロ定義部 ]----------------------------------------
#define g 9.8//重力加速度
#define BMAX 100 //ボールの最大出現数を100個に
//----------[ グローバル変数 ]----------------------------------------
int clickcount;//クリック格納変数
int beforeMouseInput;//1フレーム前のマウスの状態
int mx,my; //マウス座標
double F, ax,ay,az; //力と加速度
static const float ROTATE_SPEED = DX_PI_F/90;//回転スピード
//----------[ ボール構造体 ]----------------------------------------
struct Ball{
int flag;//1:使用 0:消去
double x ; //x座標
double y ; //y座標
double z ; //z座標
double vx ; //x軸方向の速度
double vy ; //y軸方向の速度
double vz ; //z軸方向の速度
double m ; //質量
double r ; //半径
double k ; //ばね定数
double c ; //粘性係数
double dt; //時間変化
}ball[BMAX];
//----------[ 初期値 ]----------------------------------------
void Ini_Game(){
clickcount=0;//クリック初期化
beforeMouseInput = 0;//1フレーム前のマウスの状態
}
//----------[ ボール作成 ]----------------------------------------------
void Createball(double x,double y){
//構造体の中で、空いている(未使用)データを探す
for(int i=clickcount;i<BMAX;i++){
//データ詰める
ball[i].x=x;
ball[i].y=y;
ball[i].z=0;
ball[i].vx=0;
ball[i].vy=0;
ball[i].vz=0;
ball[i].m=1.0;
ball[i].r=40.0;
ball[i].k=0.5;
ball[i].c=2.5;
ball[i].dt=0.1;
ball[i].flag=1;//使用にする
}
}
//----------[ ボール発射判定 ]----------------------------------------------
void Shot_Hantei(){
//クリックした瞬間
if( (beforeMouseInput & MOUSE_INPUT_LEFT ) != MOUSE_INPUT_LEFT
&& (GetMouseInput() & MOUSE_INPUT_LEFT)== MOUSE_INPUT_LEFT){
clickcount+=1;//クリックカウント増やす
Createball(mx,my);//マウスの座標にボール作成
}
beforeMouseInput = GetMouseInput();
}
//----------[ ボール移動 ]----------------------------------------------
void Moveball(){
for(int i=0;i<BMAX;i++){
if(ball[i].flag==1&&clickcount>=1){//ボールが使用中なら
F = -ball[i].m * g; //自由落下
//バウンド処理
if( ball[i].y+ball[i].r < 0 ) {//地面に当たったら
F = ball[i].m * g;//バウンドさせる。
//沈み込み量に応じてバウンド減衰
if( ball[i].y < ball[i].r ) {
F += ball[i].k * ( ball[i].r -ball[i]. y) - ball[i].c *ball[i]. vy;
}
}
ax = F / ball[i].m; //加速度
ay = F / ball[i].m; //加速度
az = F / ball[i].m; //加速度
ball[i].vx += ax * ball[i].dt; //加速度から速度
ball[i].vy += ay * ball[i].dt; //加速度から速度
ball[i].vz += az * ball[i].dt; //加速度から速度
ball[i].x += ball[i].vx*ball[i].dt; //速度から座標
ball[i].y += ball[i].vy*ball[i].dt; //速度から座標
ball[i].z += ball[i].vz*ball[i].dt; //速度から座標
}
}
}
//----------[ ボール描画 ]----------------------------------------------
void Drawball(){
for(int i=0;i<BMAX;i++){
if(ball[i].flag==1&&clickcount>=1){//ボールが使用中なら
DrawSphere3D( VGet( ball[i].x,ball[i].y,ball[i].z), 40.0f, 32, GetColor( 255,0,0 ), GetColor( 255, 255, 255 ), TRUE ) ;
}
}
}
//カメラ回転(x,y)の点を(mx,my)を中心にang角回転する
void rotate(float *x, float *y, const float ang, const float mx, const float my){
const float ox = *x-mx, oy = *y-my;
*x = ox * cos(ang) + oy * sin(ang);
*y = -ox * sin(ang) + oy * cos(ang);
*x += mx;
*y += my;
}
//----------[ メイン関数 ]----------------------------------------------
int WINAPI WinMain( HINSTANCE, HINSTANCE, LPSTR, int ) {
ChangeWindowMode( TRUE ), DxLib_Init(), SetDrawScreen( DX_SCREEN_BACK ); //ウィンドウモード変更と初期化と裏画面設定
float cameraX=0, cameraZ=-20; //カメラの座標
const float targetX=0, targetZ=0;//カメラの視線の先ターゲットの座標
VECTOR CameraPos;
// カメラの座標を初期化
CameraPos.x = 0.0f ;
CameraPos.y = 0.0f ;
CameraPos.z = 0.0f ;
//奥行0.1~1000までをカメラの描画範囲とする
SetCameraNearFar( 0.1f, 1000.0f ) ;
Ini_Game();//初期値
//----------[ メインループ ]----------------------------------------------
// while( 裏画面を表画面に反映, メッセージ処理, 画面クリア,ESCAPEで終了 )
while( ScreenFlip() == 0 && ProcessMessage() == 0 && ClearDrawScreen() == 0 && CheckHitKey( KEY_INPUT_ESCAPE ) == 0 ) {
// 方向キーでカメラの座標を移動
if( CheckHitKey( KEY_INPUT_UP ) == 1 )
{
CameraPos.y += 20.0f ;
}
if( CheckHitKey( KEY_INPUT_DOWN ) == 1 )
{
CameraPos.y -= 20.0f ;
}
if( CheckHitKey( KEY_INPUT_LEFT ) == 1 )
{
CameraPos.x -= 20.0f ;
}
if( CheckHitKey( KEY_INPUT_RIGHT ) == 1 )
{
CameraPos.x += 20.0f ;
}
// カメラの位置と注視点をセット、注視点は原点
SetCameraPositionAndTarget_UpVecY( CameraPos, VGet( 0.0f, 0.0f, 0.0f ) ) ;
if( CheckHitKey(KEY_INPUT_LEFT) > 0 ){//左キーが押されていたら
rotate(&cameraX, &cameraZ, +ROTATE_SPEED, targetX, targetZ);//回転
}
if( CheckHitKey(KEY_INPUT_RIGHT) > 0 ){//右キーが押されていたら
rotate(&cameraX, &cameraZ, -ROTATE_SPEED, targetX, targetZ);//回転
}
GetMousePoint( &mx, &my);//マウスの入力状態更新
Shot_Hantei();//ボール発射判定
Moveball();//ボール移動
Drawball();//ボール描画
}
DxLib_End(); // DXライブラリ終了処理
return 0;
}
カメラの概念はどのようにして勉強すればよいでしょうか?
また、このソースコードの場合、どこを改良すれば、きちんと画面上にボールを表示することができるでしょうか?
アドバイスをお願いいたします。