èæ¯
é»åæè¡è ã«ãªããã£ãšåãããçŽç²ã«ãœãããŠã§ã¢ãããžã§ã¯ããéçºããŠããŸããã ã³ãŒãã®æåã®è¡ïŒ2çªç®ã®ã¯ã©ã¹ãTurbo BasicããPalace of Pioneersãã®ã¯ã©ã¹ïŒãæžãããã®ç¬éãããã²ãŒã ãæžããšãã欲æ±ãæ®ããŸããã§ããã ããã°ã©ãã³ã°ã®åŠç¿ãå§ããã»ãŒå šå¡ãããã«çŽé¢ãããšæããŸãã ãã¡ããããã®åŸã倧èŠæš¡ãªãã®ã«ã€ããŠã¯ååãªç¥èããªããåãTurbo BasicãšQuick Basicã«ã¯åçŽãªããã¹ãã²ãŒã ãããããŸããã§ããã æã ãç§ã¯è²§åŒ±ãªBASICã°ã©ãã£ãã¯ã¹åºåæ©èœã䜿çšããŸãããããšãã°ãç·ã®ãã¯ã»ã«ãå¶åŸ¡ããèµ€ããéããçœã®ãã¯ã»ã«ã®åœ¢ã§ãã©ãããèšå®ããå¿ èŠãããã²ãŒã ããããŸããã ããããæéãçµã€ã«ã€ããŠãç§ã¯ããå€ããåŠã³ãæçµçã«ã¯ã8幎çã§ã2人çšã®2Dã·ã¥ãŒãã£ã³ã°ã²ãŒã ãæžãããšã«ããŸããã ãªã2人ã ãã§ããïŒ ãããã¯ãŒã¯ã¯ããã»ã©æ®åããŠããªãã£ããããæãæé ãªãã«ããã¬ã€ã€ãŒã¢ãŒãã¯ãããã·ãŒãã§ããã åœæãç§ãã¡ã¯ãã®æ¹æ³ã§ã¯ãŒã ãšããŒããŒã®å人ãšãã°ãã°æŠããŸããããç§ã¯ãªã¢ã«ã¿ã€ã ã§é転ãããã£ãã§ãã ããã§ããªã¢ã«ã¿ã€ã ã§å®è¡ããããããŸããŸãªæŠåšããæã£ãããç©è³ã®å ¥ã£ãç®±ãæŸã£ããã§ããã²ãŒã ãæžãããšã«ããŸããã -ããããåæã«ãç§ãã¡ã¯äžç·ã«éã¶ããšãã§ããŸããã 1人ã®ãã¬ãŒã€ãŒã«ã¯ããŒããŒãã®ã¢ã«ãã¡ãããéšåãå²ãåœãŠããããã1人ã®ãã¬ãŒã€ãŒã«ã¯ããžã¿ã«éšåãå²ãåœãŠãããŸããã ããŠã¹ã¯åäžã§ããããããã¬ãŒã€ãŒã®1人ã«å©ç¹ãäžããªãããã«ãããŠã¹ã¯äœ¿çšãããŸããã§ããã ãããŠä»¥æ¥ ã¢ãã¿ãŒã1ã€ãããæŠéã¯ã¹ã¯ããŒã«ã§ããªãã¯ã©ã¿ã«éå®ãããŠããŸããã
ãŽããªã³æŠäºãç»å ŽããŸããã

ã²ãŒã ãã¬ã€

圌ã¯
ã²ãŒã ã¯æžãããŠããŸãã-ã¯ããããã¯ç§ã«æ æ²ãæ±ããŠããã§ãããã ç§ã¯ãã¿ã€ã«ã»ãããå«ã3D Maxã§ããã¹ãŠã®ã°ã©ãã£ãã¯ãèªåã®ã¹ãã«ãæ倧éã«åŒãåºããŸããã åéãšäžç·ã«ã²ãŒã ãè¡šæããŸããã ã²ãŒã ã«ã¯è£è©±ããããŸãããèŠããã«ããŽããªã³ã¯ãã€ãŠå°çã«äœãã§ããŠã人ã ãæ¥ãŠåœŒããç Žå£ãå§ãããŽããªã³ã¯å°äžã«è¡ããªããã°ãªããŸããã§ããã ãã以æ¥ããŽããªã³éœåžã¯äººã ã®å€§éœåžã®äžã«ååšããŠããŸããã ãŽããªã³ã¯ã人ã ãæãæšãŠãå€ãã¢ã€ãã«ãã¬ããªã©ãããããçš®é¡ã®æè¡çãªãŽããåéãããããããªã©ã®å·¥èžåãæ§ç¯ããŸãã ãããŠããããã®æ°ãå°ãªãã£ããããéœåžéã§çããçŽäºã¯ãè¡ãªãŸãããæŠäºã§ã¯ãªããåéœåžãæé«ã®æŠéæ©ãéã£ãç¹å¥ãªããŒãã¡ã³ãã«ãã£ãŠè§£æ±ºãããããšã«æ±ºããŸããã ãããã®ããŒãã¡ã³ãã¯ãŽããªã³æŠäºãšåŒã°ããŠããŸããã
ã²ãŒã ã«ã¯ãç匟ãærena匟ããã¹ãã«ãèªåæŠåšãããµã€ã«ãè·é¢ç匟ãå°é·ããã§ãŒãºã¬ã³ïŒãã¬ããŒã¿ãŒïŒãããã³ã²ãŒã ã®äž»ãªç¹åŸŽ-ããã«å¯Ÿãããªã³ã·ã©ã+æŠåš-ABOã
ãŽããªã³ããªã³ã®ã·ã©ããçºå°ããåŸãå¶åŸ¡ãããã«åãæ¿ãããŸããã 圌女ãæ¢ããããšã¯äžå¯èœã§ãåãã®æ¹åãå€ããã ãã§ããã å£ãä»ã®ãŽããªã³ã«è¡çªããŠççºããéæºå°ã«å€§ããªãã¡ãŒãžãäžããŸããã æãé¢çœãã®ã¯ããã®ãããŒãžã£ãŒã§ãããŽããªã³ã殺ãããããABOããã·ã©ãã«ãªã£ãå Žåããã¯ã€ã«ããã«ãªã£ãããšã§ããé床ã2åã«ãªãããããäžã§å¶åŸ¡äžèœã«èµ°ãå§ããŸãããéããŠããããã«å°éããããšããŠããŸãã ããã«ãç®±ã®äžã«ãããŒãã¹ããèœã¡ãŠãã«ãŒãã«äžããŒã¹ã®éçã®ã·ã©ããäžåºŠã«æããããšããããããããã©ã€ããè¿œå ããŸããã è©ŠååŸãã©ã³ã¯ã§çµ±èšãçºè¡ãããŸããïŒ

