// 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);
 }
示例#5
0
        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);
        }
示例#7
0
        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));
        }