// check for any collisions with snake (returns zero if no collision) public int Collided(PictureBox collider) { // if the picturebox is null, obviously no collision if (collider == null) { return(0); } // final result int final = 0; if (snakeHead.picBox.Bounds.IntersectsWith(collider.Bounds)) // check for head collision first { final |= HEAD_COLLISION; // shift the bits into the final result for head collision } // check for self collision // loop through entire snake body to check for collisions for (int i = 0; i < bodySegments.Count; i++) // start at 1 to skip the head { // retrieve current body part BodySegment bdPart = bodySegments[i]; if (bdPart.Bounds.IntersectsWith(collider.Bounds)) // check for collision { final |= BODY_COLLISION; // shift the bits for body collision break; // end the loop as no need to check other parts } // check for self collisions as well (head and body) /*if (bdPart.Bounds.IntersectsWith(snakeHead.picBox.Bounds)) * { * final |= SELF_COLLISION; // shift bits for head collision * }*/ } return(final); }
void addLength(int size) // add a length to the snake in pixels { BodySegment trailing = bodySegments[bodySegments.Count - 1]; // retrieve the last body segment since we're building off the tail of the snake // get the buildup angle double buildAngle = trailing.velocity.Degrees * Math.PI / 180 + Math.PI; // flip it around // get the change in each dimension int dx = (int)(size * Math.Cos(buildAngle)); int dy = (int)(size * Math.Sin(buildAngle)); // add the new dimensions trailing.grow(dx, dy); }
// temporary constructor public ContinuousSnake(int x, int y, CoreForm _mainForm, Vector _velocity, double size, bool red = false) { // assign all variables this.Size = (int)size; this.mainForm = _mainForm; this.red = red; // find angle to build the body in rads double angle = _velocity.Degrees * Math.PI / 180 + Math.PI; // add PI radians to flip the angle around // since the build must occur in opposite direction of velocity int[] coords = new int[] { x, y }; // coords in proper form to be used BodySegment segment = new BodySegment(0, 0, coords, _velocity.Clone(), mainForm); // set size to zero for now int dx = (int)(BodyPart.SIZE * size * Math.Cos(angle)); // get change in each direction for the new size int dy = (int)(BodyPart.SIZE * size * Math.Sin(angle)); // add negative because coords are reversed on screen // whichever is zero will be default width if (dx == 0) { dx = BodyPart.SIZE; } else { dy = BodyPart.SIZE; } segment.grow(dx, dy); if (_velocity.Degrees == 180 || _velocity.Degrees == 90) // make the snake head at proper coords { snakeHead = new BodyPart(segment.X, segment.Y, _velocity.Clone(), mainForm); } else if (_velocity.Degrees == 0) { snakeHead = new BodyPart((int)(segment.X + BodyPart.SIZE * size - BodyPart.SIZE), segment.Y, _velocity.Clone(), mainForm); } else if (_velocity.Degrees == 0) { snakeHead = new BodyPart(segment.X, (int)(segment.Y + BodyPart.SIZE * size - BodyPart.SIZE), _velocity.Clone(), mainForm); } FixHead(); // fix head orientation based on velocity // add the segment to the bodySegments list to keep track of it bodySegments.Add(segment); // set the timer event for preventing too fast player responses interval.Elapsed += new ElapsedEventHandler(intervalFunc); // do the red colour thing if (red) { // make the segment red if the red flag is set bodySegments[0].picBox.BackColor = Color.Red; bodySegments[0].picBox.Image = null; } }
// check for self-collision public bool SelfCollision() { for (int i = 2; i < bodySegments.Count; i++) // start at the third body part (index 2) since thats the only // logical self-collision { // retrieve the target body part BodySegment target = bodySegments[i]; // will be tested with head (also only logical means of collision) if (snakeHead.picBox.Bounds.IntersectsWith(target.Bounds)) { // return true as no need to test any longer return(true); } } // if the function reached this point, no collision occurred return(false); }
void clipPrev() { // get the previous item (second item) BodySegment previous = bodySegments[1]; double removeAngle = previous.velocity.Degrees * Math.PI / 180 + Math.PI; // angle to remove material (add pi to flip around) // amount to shrink in each dimension int dx = (int)((BodyPart.SIZE - overlap) * Math.Cos(removeAngle)); int dy = (int)((BodyPart.SIZE - overlap) * Math.Sin(removeAngle)); previous.shrink(dx, dy); // shrink it // clip the collider for this segment to the proper size // amount to shrink in each dimension dx = (int)((BodyPart.SIZE) * Math.Cos(removeAngle)); dy = (int)((BodyPart.SIZE) * Math.Sin(removeAngle)); previous.shrinkBounds(dx, dy); // shrink it }
// check for any collisions with a gameobject public int Collided(GameObject gameObject) { // final result int final = 0; if (gameObject.Collided(snakeHead.picBox)) // check for head collision first { final |= HEAD_COLLISION; // shift the bits into the final result for head collision } // loop through entire snake body to check for collisions for (int i = 1; i < bodySegments.Count; i++) // start at 1 to skip the head { // retrieve current body part BodySegment bdPart = bodySegments[i]; if (gameObject.Collided(bdPart.picBox)) // check for collision { final |= BODY_COLLISION; // shift the bits for body collision break; // end the loop as no need to check other parts } } return(final); }
void turn(double degrees) // turn in a certain direction { // dont turn if dead or timer from last time is still ticking if (!Alive && !interval.Enabled) { return; } // dont turn if the front-most body segment length is not equal or greater than two times the standard // body part size try { if ((2 * BodyPart.SIZE) > bodySegments[0].Length) { return; } } catch (IndexOutOfRangeException e) { return; } // create new body segment with velocity upward // coords for the segment (same as head) int[] coords = new int[] { snakeHead.picBox.Location.X, snakeHead.picBox.Location.Y }; Vector newVelocity = new Vector(Velocity.Magnitude, degrees);// velocity for new segment (same magnitude but different velocity) BodySegment newSegment = new BodySegment(BodyPart.SIZE, BodyPart.SIZE, coords, newVelocity, mainForm); // make the new segment red if the snake is red if (red) { newSegment.picBox.BackColor = System.Drawing.Color.Red; newSegment.picBox.Image = null; } bodySegments.Insert(0, newSegment); // add it as the first item clipPrev(); // clip off the previous first item to correct for size snakeHead.velocity = newVelocity.Clone(); // snakehead velocity same as the first part correctMovement(); // correct all movement interval.Start(); // start timer FixHead(); // correct snake head }
void ContinuedRun(BodyPart snakeHead, List <ContinuousSnake> snakes, List <Obstacle> obstacles) { // get x and y comps of velocity double thisX = picBox.Location.X + (double)picBox.Width / (double)2; double thisY = picBox.Location.Y + (double)picBox.Height / (double)2; double snakeX = snakeHead.picBox.Location.X + (double)snakeHead.picBox.Width / (double)2; double snakeY = snakeHead.picBox.Location.Y + (double)snakeHead.picBox.Height / (double)2; // get the comps double deltaX = snakeX - thisX; double deltaY = snakeY - thisY; // scale them according to target velocity magnitude double triMag = Math.Sqrt(Math.Pow(deltaX, 2) + Math.Pow(deltaY, 2)); deltaX = deltaX * velocityMag / triMag; deltaY = deltaY * velocityMag / triMag; // run checks here for obstacles foreach (Obstacle obstacle in obstacles) { // get the rectangle that represents collision area with an obstacle Rectangle collision = Rectangle.Intersect(obstacle.picBox.Bounds, picBox.Bounds); if (collision != Rectangle.Empty) // only run if collision is existent { if (collision.Width > collision.Height) { deltaY = 0; // push the enemy out by the height if (collision.Y > picBox.Location.Y) { picBox.Location = new Point(picBox.Location.X, picBox.Location.Y - collision.Height - 1); } else if (collision.Y < picBox.Location.Y) { picBox.Location = new Point(picBox.Location.X, picBox.Location.Y + collision.Height + 1); } } else if (collision.Height > collision.Width) { deltaX = 0; if (collision.X > picBox.Location.X) { picBox.Location = new Point(picBox.Location.X - collision.Width - 1, picBox.Location.Y); } else if (collision.Y < picBox.Location.Y) { picBox.Location = new Point(picBox.Location.X + collision.Width + 1, picBox.Location.Y); } } else { //deltaX = 0; //deltaY = 0; } } } // run checks here for snakes foreach (ContinuousSnake snake in snakes) { // get body segment that the enemy collided with BodySegment segment = snake.CollidedWith(picBox); // end the current loop if no segment returned if (segment == null) { continue; } // get the rectangle that represents collision area with an obstacle Rectangle collision = Rectangle.Intersect(segment.picBox.Bounds, picBox.Bounds); if (collision != Rectangle.Empty) // only run if collision is existent { if (collision.Width > collision.Height) { deltaY = 0; } else if (collision.Height > collision.Width) { deltaX = 0; } else { //deltaX = 0; //deltaY = 0; } } } // move the picturebox picBox.Location = new System.Drawing.Point((int)(picBox.Location.X + deltaX), (int)(picBox.Location.Y + deltaY)); }