예제 #1
0
        /// <summary>
        /// Allows the game to run logic such as updating the world,
        /// checking for collisions, gathering input, and playing audio.
        /// </summary>
        /// <param name="gameTime">Provides a snapshot of timing values.</param>
        protected override void Update(GameTime gameTime)
        {
            // Allows the game to exit
            if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) {
                this.Exit();
            }

            SnakeDirection oldDirection = snakeDirection;
            Vector2 oldSnakePosition = snakePosition;
            bool justInitialized = false;

            // Get keyboard input
            KeyboardState state = Keyboard.GetState();
            if (IsKeyReleased(Keys.Space, state)) {
                TogglePaused();
            }
            if (IsKeyReleased(Keys.R, state)) {
                InitializeSnake();
                justInitialized = true;
            }
            if (!paused && !justInitialized) {
                if (state.IsKeyDown(Keys.Left)) {
                    if (snakeDirection != SnakeDirection.Right) {
                        snakeDirection = SnakeDirection.Left;
                    }
                }
                if (state.IsKeyDown(Keys.Right)) {
                    if (snakeDirection != SnakeDirection.Left) {
                        snakeDirection = SnakeDirection.Right;
                    }
                }
                if (state.IsKeyDown(Keys.Up)) {
                    if (snakeDirection != SnakeDirection.Down) {
                        snakeDirection = SnakeDirection.Up;
                    }
                }
                if (state.IsKeyDown(Keys.Down)) {
                    if (snakeDirection != SnakeDirection.Up) {
                        snakeDirection = SnakeDirection.Down;
                    }
                }
            }
            if (IsKeyReleased(Keys.G, state)) {
                GrowSnake();
            }
            if (state.IsKeyDown(Keys.OemPlus)) {
                snakeSpeed += 5;
            }
            if (state.IsKeyDown(Keys.OemMinus)) {
                snakeSpeed -= 5;
                if (snakeSpeed < 0) {
                    snakeSpeed = 0;
                }
            }
            if (state.IsKeyDown(Keys.OemCloseBrackets)) {
                snakeLength += 1.0f;
            }
            if (state.IsKeyDown(Keys.OemOpenBrackets)) {
                snakeLength -= 1.0f;
                if (snakeLength < initialSnakeLength) {
                    snakeLength = initialSnakeLength;
                }
            }
            if (state.IsKeyDown(Keys.W)) {
                cameraPitch += 1.0f;
                if (cameraPitch > 360.0f) {
                    cameraPitch -= 360.0f;
                }
                UpdateViewMatrix();
            }
            if (state.IsKeyDown(Keys.S)) {
                cameraPitch -= 1.0f;
                if (cameraPitch < 0) {
                    cameraPitch += 360.0f;
                }
                UpdateViewMatrix();
            }
            if (state.IsKeyDown(Keys.D)) {
                cameraDistance += 1.0f;
                UpdateViewMatrix();
            }
            if (state.IsKeyDown(Keys.A)) {
                cameraDistance -= 1.0f;
                if (cameraDistance < 0) {
                    cameraDistance = 0;
                }
                UpdateViewMatrix();
            }
            if (IsKeyReleased(Keys.V, state)) {
                if (cameraType == CameraType.FromAbove) {
                    SetCameraType(CameraType.Angled);
                } else {
                    SetCameraType(CameraType.FromAbove);
                }
            }
            if (IsKeyReleased(Keys.T, state)) {
                Toggle2DSnake();
            }
            if (IsKeyReleased(Keys.I, state)) {
                ToggleOverlay();
            }
            if (IsKeyReleased(Keys.C, state)) {
                ToggleIgnoreCollisions();
            }
            if (IsKeyReleased(Keys.B, state)) {
                if (arenaBoundaryType == ArenaBoundaryType.WrapAround) {
                    arenaBoundaryType = ArenaBoundaryType.Collision;
                } else if (arenaBoundaryType == ArenaBoundaryType.Collision) {
                    arenaBoundaryType = ArenaBoundaryType.NoBoundary;
                } else {
                    arenaBoundaryType = ArenaBoundaryType.WrapAround;
                }
            }
            if (state.IsKeyDown(Keys.Q) || state.IsKeyDown(Keys.Escape)) {
                Exit();
            }
            oldKeyboardState = state;

            if (!paused && !justInitialized) {
                // Check if snake switched direction
                if (snakeDirection != oldDirection) {
                    // Add position to list of joints
                    snakePositions.Add(new Vector2(oldSnakePosition.X, oldSnakePosition.Y));
                    disconnectedToPreviousPoint.Add(false);
                }

                // Move the snake
                float displacement = (float)gameTime.ElapsedGameTime.TotalSeconds * snakeSpeed;
                switch (snakeDirection) {
                    case SnakeDirection.Up:
                        snakePosition.Y -= displacement;
                        break;
                    case SnakeDirection.Down:
                        snakePosition.Y += displacement;
                        break;
                    case SnakeDirection.Left:
                        snakePosition.X -= displacement;
                        break;
                    case SnakeDirection.Right:
                        snakePosition.X += displacement;
                        break;
                }

                bool hit = false;

                // Check if snake went out of bounds
                if (arenaBoundaryType == ArenaBoundaryType.Collision) {
                    if (snakePosition.X < 0 ||
                            snakePosition.X > graphics.GraphicsDevice.Viewport.Width - 1 ||
                            snakePosition.Y < 0 ||
                            snakePosition.Y > graphics.GraphicsDevice.Viewport.Height - 1) {
                        hit = true;
                    }
                } else if (arenaBoundaryType == ArenaBoundaryType.WrapAround) {
                    if (snakePosition.X < 0) {
                        oldSnakePosition = new Vector2(graphics.GraphicsDevice.Viewport.Width, snakePosition.Y);
                        snakePositions.Add(new Vector2(0, snakePosition.Y));
                        disconnectedToPreviousPoint.Add(false);
                        snakePositions.Add(oldSnakePosition);
                        disconnectedToPreviousPoint.Add(true);
                        snakePosition = new Vector2(graphics.GraphicsDevice.Viewport.Width + snakePosition.X, snakePosition.Y);
                    } else if (snakePosition.X > graphics.GraphicsDevice.Viewport.Width) {
                        oldSnakePosition = new Vector2(0, snakePosition.Y);
                        snakePositions.Add(new Vector2(graphics.GraphicsDevice.Viewport.Width, snakePosition.Y));
                        disconnectedToPreviousPoint.Add(false);
                        snakePositions.Add(oldSnakePosition);
                        disconnectedToPreviousPoint.Add(true);
                        snakePosition = new Vector2(snakePosition.X - graphics.GraphicsDevice.Viewport.Width, snakePosition.Y);
                    } else if (snakePosition.Y < 0) {
                        oldSnakePosition = new Vector2(snakePosition.X, graphics.GraphicsDevice.Viewport.Height);
                        snakePositions.Add(new Vector2(snakePosition.X, 0));
                        disconnectedToPreviousPoint.Add(false);
                        snakePositions.Add(oldSnakePosition);
                        disconnectedToPreviousPoint.Add(true);
                        snakePosition = new Vector2(snakePosition.X, graphics.GraphicsDevice.Viewport.Height + snakePosition.Y);
                    } else if (snakePosition.Y > graphics.GraphicsDevice.Viewport.Height) {
                        oldSnakePosition = new Vector2(snakePosition.X, 0);
                        snakePositions.Add(new Vector2(snakePosition.X, graphics.GraphicsDevice.Viewport.Height));
                        disconnectedToPreviousPoint.Add(false);
                        snakePositions.Add(oldSnakePosition);
                        disconnectedToPreviousPoint.Add(true);
                        snakePosition = new Vector2(snakePosition.X, snakePosition.Y - graphics.GraphicsDevice.Viewport.Height);
                    }
                }

                // Trim the snake tail, making sure the length of the snake is correct.
                // Go backwards from current point through each point, adding up the displacement.
                // Stop when you reach the right length, removing history of non relevant points.
                float length = 0;
                Vector2 lastPosition = snakePosition;
                Vector2 vector = new Vector2();
                int i;

                for (i = snakePositions.Count - 1; i >= 0 && length <= snakeLength; --i) {
                    Vector2 position = snakePositions[i];

                    if (i == snakePositions.Count - 1 || !disconnectedToPreviousPoint[i + 1]) {
                        vector = lastPosition - position;
                        length += vector.Length();
                    }

                    lastPosition = position;
                }
                if (length > snakeLength) {
                    // Modify the tail end position
                    float changeAmount = length - snakeLength;
                    vector.Normalize();
                    vector = vector * changeAmount;
                    Vector2 newPosition = snakePositions[i + 1] + vector;
                    snakePositions[i + 1] = newPosition;
                }
                if (i >= 0) {
                    snakePositions.RemoveRange(0, i + 1);
                    disconnectedToPreviousPoint.RemoveRange(0, i + 1);
                    // Make sure the first element (the tail end point) is set to false
                    disconnectedToPreviousPoint[0] = false;
                }

                // Check if snake intersected with itself
                LineSegment2 recentMovement = new LineSegment2(oldSnakePosition, snakePosition);
                if (!hit && !ignoreSnakeCollisions) {
                    if (snakePositions.Count > 1) {
                        lastPosition = snakePositions[snakePositions.Count - 2];
                        i = snakePositions.Count - 3;
                        for (; i >= 0 && !hit; --i) {
                            Vector2 position = snakePositions[i];
                            LineSegment2 snakeSegment = new LineSegment2(position, lastPosition);

                            if (!disconnectedToPreviousPoint[i + 1]) {
                                hit = LineSegment2.SegmentsIntersect(recentMovement, snakeSegment);
                            }

                            lastPosition = position;
                        }
                    }
                }
                if (hit) {
                    InitializeSnake();
                } else {
                    // Check if snake reached a goal
                    if (LineSegment2.SegmentsIntersect(recentMovement, goalLeftSide) ||
                            LineSegment2.SegmentsIntersect(recentMovement, goalRightSide) ||
                            LineSegment2.SegmentsIntersect(recentMovement, goalBottomSide) ||
                            LineSegment2.SegmentsIntersect(recentMovement, goalLeftSide)) {
                        // intersection
                        GrowSnake();
                        RepositionGoal();
                    }

                    Update3DSnakeData();
                }
            }

            base.Update(gameTime);
        }
