ïŒKao CardosoFélixã«æè¬ããŸãããã®èšäºã¯ãã©ãžã«ç³»ãã«ãã¬ã«èªã§ãå©çšã§ããŸãïŒïŒãã·ã¢èªã§ãããããããããšãããããŸããïŒ
ã²ãŒã ãµã€ã¯ã«
åã²ãŒã ã«ã¯ããŠãŒã¶ãŒå ¥åã®èªã¿åããã²ãŒã ã®ç¶æ ã®æŽæ°ãAIã®åŠçãé³æ¥œãå¹æé³ã®åçãã°ã©ãã£ãã¯ã®ã¬ã³ããªã³ã°ãè¡ãäžé£ã®åŒã³åºããå«ãŸããŠããŸãã ãã®åŒã³åºãã·ãŒã±ã³ã¹ã¯ãã²ãŒã ã«ãŒãå ã§å®è¡ãããŸãã ã€ãŸãããã£ãŒã¶ãŒã§è¿°ã¹ãããã«ãã²ãŒã ãµã€ã¯ã«ã¯ãã¹ãŠã®ã²ãŒã ã®ãã«ã¹ã§ãã èšäºã§ã¯ãäžèšã®ã¿ã¹ã¯ã®å®è£ ã®è©³çŽ°ã«ã€ããŠã¯èª¬æããŸããããã²ãŒã ãµã€ã¯ã«ã®åé¡ã®ã¿ã«éäžããŸãã åãçç±ã§ãã¿ã¹ã¯ã®ãªã¹ãã2ã€ã®æ©èœïŒç¶æ ã®æŽæ°ãšã¬ã³ããªã³ã°ïŒã«åçŽåããŸãã 以äžã¯ãã²ãŒã ã«ãŒãã®æãåçŽãªå®è£ ã®ãµã³ãã«ã³ãŒãã§ãã
bool game_is_running = true; while( game_is_running ) { update_game(); display_game(); }
ãã®å®è£ ã®åé¡ã¯ãæéãåŠçããªãããšã§ãã ã²ãŒã ã¯å®è¡äžã§ãã 匱ãããŒããŠã§ã¢ã§ã¯ãã²ãŒã ã®å®è¡é床ã¯é ãã匷ãããŒããŠã§ã¢ã§ã¯é«éã§ãã ãããããããã³ã³ãã¥ãŒã¿ãŒã®ããã©ãŒãã³ã¹ãç°ãªããã·ã³ã§ã»ãŒåãã§ããããšãããã£ãŠãããšãããã®ãããªå®è£ ã¯åé¡ãåŒãèµ·ãããŸããã§ããã ä»æ¥ãããã©ãŒãã³ã¹ãç°ãªããã©ãããã©ãŒã ãå€æ°ããå ŽåãæéåŠçãå¿ èŠã«ãªããŸãã ãããè¡ãã«ã¯ããã€ãã®æ¹æ³ããããŸãã ãããã«ã€ããŠã¯åŸã§èª¬æããŸãã ãããŸã§ã®éãåŸã§äœ¿çšããããã€ãã®ãã€ã³ããæ確ã«ããŸãããã
Fps
FPSã¯ãFrames Per SecondãïŒ1ç§ãããã®äººå¡ãçŽTranslãïŒã®ç¥ã§ãã äžèšã®ã²ãŒã ã«ãŒãå®è£ ã®ã³ã³ããã¹ãã§ã¯ãããã¯1ç§éã®display_gameïŒïŒã®åŒã³åºãåæ°ã§ãã
ã²ãŒã é床
ã²ãŒã é床ã¯ã1ç§éã®ã²ãŒã ç¶æ ã®æŽæ°åæ°ã§ãã ã€ãŸãã1ç§ãããã®update_gameïŒïŒã®åŒã³åºãåæ°ã
äžå®ã®ã²ãŒã é床ã«å¿ããFPS
å®è£
ã¿ã€ãã³ã°ã®åé¡ã«å¯Ÿããæãç°¡åãªè§£æ±ºçã¯ã25å/ç§ã®åºå®åšæ³¢æ°ã§åçŽã«åŒã³åºããè¡ãããšã§ãã ãã®ã¢ãããŒããå®è£ ããã³ãŒãã¯æ¬¡ã®ãšããã§ãã
const int FRAMES_PER_SECOND = 25; const int SKIP_TICKS = 1000 / FRAMES_PER_SECOND; DWORD next_game_tick = GetTickCount(); // GetTickCount() returns the current number of milliseconds // that have elapsed since the system was started int sleep_time = 0; bool game_is_running = true; while( game_is_running ) { update_game(); display_game(); next_game_tick += SKIP_TICKS; sleep_time = next_game_tick - GetTickCount(); if( sleep_time >= 0 ) { Sleep( sleep_time ); } else { // Shit, we are running behind! } }
ããã¯1ã€ã®å€§ããªãã©ã¹ã®å®è£ ã§ãïŒã·ã³ãã«ïŒ update_gameïŒïŒã1ç§éã«25ååŒã³åºãããããšãããããšãæ®ãã®ã³ãŒãã®èšè¿°ã¯èžãã«ãããç°¡åã«ãªããŸãã ããšãã°ãåçæ©èœã®å®è£ ã¯ç°¡åãªã¿ã¹ã¯ã«ãªããŸãã ã²ãŒã ã§ã©ã³ãã å€æ°ã䜿çšãããŠããªãå Žåã¯ããŠãŒã¶ãŒå ¥åã§ãã°ã€ã³ããŠåŸã§ãã¬ã€ã§ããŸãã ãã¹ããã·ã³ã§ã¯ãFRAMES_PER_SECONDã®åŠ¥åå€ãèŠã€ããããšãã§ããŸãããé«éãŸãã¯äœéã®ããŒããŠã§ã¢ã§ã¯ã©ããªããŸããïŒ èª¿ã¹ãŠã¿ãŸãããã
匱ãé
ã¢ã€ãã³ãç¹å®ã®FPSã«èããããšãã§ããå Žåãåé¡ã¯ãããŸããã ãã·ã³ãFPSãç¹å®ã®ã¬ãã«ã«ç¶æã§ããªãå Žåãåé¡ãçºçããŸãã ã²ãŒã ã®å®è¡é床ãé ããªããŸãã ææªã®å Žåãã²ãŒã ã¯ããã€ãã®ééããé ããŸãããä»ã®å Žåã¯æ£åžžã«åäœããŸãã æéã¯ããŸããŸãªé床ã§æµããæçµçã«ã¯ã²ãŒã ããã¬ã€ã§ããªããªããŸãã
çç£çãªé
匷åãªããŒããŠã§ã¢ã§ã¯åé¡ã¯ãããŸããããã³ã³ãã¥ãŒã¿ãŒã¯ã¢ã€ãã«ç¶æ ã«ãªããã貎éãªãïŒæããã«ç®èã§ããïŒ-ãããTranslãïŒããã»ããµãŒæéã浪費ããŸãã 25..30 FPSããã²ãŒã ãéå§ããããšãæ¥ããããæããŸãã ããã»ããµãæ倧éã«äœ¿çšãããšãã«è¡šç€ºããããã®ãšæ¯èŒããŠãã²ãŒã ã®é åã倱ãããŸãã äžæ¹ãã¢ãã€ã«ãã©ãããã©ãŒã ã§ã¯ãããè¯ãçµæãåŸãããå¯èœæ§ããããŸãããšãã«ã®ãŒãç¯çŽã§ããŸãã
ãããã«
FPSãåºå®ã²ãŒã é床ã«çµã³ã€ããããšã¯ãã³ãŒããã·ã³ãã«ã«ä¿ã€ã·ã³ãã«ãªãœãªã¥ãŒã·ã§ã³ã§ãã ãã ããåé¡ããããŸããFPSã®å€ãé«ãèšå®ãããããšã匱ãããŒããŠã§ã¢ã§åé¡ãçºçããŸãã å€ãäœãèšå®ãããããšã匷åãªéãéå¹ççã«äœ¿çšãããŸãã
å¯å€FPSã²ãŒã é床
å®è£
ãã®åé¡ã®å¥ã®è§£æ±ºçã¯ãã²ãŒã ãã§ããã ãéãå®è¡ããã²ãŒã ã®é床ãçŸåšã®FPSã«äŸåãããããšã§ãã åã®ãã¬ãŒã ã®æç»ã«è²»ãããæéã䜿çšããŠãã²ãŒã ãæŽæ°ãããŸãã
DWORD prev_frame_tick; DWORD curr_frame_tick = GetTickCount(); bool game_is_running = true; while( game_is_running ) { prev_frame_tick = curr_frame_tick; curr_frame_tick = GetTickCount(); update_game( curr_frame_tick - prev_frame_tick ); display_game(); }
ã³ãŒãã¯è€éã§ã update_gameïŒïŒã§æéå·®ãåŠçãââãå¿ èŠããããŸãã ããããã³ãŒãã¯å°ãè€éã«ãªããŸããã ç§ã¯ãã®ã¢ãããŒããå®è£ ããå€ãã®è³¢ãéçºè ãèŠãŸããã 確ãã«åœŒãã®äžäººã¯ããã®ãããªãµã€ã¯ã«ãèªåã§å®è£ ããåã«ãã®æçš¿ãèªã¿ãããšæãã§ãããã 以äžã«ããã®ã¢ãããŒãã匱ãããŒããŠã§ã¢ãšåŒ·åãªããŒããŠã§ã¢ã®äž¡æ¹ã§æ·±å»ãªåé¡ãæ±ããŠããçç±ã瀺ããŸãïŒããã§ã...匷åãªããŒããŠã§ã¢ã§ãïŒã
匱ãé
ããŒããŠã§ã¢ã匱ããšãã²ãŒã ããéããªããå Žæã§é 延ãçºçããããšããããŸãã ããã¯ã3Dã²ãŒã ã§æç»ãããããªãŽã³ãå€ãããå Žåã«å¿ ãåœãŠã¯ãŸããŸãã ãã®çµæãFPSã§é害ãçºçãããšããŠãŒã¶ãŒã®å ¥ååŠçãé ããªããŸãã ã²ãŒã ã®æŽæ°ã¯FPSã®å€±æã«å¯Ÿå¿ããŸãããã®çµæãã²ãŒã ã®ç¶æ ã¯é¡èãªé ãã䌎ã£ãŠå€åããŸãã ãã®çµæããã¬ã€ã€ãŒã®åå¿æéã¯AIãšåãããã«é ããªããåçŽãªæäœã§ããäžå¯èœã«ãªãå¯èœæ§ããããŸãã ããšãã°ãéåžžã®FPSã§å æã§ããé害ã¯ãäœFPSã§ã¯å æãããŸããã ç©çã䜿çšããå Žåã匱ãããŒããŠã§ã¢ã§ããã«æ·±å»ãªåé¡ãçºçããŸãã ç©çã·ãã¥ã¬ãŒã·ã§ã³ã¯ççºããå¯èœæ§ããããŸãã
匷åãªé
äžèšã®ã²ãŒã ãµã€ã¯ã«ã®å®è£ ãé«éããŒããŠã§ã¢ã§æ£ããåäœããªãå¯èœæ§ãããããšã«é©ããããããŸããã æ®å¿µãªããã§ããŸãã ãããŠãçç±ã瀺ãåã«ãã³ã³ãã¥ãŒã¿ãŒã§ã®æ°åŠã®ããã€ãã®ãã€ã³ããæ確ã«ããŸãããã æµ®åå°æ°ç¹åœ¢åŒã®æ°å€ã®è¡šçŸã®æéããã深床ãèæ ®ããŠãäžéšã®å€ã¯è¡šçŸã§ããŸããã ãã®ãããå€0.1ã¯ãã€ããªåœ¢åŒã§è¡šçŸã§ãããdoubleåã®å€æ°ã«æ ŒçŽããããšäžžããããŸãã Pythonã³ã³ãœãŒã«ã䜿çšããŠãããå®èšŒããŸãã
>>> 0.1
0.10000000000000001
ããèªäœã¯å€§èã§ãããé次èšç®ã§ã¯åé¡ãçºçããŸãã ãªãŠã ã®é床ã0.001ã®è»ããããšä»®å®ããŸãïŒèªç±ãªç¿»èš³ãçŽTranslãïŒã 10ç§åŸããã·ã³ã¯10.0ãªãŠã ã®è·é¢ã移åããŸãã ãã®èšç®ããã¬ãŒã ã«åå²ãããšãFPSããã©ã¡ãŒã¿ãŒãšããŠæ¬¡ã®é¢æ°ãåŸãããŸãã
>>> def get_distance( fps ):
... skip_ticks = 1000 / fps
... total_ticks = 0
... distance = 0.0
... speed_per_tick = 0.001
... while total_ticks < 10000:
... distance += speed_per_tick * skip_ticks
... total_ticks += skip_ticks
... return distance
ãããŠãã«ã40 FPSã®ç§»åè·é¢ãèšç®ããŠã¿ãŸãããã
>>> get_distance( 40 )
10.000000000000075
ã¡ãã£ãšåŸ ã£ãŠïŒ ããã¯10.0ãªãŠã ã§ã¯ãããŸããïŒ ã©ããã ãã¹ãŠãã·ã³ãã«ã§ã... ãã¹èšç®ã400ãã¬ãŒã ã«åå²ãããããå ç®äžã«å€§ããªãšã©ãŒãèç©ãããŸããã 100 FPSã§äœãèµ·ãããæ³åããŠã¿ãŠãã ããã
>>> get_distance( 100 )
9.9999999999998312
ããïŒ ãšã©ãŒã¯ããã«å€§ãããªããŸãã!!! ããã¯ã100 FPSã§ããã«è¿œå ããããã§ãã ãã®çµæããšã©ãŒã¯ããã«èç©ãããŸãã ãããã£ãŠãã²ãŒã ã®åäœã¯40 FPSãš100 FPSã§ç°ãªããŸãã
>>> get_distance( 40 ) - get_distance( 100 )
2.4336088699783431e-13
ãã®éãã¯åãã«è¶³ããªããã®ã§ãããç¡èŠã§ãããšæããããããŸããã ãã ãããã®å€ãèšç®ã«äœ¿çšãããšãåé¡ã¯ããæ·±å»ã«ãªããŸãïŒäŸãšããŠãdiffãUrãçŽTranslãã®çµ±åïŒã ãããã£ãŠããšã©ãŒã¯éåžžã«å€§ããèç©ããå¯èœæ§ããããããã¶ã«ã«ãããïŒå ã®ãã©ã³ã¶ã¯ã·ã§ã³ãããå€å°æã¡æ¶ãããŸãïŒå€§ããFPSäžã®è£œåã ããã¯ã©ããããããããã§ããïŒ ãããã泚ç®ãéããã®ã«ååã§ãã ãã®ãããªã²ãŒã ãµã€ã¯ã«ã®å®è£ ãåããã²ãŒã ãèŠãããšãã§ããŠå æ ã§ããã ãããŠå®éã倧ããªFPSã§åé¡ãçºçããŸããã éçºè ã¯ãã²ãŒã ã³ãŒãã®ã³ã¢ã«ãç¬ãåãããŠãããããšã«æ°ä»ããåŸã倧éã®ã³ãŒãããªãã¡ã¯ã¿ãªã³ã°ããŠãã°ãä¿®æ£ããŸããã
ãããã«
äžèŠãããšããã®ã¿ã€ãã®ã²ãŒã ãµã€ã¯ã«ã¯éåžžã«è¯ãããã«èŠããŸãããæåã¯åããŠã§ãã 匱ãéãšåŒ·åãªéã®äž¡æ¹ãåé¡ãåŒãèµ·ããå¯èœæ§ããããŸãã ããã«ãç¶æ æŽæ°é¢æ°ã®å®è£ ã¯ãæåã®å®è£ ã«æ¯ã¹ãŠè€éã«ãªããŸããã ã ããããã®çã«ããã®ã§ããïŒ
äžå®ã®ã²ãŒã é床ãšæ倧FPS
å®è£
æåã®å®è£ ã§ãããäžå®ã®ã²ãŒã é床ã«äŸåããFPSãã«ã¯ã匱ãããŒããŠã§ã¢ã§åé¡ããããŸãã FPSãšã²ãŒã ã¹ããŒã¿ã¹ã®äž¡æ¹ã®æŽæ°ã®é ããçæããŸãã ãã®åé¡ã®å¯èœãªè§£æ±ºçã¯ãåºå®ã®é »åºŠã§ç¶æ ãæŽæ°ããããšã§ãããã¬ã³ããªã³ã°ã®é »åºŠãæžãããŸãã 以äžã¯ããã®ã¢ãããŒãã®å®è£ ã³ãŒãã§ãã
const int TICKS_PER_SECOND = 50; const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; const int MAX_FRAMESKIP = 10; DWORD next_game_tick = GetTickCount(); int loops; bool game_is_running = true; while( game_is_running ) { loops = 0; while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { update_game(); next_game_tick += SKIP_TICKS; loops++; } display_game(); }
ã²ãŒã ã¯1ç§ããã50åã®åºå®é »åºŠã§æŽæ°ãããã¬ã³ããªã³ã°ã¯å¯èœãªéãé«ãé »åºŠã§å®è¡ãããŸãã ç¶æ ã®æŽæ°ãããã¬ã³ããªã³ã°ãé »ç¹ã«å®è¡ãããå Žåãé£æ¥ãããã¬ãŒã ã®äžéšãåãã«ãªããããå®éã«ã¯ã²ãŒã ã®ç¶æ ãæŽæ°ããé »åºŠã«ãã£ãŠæ倧FPSå€ãå¶éãããããšã«æ³šæããŠãã ããã 匱ãããŒããŠã§ã¢ã§ã¯ãã¹ããŒã¿ã¹æŽæ°ãµã€ã¯ã«ãMAX_FRAMESKIPã«éãããŸã§FPSã¯æžå°ããŸãã å®éã«ã¯ãããã¯ãã¬ã³ããªã³ã°FPSã5ïŒ= FRAMES_PER_SECOND / MAX_FRAMESKIPïŒãäžåã£ãå Žåã«ã®ã¿ãã²ãŒã ã®é床ãäœäžãå§ããããšãæå³ããŸãã
匱ãé
匱ãããŒããŠã§ã¢ã§ã¯ãFPSã¯ããããã¢ãŠãããŸãããã²ãŒã èªäœã¯éåžžã®é床ã§é«ã確çã§åäœããŸãã ã¢ã€ãã³ãæå°FPSã«ãèããããªãå Žåãç¶æ ã®æŽæ°ãé ããªããã¬ã³ããªã³ã°ã¯æ»ãããªã¢ãã¡ãŒã·ã§ã³ã®ãã³ããã倱ããŸãã
匷åãªé
ã²ãŒã ã¯åé¡ãªã匷åãªããŒããŠã§ã¢ã§åäœããŸãããæåã®å®è£ ãšåæ§ã«ãããã»ããµã¯éå¹ççã«äœ¿çšãããŸãã è¿ éãªæŽæ°ãšåŒ±ãããŒããŠã§ã¢ã§äœæ¥ããèœåãšã®ãã©ã³ã¹ãèŠã€ããããšãéèŠã§ãã
ãããã«
åºå®ã®ã²ãŒã é床ãšå¯èœãªéãæé«ã®FPSã䜿çšããããšã¯ãå®è£ ãç°¡åã§ãã³ãŒããã·ã³ãã«ã«ä¿ã€ãœãªã¥ãŒã·ã§ã³ã§ãã ãããããŸã ããã€ãã®åé¡ããããŸãïŒç¶æ ã®æŽæ°é »åºŠãé«ãèšå®ãããããšã匱ãããŒããŠã§ã¢ã§åé¡ãçºçããŸãïŒæåã®å®è£ ã®å Žåã»ã©æ·±å»ã§ã¯ãããŸãããïŒãã¢ãã¡ãŒã·ã§ã³ã®æ»ããããå¢ããŸããã代ããã«é »ç¹ãªã¬ã³ããªã³ã°ã«è²»ããããŸãïŒã
å¯å€FPSã«äŸåããªãäžå®ã®ã²ãŒã é床
å®è£
以åã®å®è£ ãæ¹åããŠã匱ãããŒããŠã§ã¢ã§ããéãåäœãã匷åãªããŒããŠã§ã¢ã§èŠèŠçã«é åçã«ããããšã¯å¯èœã§ããïŒ ãŸããç§ãã¡ã«ãšã£ãŠå¹žããªããšã«ãã¯ããããã¯å¯èœã§ãïŒ ã²ãŒã ã®ç¶æ ãæ¯ç§60åæŽæ°ããå¿ èŠã¯ãããŸããã ãŠãŒã¶ãŒå ¥åãAIãããã³ã²ãŒã ã®ç¶æ ã®æŽæ°ã¯ã1ç§éã«25åæŽæ°ããã ãã§ååã§ãïŒããã«åæããããã§ã¯ãããŸããããåžžã«çŽã§ã¯ãããŸããïŒã ããã§ã¯update_gameïŒïŒã1ç§éã«25ååŒã³åºããŠã¿ãŸãããã ãã ããéãåŒã£åŒµãã®ãšåãé »åºŠã§ã¬ã³ããªã³ã°ãå®è¡ããŠãã ããã ãã ããã¬ã³ããªã³ã°ãé ãå Žåã§ããç¶æ ã®ãªãã¬ãã·ã¥ã¬ãŒãã«ã¯åœ±é¿ããŸããã ãããå®çŸããæ¹æ³ã次ã®ã³ãŒãã«ç€ºããŸãã
const int TICKS_PER_SECOND = 25; const int SKIP_TICKS = 1000 / TICKS_PER_SECOND; const int MAX_FRAMESKIP = 5; DWORD next_game_tick = GetTickCount(); int loops; float interpolation; bool game_is_running = true; while( game_is_running ) { loops = 0; while( GetTickCount() > next_game_tick && loops < MAX_FRAMESKIP) { update_game(); next_game_tick += SKIP_TICKS; loops++; } interpolation = float( GetTickCount() + SKIP_TICKS - next_game_tick ) / float( SKIP_TICKS ); display_game( interpolation ); }
ãã®çµæãupdate_gameïŒïŒã®å®è£ ã¯ã·ã³ãã«ãªãŸãŸã§ãã ãã ããæ®å¿µãªãããdisplay_gameïŒïŒé¢æ°ã¯ããè€éã«ãªããŸãã è£éãšäºæž¬ãå®è£ ããå¿ èŠããããŸãã ããããå¿é ããªãã§ãã ãããèŠãç®ã»ã©é£ãããããŸããã åŸã»ã©ãè£éãšäºæž¬ãã©ã®ããã«æ©èœãããã説æããŸãããæåã«ããããå¿ èŠãªçç±ã瀺ããŸãã
è£éãå¿ èŠãªçç±
ã²ãŒã ã®ç¶æ ã¯1ç§éã«25åæŽæ°ãããŸãã ãããã£ãŠãè£éã䜿çšãããªãå Žåããã¬ãŒã ã¯åãæ倧åšæ³¢æ°ã§è¡šç€ºãããŸãã ããã§ã¯ã1ç§ããã25ãã¬ãŒã ã誰ãã«èŠããã»ã©é ããªãããšã«æ³šæããå¿ èŠããããŸãã ããšãã°ããã£ã«ã ã§ã¯ããã¬ãŒã ã¯æ¯ç§24ãã¬ãŒã ã®é »åºŠã§å€åããŸãã ãããã£ãŠãæ¯ç§25ãã¬ãŒã ã§ååãšæãããŸãããé«éã§ç§»åãããªããžã§ã¯ãã«ã¯ååã§ã¯ãããŸããã ãã®ãããªãªããžã§ã¯ãã®å Žåã¯ãç¶æ ã®ãªãã¬ãã·ã¥ã¬ãŒããäžããŠãããã¹ã ãŒãºãªã¢ãã¡ãŒã·ã§ã³ãååŸããå¿ èŠããããŸãã ãªãã¬ãã·ã¥ã¬ãŒãã®å¢å ã«ä»£ãããã®ã¯ãæ£ç¢ºã«è£éãšäºæž¬ã®çµã¿åããã§ãã
*泚 perevãïŒNeoAxisã®ç©çãªããžã§ã¯ãã®ãšã³ãžã³ã§ã¯ããã©ã°Continuous Collision Detectionãèšå®ã§ããŸãã äžèšã®ã²ãŒã ãµã€ã¯ã«ã®å®è£ ãšåæ§ã«å®è¡ãããã®ã¯ãåãªãåŠçã§ãããšæãããŸãã
è£éãšäºæž¬
äžèšã®ããã«ãç¶æ ã¯ç¬ç«ããé »åºŠã§æŽæ°ãããŸãã ãããã£ãŠãé£ç¶ãã2ã€ã®ãã£ãã¯ã®éã§æç»ãéå§ãããå ŽåããããŸãã ç¶æ ã10åæŽæ°ãããšããŸãã 次ã«ãæç»ãåŒã³åºããã10ãã11ãã£ãã¯ã®éã«å®è¡ãããŸãã 10.3ã®é¢æ£æéãšããŸãã ãã®çµæããè£éãã®å€ã¯0.3ã«ãªããŸãã äŸãšããŠã次ã®ããã«åãè»ãæ³åããŠãã ããã
position = position + speed;
ç¶æ æŽæ°ãµã€ã¯ã«ã®10çªç®ã®ã¹ãããã§äœçœ®ã500ã§ããå Žåãé床ã¯100ã§ãã11çªç®ã®ã¹ãããã§äœçœ®ã¯600ã«ãªããŸããã¬ã³ããªã³ã°äžã®ãã·ã³ã®äœçœ®ã¯ã©ããªããŸããïŒ æåŸã®ã¹ãããã§ããžã·ã§ã³ãåãããšãã§ããŸãã 500.ãããã次ã®ã¹ãããã§äœçœ®ãäºæž¬ããæé10.3ã§è£éããæ¹ãã¯ããã«åªããŠããŸãã 次ã®åœ¢åŒã®ã³ãŒããååŸããŸãã
view_position = position + (speed * interpolation)
ãããã£ãŠããã·ã³ã¯äœçœ®530ã«æç»ãããŸããå€æ°ãè£éãã«ã¯ãéåžžãçŸåšã®ãã¬ãŒã ãšæ¬¡ã®ãã¬ãŒã ã®éã®æéã®çžå¯Ÿäœçœ®0ã1ã®å€ãå«ãŸããŸãïŒç解ãæ·±ããããã«ããçŽããŸãã ã¹ã ãŒãºãªã¢ãã¡ãŒã·ã§ã³ã確ä¿ããããã«ãäºæž¬ãè€éã«ããããå¿ èŠã¯ãããŸããã ãã¡ãããè¡çªæ€åºã®çŽåã«ããããªããžã§ã¯ããå¥ã®ãªããžã§ã¯ããšéšåçã«äº€å·®ããç¶æ³ãèããããŸãã ããããåã«èŠãããã«ãã²ãŒã ã®ç¶æ ã¯1ç§ããã25åæŽæ°ããããããã¬ã³ããªã³ã°ã¢ãŒãã£ãã¡ã¯ãã¯1ç§éã ã衚瀺ãããŸãïŒãªããžã§ã¯ãã®å¯åºŠãé«ããè¡çªãå€ãå Žåã¯ã©ãã§ããããïŒ-ãããTranslïŒã
匱ãé
ã»ãšãã©ã®å Žåãupdate_gameïŒïŒã¯display_gameïŒïŒãããã¯ããã«é«éã«å®è¡ãããŸãã å®éã匱ãããŒããŠã§ã¢ã§ãã£ãŠããupdate_gameïŒïŒé¢æ°ã¯1ç§éã«25ååŒã³åºãããããšã¯åœç¶ãšèããããšãã§ããŸãã ãããã£ãŠã1ç§ããã15ãã¬ãŒã ã®é »åºŠã§ã¬ã³ããªã³ã°ãå®è¡ãããå Žåã§ããã²ãŒã ã¯ãŠãŒã¶ãŒå ¥åãåŠçããåé¡ãªãç¶æ ãæŽæ°ããŸãã
匷åãªé
匷åãªããŒããŠã§ã¢ã§ã¯ãã²ãŒã ã¯25ãã£ãã¯/ç§ã®åºå®é床ã§åäœããŸãããã¬ã³ããªã³ã°ã¯é«éã«ãªããŸãã è£é+äºæž¬ã¯ãã¢ãã¡ãŒã·ã§ã³ã®é åãè¿œå ããŸãã å®éãã¬ã³ããªã³ã°ã¯ããé«ãFPSã§å®è¡ãããŸãã çŸããã¯ããã®ããã«ããªããFPSã§äžæ£ã§ãããšããããšã§ãã ã²ãŒã ã®ç¶æ ãé »ç¹ã«æŽæ°ããã®ã§ã¯ãªããç»åã®ã¿ãæŽæ°ããŸãã ãã ããåæã«ãã²ãŒã ã®FPSã¯é«ããªããŸãã
ãããã«
æŽæ°ãšã¬ã³ããªã³ã°ãçžäºã«åé¢ããããšãæåã®è§£æ±ºçã®ããã§ãã ãã ããdisplay_gameïŒïŒã§è£éãšäºæž¬ãå®è£ ããå¿ èŠããããŸãã 確ãã«ããã®ã¿ã¹ã¯ã¯ããã»ã©è€éã§ã¯ãããŸããïŒããªããã£ãã¡ã«ããã¯ããªããžã§ã¯ãããããTranslã䜿çšããå Žåã®ã¿ïŒã
ãããã«
ã²ãŒã ã«ãŒãã¯ãèããããã»ã©åçŽãªãã®ã§ã¯ãããŸããã 4ã€ã®å¯èœãªå®è£ ãæ€èšããŸããã ãããŠããããã®ãã¡ãå°ãªããšã1ã€ïŒç¶æ ã®æŽæ°ãFPSã«å¯æ¥ã«é¢é£ããŠããïŒãããã絶察ã«é¿ããå¿ èŠããããŸãã ã¢ãã€ã«ããã€ã¹ã§ã¯ãäžå®ã®ãã¬ãŒã ã¬ãŒãã蚱容ãããå ŽåããããŸãã ãã ããã²ãŒã ãç°ãªããã©ãããã©ãŒã ã«ç§»æ€ããå Žåã¯ããªãã¬ãã·ã¥ã¬ãŒããšã¬ã³ããªã³ã°é »åºŠãåé¢ããè£éãšäºæž¬ãå®è£ ããå¿ èŠããããŸãã äºæž¬ãšè£éã«ç ©ããããããªãå Žåãç¶æ ãæŽæ°ããé »åºŠãé«ãããããšãã§ããŸããã匱ããŠåŒ·åãªéã®æé©å€ãèŠã€ããã®ã¯é£ããäœæ¥ã§ãã
<ïŒ place_your_game_title_hereïŒ >ãã³ãŒãã£ã³ã°ããããã«è¡é²ããŸãïŒ
é¢é£èšäºïŒç¿»èš³è ããïŒ
- habrahabr.ru/blogs/silverlight/125037-SLã®ã²ãŒã ãµã€ã¯ã«
- habrahabr.ru/blogs/gdev/112444-Unity3Dã«ã¯ã²ãŒã ã«ãŒãèªäœã¯ãªããšããèšè¿°ããããŸãïŒæããã«é ãããŠããŸããïŒïŒ
- habrahabr.ru/blogs/gdev/102930-ã²ãŒã ãšã³ãžã³ã®äœæã«ã€ããŠ
- habrahabr.ru/blogs/android_development/136968-ã³ã³ãããã®ã²ãŒã ã®äŸ
- gafferongames.com/game-physics/fix-your-timestep-ã²ãŒã ã®é¢æ£æéã«é¢ããå¥ã®èšäº