目標地点を指定すると、そのために必要な射出方向を計算する。
射出速度は一定なので、遠方を狙うほど早く着弾する。// ang ... 角度, pos ... 位置(座標), velo... 速さ
// distance ... 距離, b ... 放物線の第2係数
#include "d3m.hsp"
#module powModule
#defcfunc pow double d1, int i2, local st
st = 1.0
repeat i2
st *= d1
loop
return st
#global
#const GRAVITY 1.0 // 重力加速度
#const VELOCITY 30.1 // 射出速度
#const DISTANCE_MAX VELOCITY * VELOCITY / GRAVITY // 最大飛距離
#const GRID_MAX 8 // グリッドの本数
#const GRID_DISTANCE 100 // グリッドの間隔
#const TARGET_RADIUS 10 // 照準の半径
#const BULLET_RADIUS 8 // 砲弾の半径
screen 0, 480, 480
// 射出点の座標
posCannonX = double(GRID_MAX) * GRID_DISTANCE / 2
posCannonY = 0.0
posCannonZ = 0.0
// 照準の座標
posTargetX = double(GRID_MAX) * GRID_DISTANCE / 2
posTargetY = double(GRID_MAX) * GRID_DISTANCE / 2
posTargetZ = 0.0
d3setcam GRID_MAX * GRID_DISTANCE / 2, -300, 200, GRID_MAX * GRID_DISTANCE / 2, GRID_MAX * GRID_DISTANCE / 2, 0
*main
gosub *move
gosub *draw
wait 4
goto *main
*move
stick key, 15
if key & 16 : gosub *shot
// 照準の移動
posTargetX += 10 * (((key >> 2) & 1) - (key & 1))
posTargetY += 10 * (((key >> 1) & 1) - ((key >> 3) & 1))
// 砲弾の移動
if posBulletZ >= 0 {
posBulletX += veloBulletX
posBulletY += veloBulletY
posBulletZ += veloBulletZ
veloBulletZ -= GRAVITY
}
return
*shot
// 射出 ここらへんのスクリプトの理解は力学と微分の知識が要ります
posBulletX = posCannonX
posBulletY = posCannonY
posBulletZ = posCannonZ
angBullet = atan(posTargetY - posCannonY, posTargetX - posCannonX)
distance = limitf(sqrt(pow(posTargetX - posCannonX, 2) + pow(posTargetY - posCannonY, 2)), 0.0, DISTANCE_MAX)
b = DISTANCE_MAX / distance + sqrt(pow(DISTANCE_MAX / distance, 2) - 1)
veloBulletR = sqrt(GRAVITY * distance / b / 2)
veloBulletZ = b * veloBulletR
veloBulletX = veloBulletR * cos(angBullet)
veloBulletY = veloBulletR * sin(angBullet)
return
*draw
redraw 0
color : boxf
color 0, 255 // グリッド
repeat GRID_MAX + 1
d3line cnt * GRID_DISTANCE, 0, 0, cnt * GRID_DISTANCE, GRID_MAX * GRID_DISTANCE, 0
d3line 0, cnt * GRID_DISTANCE, 0, GRID_MAX * GRID_DISTANCE, cnt * GRID_DISTANCE, 0
loop
color 255 // 照準
d3circle posTargetX, posTargetY, posTargetZ, TARGET_RADIUS, 0
if posBulletZ >= 0 {
color 0, 0, 255 // 砲弾
d3circle posBulletX, posBulletY, posBulletZ, BULLET_RADIUS
color 191, 191, 191 // 影
d3circle posBulletX, posBulletY, 0, BULLET_RADIUS
}
redraw 1
return
2007年5月4日金曜日
砲弾の射出(d3module)
登録:
コメントの投稿 (Atom)
0 件のコメント:
コメントを投稿