ããªãã¯äŒèª¬ã®éè¡åž«ã«ãªããŸããïŒ
ç§ãã¡ã¯éåžžã«é »ç¹ã«ãŽããªã³ãå人ãšãã¬ã€ããåŠæ ¡ã§ãé åžããŸãããã³ã³ãã¥ãŒã¿ãŒãµã€ãšã³ã¹ã®ã¬ãã¹ã³ã§ã¯ãç§ãã¡ãšäžŠè¡ã¯ã©ã¹ã®äººã ããŽããªã³ãæŒå¥ãããã·ã©ãã奜ãã§ããïŒã äžè¬ã«ããã®ã²ãŒã ã¯ç§ãã¡ã«äœããæŽãã ã®ã§ãé·å¹Žçµã£ãŠããStarcraft 2ã®éã«ããããããæãæãåºãããã«ãŽããªã³ã§1ã€ã2ã€ã®è©ŠåãããŸããã ãŽããªã³æŠäºã®æåã®ãªãªãŒã¹ãã10幎以äžãçµéããŸããã
ãŽããªã³æŠäºII.Net
ç§ã¯é·ãéã2çªç®ã®ããŒãžã§ã³ãæžãããšãèããŠããŸãã-ä»ã§ã¯é«éãããã¯ãŒã¯æ¥ç¶ã¯ãã¯ãåé¡ã§ã¯ãªãã®ã§ãåãããŒããŒãã§1x1ã ãã§ãªãããããã¯ãŒã¯äžã®å人ãšãã¬ã€ã§ããããã«ãªãããã£ãã®ã§ãã ç§ãã€ãã«å·çã®ããã«æçãããšããç§ã¯C ++ã§GWIIãæžãå§ããŸããã 圌ã¯ã¢ã«ãã¡çã®ç¶æ ã«æã£ãŠãããäœãç±æãèããã å°ãåã«ãç±æãæ»ããç§ã¯ãä»åã¯CïŒãéžæããç§ãèšç»ããŠããããšãå®çŸããããšã«ããŸããã åœåãèšç»ã¯ããéå¿çã§ãã-å°ãªããšãäžé¢å³ãã¢ã€ãœã¡ã«çœ®ãæããŸããã ããããæéïŒä»äºãä»ã®ãããžã§ã¯ãïŒãã»ãšãã©ãªããã¢ãŒãã£ã¹ããããªãã£ããããæçµçã«ãããè¡ãããšã«ããŸãããå®å šã«èŠããç¹ãé€ããŠãå€ãã°ã©ãã£ãã¯ã¹ããæ倧ã®ã°ã©ãã£ãã¯ã¹ãåããåæç»ããŸãããããïŒããšãã°ãæ°ããããŒãžã§ã³ã®ã¿ã€ã«ã¯64x64ã«ãªããäœããã®æ¹æ³ã§åæç»ããå¿ èŠããããŸããïŒãããããã¥ãŒãæ®ããŸããããããã¯ãŒã¯ã²ãŒã ãå®è£ ããæªäœ¿çšã®æŠåšïŒå€ãç匟ãærena匟ãªã©ïŒãåé€ããŸãã
äœãèµ·ãããã®ã¹ã¯ãªãŒã³ã·ã§ãããããã«æ瀺ããŸãã

æ°ããå ã§
以äžãèªè ã®ãªã¯ãšã¹ãã«å¿ããŠ-ã²ãŒã ãã¬ã€åç»ãå人ãšã®3åéã®ãã¹ãè©Šåã
æ®å¿µãªãããæ®ãã®åéã¯æã®å±ããªããšããã«ããã®ã§ã1x1ã§ãã¬ã€ããªããã°ãªããŸããã§ããã
ãŽããªã³ãŠã©ãŒãºIIãšã¯äœã§ããïŒ
ã²ãŒã ã¯ã¯ã©ã€ã¢ã³ããµãŒããŒã®ååã«åºã¥ããŠæ§ç¯ããããã¹ãŠã®èšç®ã¯ãµãŒããŒåŽã§å®è¡ãããã¯ã©ã€ã¢ã³ãã¯ã¬ã³ããªã³ã°ã®ã¿ãç®çãšããŠããŸãã ã¬ã³ããªã³ã°ã¯OpenGLããŒã«ã䜿çšããŠè¡ãããé³å£°ã¯OpenALãä»ããŠåºåãããç»åã¯DevILã«ãã£ãŠããŒããããŸãã ãããã¯ãŒã¯ã©ã€ãã©ãª-Lindgrenãããã¯ãŒã¯ã OpenGLãOpenALãããã³DevILã¯ãTao Frameworkã©ãããŒãä»ããŠã·ã£ãŒãã«æ¥ç¶ãããŠããŸãã
æ¢è£œã®ãšã³ãžã³ã¯äœ¿çšããŸããã§ãããã¯ããããããæ¢è£œã®3Dãšã³ãžã³ã䜿çšããŠæé«ã®çµæãåŸãããšãã§ããŸããããã¹ãŠãèªåã§æžãããŒãããããã€ã¯ãã楜ãã¿ãããšæããŸããã
ãã®èªè»¢è»ã®ã¢ãŒââããã¯ãã£ã«ã€ããŠã¯ãèšäºã®ä»¥äžã®ç« ã§èª¬æããŸãã
ã²ãŒã ã¢ãŒããã¯ãã£ïŒäžè¬çãªæŠèŠ
ãŸã第äžã«æ³šæãããããš-ã²ãŒã ã¯ã¢ãžã¥ãŒã«åŒã§ãã éåžžã«ã¢ãžã¥ãŒã«åŒã ã²ãŒã ã®ãã¹ãŠã®ãµãã·ã¹ãã ã¯å¥åã®dllã§ããããã®ã»ãšãã©ã¯æ±ºããŠçžäºã«æ¥ç¶ãããŠããããæ¥ç¶ãããŠãããµãã·ã¹ãã ã¯ã€ã³ã¿ãŒãã§ãŒã¹ã®ã¿ãç¥ã£ãŠãããšããæå³ã§ã ããã«ãããã·ã¹ãã ã®äžéšãç°¡åã«ç Žæ£ããå¥ã®éšåã亀æã§ããŸãã UDPãããã¯ãŒã¯ãlindgrenãããã¯ãŒã¯ã奜ãã§ã¯ãããŸãããïŒ INetworkClientãINetworkServerã®ã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£ ãå¿ããã«ã1ã€ã®dllãNetwork.dllã䜿çšããŠç¬èªã®DLLãäœæããŠãã ããã ããšãã°ãåäžã®ãã¬ãŒã€ãŒãå®è£ ããããã«ããããããŒããããã¯ãŒã¯ãå®è£ ãããŸãããããã¯ããããã¯ãŒã¯ãªãã®ã¯ã©ã€ã¢ã³ããšãµãŒããŒã®åãªãæ¥ç¶ã§ãããã€ã³ã¿ãŒãã§ãŒã¹ã¡ãœããã®çŽç²ãªåŒã³åºãã§ãã åæã«ãã¯ã©ã€ã¢ã³ããšãµãŒããŒã¯ãZero-Networkãšå®éã®ãããã¯ãŒã¯ã®ã©ã¡ãã§åäœããããæ°ã«ããŸããã
åãããšããäŸãã°ã°ã©ãã£ãã¯ã¹ã«é¢ããŠãèšããã ãã®ã¢ãŒããã¯ãã£ã«ãããGraphics.dllãæžãæããŠãOpenGLåºåãå°ãªããšãWinAPIãå°ãªããšãD3Dã«çœ®ãæããããšãã§ããŸãã ãŸãã1ã€ã®dllã眮ãæããããšã«ãããååãšããŠããã®ãããªèŠæãçããå Žåã«å¹³é¢å³ãã¢ã€ãœã¡å³ã«çœ®ãæããããšãã§ããŸãã
以äžã¯ãã¢ã»ã³ããªã¬ãã«ã®äŸåé¢ä¿garfã§ãã