예제 #2
0
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Set up the arena
            arenaVertices = new VertexPositionNormalTexture[4];
            arenaVertices[0] = new VertexPositionNormalTexture(new Vector3(0, 0, graphics.GraphicsDevice.Viewport.Height),
                    new Vector3(0, 1, 0),
                    new Vector2(0, 0));
            arenaVertices[1] = new VertexPositionNormalTexture(new Vector3(0, 0, 0),
                    new Vector3(0, 1, 0),
                    new Vector2(0, 0));
            arenaVertices[2] = new VertexPositionNormalTexture(new Vector3(graphics.GraphicsDevice.Viewport.Width, 0, 0),
                    new Vector3(0, 1, 0),
                    new Vector2(0, 0));
            arenaVertices[3] = new VertexPositionNormalTexture(new Vector3(graphics.GraphicsDevice.Viewport.Width, 0,
                    graphics.GraphicsDevice.Viewport.Height),
                    new Vector3(0, 1, 0),
                    new Vector2(0, 0));
            arenaVertexBuffer = new VertexBuffer(graphics.GraphicsDevice, typeof(VertexPositionNormalTexture),
                    arenaVertices.Length, BufferUsage.None);
            arenaVertexBuffer.SetData<VertexPositionNormalTexture>(arenaVertices);
            arenaIndexBuffer = new IndexBuffer(graphics.GraphicsDevice, typeof(int), arenaIndices.Length, BufferUsage.None);
            arenaIndexBuffer.SetData<int>(arenaIndices);

            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);

            // Load the basic white texture for snake and goal
            blockTexture = new Texture2D(GraphicsDevice, (int)blockSize.X, (int)blockSize.Y, false, SurfaceFormat.Color);
            Int32[] pixels = new Int32[blockTexture.Width * blockTexture.Height];
            for (int i = 0; i < blockTexture.Width * blockTexture.Height; ++i) {
                pixels[i] = 0xFFFFFF;
            }
            blockTexture.SetData<Int32>(pixels, 0, blockTexture.Width * blockTexture.Height);

            overlayFont = Content.Load<SpriteFont>("OverlayFont");
            fontPosition = new Vector2(5, 5);

            snakeSpeed = defaultSnakeSpeed;
            snakeGrowLength = defaultSnakeGrowLength;
            fieldOfViewAngle = defaultFieldOfViewAngle;
            show2DSnake = defaultShow2DSnake;
            showOverlay = defaultShowOverlay;
            ignoreSnakeCollisions = defaultIgnoreSnakeCollisions;
            arenaBoundaryType = defaultArenaBoundaryType;
            SetCameraType(defaultCameraType);

            InitializeSnake();
        }