0

私は一種の宇宙船ゲームに取り組んでいます。このゲームでは、着陸船を離陸させて、墜落するまでできるだけ高く飛ばします。私が直面している問題は、私が実装しようとしたカメラが着陸機を中央に保持しないことです。着陸機は最終的にカメラよりも速くなり、画面から外れます。理由がわかりません。それを機能させるためにあらゆることを試みました。スプライトが 4 方向に移動する単純なプログラムでカメラを使用するテスト ケースを作成しました。それはうまくいきましたが、メインのゲームにカメラを実装すると、正しく動作しません。どんな助けでも大歓迎です。

これはカメラクラスです:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace WindowsGame4.Main
{
  class Camera
  {
    public Matrix transform;
    Viewport view;
    Vector2 centre;

    public Camera(Viewport newView)
    {
        view = newView;
    }

    public void Update(GameTime gameTime, Game1 lander, Lander _lander)
    {
        centre = new Vector2(_lander.Position.X + (lander.lander.Width / 2) - 455, _lander.Position.Y + (lander.lander.Height/2)-910);
        transform = Matrix.CreateTranslation(new Vector3(-centre.X - _lander.Velocity.X, -centre.Y - _lander.Velocity.Y, 0));
    }
    }
    }

これは、Game1 の主な更新方法です。

    // Creates the handler to allow the use of the keyboard inputs
            KeyboardState keyboard = Keyboard.GetState(); 
            // Sets up the launch position to allow for scoring and height determining
            startPos = 700f;                
            // Mainly for debug, allows for leaving the game whenever desired
            if (keyboard.IsKeyDown(Keys.Escape))
            {
                Exit();
            }

       // The logic for the thruster, checks for if the space key is down and if 
       // the lander has any fuel remaining.  If there is no fuel the thrusters
       // will not work.
        if (keyboard.IsKeyDown(Keys.Space) && !empty)
        {
            _lander.Accelerate(_thruster.GetAcceleration(), gameTime.ElapsedGameTime);               
            // Turns on the thruster
            _thruster.Active = true; 
            // Tells the program that the lander has taken off, allowing the gravity to kick in
            landed = false;
            // Keeps track of the amount of fuel you have
            if (_lander.Fuel > 0)
            {
                // Subtracts 1 from the fuel for every second that the 'SPACE' key is down
                _lander.Fuel--;
            }
            else if (_lander.Fuel <= 0)
            {
                empty = true;
                endPos = _lander.Position.Y;
            }
        }
        if (keyboard.IsKeyUp(Keys.Space) || empty)
        {
            // Turns off the thruster as long as the player is not pressing 'SPACE'
            _thruster.Active = false; 
        }

        // This is the logic structure for the landing portion of the game, it sets up a 
        // level area in which the player can land on, which in turn then checks the Position.X value
        // to see how many points to give based on their close proximity to the landing site.  
        // ** Could possibly add depth or different levels based on location, like landing on a mountain
        // ** Or landing in the bottom of a crater
        if (_lander.Position.Y >= 800)
        {
            landed = true;
            // If you have died or Failed a mission 3 times then the game is over
            if (_lander.Lives == 1)
            {
                currentGameState = GameState.GameOver;                    
            }
            // As long as you have a life left the game will continue
            // This logic also is only applied if the player has landed on the ground
            // ** Add a rotational fixer as to make the lander stand straight up as opposed to the way its oriented
            // ** Upon landing
            else if (_lander.Lives > 0)
            {                   
                    // Sets the landers position to the current position that its landed at, thus stopping the gravity
                    // Resets the velocity, thus making sure it doesnt continue to fall
                    _lander.Position = new Vector2(_lander.Position.X, _lander.Position.Y);
                    _lander.Velocity = new Vector2();

                    // Sets up the first landing site, this particular one is the highset value landing site is almost right 
                    // On top of the flag that is placed to indicate where to land.
                    // *** Will Not Use In Final Version, Will Substitue With Logic For Height And Cash Gained ***
                    if ((_lander.Position.X >= 600 && _lander.Position.X <= 650) || (_lander.Position.X <= 600 && _lander.Position.X >= 550))
                    {   
                        // *** Will be implemented to display a "YOU HAVE FAILED THE MISSION" screen. ***
                        failure = false;
                        // This is for debugging purposes only, will change to be automatic once all functions are complete
                        if (keyboard.IsKeyDown(Keys.Enter))
                        {
                            // (1) -- Resets the position of the lander back to its original position and Velocity
                            // (2) -- Add 150 points to the score based on the location that the lander set down at
                            // (3) -- Continues on to the next level

                            _lander.Position = new Vector2(graphics.PreferredBackBufferWidth / 2, 100); // (1)
                            _lander.Velocity = new Vector2(); // (1)
                            _lander.Score += 150; // (2)
                            currentGameState = GameState.Level2; // (3) 
                        }
                    }
                    // Sets up the second landing site, this particular one is the second highest value landing site that is 
                    // A large circle surrounding the landing site above
                    else if ((_lander.Position.X >= 651 && _lander.Position.X <= 750 ) || (_lander.Position.X <= 549 && _lander.Position.X >= 450))
                    {
                        // *** Will be implemented to display a "YOU HAVE FAILED THE MISSION" screen. ***
                        failure = false;
                        // This is for debugging purposes only, will change to be automatic once all functions are complete
                        if (keyboard.IsKeyDown(Keys.Enter))
                        {
                            // (1) -- Resets the position of the lander back to its original position and Velocity
                            // (2) -- Add 50 points to the score based on the location that the lander set down at
                            // (3) -- Continues on to the next level

                            _lander.Position = new Vector2(graphics.PreferredBackBufferWidth / 2, 100); // (1)
                            _lander.Velocity = new Vector2(); // (1)
                            _lander.Score += 50; // (2)
                            currentGameState = GameState.Level2; // (3)
                        }                            
                    }
                    // Sets up the final landing site, this particular one is the failing portion of the map that is 
                    // A large area that encompasses the rest of the map.
                    else if ((_lander.Position.X >= 751 && _lander.Position.X <= 850) || (_lander.Position.X <= 449 && _lander.Position.X >= 0))
                    {
                        // You get no points so it does not only need to done once, it can be done as many times as needed
                        // And it will not change the data
                        _lander.Score = 0;
                        // *** Will be implemented to display a "YOU HAVE FAILED THE MISSION" screen. ***
                        failure = true;
                        // This is for debugging purposes only, will change to be automatic once all functions are complete
                        if (keyboard.IsKeyDown(Keys.Enter))
                        {
                            // (1) -- Resets the position of the lander back to its original position and Velocity
                            // (2) -- Takes away one of your lives as a result of the players failure to land correctly

                            _lander.Position = new Vector2(graphics.PreferredBackBufferWidth / 2, 100); // (1)
                            _lander.Velocity = new Vector2(); // (1)
                            _lander.Lives--; // (2)
                        }                              

                    }
                    // This is just a loop that gives a visual representation of refueling before the next level begins.
                    for (double i = _lander.Fuel; i < 500; i++)
                    {
                        _lander.Fuel += .05;                            
                    }
                }
            }
        // A very simple call to the Gravity and Lander classes that simulates gravity as long as the 
        // lander has not landed            
        else if (!landed)
        {
           _lander.Accelerate(_gravity.GetAcceleration(), gameTime.ElapsedGameTime);               
        }

        // Moves the lander according to gravity calculated by the lander class
        _lander.DoMovement(gameTime.ElapsedGameTime);

        // Calculates the height achieved based off of starting height and ending height
        height = startPos - endPos;
        // This will rotate the lander when the keys are pressed down
        // They will also check to make sure if it is landed or not
        // If it's landed then it will not allow the lander to rotate.
        if (keyboard.IsKeyDown(Keys.Left) && landed == false)
        {
            // (1) -- This will also change the angle of rotation for the thruster as to all for movement in 
            // That specific direction. 
            // Example: if you rotate to the left and turn on the thrusters you will starting moving
            // to the left

            rotation -= 0.1f;
            _lander.Rotation = rotation;
            _thruster.Rotation = rotation; // (1)
        }
        if (keyboard.IsKeyDown(Keys.Right) && landed == false)
        {
            // (1) -- This will also change the angle of rotation for the thruster as to all for movement in that specific direction.
            // (2) -- This will also change the angle of rotation for the lander as to all for movement in that specific direction.
            // Example: if you rotate to the right and turn on the thrusters you will starting moving
            // to the right

            rotation += 0.1f;
            _lander.Rotation = rotation; // (2)
            _thruster.Rotation = rotation;   // (1)
        }

        // Calls the camera class to allow the screen to move with the player
        camera.Update(gameTime, this, _lander);

もっとコードが必要な場合は、他に必要なものをアップロードできます

4

2 に答える 2

0

@Sarkilasには同意しません。変換を使用すると、毎回カメラを指定する必要がなくなり、コードが簡素化されると思います。

このコードを、位置、原点、ズーム、および回転のベースとして使用できます。

return Matrix.CreateTranslation(new Vector3(-Position, 0.0f)) *
       Matrix.CreateTranslation(new Vector3(-Origin, 0.0f)) *
       Matrix.CreateRotationZ(Rotation) *
       Matrix.CreateScale(Zoom, Zoom, 1) *
       Matrix.CreateTranslation(new Vector3(Origin, 0.0f));

問題は、着陸船があなたの原点ではなく、あなたの位置でなければならないということです.原点はあなたのビューポートサイズの半分でなければなりません.

Position = lander.Position;
Origin = new Vector2(view.Width / 2, view.Height / 2);

少しずれているように見える場合は、おそらく着陸船の位置の半分を原点または位置に戻す必要があります。

于 2013-10-13T12:30:18.803 に答える