ã²ãŒã ã¢ãŒããã¯ãã£
GoblinWarsII.exeããã³Server.exeã¯ãå®éã«ã¯å®è¡å¯èœãã¡ã€ã«ã§ãã æ°è¡ããå«ãŸããŠããŸããããªããªã ãã¹ãŠã®ããžãã¯ã¯dllokã«ãããŸãã ããšãã°ããã¹ãŠã®ãµãŒããŒã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãã
class Program { static void Main(string[] args) { var game = new Game(); var networkServer = new UDPGameServer(game, int.Parse(args[2])); var matchParameters = new MatchParameters {Difficulty = DifficultyLevel.Easy, FragLimit=0, TimeLimit = uint.Parse(args[0]), MapName=args[1]}; game.StartMatch(matchParameters); networkServer.Start(); while (Console.ReadKey().KeyChar != 'q'); game.Halt(); networkServer.Stop(); } }
Common.dllã«ã¯ãäžè¬çãªå®£èšãšç¹å¥ãªã¿ã€ããŒãªã©ã®ãã«ããŒã¯ã©ã¹ãå«ãŸããŠããŸãã åºæ¬çã«ãããŒã¿æ§é ã®èª¬æããããŸããããšãã°ããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®äž¡æ¹ã«å¿ èŠãªã¢ã€ãã ã®åæåã§ãã
public enum ItemType { PistolBullet, AKBullet, ShotgunBullet, Rocket, Louse, AVOBullet, PhaseBullet, Trapped, StronglyTrapped, WildLouse, LouslyTrapped, PoisonTrapped, FirstAid, MegaHealth, AVOModifier, Boost, LousePack, Equipment, GunabadianHello, LouseHunterEquipment }
Network.dllã«ã¯ããã¡ãããã¯ã©ã€ã¢ã³ããšãµãŒããŒãæ¥ç¶ãããããã¯ãŒã¯ããžãã¯ãå«ãŸããŠããŸãã
ServerLogic.dllã¯ãµãŒããŒã«ãã£ãŠã®ã¿äœ¿çšããããã¹ãŠã®ã²ãŒã ããžãã¯ãå«ãŸããŸããããã§ãã²ãŒã ãªããžã§ã¯ãã®ãã¹ãŠã®èšç®ãè¡ãããŸãã
Media.dllã¯ã¯ã©ã€ã¢ã³ãã«ãã£ãŠã®ã¿äœ¿çšãããã¯ã©ã€ã¢ã³ãäžã«ãµãŒããŒãªããžã§ã¯ãã衚瀺ããããã®ããžãã¯ãå«ãŸããŠããŸãïŒããã«ã€ããŠã¯åŸã§èª¬æããŸãïŒã
æåŸã«ãGraphics.dllã«ã¯ãªããžã§ã¯ããçŽæ¥ã¬ã³ããªã³ã°ããããã®ã³ãŒããå«ãŸããŠããŸãã
ã»ãšãã©ãã¹ãŠã®dllkaã¯ç¬èªã®åŠçã¹ã¬ãããéå§ããä»ã®ã¹ã¬ãããåæ¢ããŸãã-ServerLogic-ã²ãŒã ããžãã¯ãèšç®ããã¹ã¬ãããNetwork-åä¿¡ããã³éä¿¡ããã¹ã¬ãããMedia-ã¡ãã£ã¢ãªããžã§ã¯ãïŒã¯ã©ã€ã¢ã³ãäžã®ãµãŒããŒãªããžã§ã¯ããè¡šãïŒãåŠçããã¹ã¬ãããGraphics-ã¬ã³ããªã³ã°ã¹ã¬ãã
ç¹å®ã®å®è£ ã«ç§»ããŸãããããµãŒããŒã®å®è£ ããå§ããŸãããã
ã²ãŒã ã¢ãŒããã¯ãã£ïŒãµãŒããŒ
ãããã£ãŠãäžèšã®ã³ãŒããããã§ã«æãããªããã«ããµãŒããŒã®äž»ãªãã®ã¯Gameã¯ã©ã¹ã§ããããã®ã€ã³ã¹ã¿ã³ã¹ã¯Server.exeãã€ããªã§äœæãããŸãã
var game = new Game();
ä»ã®ãã¹ãŠã®ã·ã¹ãã ã¯ã次ã®ãããªãµãŒããŒããžãã¯ã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ã衚瀺ã§ããŸãã

