{"id":78,"date":"2010-03-22T22:02:51","date_gmt":"2010-03-22T21:02:51","guid":{"rendered":"http:\/\/www.aymericlamboley.fr\/blog\/?p=78"},"modified":"2014-11-01T15:13:04","modified_gmt":"2014-11-01T14:13:04","slug":"my-first-artificial-intelligence-and-hittestobject","status":"publish","type":"post","link":"http:\/\/www.aymericlamboley.fr\/blog\/my-first-artificial-intelligence-and-hittestobject\/","title":{"rendered":"My first Artificial Intelligence and HitTestObject"},"content":{"rendered":"<p>Hey, what&#8217;s up ?<br \/>\nSince my last post, I have pursued the little game started. I have added 3 things : a shot function (space bare), collisions, and AI. You can see the application <a href=\"http:\/\/www.aymericlamboley.fr\/works\/galacticwars\/GalacticWars.html\"><strong>here<\/strong><\/a>, but you must click on the swf before using keyboard (I try to change this, but I always have the problem).<\/p>\n<p><!--more--><\/p>\n<p>Now, I will explain a part of the code :<br \/>\n&#8211; collision : if an enemy hits the Starship, it will be removed. The function is called by an EnterFrame&#8217;s Event. At its creation, an enemy is put in the array &#8220;enemies&#8221;.<\/p>\n<pre lang=\"actionscript3\">private function collisionManagement():void {\r\n\t\t\t\r\n\tfor (var i:uint = 0; i < enemies.length; i++) {\r\n\t\tif (vaisseau.hitTestObject(enemies[i] as Enemy)) {\r\n\t\t\t\t\t\r\n\t\t\tvar killed:Enemy = enemies[i] as Enemy;\r\n\t\t\tkilled.die();\r\n\t\t\tenemies.splice(i, 1);\r\n\t\t}<\/pre>\n<p>- the shot management, in an EnterFrame too. And a shot is in a Array, containerShot.<\/p>\n<pre lang=\"actionscript3\">private function shotManagement():void {\r\n\t\t\t\r\n\tfor (var j:uint = 0; j < containerShot.length; j++) {\r\n\t\tfor (var k:uint = 0; k < enemies.length; k++) {\r\n\t\t\tif ((containerShot[j] as Shot).hitTestObject(enemies[k] as Enemy)) {\r\n\t\t\t\tvar killed:Enemy = enemies[k] as Enemy;\r\n\t\t\t\tkilled.die();\r\n\t\t\t\tenemies.splice(k, 1);\r\n\t\t\t\t\t\t\r\n\t\t\t\tremoveChild(containerShot[j] as Shot);\r\n\t\t\t\tvar shotEnd:Shot = containerShot[j] as Shot;\r\n\t\t\t\tshotEnd.die();\r\n\t\t\t}\t\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>- the most interesting : AI. The AI moves by itself, in fact AI depends of one thing : the timer's duration chosen randomly. At each period it changes the angle of the AI. Like the Starship's deplacement, it only needs angle to move in this direction. After that, if we want a special reaction if the two items are close, we must calculate the distance between them. That is a <a href=\"http:\/\/en.wikipedia.org\/wiki\/Distance#Geometry\">mathematical<\/a> function. In my case :<\/p>\n<pre lang=\"actionscript3\">if ((Math.sqrt(Math.pow((-conteneur.x + stage.stage.width \/ 2 - enemy.posX()), 2) + Math.pow((-conteneur.y + stage.stage.height \/ 2 - enemy.posY()), 2)) < 250)) {\r\n\t\t\t\t\t\r\n\tif (Math.random() > 0.6) { \/\/dynamic probability\r\n\t\tenemy.goOnPoint(-conteneur.x + stage.stage.width\/2, -conteneur.y + stage.stage.height \/ 2);\r\n\t}\t\r\n} else {\r\n\tenemy.startAgainTimer();\r\n})<\/pre>\n<p>For the AI next step, I wanted that the enemy go on the Starship to crash on it. But that was not easy to find how find enemy's angle to go on the Starship (it could be every where). I had as data enemy's angle, position in x and y, and starship'x with y. And after some time, I found the solution : Pythagore... Never reused since several years. Shame on me !<\/p>\n<pre lang=\"actionscript3\">public function goOnPoint(starshipX:int, starshipY:int):void {\r\n\tmyTimer.stop();\r\n\tstatusTimer = false;\r\n\tenemy.rotationZ = Math.atan2((starshipX - enemy.x), -(starshipY - enemy.y)) * 180 \/ Math.PI;\r\n}<\/pre>\n<p>The enemy class :<\/p>\n<pre lang=\"actionscript3\" line=\"1\">package {\r\n\timport com.greensock.TweenLite;\r\n\r\n\timport flash.display.MovieClip;\r\n\timport flash.events.Event;\r\n\timport flash.events.TimerEvent;\r\n\timport flash.utils.Timer;\r\n\r\n\t\/**\r\n\t * @author Aymeric\r\n\t *\/\r\n\tpublic class Enemy extends MovieClip {\r\n\t\t\r\n\t\tprivate var enemy:MovieClip;\r\n\t\tprivate var myTimer:Timer;\r\n\t\tprivate var statusTimer:Boolean = false;\r\n\t\t\r\n\t\tpublic function Enemy(posX:int, posY:int, rotate:int, time:int) {\r\n\t\t\t\r\n\t\t\tenemy = new Ennemi();\r\n\t\t\taddChild(enemy);\r\n\t\t\tenemy.x = posX;\r\n\t\t\tenemy.y = posY;\r\n\t\t\tenemy.rotationZ = rotate;\r\n\t\t\t\r\n\t\t\tmyTimer = new Timer(time, 0);\r\n\t\t\tmyTimer.start();\r\n\t\t\tstatusTimer = true;\r\n\t\t\t\r\n\t\t\tmyTimer.addEventListener(TimerEvent.TIMER, move);\r\n\t\t\tenemy.addEventListener(Event.ENTER_FRAME, loop);\r\n\t\t}\r\n\t\t\r\n\t\tpublic function posX():int {\r\n\t\t\treturn enemy.x;\r\n\t\t}\r\n\t\t\r\n\t\tpublic function posY():int {\r\n\t\t\treturn enemy.y;\r\n\t\t}\r\n\t\t\r\n\t\tpublic function rotatePosition():int {\r\n\t\t\treturn enemy.rotationZ;\r\n\t\t}\r\n\t\t\r\n\t\tpublic function goOnPoint(starshipX:int, starshipY:int):void {\r\n\t\t\tmyTimer.stop();\r\n\t\t\tstatusTimer = false;\r\n\t\t\tenemy.rotationZ = Math.atan2((starshipX - enemy.x), -(starshipY - enemy.y)) * 180 \/ Math.PI;\r\n\t\t}\r\n\r\n\t\tpublic function startAgainTimer():void {\r\n\t\t\tif (statusTimer == false) {\r\n\t\t\t\tmyTimer.start();\r\n\t\t\t\tstatusTimer = true;\r\n\t\t\t}\r\n\t\t}\r\n\r\n\t\tpublic function die():void {\r\n\t\t\tmyTimer.stop();\r\n\t\t\tstatusTimer = false;\r\n\t\t\tmyTimer.removeEventListener(TimerEvent.TIMER, move);\r\n\t\t\tenemy.removeEventListener(Event.ENTER_FRAME, loop);\r\n\t\t\tTweenLite.to(enemy, 0.5, {alpha:0, onComplete:remove});\r\n\t\t}\r\n\t\t\r\n\t\tprivate function remove():void {\r\n\t\t\tremoveChild(enemy);\r\n\t\t}\r\n\r\n\t\tprivate function move(t:TimerEvent):void {\r\n\t\t\tTweenLite.to(enemy, 0.5, {rotationZ:Math.round(Math.random() * 360)});\r\n\t\t}\r\n\t\t\r\n\t\tprivate function loop(e:Event):void {\r\n\t\t\tenemy.x += 7 * Math.sin(enemy.rotationZ * Math.PI \/ 180);\r\n\t\t\tenemy.y -= 7 * Math.cos(enemy.rotationZ * Math.PI \/ 180);\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>And the shot class : <\/p>\n<pre lang=\"actionscript3\" line=\"1\">package {\r\n\timport flash.display.MovieClip;\r\n\timport flash.events.Event;\r\n\timport flash.events.TimerEvent;\r\n\timport flash.utils.Timer;\r\n\r\n\t\/**\r\n\t * @author Aymeric\r\n\t *\/\r\n\tpublic class Shot extends MovieClip {\r\n\t\t\r\n\t\tprivate var shot:MovieClip;\r\n\t\tprivate var myTimer:Timer;\r\n\t\t\r\n\t\tpublic function Shot(rotate:int, posX:int, posY:int) {\r\n\t\t\t\r\n\t\t\tshot = new Fire();\r\n\t\t\taddChild(shot);\r\n\t\t\tshot.rotationZ = rotate;\r\n\t\t\tshot.x = posX;\r\n\t\t\tshot.y = posY;\r\n\t\t\t\r\n\t\t\tmyTimer = new Timer(3000, 1);\r\n\t\t\tmyTimer.start();\r\n\t\t\t\r\n\t\t\tmyTimer.addEventListener(TimerEvent.TIMER_COMPLETE, endShot);\r\n\t\t\tshot.addEventListener(Event.ENTER_FRAME, loop);\r\n\t\t}\r\n\t\t\r\n\t\t\/\/If it hits an enemy :\r\n\t\tpublic function die():void {\r\n\t\t\tmyTimer.stop();\r\n\t\t\tshot.removeEventListener(Event.ENTER_FRAME, loop);\r\n\t\t\tmyTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, endShot);\r\n\t\t\tremoveChild(shot);\r\n\t\t}\r\n\t\t\r\n\t\tprivate function endShot(t:TimerEvent):void {\r\n\t\t\tmyTimer.stop();\r\n\t\t\tshot.removeEventListener(Event.ENTER_FRAME, loop);\r\n\t\t\tmyTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, endShot);\r\n\t\t\tremoveChild(shot);\r\n\t\t}\r\n\r\n\t\tprivate function loop(e:Event):void {\r\n\t\t\tshot.x += 20 * Math.sin(shot.rotationZ * Math.PI \/ 180);\r\n\t\t\tshot.y -= 20 * Math.cos(shot.rotationZ * Math.PI \/ 180);\r\n\t\t}\r\n\t}\r\n}<\/pre>\n<p>And I have seen a difference between two lines which should have the same result. The first works perfectly, but not the second... If you have any idea \ud83d\ude42<\/p>\n<pre lang=\"actionscript3\">conteneur.removeChild(enemies[k] as Enemy);\r\nconteneur.removeChild(conteneur.getChildByName(\"enemy\" + k));<\/pre>\n<p>There are some random bug (my favorites) but it should works normally. Don't forget to update the page, if you want to restart !<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Hey, what&#8217;s up ? Since my last post, I have pursued the little game started. I have added 3 things : a shot function (space bare), collisions, and AI. You can see the application here, but you must click on the swf before using keyboard (I try to change this, but I always have the &hellip; <a href=\"http:\/\/www.aymericlamboley.fr\/blog\/my-first-artificial-intelligence-and-hittestobject\/\" class=\"more-link\">Continue reading <span class=\"screen-reader-text\">My first Artificial Intelligence and HitTestObject<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0},"categories":[4],"tags":[],"_links":{"self":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/78"}],"collection":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/comments?post=78"}],"version-history":[{"count":8,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/78\/revisions"}],"predecessor-version":[{"id":1306,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/posts\/78\/revisions\/1306"}],"wp:attachment":[{"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/media?parent=78"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/categories?post=78"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/www.aymericlamboley.fr\/blog\/wp-json\/wp\/v2\/tags?post=78"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}