- 追加された行はこの色です。
- 削除された行はこの色です。
- Ex.01 へ行く。
#author("2023-05-18T21:53:22+09:00","","")
#author("2023-05-20T10:56:42+09:00","","")
* 円運動の実現 [#vd2b23f4]
** シューティングにも円運動を! [#fbcf9c3f]
例えば「自機をナナメに移動させた際に、普通の縦/横移動のみの時よりも約1.41421356倍速く進む」とか、「敵が7WAY弾を撃つ際にも以下のように左図とならず、右図になってしまう」というのは、個人的にアツくなかったりします。ここでの紹介は方向感覚をより自然に、より奇麗に見せるための手法です。[[固定小数点>doc.18]]を使用した計算を前提としていますので、まだ読んでない方は予習して来てください。
#ref(1.png,nolink)
** 増分値のテーブル化 [#b709246e]
円運動の増分値を算出するには、''三角比''を避けて通れません。しかし三角関数の計算はとりわけ時間を要します。そこでまず、方向数を有限個(ここでは256個)に限定して、予め全方向の解データをテーブルで持ってします。方向値と移動方向の関係は次の通りです。
192
↑
128 ← ○ → 000
↓
064
256方向もあれば十分でしょうがPCゲームの場合、360方向では精度が甘いとのことで4096にしていることもあるそうです。このようにして最初に「テーブル定義」してしまえば、あとは配列データから値を引っ張り出すだけで解が求まるので、超高速になります。
** テーブルの製作方法 [#o04d060d]
さっそく「256を1ドットとみなす固定小数点方式」でテーブルを出力してみることにしましょう。
#include <stdio.h>
#include <math.h>
#define PI (3.1415926536)
int main(int argc, char* argv[])
{
FILE* fp;
int i;
short val;
char str[80];
// コサインテーブルを出力します
fp = fopen("cosdata.txt","w");
if(fp == NULL)
{
return -1;
}
fprintf(fp,"cos:\n");
for(i=0; i<256; i++)
{
val = (short)(cos(((double)i / 128) * PI) * 256);
sprintf(str, "\t,%5d\t\t/* no.%3d */\n", val, i);
fprintf(fp, str);
}
fclose(fp);
// サインテーブルを出力します
fp = fopen("sindata.txt","w");
if(fp == NULL)
{
return -1;
}
fprintf(fp,"sin:\n");
for(i=0; i<256; i++)
{
val = (short)(sin(((double)i / 128) * PI) * 256);
sprintf(str, "\t,%5d\t\t/* no.%3d */\n", val, i);
fprintf(fp, str);
}
fclose(fp);
return 0;
}
上記のcos()とsin()が、円運動のための移動増分を算出している部分です。実は!・・・自分自身、何故三角比で求まるのか、そのメカニズムの詳細はよく分かっていません(爆)。・・・すいません数学苦手なもので。まぁ、難しく考えるよりも、「こんな呪文で、あーら不思議!」・・・そういうものだと思っておいたほうが気楽で良いですよ。
- 出力結果
- cosdata.txt
cos:
, 256 /* no. 0 */
, 255 /* no. 1 */
, 255 /* no. 2 */
, 255 /* no. 3 */
, 254 /* no. 4 */
, 254 /* no. 5 */
, 253 /* no. 6 */
, 252 /* no. 7 */
, 251 /* no. 8 */
, 249 /* no. 9 */
, 248 /* no. 10 */
, 246 /* no. 11 */
, 244 /* no. 12 */
, 243 /* no. 13 */
, 241 /* no. 14 */
, 238 /* no. 15 */
, 236 /* no. 16 */
, 234 /* no. 17 */
, 231 /* no. 18 */
, 228 /* no. 19 */
, 225 /* no. 20 */
, 222 /* no. 21 */
, 219 /* no. 22 */
, 216 /* no. 23 */
, 212 /* no. 24 */
, 209 /* no. 25 */
, 205 /* no. 26 */
, 201 /* no. 27 */
, 197 /* no. 28 */
, 193 /* no. 29 */
, 189 /* no. 30 */
, 185 /* no. 31 */
, 181 /* no. 32 */
, 176 /* no. 33 */
, 171 /* no. 34 */
, 167 /* no. 35 */
, 162 /* no. 36 */
, 157 /* no. 37 */
, 152 /* no. 38 */
, 147 /* no. 39 */
, 142 /* no. 40 */
, 136 /* no. 41 */
, 131 /* no. 42 */
, 126 /* no. 43 */
, 120 /* no. 44 */
, 115 /* no. 45 */
, 109 /* no. 46 */
, 103 /* no. 47 */
, 97 /* no. 48 */
, 92 /* no. 49 */
, 86 /* no. 50 */
, 80 /* no. 51 */
, 74 /* no. 52 */
, 68 /* no. 53 */
, 62 /* no. 54 */
, 56 /* no. 55 */
, 49 /* no. 56 */
, 43 /* no. 57 */
, 37 /* no. 58 */
, 31 /* no. 59 */
, 25 /* no. 60 */
, 18 /* no. 61 */
, 12 /* no. 62 */
, 6 /* no. 63 */
, 0 /* no. 64 */
, -6 /* no. 65 */
, -12 /* no. 66 */
, -18 /* no. 67 */
, -25 /* no. 68 */
, -31 /* no. 69 */
, -37 /* no. 70 */
, -43 /* no. 71 */
, -49 /* no. 72 */
, -56 /* no. 73 */
, -62 /* no. 74 */
, -68 /* no. 75 */
, -74 /* no. 76 */
, -80 /* no. 77 */
, -86 /* no. 78 */
, -92 /* no. 79 */
, -97 /* no. 80 */
, -103 /* no. 81 */
, -109 /* no. 82 */
, -115 /* no. 83 */
, -120 /* no. 84 */
, -126 /* no. 85 */
, -131 /* no. 86 */
, -136 /* no. 87 */
, -142 /* no. 88 */
, -147 /* no. 89 */
, -152 /* no. 90 */
, -157 /* no. 91 */
, -162 /* no. 92 */
, -167 /* no. 93 */
, -171 /* no. 94 */
, -176 /* no. 95 */
, -181 /* no. 96 */
, -185 /* no. 97 */
, -189 /* no. 98 */
, -193 /* no. 99 */
, -197 /* no.100 */
, -201 /* no.101 */
, -205 /* no.102 */
, -209 /* no.103 */
, -212 /* no.104 */
, -216 /* no.105 */
, -219 /* no.106 */
, -222 /* no.107 */
, -225 /* no.108 */
, -228 /* no.109 */
, -231 /* no.110 */
, -234 /* no.111 */
, -236 /* no.112 */
, -238 /* no.113 */
, -241 /* no.114 */
, -243 /* no.115 */
, -244 /* no.116 */
, -246 /* no.117 */
, -248 /* no.118 */
, -249 /* no.119 */
, -251 /* no.120 */
, -252 /* no.121 */
, -253 /* no.122 */
, -254 /* no.123 */
, -254 /* no.124 */
, -255 /* no.125 */
, -255 /* no.126 */
, -255 /* no.127 */
, -256 /* no.128 */
, -255 /* no.129 */
, -255 /* no.130 */
, -255 /* no.131 */
, -254 /* no.132 */
, -254 /* no.133 */
, -253 /* no.134 */
, -252 /* no.135 */
, -251 /* no.136 */
, -249 /* no.137 */
, -248 /* no.138 */
, -246 /* no.139 */
, -244 /* no.140 */
, -243 /* no.141 */
, -241 /* no.142 */
, -238 /* no.143 */
, -236 /* no.144 */
, -234 /* no.145 */
, -231 /* no.146 */
, -228 /* no.147 */
, -225 /* no.148 */
, -222 /* no.149 */
, -219 /* no.150 */
, -216 /* no.151 */
, -212 /* no.152 */
, -209 /* no.153 */
, -205 /* no.154 */
, -201 /* no.155 */
, -197 /* no.156 */
, -193 /* no.157 */
, -189 /* no.158 */
, -185 /* no.159 */
, -181 /* no.160 */
, -176 /* no.161 */
, -171 /* no.162 */
, -167 /* no.163 */
, -162 /* no.164 */
, -157 /* no.165 */
, -152 /* no.166 */
, -147 /* no.167 */
, -142 /* no.168 */
, -136 /* no.169 */
, -131 /* no.170 */
, -126 /* no.171 */
, -120 /* no.172 */
, -115 /* no.173 */
, -109 /* no.174 */
, -103 /* no.175 */
, -97 /* no.176 */
, -92 /* no.177 */
, -86 /* no.178 */
, -80 /* no.179 */
, -74 /* no.180 */
, -68 /* no.181 */
, -62 /* no.182 */
, -56 /* no.183 */
, -49 /* no.184 */
, -43 /* no.185 */
, -37 /* no.186 */
, -31 /* no.187 */
, -25 /* no.188 */
, -18 /* no.189 */
, -12 /* no.190 */
, -6 /* no.191 */
, 0 /* no.192 */
, 6 /* no.193 */
, 12 /* no.194 */
, 18 /* no.195 */
, 25 /* no.196 */
, 31 /* no.197 */
, 37 /* no.198 */
, 43 /* no.199 */
, 49 /* no.200 */
, 56 /* no.201 */
, 62 /* no.202 */
, 68 /* no.203 */
, 74 /* no.204 */
, 80 /* no.205 */
, 86 /* no.206 */
, 92 /* no.207 */
, 97 /* no.208 */
, 103 /* no.209 */
, 109 /* no.210 */
, 115 /* no.211 */
, 120 /* no.212 */
, 126 /* no.213 */
, 131 /* no.214 */
, 136 /* no.215 */
, 142 /* no.216 */
, 147 /* no.217 */
, 152 /* no.218 */
, 157 /* no.219 */
, 162 /* no.220 */
, 167 /* no.221 */
, 171 /* no.222 */
, 176 /* no.223 */
, 181 /* no.224 */
, 185 /* no.225 */
, 189 /* no.226 */
, 193 /* no.227 */
, 197 /* no.228 */
, 201 /* no.229 */
, 205 /* no.230 */
, 209 /* no.231 */
, 212 /* no.232 */
, 216 /* no.233 */
, 219 /* no.234 */
, 222 /* no.235 */
, 225 /* no.236 */
, 228 /* no.237 */
, 231 /* no.238 */
, 234 /* no.239 */
, 236 /* no.240 */
, 238 /* no.241 */
, 241 /* no.242 */
, 243 /* no.243 */
, 244 /* no.244 */
, 246 /* no.245 */
, 248 /* no.246 */
, 249 /* no.247 */
, 251 /* no.248 */
, 252 /* no.249 */
, 253 /* no.250 */
, 254 /* no.251 */
, 254 /* no.252 */
, 255 /* no.253 */
, 255 /* no.254 */
, 255 /* no.255 */
- sindata.txt
sin:
, 0 /* no. 0 */
, 6 /* no. 1 */
, 12 /* no. 2 */
, 18 /* no. 3 */
, 25 /* no. 4 */
, 31 /* no. 5 */
, 37 /* no. 6 */
, 43 /* no. 7 */
, 49 /* no. 8 */
, 56 /* no. 9 */
, 62 /* no. 10 */
, 68 /* no. 11 */
, 74 /* no. 12 */
, 80 /* no. 13 */
, 86 /* no. 14 */
, 92 /* no. 15 */
, 97 /* no. 16 */
, 103 /* no. 17 */
, 109 /* no. 18 */
, 115 /* no. 19 */
, 120 /* no. 20 */
, 126 /* no. 21 */
, 131 /* no. 22 */
, 136 /* no. 23 */
, 142 /* no. 24 */
, 147 /* no. 25 */
, 152 /* no. 26 */
, 157 /* no. 27 */
, 162 /* no. 28 */
, 167 /* no. 29 */
, 171 /* no. 30 */
, 176 /* no. 31 */
, 181 /* no. 32 */
, 185 /* no. 33 */
, 189 /* no. 34 */
, 193 /* no. 35 */
, 197 /* no. 36 */
, 201 /* no. 37 */
, 205 /* no. 38 */
, 209 /* no. 39 */
, 212 /* no. 40 */
, 216 /* no. 41 */
, 219 /* no. 42 */
, 222 /* no. 43 */
, 225 /* no. 44 */
, 228 /* no. 45 */
, 231 /* no. 46 */
, 234 /* no. 47 */
, 236 /* no. 48 */
, 238 /* no. 49 */
, 241 /* no. 50 */
, 243 /* no. 51 */
, 244 /* no. 52 */
, 246 /* no. 53 */
, 248 /* no. 54 */
, 249 /* no. 55 */
, 251 /* no. 56 */
, 252 /* no. 57 */
, 253 /* no. 58 */
, 254 /* no. 59 */
, 254 /* no. 60 */
, 255 /* no. 61 */
, 255 /* no. 62 */
, 255 /* no. 63 */
, 256 /* no. 64 */
, 255 /* no. 65 */
, 255 /* no. 66 */
, 255 /* no. 67 */
, 254 /* no. 68 */
, 254 /* no. 69 */
, 253 /* no. 70 */
, 252 /* no. 71 */
, 251 /* no. 72 */
, 249 /* no. 73 */
, 248 /* no. 74 */
, 246 /* no. 75 */
, 244 /* no. 76 */
, 243 /* no. 77 */
, 241 /* no. 78 */
, 238 /* no. 79 */
, 236 /* no. 80 */
, 234 /* no. 81 */
, 231 /* no. 82 */
, 228 /* no. 83 */
, 225 /* no. 84 */
, 222 /* no. 85 */
, 219 /* no. 86 */
, 216 /* no. 87 */
, 212 /* no. 88 */
, 209 /* no. 89 */
, 205 /* no. 90 */
, 201 /* no. 91 */
, 197 /* no. 92 */
, 193 /* no. 93 */
, 189 /* no. 94 */
, 185 /* no. 95 */
, 181 /* no. 96 */
, 176 /* no. 97 */
, 171 /* no. 98 */
, 167 /* no. 99 */
, 162 /* no.100 */
, 157 /* no.101 */
, 152 /* no.102 */
, 147 /* no.103 */
, 142 /* no.104 */
, 136 /* no.105 */
, 131 /* no.106 */
, 126 /* no.107 */
, 120 /* no.108 */
, 115 /* no.109 */
, 109 /* no.110 */
, 103 /* no.111 */
, 97 /* no.112 */
, 92 /* no.113 */
, 86 /* no.114 */
, 80 /* no.115 */
, 74 /* no.116 */
, 68 /* no.117 */
, 62 /* no.118 */
, 56 /* no.119 */
, 49 /* no.120 */
, 43 /* no.121 */
, 37 /* no.122 */
, 31 /* no.123 */
, 25 /* no.124 */
, 18 /* no.125 */
, 12 /* no.126 */
, 6 /* no.127 */
, 0 /* no.128 */
, -6 /* no.129 */
, -12 /* no.130 */
, -18 /* no.131 */
, -25 /* no.132 */
, -31 /* no.133 */
, -37 /* no.134 */
, -43 /* no.135 */
, -49 /* no.136 */
, -56 /* no.137 */
, -62 /* no.138 */
, -68 /* no.139 */
, -74 /* no.140 */
, -80 /* no.141 */
, -86 /* no.142 */
, -92 /* no.143 */
, -97 /* no.144 */
, -103 /* no.145 */
, -109 /* no.146 */
, -115 /* no.147 */
, -120 /* no.148 */
, -126 /* no.149 */
, -131 /* no.150 */
, -136 /* no.151 */
, -142 /* no.152 */
, -147 /* no.153 */
, -152 /* no.154 */
, -157 /* no.155 */
, -162 /* no.156 */
, -167 /* no.157 */
, -171 /* no.158 */
, -176 /* no.159 */
, -181 /* no.160 */
, -185 /* no.161 */
, -189 /* no.162 */
, -193 /* no.163 */
, -197 /* no.164 */
, -201 /* no.165 */
, -205 /* no.166 */
, -209 /* no.167 */
, -212 /* no.168 */
, -216 /* no.169 */
, -219 /* no.170 */
, -222 /* no.171 */
, -225 /* no.172 */
, -228 /* no.173 */
, -231 /* no.174 */
, -234 /* no.175 */
, -236 /* no.176 */
, -238 /* no.177 */
, -241 /* no.178 */
, -243 /* no.179 */
, -244 /* no.180 */
, -246 /* no.181 */
, -248 /* no.182 */
, -249 /* no.183 */
, -251 /* no.184 */
, -252 /* no.185 */
, -253 /* no.186 */
, -254 /* no.187 */
, -254 /* no.188 */
, -255 /* no.189 */
, -255 /* no.190 */
, -255 /* no.191 */
, -256 /* no.192 */
, -255 /* no.193 */
, -255 /* no.194 */
, -255 /* no.195 */
, -254 /* no.196 */
, -254 /* no.197 */
, -253 /* no.198 */
, -252 /* no.199 */
, -251 /* no.200 */
, -249 /* no.201 */
, -248 /* no.202 */
, -246 /* no.203 */
, -244 /* no.204 */
, -243 /* no.205 */
, -241 /* no.206 */
, -238 /* no.207 */
, -236 /* no.208 */
, -234 /* no.209 */
, -231 /* no.210 */
, -228 /* no.211 */
, -225 /* no.212 */
, -222 /* no.213 */
, -219 /* no.214 */
, -216 /* no.215 */
, -212 /* no.216 */
, -209 /* no.217 */
, -205 /* no.218 */
, -201 /* no.219 */
, -197 /* no.220 */
, -193 /* no.221 */
, -189 /* no.222 */
, -185 /* no.223 */
, -181 /* no.224 */
, -176 /* no.225 */
, -171 /* no.226 */
, -167 /* no.227 */
, -162 /* no.228 */
, -157 /* no.229 */
, -152 /* no.230 */
, -147 /* no.231 */
, -142 /* no.232 */
, -136 /* no.233 */
, -131 /* no.234 */
, -126 /* no.235 */
, -120 /* no.236 */
, -115 /* no.237 */
, -109 /* no.238 */
, -103 /* no.239 */
, -97 /* no.240 */
, -92 /* no.241 */
, -86 /* no.242 */
, -80 /* no.243 */
, -74 /* no.244 */
, -68 /* no.245 */
, -62 /* no.246 */
, -56 /* no.247 */
, -49 /* no.248 */
, -43 /* no.249 */
, -37 /* no.250 */
, -31 /* no.251 */
, -25 /* no.252 */
, -18 /* no.253 */
, -12 /* no.254 */
, -6 /* no.255 */
** 増分値テーブルの利用法 [#y883b990]
上記の解答データをカットアンドペースト(と言ってもno.0の最初の「,」は削除)して、少々整形します。
const s16 CosTbl[] = {
:
(cosデータ)
:
};
const s16 SinTbl[] = {
:
(sinデータ)
:
};
int main()
{
u16 x,y;
u8 angle;
// 初期処理
for(;;)
{
// もろもろの処理
// 円運動
x += CosTbl[angle];
y += SimTbl[angle];
angle++;
// 表示処理
}
return 0;
}
・・・とすれば、円運動ぽい動きになる気がしませんか?
** メモリ節約 [#e955f586]
上記説明ではsin用、cos用でデータをそれぞれ用意していましたが、実はcos分だけでOKだったりします。なぜならば!
SinTbl[angle] = CosTbl[(angle + 192) & 0xff]
という式が成り立つためです。先ほどのデータを見比べてみて下さい。マクロを使ってみると簡単になります。
#define SQR_VX(a, b) (((s32)CosTbl[(a)] * (b)) >> 8)
#define SQR_VY(a, b) (((s32)CosTbl[(192+(a)) & 0xff] * (b)) >> 8)
// 円運動(変更案)
x += SQR_VX(angle, speed);
y += SQR_VY(angle, speed);
angle++;
に置換えれば、見事CosTblのデータだけで同じ動作が可能になっています。ちなみに、SQR_VX(a, b)の b にはスピード値が入り、ここでも「256を1とみなす固定小数点」を使っています。したがって、例えばここに256を設定すれば、[1ドット * 三角比]の移動量になります。
** 出典元 [#lf05c45c]
- M-KAIさんの「Witchシューティングゲーム制作記帳」
** 履歴 [#cf651bbb]
- 2023/05/18
- 2008/07/01