ãµãŒããŒã¢ãŒããã¯ãã£
ãããã£ãŠãå€éšããã²ãŒã ãéå§ãããããã¬ãŒã€ãŒãè¿œå ãŸãã¯åé€ããããè©Šåã«é¢ããããŸããŸãªæ å ±ãååŸããããæãéèŠãªããšãšããŠãã²ãŒã ãªããžã§ã¯ãã®ãã¹ãŠã®ç¶æ ãååŸãããã§ããŸãã
public IList<GameObjectState> GetAllObjectStates()
-ã²ãŒã ã®æãéèŠãªæ©èœã®1ã€ã
å®å šã«ã¬ã³ããªã³ã°ã§ããäžçã®ã¹ãããã·ã§ãããè¿ãã®ã¯åœŒå¥³ã§ãã ãããã£ãŠãéä¿¡ã¹ã¬ããã®ãããã¯ãŒã¯ã·ã¹ãã ã¯ãåŸã§ã·ãªã¢ã«åããå§çž®ããŠã¯ã©ã€ã¢ã³ãã«éä¿¡ããããã«ãå®æçã«ã²ãŒã ã®äžçã®ã¹ãããã·ã§ãããèŠæ±ããŸãã
ãã¬ãŒã€ãŒèªäœãè¡šãã²ãŒã ãªããžã§ã¯ããšã®çžäºäœçšïŒããšãã°ãã¯ã©ã€ã¢ã³ãããã®ã¢ã¯ã·ã§ã³ã®è»¢éïŒããçŽæ¥ã§ã¯ãªããIPlayerDescriptorã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠè¡ãããŸãã
public interface IPlayerDescriptor { void PerformAction(PlayerAction action); Tuple<double, double> GetLookCoords(); long GetId(); double GetLoginTime(); }
ãã®çµæãäžèšã®å 容ãã€ãŸãã²ãŒã ããžãã¯ãåããå®å šã«åé¢ããããµãã·ã¹ãã ãåŸãããŸãã ããã§ã¯ãå®éã«å éšã§ã©ã®ããã«æ©èœããããèããŠã¿ãŸãããã
ãæäžå±€ãã¯ãéåžžã«æšæºçãªã¹ã¬ããã»ãŒããªãã£ã¯ã·ã§ããª<ãªããžã§ã¯ãIDããªããžã§ã¯ã>ã«èŠããŸã-
private readonly ConcurrentDictionary<ushort, GameObject> gameObjects;
ãããŠã1ç§ãããã®æå®åæ°ãšåŒã°ããåŠçãµã€ã¯ã«ã§ãæåŸã®èª€ç®ããã®çµéæéãã«ãŠã³ãããŸãã
private void ObjectProcessingTaskRoutine() { quantTimer.Tick(); Statistics.TimeQuantPassed(quantTimer.QuantValue); if (currentMatchParameters.TimeLimit > 0 && Statistics.MatchTime > currentMatchParameters.TimeLimit) EndMatch(); foreach(var gameObject in gameObjects) { if (!gameObject.Value.Destroyed()) gameObject.Value.Process(quantTimer.QuantValue); else gameContext.RemoveObject(gameObject.Key); } }
GameContextã¯ã¯ã©ã¹ã§ãããã€ã³ã¹ã¿ã³ã¹ãžã®ãªã³ã¯ã¯äœæããããã¹ãŠã®ã²ãŒã ãªããžã§ã¯ãã®ã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ãããã²ãŒã ããããžã®ãªã³ã¯ããã¬ãŒã€ãŒã®ãªã¹ãããªã³ã¯ãæž¡ãå¿ èŠããªãããã«ã²ãŒã ã«æ°ãããªããžã§ã¯ããè¿œå ããã¡ãœãããªã©ãã²ãŒã ã«é¢ãããã¹ãŠã®å¿ èŠãªæ å ±ãå«ãŸããŸãèªåã§
ConcurrentDictionary<ushort, GameObject> gameObjects;
GameContextã®ãã¹ãŠã®ãã£ãŒã«ãã¯äžå€ã§èªã¿åãå°çšã§ãããã²ãŒã ãªããžã§ã¯ãã®ã³ã³ããã¹ããžã®ãæå·ããæé€ããŸãã
ããããã²ãŒã ãªããžã§ã¯ãã®å®è£ ã¯ããèå³æ·±ããã®ã§ãã åœåã¯ãåºæ¬çãªGameObjectãäœæããããããPlayerãBombãªã©ã®ç¹å®ã®å®è£ ãç¶æ¿ããŠãéåžžã«ç°¡åã«è¡åããã€ããã§ããã ãããããã®ã¢ãããŒãã«ã¯æ¬ ç¹ããªãããã§ã¯ãããŸããã å€ãã®ã¯ã©ã¹ããããç¹ã«ããã¬ããŒãå¯èœãªãªããžã§ã¯ãããããã«ã¹ãæã€ãªããžã§ã¯ãããªã©ã®ãµãã¯ã©ã¹ãå€ãå Žå-ãã®ã¢ãŒããã¯ãã£ã¯ãã¹ãŠé¢åã§äžäŸ¿ã«ãªããŸãã
ããããªå€æŽã§ããæåããåæç»ããå¿ èŠããããŸãã ããã§ãç§ã¯åœŒã®ãã¬ãŒã³ããŒã·ã§ã³ããåŠãã ã²ãŒã Dungeon Siegeã®äœæè ã®çµéšã«ç®ãåããŸããã
èŠããã«ãæ¬è³ªã¯æ¬¡ã®ãšããã§ãããã¹ãŠã®ã²ãŒã ãªããžã§ã¯ãã¯ãã²ãŒã ã³ã³ããŒãã³ãã®ã³ã³ããã§ãããã¡ãã»ãŒãžã³ã°ã®ããžãã¯ãé€ããŠãããžãã¯ãšããŒã¿ãå«ã¿ãŸããã ã³ã³ããŒãã³ãã¯ãåºå®ã¿ã¹ã¯ã«å¿ èŠãªããžãã¯ãšããŒã¿ãå«ãå®å šãªãããã¯ã§ãã ãªããžã§ã¯ãéã®çžäºäœçšã¯ãã³ã³ããŒãã³ãã«ã«ãŒãã£ã³ã°ãããã¡ãã»ãŒãžã®äº€æãéããŠçºçããŸãã
ããã«ããäœãåŸãããŸããïŒ ããã«ãããéåžžã«æè»ã§äŸ¿å©ãªã²ãŒã ããžãã¯ã®å®è£ æ¹æ³ãæäŸãããŸãã ãªããžã§ã¯ããã²ãŒã ã®äžçã§ã©ããªããã¯ããã®ã³ã³ããŒãã³ãã®ã»ãããšãã®ã³ã³ã¹ãã©ã¯ã¿ãŒãã©ã¡ãŒã¿ãŒã«ãã£ãŠã®ã¿æ±ºãŸããŸãã ããžãã¯ã®äžéšã§ã³ã³ããŒãã³ããå®è£ ããããåŸæ¥ã®ã¢ãããŒããšã¯å¯Ÿç §çã«ãã¯ã©ã¹ãå解ããæ¹æ³ã«ã€ããŠæ··ä¹±ããããšãªããã²ãŒã ãªããžã§ã¯ãã«ã³ã³ããŒãã³ããæŒã蟌ãããšãã§ããŸãã
ããã«ããã¹ãŠã®ãªããžã§ã¯ãã1ã€ã®ã¯ã©ã¹GameObjectã§äœæããå€åºå ã§ããã€ãã®æ§æããã³ã³ããŒãã³ãã®ãªã¹ããããŠã³ããŒãã§ããããã«ãªããŸããã
ãã®å Žåãç§ã¯ãŸã æåŸã®ãã€ã³ãã掻çšããŠããŸãã-æ§æããã®ããŠã³ããŒãããåŸã§ãæ®ããããŸããŸãªã¯ã©ã¹ã®ãªããžã§ã¯ããå®è¡ããŸããããæ°ã«ããªãã§ãã ãã-ããã¯å€éšãã¡ã€ã«ããæ§æããŸã ããŒãããªãããã«ããããã ãã«è¡ãããŸããã PlayerãBombãBulletãªã©ã®ã¯ã©ã¹ã®ãã®ä»ã®éã ååšãããç§ã®æãããã«éãããšããã«ããããã¯ãã¹ãŠåäžã®GameObjectã«çœ®ãæããããŸãã
ãããã©ã®ããã«å®è£ ãããŠãããã詳ããèŠãŠã¿ãŸãããã ãããã£ãŠããã¹ãŠã®äžå¿ã«ããã®ã¯IGameObjectã€ã³ã¿ãŒãã§ã€ã¹ã§ãã
internal interface IGameObject { void SendMessage(ComponentMessageBase msg); GameObjectState GetState(); IComponent[] GetComponents(); ushort GetId(); GameObjectType GetGOType(); IGameObject GetParent(); void Dispose(); bool Destroyed(); }
ã²ãŒã ãªããžã§ã¯ãã¯ã誀çšã«å¯Ÿããè¿œå ã®ä¿è·ãæäŸããå¥ã®ãªããžã§ã¯ãã®ãã®ãããªã€ã³ã¿ãŒãã§ã€ã¹ã®ã¿ãååŸã§ããŸã-ãµãŒãããŒãã£ã®ãªããžã§ã¯ãã¯ããªããžã§ã¯ãã«ã³ã³ããŒãã³ããè¿œå ããããäœããã®æ¹æ³ã§ããããšå¯Ÿè©±ãããããããšã¯ã§ããŸãããIComponentãååšãã1ã€ãŸãã¯å¥ã®ã³ã³ããŒãã³ãã®ååšã®ã¿ããã§ãã¯ããŸã[ ] GetComponentsïŒïŒ;
ã€ã³ã¿ãŒãã§ã€ã¹ã®å®è£ ã§ããGameObjectã«ã¯ãã¡ãã»ãŒãžã³ã°ãšåä¿¡ç¶æ ã®ããžãã¯ãå«ãŸããŠããŸãïŒäžçã®ã¹ãããã·ã§ãããåä¿¡ãããšãã«äœ¿çšãããŸãïŒã
public void SendMessage(ComponentMessageBase msg) { messageQueue.Enqueue(msg); } public GameObjectState GetState() { var states = new List<ComponentState>(components.Count); lock (lockObj) { if (Destroyed()) return null; foreach (var component in components) { var state = component.GetState(); if (state != null) states.Add(state); } } return new GameObjectState(Id, type, states); } public void Process(double quantValue) { if (Destroyed()) return; lock (lockObj) { SendMessage(new MsgTimeQuantPassed(this, quantValue)); // , while (messageQueue.Count > 0) { ComponentMessageBase msg; messageQueue.TryDequeue(out msg); foreach (var component in components) component.ProcessMessage(msg); } } }
ãããã¯ãŒã¯èŠæ±æã®ãªããžã§ã¯ãã®ç¶æ ã®äžå€æ§ãä¿èšŒããããã«ãããããã³ã°ãªããžã§ã¯ããå¿ èŠã§ãã
ã¡ãã»ãŒãžã¯ãã©ãŒã ã®CANCARENTãã¥ãŒã«è¿œå ãããŸã
ãã©ã€ããŒãèªã¿åãå°çšConcurrentQueue messageQueue;
äžèŠ§
private readonly List<Component> components;
ãã¡ããããªããžã§ã¯ãã®ãã¹ãŠã®ã³ã³ããŒãã³ããå«ãŸããŠããŸãã
ã²ãŒã ã¢ãŒããã¯ãã£ïŒã³ã³ããŒãã³ã
ã³ã³ããŒãã³ãã®åºæ¬ã¯ã©ã¹ã«ã¯ããŸã3ã€ã®äž»èŠãªæ©èœãå«ãŸããŸãã
public abstract void ProcessMessage(ComponentMessageBase msg); public virtual ComponentState GetState() { return null; } public virtual bool Probe() { return true; }
ProcessMessageã¯ãã³ã³ããŒãã³ãã«ãã£ãŠå®è£ ãããããžãã¯ãæ åœããã®ã§ãå¿ ãåŸç¶æ©ã§åå®çŸ©ããå¿ èŠããããŸãã
IComponentã€ã³ã¿ãŒãã§ã€ã¹ãä»ããŠå€éšã·ã¹ãã ã«äœ¿çšã§ããå¯äžã®é¢æ°ã§ããGetStateã¯ããªããžã§ã¯ãã®ãããªãã¯ç¶æ ïŒååšããå ŽåïŒãè¿ããŸãïŒããšãã°ããã«ã¹ãŸãã¯åº§æšïŒã ãªããžã§ã¯ãã«ãããªãã¯ç¶æ ããªãå Žåãåå®çŸ©ããããšã¯ã§ããŸããã
ãããŒãæ©èœã¯ãã³ã³ããŒãã³ãã®äŸåé¢ä¿ããã§ãã¯ããŸãã ã³ã³ããŒãã³ããäœã«ãäŸåããŠããªãå Žåã¯ãããã«è§Šããããšã¯ã§ããŸããã ããšãã°ãCollectorã³ã³ããŒãã³ããInventoryã³ã³ããŒãã³ãã«äŸåããŠãããªã©ãäŸåé¢ä¿ãããå Žåã¯ããã®é¢æ°ã§ãã§ãã¯ããå¿ èŠããããŸãã ããã¯ããã§ãã¯ã ãã§ãªãã察å¿ããäŸåé¢ä¿ãžã®ãªã³ã¯ã®ãã£ãã·ã¥ã«ã䜿çšãããæ¯åããããå床æ€çŽ¢ããªãããã«ããŸãã
ããŠãäžèšã¯ãããŸãã«èŠãããããããŸããããäŸãèŠãŠã¿ãŸãããããã¹ãŠãã¯ã£ããããŠããã¯ãã§ãã
ããšãã°ããã®ãããªã¢ãŒããã¯ãã£ã§åŒŸäžžãäœãã«ã¯ã©ãããã°ããã§ããïŒ ãã±ããïŒ
ãããã£ãŠãæåã«å®è£ ãããã³ã³ããŒãã³ãã¯SolidBodyã§ããã ããã¯ãã²ãŒã ã¯ãŒã«ãã§ã®ãªããžã§ã¯ãã®ç©ççãªå ·äœåãã€ãŸãã座æšãããããšã®çžäºäœçšãããã³ãã£ã¡ã³ã·ã§ã³ãæ åœããã³ã³ããŒãã³ãã§ãã
public SolidBody(GameObject owner, GameContext gameContext, double x, double y, double sizeX, double sizeY, byte angle = 0, bool semisolid = false)
ãã¹ãŠã®ã³ã³ããŒãã³ããšåæ§ã«ãOwnerãownerãªããžã§ã¯ããããã³gameContextã¯ãã²ãŒã ã®ã³ã³ããã¹ãã§ãããããããGameMapãžã®ãªã³ã¯ãååŸããã³ã³ã¹ãã©ã¯ã¿ãŒã«è»¢éãããŸãã
æ®ãã¯ãã§ã«SolidBodyåºæã®ãã®ã§ã-ãªããžã§ã¯ãã®åº§æšããã®ç©çç寞æ³ãå転è§åºŠãããã³ãã©ã°ã®ãã¢-èšç®ãæé©åããããã«ãäºãã«è¡çªããŠã¯ãªããªããªããžã§ã¯ãã¯ååºäœãšåŒã°ããŸã-è¡çªã¯åºäœ-åºäœããã³åºäœ-ååºäœã2ã€ã®ååºäœã«å¯ŸããŠã®ã¿èšç®ãããŸãè¡çªããªãã§ãã ããã ãããã«ã¯ãããšãã°ãäºãã«è¡çªã§ããªã匟䞞ãå«ãŸããŸãã
ãã¡ãããç®æ¡æžãã¯SolidBodyã«ãªããŸãã 座æšãšå¯žæ³ããããŸãã ããã«ãçžäºã®åŒŸäžžè¡çªã®ç¡é§ãªèª€èšç®ãå¿ èŠãšããªããããååºäœã«ãªããŸããããã¯èŠããŠããå¿ èŠããããŸãã
SolidBodyã®å®è£ ã¯éåžžã«å€§ãããããçŸæç¹ã§ã¯çç¥ããŸãã
èšç®ãé«éåããããã«ãããã«é¢é£ãããªããžã§ã¯ãã®ãªã¹ãããããã®åã¿ã€ã«ã«æ·»ä»ãããŠããããšã«æ³šæããŠãã ããã ãããäžã§ãªããžã§ã¯ãã移åãããšããããã®ãªã¹ããæŽæ°ãããŸãã ãããã£ãŠãè¡çªãèšç®ããå Žåãåãªããžã§ã¯ãããåãªããžã§ã¯ããŸã§ã®è·é¢ãã«ãŠã³ãããå¿ èŠã¯ãããŸãããããŸãé¢å¿ã®ããååŸå ã®ã¿ã€ã«ããã°ããéžæãããããã«æ¥è§Šãããªããžã§ã¯ãã«ã€ããŠã®ã¿è·é¢ã®èšç®ãå®è¡ããŸãã
次ã«ããã¹ãŠã®åŒŸäžžãããµã€ã«ãããã³ãã®ä»ã®ç ²åŒŸã®ããžãã¯ã®äžå¿ãšãªãã³ã³ããŒãã³ããå®è£ ããŸããããã¯ãåçŽã§åäžãªãç°¡åãªé£è¡ãæ åœããŸãã
internal class Projectile : Component { private SolidBody solidBody; // , SolidBody! private readonly double speed; // â public Projectile(GameObject owner, double speed) : base(owner) { this.speed = speed; } public override void ProcessMessage(ComponentMessageBase msg) { // â , . if (msg.MessageType == MessageTypes.TimeQuantPassed) ProcessTimeQuantPassed(msg as MsgTimeQuantPassed); } // . , , , private void ProcessTimeQuantPassed(MsgTimeQuantPassed msg) { double dT = msg.MillisecondsPassed; var solidState = (SolidBodyState)solidBody.GetState(); byte angle = solidState.Angle; double dX = SpecMath.Cos(angle) * speed * dT, dY = SpecMath.Sin(angle) * speed * dT; // , â , . â . solidBody.AppendCoords(dX, dY, angle); } // , . GetOwnerComponent, , . , , . . public override bool Probe() { solidBody = GetOwnerComponent<SolidBody>(); return solidBody != null; } }
ããã§ããæ確ã«ãªãã¯ãã§ãã å®å šã«æ確ã«ããããã«ãéåžžã«ã·ã³ãã«ã§ãäŸåé¢ä¿ã®ãªãå¥ã®ã³ã³ããŒãã³ãDieOnTTLã玹ä»ããŸãã ååã瀺ãããã«ãã³ã³ããŒãã³ãã¯æå®ãããæéåŸã®ãªããžã§ã¯ãã®æ»ã«è²¬ä»»ããããŸãã
internal class DieOnTTL : Component { private readonly double ttl; private double lifetime; public DieOnTTL(GameObject owner, double ttl) : base(owner) { this.ttl = ttl; lifetime = 0.0; } public override void ProcessMessage(ComponentMessageBase msg) { if (msg.MessageType == MessageTypes.TimeQuantPassed) ProcessTimeQuantPassed(msg as MsgTimeQuantPassed); } private void ProcessTimeQuantPassed(MsgTimeQuantPassed msg) { var dT = msg.MillisecondsPassed; lifetime += dT; if (lifetime >= ttl) // Owner.SendMessage(new MsgDeath(Owner)); } }
ããã§ã¯ãç®æ¡æžãã¯ã©ã®ããã«ãªããŸããïŒ ãšãŠãç°¡åã§ãã ããã§ãããšãã°ããã¹ãã«ã®åŒŸäžžïŒ
class PistolBullet : GameObject { public PistolBullet(GameContext context, IGameObject parent, double x, double y, byte angle, double speed, double ttl) : base(context, GameObjectType.PistolBullet, parent) { AddComponents( new SolidBody(this, context.GameMap, x, y, 9, 9, angle, true), new DieOnTTL(this, ttl), new Projectile(this, speed), new DieOnCollide(this,new GameObjectType[]{GameObjectType.Player, GameObjectType.WildLouse}, true, new ushort[]{parent.GetId()}), new DecayOnDeath(this) ); } }
ç§ãèšã£ãããã«ãæããŸã å€éšããèšå®ã®è² è·ã«éããŠããªããšããçç±ã ãã§ãå¥ã®ã¯ã©ã¹ãäœæãããŸããã ãã®ã³ãŒãã¯äœãããŸããïŒ ãŸããã²ãŒã ã¿ã€ããããŒã¹ã®GameObjectã³ã³ã¹ãã©ã¯ã¿ãŒ-GameObjectType.PistolBulletã«æž¡ããŸã
ã¯ã©ã€ã¢ã³ãã§ã®ã¬ã³ããªã³ã°ãè¡ãããã®ã¯ãã®ã¿ã€ãã§ãããããŸããŸãªã³ã³ããŒãã³ãã«ãã£ãŠãã§ãã¯ãããã®ã¯ã匟䞞ãšã®çžäºäœçšãªã©ã®éèŠãªè¡çªã§ãã
æ®ã£ãŠããã®ã¯ã匟䞞ã匟䞞ã«ããã³ã³ããŒãã³ããè¿œå ããããšã§ãã ãã®å Žåããã©ã¡ãŒã¿ãŒã¯å€éšãããªããžã§ã¯ãèªäœã®ã³ã³ã¹ãã©ã¯ã¿ãŒã«è»¢éãããããããã³ã³ããŒãã³ãã³ã³ã¹ãã©ã¯ã¿ãŒã«è»¢éãããŸãã ããããããã§ã³ãŒãå ã§ããããããŒãèšè¿°ããããXMLã®ã³ã³ããŒãã³ãã®ãªã¹ããšäžç·ã«ããŒããããããããšã¯ã誰ãæ°ã«ããŸããã
ãŸã第äžã«ãSolidBodyã¯ã匟䞞ã座æšãæã¡ãä»ãšè¡çªããå®å šã«ç©ççãªãªããžã§ã¯ãã§ããããã§ãã semisolidãã©ã¡ãŒã¿ãŒã§trueãæå®ããããšãå¿ããªãã§ãã ãã-è¿œå ã®èšç®ã¯äžèŠã§ãã
匟䞞ã¯ãããšãäœãè¡çªããªããŠããäžå®ã®é£è¡æéåŸã«æ¶ããŸãã ãããã£ãŠãlifetimeãã©ã¡ãŒã¿ãŒã§æ¢ã«äœæããDieOnTTLãªããžã§ã¯ããè¿œå ããŸãã
匟䞞ã¯åæ¹ã«é£ã¶ã¯ãã§ãã ãããProjectileã«å®è£ ãã察å¿ããé床ã§è¿œå ããŸãã
匟䞞ã¯è¡çªã«ããæ»ã¬ã¯ãã§ãã DieOnCollideãè¿œå ããŸãã çç¥ããŸããããå®å šã«äºçŽ°ãªããšã§ããSolidBodyã¯MsgCollideã¡ãã»ãŒãžãéä¿¡ãããããäœãåå®è£ ããå¿ èŠã¯ãããŸãããMsgCollide.CollidedObjectã確èªããŠãã ããã ããã§ã®ãã©ã¡ãŒã¿ãŒã¯ãç¡èŠã§ããªãè¡çªã瀺ããŸããå£ãšã®è¡çªã瀺ãããªããžã§ã¯ãã®IDã瀺ããŸããç¡èŠããå¿ èŠããããŸãããã®åŒŸäžžãäœæãã芪ã®IDãããã«æž¡ãããããã匟䞞ã¯å·ã€ããŸããã
æåŸã«ãæåŸã«è¡ãå¿ èŠãããã®ã¯ãæ»ãã ã¡ãã»ãŒãžã«äœããã®åœ¢ã§å¿çããããšã§ããDesayOnDeathã¯ãMsgDeathã¡ãã»ãŒãžãåä¿¡ãããšããªããžã§ã¯ããéãã«åŒ·å¶çµäºããŸãã
ããŠããã±ãããå¿ èŠãªå Žåã¯ã©ãã§ããããïŒ ç°¡åãªãã®ã¯ãããŸããïŒ
class Rocket : GameObject { public Rocket(GameContext context, IGameObject parrent, double x, double y, byte angle, double speed, double ttl, double radius) : base(context, GameObjectType.Rocket, parrent) { AddComponents( new SolidBody(this, context.GameMap, x, y, 15, 15, angle, true), new DieOnTTL(this, ttl), new Projectile(this, speed), new DieOnCollide(this,new[]{GameObjectType.Player, GameObjectType.WildLouse}, true, new ushort[]{parrent.GetId()}), new ExplodeOnDeath(this,context, radius) ); } }
ãã±ããã匟䞞ããå°ã倧ããïŒSolidBodyã®å¹ŸäœåŠç寞æ³ã倧ããïŒããšããã±ãããWildLouseãªã©ã®ãªããžã§ã¯ããšè¡çªããªããªã£ãããšãé€ããŠãåãããšãè¡ããŸãã DieOnCollideã³ã³ã¹ãã©ã¯ã¿ãŒã®åŒŸäžžã«ãã£ãŠããããŠæãéèŠãªããš-ãã±ããã¯æ»ãã§éãã«æ»ã¬ã®ã§ã¯ãªãã倧声ã§ççºããã®ã§ãDecayOnDeathã®ä»£ããã«ãååŸãã©ã¡ãŒã¿ãŒã§ExplodeOnDeathãè¿œå ããŸãã ããã ãã§ãïŒ ã»ãŒåãã³ã³ããŒãã³ãã§ãã±ãããäœããŸãã-æ¢åã®ã³ãŒãã®æžãæãã¯ãããŸããã å¿ èŠãªã®ã¯ãæ»äº¡æã®ççºã®åå ãšãªãå¥ã®ã³ã³ããŒãã³ããäœæããããšã ãã§ããïŒDecayOnDeathãšåãããã«åäœããŸãããæ»ã®ãã€ã³ãã§ããExplosionã§æ°ãããªããžã§ã¯ããäœæããŸãïŒã
ã¯ãããªããžã§ã¯ãã«é©åãªã¿ã€ããæå®ããããšãå¿ããªãã§ãã ãã-GameObjectType.Rocketã
ããšãã°ããã¬ããŒãã®åŒŸäžžã¯ããã¬ããŒã¿ãŒã³ã³ããŒãã³ãã®ååšã®ã¿ãç°ãªããŸãã
AddComponents( new SolidBody(this, context.GameMap, x, y, 30, 30, angle,false, false, true), new DieOnTTL(this, ttl), new Projectile(this, speed), new Teleporter(this, context), new DieOnCollide(this, new GameObjectType[] {}, true, new ushort[] { parrent.GetId() }), new PhaseOnDeath(this, context, radius) );
圌ã¯ãTeleportableã³ã³ããŒãã³ããå«ããªããžã§ã¯ãããã¬ããŒããã責任ããããŸãã ãªããžã§ã¯ãããã¬ããŒãå¯èœã«ããã«ã¯ãã³ã³ããŒãã³ãã®ãªã¹ãã«ãã¬ããŒããè¿œå ããã ãã§ãã
ã³ã³ããŒãã³ãã®å€§éšåã¯è¿œå ã®ç¶æ¿ããå¿ èŠãšããªããããã¢ãŒããã¯ãã£å šäœãéåžžã«æè»ã§ééçã«ãªããŸãã
ã²ãŒã ã§äœ¿çšãããã³ã³ããŒãã³ãã®ãªã¹ãã¯æ¬¡ã®ãšããã§ãã
- AOE-圱é¿ãåããé åã®è²¬ä»»ã å¹æãã£ãŒã«ããæã€ãªããžã§ã¯ãMsgAOEã¯ãã¢ã¯ã·ã§ã³ã®ç¯å²å
ã®ãªããžã§ã¯ãã«éä¿¡ãããŸããããã¯ãå¹æã®å¹æã®åŒ·ãã瀺ããŸãïŒéæºãŸã§ã®è·é¢ã«å¿ããŠèšç®ãããŸããå¹æãããã¡ã€ã«ãã³ã³ããŒãã³ãã³ã³ã¹ãã©ã¯ã¿ãŒã«æž¡ããŠãå¹æãè·é¢ãšãšãã«ã©ã®ããã«å€åããããã«ã¹ã¿ãã€ãºã§ããŸãïŒã
ççºããã¬ããŒãã®åŒŸäžžã«ãã£ãŠäœ¿çšãããŸãã - BaseModifierManager-修食åãæ
åœããã³ã³ããŒãã³ãã ã€ãŸããã¢ã€ãã ãèŠã€ããåŸã«ãã¬ãŒã€ãŒã«è¡šç€ºãããäžå®ã®æéæå¹ãªã4åã®ãã¡ãŒãžãããå éããããã³ãã®ä»ã®ããã³ããªã©ã§ãã åºæ¬ããŒãžã§ã³ã«ã¯é¢æ°ã®ãªãŒããŒã©ã€ããå«ãŸãããããç¶æ¿ãå¿
èŠãªã³ã³ããŒãã³ãã®1ã€ïŒ
protected virtual void ProcessModifier(ItemType itemType, ModifierDescriptor modifier, double quantValue)
protected virtual void ModifierAcquired(ItemType itemType, ModifierDescriptor modifier)
protected virtual void ModifierLost(ItemType itemType, ModifierDescriptor modifier)
- BaseWeapon-æŠåšãæ
åœããç¶æ¿ãå¿
èŠã§ãã åºæ¬çãªããžãã¯ã«ã¯ãæŠåšã®ã«ãŒããªããžã§ãã察å¿ããã¢ã€ãã ã®å¯çšæ§ã®ç¢ºèªãã¯ãŒã«ããŠã³ã®ç¢ºèªãå«ãŸããŸãããã®æ
å ±ã¯WeaponDescriptorsã«èšé²ããããã®ã³ã³ããŒãã³ããåŠçãããŸãã ãªãŒããŒã©ã€ãããããªãŒããŒã©ã€ãé¢æ°ã®ãã«
protected abstract void Shoot(WeaponDescriptor weaponDescriptor, SolidBody solidBody)
protected virtual void OutOfAmmo(WeaponDescriptor weaponDescriptor, SolidBody solidBody)
protected virtual void Cooldowning(WeaponDescriptor weaponDescriptor)
- åéå¯èœ-MsgItemsAvailableã¡ãã»ãŒãžããCollectorã³ã³ããŒãã³ããšè¡çªãããªããžã§ã¯ãã«éä¿¡ãããç§ã¯ããã«ããŸããè¿ãã«æ¥ãŠããšå«ã¶ã³ã³ããŒãã³ã
- ã³ã¬ã¯ã¿ãŒ-MsgItemsAvailableãèãããšãã«ãã¢ã€ãã ãã€ã³ãã³ããªã«å ¥ããã³ã³ããŒãã³ãã
- ããŸããŸãªDecayOn ...ããã³DieOn ...ã¯ãã§ã«äžèšã§èª¬æãããŠããŸãã
- å¥åº·-å¥åº·ãšæå·ã«è²¬ä»»ããããŸãã ãŸãããã«ã¹ã0ã«éãããšãã«MsgDeathãéä¿¡ããŸãã
- ã€ã³ãã³ããªã¯ãã¢ã€ãã ã®ãªã¹ããšãã®çªå·ãæ ŒçŽããã€ã³ãã³ããªã³ã³ããŒãã³ãã§ãã ã³ã¬ã¯ã¿ãŒãæŠåšãªã©ãã¢ã€ãã ã䜿çšãããã¹ãŠã®ãã®ãå¿ èŠã§ãã
- çºå°ç©ã¯åçŽãªçºå°ç©ã§ãã
- SolidBody-åè¿°ã®ç©ççãªå®æœåœ¢æ -座æšãè¡çªã ãŸãããããäžã®ãã¹ãæ€çŽ¢ããããã®éçFindPathé¢æ°ãæäŸããŸãã
- Walker-ProjectileãšäŒŒãŠããŸããããåççãªããªããžã§ã¯ãã®å Žå-MsgWalkã¡ãã»ãŒãžã§èšå®ãããç¹å®ã®æ¹åã«ç§»åããŸãã Direction.StopãMsgWalkã®æ¹åãšããŠæå®ãããŠããå Žåã«åæ¢ããŸãã
ããã¯ãå®è£ ã«é¢ä¿ã®ãªãã²ãŒã ã®äž»èŠã³ã³ããŒãã³ãã®ã»ãŒå®å šãªãªã¹ãã§ããããã¯ãšã³ãžã³ã®äžéšã§ããGoblinWarsã«çŽæ¥é¢é£ããããã€ãã®ã³ã³ããŒãã³ããå®è£ ããŸãããããã«ã¯ãå ·äœçãªåŠçãå®è£ ããBaseWeaponããã³BaseModidierManagerã®åå«ã®å®è£ ãWildLouseLogic-éçã®ã·ã©ããªã©ã®åäœãæ åœããã³ã³ããŒãã³ããå«ãŸããŸãã
æ¢ã«è¿°ã¹ãããã«ãå€éšã·ã¹ãã ããŸãã¯ãããã¯ãŒã¯ã¯ãåãã¡ãã»ãŒãžã§ãã¬ãŒã€ãŒãšå¯Ÿè©±ããŸãããããè¡ãããã«ããããã¯ãŒã¯ã¯ãPerformActionïŒïŒã¡ãœããã®å¯Ÿå¿ããPlayerDescriptorãã€ã³ã¯ããŸãã
ãã®ã¡ãœããã®å®è£ ã¯ãéåžžã®ã¡ãã»ãŒãžã®äœæãšãå¿ èŠãªã¢ã¯ã·ã§ã³ã«å¿ããŠPlayerRescriptor.PlayerObject.SendMeddageïŒïŒã«éä¿¡ããããšã§ãã
ãããã«
ããã§ã¯ãååãšããŠãServerLogic.dllã®åºç€ã圢æãããã¹ãŠã®ãã®ã次ã®èšäºã§ã¯ããµãŒããŒãšã¯ã©ã€ã¢ã³ãã®ãããã¯ãŒã¯éšåãšãä»ã®ãµãã·ã¹ãã ãšã®çžäºäœçšã«ã€ããŠèª¬æããŸãã
ãŸã å®å šãªãœãŒã¹ã³ãŒããã¢ããããŒãããã€ããã¯ãããŸããããå®è£ ã«é¢ãã質åãããã°ãããã«åçããŸããèå³ã®ããæ¹ã¯ãååã®èšäºã®æåŸã«ãã¹ãçšã®ã²ãŒã ãæçš¿ããŸãã
ã°ã©ãã£ãã¯ãåæç»ããåã³ãçŽç²ã«çšæããŠããã¢ãŒãã£ã¹ããããã°ããšãŠãæè¬ããŸããããã§ã®ã°ã©ãã£ãã¯ã¯ãã¹ãŠåçŽãª2次å ã¹ãã©ã€ãã§ãã8æ¹åã«ãŽããªã³ã8æ¹åã«ãªã³ã·ã©ãããããŠæãéèŠãªããšãšããŠã¿ã€ã«ãæç»ããå¿ èŠããããŸãããä»ã§ã¯éåžžã«äžè¶³ããŠããŸãã
ãŸããååãšããŠãã¯ã©ã€ã¢ã³ããä»ã®ãã©ãããã©ãŒã ã«ç§»æ€ããããšã«èå³ããããŸããããããåç¬ã§è¡ãããã¯ãããŸããã誰ããHTML5ã§ã¢ãã€ã«ã·ã¹ãã ãŸãã¯Webãžã®ç§»æ€ãè©Šã¿ããå Žå-ããã«ã€ããŠã説æããŸãã
ãæž èŽããããšãããããŸããã