〜物理入門〜
ジャンプ動作やボールの跳ね返りなどを忠実に表現したいのに物理を知らないからプログラムがかけない・・・。
サンプルプログラムを見ても、基本的な物理の知識がないから何かいてあるのかわからない・・・。
そんな人の為に作りました「物理入門」。ここでは難しい話や億劫になるまじめなお勉強はいたしません!
ゲームに必要な最低限の事を実際にゲームプログラムと交えながらわかりやすく解説しています。
文型の人でも、数学・物理が嫌いな人でも抵抗無く読んでいただけるよう作ったつもりなので是非今まで
苦手意識を持っていた方でも肩の力を抜いて読んでください。
p1. 物体の速さとモニタのピクセル位置
--------どうでもよい前置き----------
小学校で 距離=速さ×時間 という方程式を習ったと思います。
速さというのはある時間で進む距離の事です。速さには単位があります。
自動車でよく「60キロ」「100キロ」と言っているのは「60(km/h)」「100(km/h)」の事です。
(km/h)は「キロメートル マイ ジ」と読みます。
kmはキロメートル、距離の単位の事です。
hはhourつまり1時間の事です。ジといっているのは1時間だからです。
単位をよく見てください。( km / h ) よく見ると距離を時間で割っていますね。
距離を時間で割っている・・・そうです「距離=速さ×時間」の式の両辺を時間でわってやると
「距離 / 時間 = 速さ」となっています。つまり単位を見ただけでこれが速さを表していることだとわかりますね。
キロメートルを時間(hour)で割ったもの。つまりこれが表す速さは
「1時間で進む距離」の事です。
一方 ( m / s )という単位があります。「メートル マイ ビョウ」と読みます。
1秒間に進む距離(メートル)です。物理では普段使っているキロメートルマイジではなくこちらの
メートルマイビョウ(m/s)を使います。
物理で「速さ」を表すときはたいてい(m/s)であり、速さは1秒間に進む距離だと覚えて置いてください。
--------------絶対覚えておく要点-----------------
速さは1秒間に進む距離(メートル)
----------------------------------------------------
これがわかればこの節OK!
問題1 |
速さ3(m/s)で10秒走りました。距離は何メートルでしょう? |
答え |
30(m) |
↑答えは「答え」の下部分を範囲指定してチェック!
問題2 |
速さ5(m/s)でt秒進みました。現在距離は何メートルでしょう? |
答え |
5*t (m) |
↑答えは「答え」の下部分を範囲指定してチェック!
問題3 |
速さ2(m/s)でt秒進みました。1メートルはモニタで言う50ピクセルです。現在モニタでは何ピクセル進んだでしょう? |
答え |
2*t*50(pixel) |
↑答えは「答え」の下部分を範囲指定してチェック!
問題3まで正解した人はOKです!
なんとなく今まで分かっていた人も問題3で「お?」と思ったと思います。
そうです、いくら計算できても、モニタでいうとどれ位進んだのかわからなければモニタで表現できませんね。
では問題3を実際にプログラムで書いて見ましょう。
速さは「v」で表します。
時間は「s」で表します。(1秒=secondの事です)
水平距離は「x」で表します。(水平方向とは横方向の事、x軸方向の事です)
モニタのキャラのx座標はch_xとしておきましょう。
速さは不変ですから定義しておきます。
#define v 2.0
oldtは計測開始時点の時間を格納します。
int oldt=0;
if(oldt==0)
oldt=GetNowCount();
tには計測開始時間からの経過時間を格納します。
t = (double)(GetNowCount() - oldt)/1000.0;
距離を求めます。
x = v * t ; //距離 = 速さ * 時間
計算した距離をモニタのピクセルサイズに合わせます。
ch_x = (int)(x * 50.0);//1mは50pix
DrawRotaGraph( ch_x , 240 , 3.15 , 0.0 , image[count%60/15+12] , TRUE )
;
拡大率3.15倍(この説明はした)で描画します。image[count%60/15+12]というのは、
まず、imgae[12] , [13] , [14] , [15] が右向きの画像であることと
リフレッシュレートが60だとして、countを60で割ったあまりをだせば1秒間で1通りの動作をさせられる。
60を15で割れば4通りの数値が出てくる。
ということから計算した式です。
---------ここわからなくてイイ----------
画像のキャラの身長が26ピクセルであることからキャラの動きを考える為に、
「1メートルはモニタでいう50ピクセル」という計算を実現してみましょう。
このキャラクタの身長が実際にリアル世界にいるとして170cmだったと仮定しましょう。
170cm・・つまり1.7mだとすると 50 : 1 = ? : 1.7より
(50ピクセルで1メートルなら何ピクセルで1.7メートル?)
?は85ピクセルであることがわかります。
よってキャラを85ピクセルで描けば1.7メートルのキャラが立っている世界を実現出来ます。
そして27ピクセルのキャラを85ピクセルに拡大するためには85/27 ≒ 3.15
つまり3.15倍拡大して表示すればいいことが分かります。
ですからDrawRotaGraph関数で拡大して表示しましょう。
---------------ココマデ--------------
全てのことをまとめて書くと以下のサンプルプログラムのようになります。
以下のサンプルプログラムは上で紹介した物をそのまま貼り付けただけです。
#include "DxLib.h" #define v 2.0 int image[16],count=0,oldt=0,ch_x; double t,x; char Key[256]; int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance,LPSTR lpCmdLine, int nCmdShow ){ if( ChangeWindowMode(TRUE) != DX_CHANGESCREEN_OK || DxLib_Init() == -1 ) return -1; SetDrawScreen( DX_SCREEN_BACK ); LoadDivGraph( "char.png" , 16 , 4 , 4 , 32 , 32 , image ) ; while(!ProcessMessage() && !ClearDrawScreen() && !GetHitKeyStateAll( Key ) && Key[KEY_INPUT_ESCAPE]==0){ if(oldt==0) oldt=GetNowCount();//計測開始時間を格納 t = (double)(GetNowCount() - oldt)/1000.0;//計測を始めてからの時間 x = v * t ; //距離 = 速さ * 時間 ch_x = (int)(x * 50.0);//1mは100pix DrawRotaGraph( ch_x , 240 , 3.15 , 0.0 , image[count%60/15+12] , TRUE ) ;//3.15倍で描画 count++; ScreenFlip(); } DxLib_End(); return 0; }
実行画面
どうでしょう、テクテクあるいているシミュレーションが出来たと思います。
お使いのモニタのリフレッシュレートの設定(処理速度を一定にする。をお読み下さい)にかかわらず、移動速度は一定になったはずです。
ご自分で1秒間に2mの速さで歩いてみてください。少々早歩きだと思います。
実際にシミュレーションしたような速さになったのではないでしょうか。
- Remical Soft -