/***************************************************************************** Tag.c - JavaScript to play tag with a computer. The size of the image is the playing field. *****************************************************************************/ // These values are constants which do not change // obstacles (rubber posts) var posts_x = [140, 280, 420, 140, 280, 420]; var posts_y = [120, 120, 120, 240, 240, 240]; var post_width = 31; var sprite_diameter = 63; var sprite_radius = 31; // These values are constants which are calculated at run-time // These variables track the playing field var image_width, image_height, right_wall, bottom_wall; // These values are not constants // These variables track the mouse var mouse_x, mouse_y; // This object tracks the person var person = []; // This object tracks the robot var robot = []; // These variables keep score var round = 0; var score_high = 0; var timer_id = 0; /*************************************************************************** Startup initialization This source depends on the functions provided in Tools.c which must be included before this source file. ***************************************************************************/ Sprite_Make ("Person"); // Save person values person.x = 0; person.y = 0; Sprite_Move (Tag, Person, person.x, person.y); // Calculate square of distance to post post_d = (sprite_diameter + post_width) >> 1; post_sq = Math.pow (post_d, 2) post_d += 1; // Save field size which can't change image_width = Tag.clientWidth; image_height = Tag.clientHeight; right_wall = image_width - sprite_diameter; bottom_wall = image_height - sprite_diameter; Sprite_Make ("Robot"); // Save robot values robot.x = right_wall; robot.y = bottom_wall; robot.dx = 0; robot.dy = 0; robot_sq = Math.pow (sprite_diameter, 2) Sprite_Move (Tag, Robot, robot.x, robot.y); Scores_List (); document.onmousemove = handlerMM; document.onclick = Play_Start; Tag_Message.innerText = "Click on the field to start the game."; /****************************************************************************** Mouse move handler ******************************************************************************/ function handlerMM () { mouse_x = document.body.scrollLeft + window.event.clientX - Tag.offsetLeft; mouse_y = document.body.scrollTop + window.event.clientY - Tag.offsetTop; } /****************************************************************************** Click handler to start play ******************************************************************************/ function Play_Start () { // Already playing? if (round) return; score_high = 0; Score_Time.innerText = score_high; Sprite_Move (Tag, Person, person.x, person.y); Sprite_Move (Tag, Robot, robot.x, robot.y); Round_Start (); } /****************************************************************************** Start the next round ******************************************************************************/ function Round_Start () { person.x = 0; person.y = 0; person.dx = 0; person.dy = 0; robot.x = right_wall; robot.y = bottom_wall; robot.dx = 0; robot.dy = 0; ++round; if (round > 2) { Scores_Update (); round = 0; Tag_Message.innerText = "Click on the field to start the game."; return; } if (round & 1) Tag_Message.innerText = "Run! Go tag the computer!"; else Tag_Message.innerText = "Run! The computer is coming to tag you!"; setTimeout ("Play_Move ()", 1000); } /****************************************************************************** timer function for moves during play ******************************************************************************/ function Play_Move () { var dmax; if (round & 1) --score_high; else ++score_high Score_Time.innerText = score_high; Move_Object (person, mouse_x, mouse_y); Sprite_Move (Tag, Person, person.x, person.y); if (round & 1) Robot_Run (); else Move_Object (robot, person.x, person.y); Sprite_Move (Tag, Robot, robot.x, robot.y); // Slow down the robot. dmax = Math.floor (20 + score_high / 100); if (dmax < 0) dmax = 0; if (dmax < Math.abs (robot.dx)) { if (robot.dx < 0) robot.dx = - dmax; else robot.dx = dmax; } if (dmax < Math.abs (robot.dy)) { if (robot.dy < 0) robot.dy = - dmax; else robot.dy = dmax; } if (Robot_Tag ()) { if (0 != timer_id) clearInterval (timer_id); timer_id = 0; Round_Start (); } else { if (0 == timer_id) timer_id = setInterval ("Play_Move ()", 50); } } /****************************************************************************** The sprite makes the moves ******************************************************************************/ function Move_Object (sprite, dx, dy) { var x, y, i; // Which way does the pointer say to run x = dx - sprite.x - sprite_radius; x = x - Factorial (sprite.dx); if (x < sprite.dx) --sprite.dx; if (x > sprite.dx) ++sprite.dx; y = dy - sprite.y - sprite_radius; y = y - Factorial (sprite.dy); if (y < sprite.dy) --sprite.dy; if (y > sprite.dy) ++sprite.dy; sprite.x += sprite.dx; sprite.y += sprite.dy; for (var i in posts_x) Post_Crash (sprite, posts_x[i], posts_y[i]); // crash into left wall? if (sprite.x < 0) { sprite.x = 0; sprite.dx = 0; } // crash into right wall? if (sprite.x > right_wall) { sprite.x = right_wall; sprite.dx = 0; } // crash into top wall? if (sprite.y < 0) { sprite.y = 0; sprite.dy = 0; } // crash into bottom wall? if (sprite.y > bottom_wall) { sprite.y = bottom_wall; sprite.dy = 0; } } /****************************************************************************** the robot runs away ******************************************************************************/ function Robot_Run () { var x, y; x = posts_x[5] - sprite_radius + posts_x[5] - person.x; y = posts_y[5] - sprite_radius + posts_y[5] - person.y; Move_Object (robot, x, y); } /****************************************************************************** Calculate factorial ******************************************************************************/ function Factorial (x) { y = 0; while (x) { y += x; if (x < 0) ++x; else --x; } return y; } /****************************************************************************** Crash into a post? ******************************************************************************/ function Post_Crash (sprite, x, y) { // How far are we from that post? dx = sprite.x + sprite_radius - x; dy = sprite.y + sprite_radius - y; d = Math.pow (dx, 2) + Math.pow (dy, 2); // Did we crash? if (post_sq > d) { // Bounce back a little bit angle = Math.atan2 (dx ,dy); dx = Math.ceil (post_d * Math.sin (angle)); dy = Math.ceil (post_d * Math.cos (angle)); sprite.x = x + dx - sprite_radius; sprite.y = y + dy - sprite_radius; } } /****************************************************************************** Tag robot? ******************************************************************************/ function Robot_Tag () { d = Math.pow (person.x - robot.x, 2) + Math.pow (person.y - robot.y, 2); // Did we tag? if (robot_sq < d) return false; return true; }