#include "DxLib.h"
#include "matrixlib.h"
//摩擦係数を変化させる。
//-----------------------------初期設定、宣言----------------------------
const float PIE = 3.1415926; //πの値
const float GMS = 9.80665; //重力加速度の値
float frametime; //1秒当たりの呼び出し回数を計測
float ToRadian(float deg){
return(deg*PIE/180); //度数をラジアンに変換
}
Point2D ground[2]={{-100,240},{740,240}}; //地面の初期座標
Point2D sled[4] = {{0,220},{40,220},{40,240},{0,240}}; //ソリの初期座標
Point2D groundr[2],sledr[4]; //変形後の座標
int angle = 0; //地面の角度
const float LIM_FRIC=0.6;//静止摩擦係数
float KIN_FRIC=0.4;//動摩擦係数
const float MASS=60;//ソリの質量
int flag=0;//初期フラグは0
float speedx=0;//ソリの速度
//-------------------------グラフ表示の宣言------------------------------------
int curidx=0;
float curdist=0;
float graphary[600];
//-------------ここに画面書き換えの処理を書いていく--------------------------
void PhysicsDraw(){
for(int i=0;i<curidx;i=i+1){
DrawLine(i,480-graphary[i]*5,i,480,GetColor(255,255,255));}//グラフの表示
float r =ToRadian(angle);//角度をラジアンに変換してrに代入
Matrix33 m=MultiMatrix(
GetTranslateMatrix(320,240),GetRotateMatrix(r)); //移動行列×回転行列
m=MultiMatrix(m,GetTranslateMatrix(-320,-240)); //(移動行列×回転行列)×移動行列
for(int i=0;i<2;i=i+1)groundr[i]=Transform2D(ground[i],m);//元の座標を行列mで変形
for(int i=0;i<4;i=i+1)sledr[i]=Transform2D(sled[i],m);//元の座標を行列mで変形
DrawLine(groundr[0].x,groundr[0].y,groundr[1].x,groundr[1].y,GetColor(255,255,255));
//変形後の座標を繋げる
for(int i=0;i<3;i=i+1){
DrawLine(sledr[i].x,sledr[i].y,sledr[i+1].x,sledr[i+1].y,GetColor(0,255,255));
}
DrawLine(sledr[3].x,sledr[3].y,sledr[0].x,sledr[0].y,GetColor(0,255,255));
//四角形の変形後の頂点の座標を繋げる
int key=GetJoypadInputState(DX_INPUT_KEY_PAD1);//キーで動かせる関数
if(key&PAD_INPUT_LEFT)angle = angle-1;//左キーで角度変更
if(key&PAD_INPUT_RIGHT)angle=angle+1;//右キーで角度変更
angle=(angle+360)%360;//角度が360度を越えないようにする。
clsDx();
printfDx("角度%d度\n",angle);//角度表示
if(flag==0){
float r=ToRadian(angle);
float slide_f=GMS*MASS*sin(r);//ソリに働く重力:mg*sin(r)
float normal_f=-GMS*MASS*cos(r);//ソリに働く垂直抗力:N=mg*cos(r)
float lfric_f=normal_f*LIM_FRIC;//ソリに働く最大静止摩擦力:μ*N
if(fabs(slide_f)>fabs(lfric_f))flag=1;//重力が静止摩擦力を超えたら滑り出す
//printfDx("重力%f 静止摩擦力%f",slide_f,lfric_f);
}
if(flag==1){
if(sledr[0].x>=200 && sledr[0].x<=300){KIN_FRIC=0.9;
DrawLine(groundr[0].x,groundr[0].y,groundr[1].x,groundr[1].y,GetColor(100,100,255));
}
else KIN_FRIC=0.4;//ソリの位置によって、動摩擦係数と地面の色を変える。
float r=ToRadian(angle);//角度をラジアンに変換
float slide_f=GMS*MASS*sin(r);//ソリに働く重力:mg*sin(r)
float normal_f=-GMS*MASS*cos(r);//ソリに働く垂直抗力:N=mg*cos(r)
float kfric_f=normal_f*KIN_FRIC;//ソリに働く動摩擦力:μ*N
//DrawLine(sledr[2].x,sledr[2].y,groundr[1].x/2,groundr[1].y/2,GetColor(250,0,0));
if(speedx==0 && slide_f<0)kfric_f=-kfric_f;
//もし速度が0かつ重力が負(左向き)になったら動摩擦力の向きを反転
if(speedx<0)kfric_f=-kfric_f;
//もし速度が負(左向き)であれば、動摩擦力の向きは正(右向き)
float fslide_f=slide_f+kfric_f;//合力
float a=fslide_f/MASS;//F=Maより
float d=speedx*frametime+(a*frametime*frametime)/2;//d=vt+0.5*a*t^2
speedx=speedx+a*frametime;//v=v+at
for(int i=0;i<4;i=i+1)sled[i].x=sled[i].x+d;//座標の変更
if((kfric_f<0 && speedx<0)||(kfric_f>0 && speedx>0)){
flag=0; speedx=0;} //静止の条件
//-------------------------グラフの記録----------------------------------
//curdist=curdist+d;
//graphary[curidx]=curdist;
//curidx=curidx+1;
//if(curidx>=600){curdist=0;}
//----------------------------------------------------------------------------
clsDx();
printfDx("動摩擦力%f 重力%f 加速度%f 速度%f\n",kfric_f,slide_f,a,speedx);
printfDx("動摩擦係数%f",KIN_FRIC);
}
}
//
--------------------------時間設定-----------------------------------------
void SetFrameTime(){
int s=GetNowCount();
for(int i=0;i<30;i=i+1){
ScreenFlip();
int e= GetNowCount();
frametime = frametime + e - s;
s=e;
}
frametime = frametime/30/1000;
printfDx("%f",frametime);
}
//-------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hI, HINSTANCE hP, LPSTR lpC, int nC)
{
ChangeWindowMode(TRUE); //ウィンドウモードで起動
if(DxLib_Init() == -1)return(-1);//DXライブラリ初期化
DrawBox(0, 0, 120, 120, 65535, TRUE);
SetDrawScreen(DX_SCREEN_BACK);
SetFrameTime();
while(ProcessMessage()==0 && CheckHitKey(KEY_INPUT_ESCAPE)==0){
ClsDrawScreen();
PhysicsDraw();
ScreenFlip();
}
DxLib_End();//DXライブラリ終了処理
return(0);//終了
}