إنشاء في فئة GamePiece

GamePiece فئة بتغليف جميع الوظائف المطلوبة لتحميل نسخة قطعة Game XNA Microsoft Office 2010 Suite مقطع صوتي الولاية ماوس بالنسبة إلى قطعة الألعاب، يلتقط ماوس، توفر المعالجة ومعالجة inertia ويوفر إمكانية bouncing عندما تصل قطعة اللعبة إلى الحدود عرض المنفذ.

الأعضاء الخاصة

في الجزء العلوي من من GamePiece فئة، يتم تعريف العديد من الأعضاء الخاصة.

#region PrivateMembers
// The sprite batch used for drawing the game piece.
private SpriteBatch spriteBatch;
// The position of the game piece.
private Vector2 position;
// The origin used for rendering the game piece.
// Gets set to be the center of the piece.
private Vector2 origin;
// The texture for the piece.
private Texture2D texture;
// The bounds of the game piece. Used for hit testing.
private Rectangle bounds;
// The rotation of the game piece, in radians.
private float rotation;
// The scale, in percentage of the actual image size. 1.0 = 100%.
private float scale;
// The view port, used to detect when to bounce.
private Viewport viewport;
// The manipulation processor for this game piece.
private ManipulationProcessor2D manipulationProcessor;
// The inertia processor for this game piece.
private InertiaProcessor2D inertiaProcessor;
// Flag to indicate that inertia processing should start or continue.
private bool processInertia;
// Flag to indicate whether this piece has captured the mouse.
private bool isMouseCaptured;
// Used during manipulation to indicate where the drag is occurring.
private System.Windows.Point dragPoint;
// The color of the game piece.
private Color pieceColor;
// Represents how spongy the walls act when the piece bounces.
// Must be <= 1.0 (if greater than 1.0, the piece will accelerate on bounce)
// 1.0 = no slowdown during a bounce.
// 0.0 (or less) = won't bounce.
private float spongeFactor = 0.925f;
#endregion

خصائص عامة

ثلاثة من هؤلاء الأعضاء خاص يتعرض من خلال العام خصائص. تغيير الحجم والخصائص PieceColor بتمكين تطبيق إلى تحديد المقياس ولون القطعة، على التوالي. حدود خاصية هو إلى تمكين قطعة واحدة باستخدام حدود آخر لتقديم نفسه، على سبيل المثال عندما قطعة واحدة يجب تراكب آخر. يلي تعليمات برمجية يظهر إعلان الخصائص العامة.

#region PublicProperties
public float Scale
{
    get { return scale; }
    set 
    { 
        scale = value;
        bounds.Width = (int)(texture.Width * value);
        bounds.Height = (int)(texture.Height * value);
        // Setting X and Y (private properties) causes 
        // bounds.X and bounds.Y to adjust to the scale factor.
        X = X;
        Y = Y;
    }
}

public Color PieceColor
{
    get { return pieceColor; }
    set { pieceColor = value; }
}

public Rectangle Bounds
{
    get { return bounds; }
}
#endregion

الدالة الإنشائية للفئة

الدالة الإنشائية ل من GamePiece فئة تقبل المعلمات التالية:

  • نوع SpriteBatchSpriteBatch.DrawGraphicsDevice. تمرير المرجع هنا هو تعيينها إلى عضو خاص spriteBatch، و هو المستخدمة للوصول SpriteBatch.DrawGraphicsDevice الطريقة عندما يعرض قطعة اللعبة نفسها. بالإضافة إلى ذلك، GraphicsDevice خاصية هو يستخدم لإنشاء الكائن مادة المقترنة بقطعة اللعبة، والحصول على الحجم العرض منفذ للكشف عن عند مواجهة قطعة اللعبة حد إطار بحيث يمكن وثب القطعة.

  • سلسلة أحرف يحدد اسم الملف للصورة المطلوب استخدامها Game قطعة.

الدالة الإنشائية أيضا بإنشاء ManipulationProcessor2Dالكائن InertiaProcessor2Dالكائن، ثم قم بإنشاء معالجات الأحداث للأحداث الخاصة بهم.

يلي تعليمات برمجية يظهر المنشئ ل GamePiece الفئة.

#region Constructor
public GamePiece(SpriteBatch spriteBatch, string fileName)
{
    // For brevity, omitting checking of null parameters.
    this.spriteBatch = spriteBatch;

    // Get the texture from the specified file.
    texture = Texture2D.FromFile(spriteBatch.GraphicsDevice, fileName);

    // Initial position set to 0,0.
    position = new Vector2(0);

    // Set the origin to be the center of the texture.
    origin = new Vector2(texture.Width / 2.0f, texture.Height / 2.0f);

    // Set bounds. bounds.X and bounds.Y are set as the position or scale changes.
    bounds = new Rectangle(0, 0, texture.Width, texture.Height);

    // Create manipulation processor.
    Manipulations2D enabledManipulations =
        Manipulations2D.Translate | Manipulations2D.Rotate;
    manipulationProcessor = new ManipulationProcessor2D(enabledManipulations);

    manipulationProcessor.Pivot = new ManipulationPivot2D();
    manipulationProcessor.Pivot.Radius = texture.Width / 2;

    manipulationProcessor.MinimumScaleRotateRadius = 10.0f;

    manipulationProcessor.Started += OnManipulationStarted;
    manipulationProcessor.Delta += OnManipulationDelta;
    manipulationProcessor.Completed += OnManipulationCompleted;

    // Create inertia processor.
    inertiaProcessor = new InertiaProcessor2D();
    inertiaProcessor.Delta += OnInertiaDelta;
    inertiaProcessor.Completed += OnInertiaCompleted;

    inertiaProcessor.TranslationBehavior.DesiredDeceleration = 0.0001F;
    inertiaProcessor.RotationBehavior.DesiredDeceleration = 1e-6F;
    inertiaProcessor.ExpansionBehavior.DesiredDeceleration = 0.0001F;

    // Save the view port. Used to detect when the piece needs to bounce.
    viewport = spriteBatch.GraphicsDevice.Viewport;

    // Set the piece in a random location.
    Random random = new Random((int)Timestamp);
    X = random.Next(viewport.Width);
    Y = random.Next(viewport.Height);

    // Set a random orientation.
    rotation = (float)(random.NextDouble() * Math.PI * 2.0);

    dragPoint = new System.Windows.Point(double.NaN, double.NaN);
    pieceColor = Color.White;

    // Set scale to normal (100%)
    Scale = 1.0f;
}
#endregion

التقاط ماوس إدخال

UpdateFromMouse الطريقة هو المسؤولة عن عند اكتشاف أحد أزرار الماوس عند هو الضغط أثناء الماوس هو داخل حدود قطعة اللعبة، ولاكتشاف عندما تم إصداره بزر الماوس.

عند اليسار ماوس زر هو الضغط (ماوس أثناء هو داخل حدود قطعة)، th هو الأسلوب بتعيين علامة للإشارة إلى ذلك th هو قطعة لعبة تم التقاط ماوس، ويبدأ معالجة معالجة.

معالجة معالجة هو بدأ بإنشاء صفيفة من Manipulator2Dالكائنات وتمريرها إلى ManipulationProcessor2Dالكائن. يؤدي هذا المعالج معالجة إلى تقييم manipulaإلىrs (في هذه حالة manipulaإلىr مفرد)، ورفع معالجة الأحداث.

بالإضافة إلى ذلك، النقطة التي عندها يسحب هو حدوث يتم تم الحفظه. Th هو هو استخدامها فيما بعد أثناء Deltaحدث لضبط قيم ترجمة دلتا حيث swings قطعة اللعبة في سطر خلف يؤشر السحب.

وأخيراً، هذا أسلوب بإرجاع الولاية يلتقط ماوس. بما يمكن من Game PieceCollection كائن إدارة الالتقاط عند وجود عدة Game القطع.

إظهار التعليمة البرمجية التالية UpdateFromMouse الأسلوب.

#region UpdateFromMouse
public bool UpdateFromMouse(MouseState mouseState)
{
    if (mouseState.LeftButton == ButtonState.Released)
    {
        if (isMouseCaptured)
        {
            manipulationProcessor.CompleteManipulation(Timestamp);
        }
        isMouseCaptured = false;
    }

    if (isMouseCaptured ||
       (mouseState.LeftButton == ButtonState.Pressed &&
       bounds.Contains(mouseState.X, mouseState.Y)))
    {
        isMouseCaptured = true;

        Manipulator2D[] manipulators = new Manipulator2D[] 
        {
            new Manipulator2D(0, mouseState.X, mouseState.Y)
        };

        dragPoint.X = mouseState.X;
        dragPoint.Y = mouseState.Y;
        manipulationProcessor.ProcessManipulators(Timestamp, manipulators);
    }

    // If the right button is pressed, stop the piece and move it to the center.
    if (mouseState.RightButton == ButtonState.Pressed)
    {
        processInertia = false;
        X = viewport.Width / 2;
        Y = viewport.Height / 2;
        rotation = 0;
    }
    return isMouseCaptured;
}
#endregion

معالجة Manipulations

عند معالجة يبدأ، Startedحدث هو raهوed. المعالج لترتيب هو يتوقف حدث معالجة inertia إذا هو الحدوث، وقم بتعيين يؤشر processInertia false.

#region OnManipulationStarted
private void OnManipulationStarted(object sender, Manipulation2DStartedEventArgs e)
{
    if (inertiaProcessor.IsRunning)
    {
        inertiaProcessor.Complete(Timestamp);
    }
    processInertia = false;
}
#endregion

تغيير القيم المقترنة المعالجة، Deltaحدث هو raهوed. يستخدم معالج لهذا حدث القيم دلتا تمرير الوسيطات في حدث لإجراء تغييرات على الموضع والاستدارة القيم Game قطعة.

#region OnManipulationDelta
private void OnManipulationDelta(object sender, Manipulation2DDeltaEventArgs e)
{
    //// Adjust the position and rotation of the game piece.
    float deltaX = e.Delta.TranslationX;
    float deltaY = e.Delta.TranslationY;
    if (dragPoint.X != double.NaN || dragPoint.Y != double.NaN)
    {
        // Single-manipulator-drag-rotate mode. Adjust for drag / rotation
        System.Windows.Point center = new System.Windows.Point(position.X, position.Y);
        System.Windows.Vector toCenter = center - dragPoint;
        double sin = Math.Sin(e.Delta.Rotation);
        double cos = Math.Cos(e.Delta.Rotation);
        System.Windows.Vector rotatedToCenter =
            new System.Windows.Vector(
                toCenter.X * cos - toCenter.Y * sin,
                toCenter.X * sin + toCenter.Y * cos);
        System.Windows.Vector shift = rotatedToCenter - toCenter;
        deltaX += (float)shift.X;
        deltaY += (float)shift.Y;
    }

    X += deltaX;
    Y += deltaY;
    rotation += e.Delta.Rotation;
}
#endregion

عند تمت إزالته الجميع manipulators (في هذه حالة، manipulator مفرد) التي تقترن معالجة، يرفع المعالج معالجة Completedحدث. يبدأ معالج لهذا حدث معالجة بواسطة إعداد velocities الأولى للمعالج inertia inertia إلى التي أعدها الوسيطات حدث، ويقوم بتعيين processInertia يؤشر إلى true.

#region OnManipulationCompleted
private void OnManipulationCompleted(object sender, Manipulation2DCompletedEventArgs e)
{
    inertiaProcessor.TranslationBehavior.InitialVelocityX = e.Velocities.LinearVelocityX;
    inertiaProcessor.TranslationBehavior.InitialVelocityY = e.Velocities.LinearVelocityY;
    inertiaProcessor.RotationBehavior.InitialVelocity = e.Velocities.AngularVelocity;
    processInertia = true;
}
#endregion

معالجة Inertia

أثناء معالجة inertia extrapolates قيم الجديدة ل velocities خطية وزاوية، ضع الإحداثيات (الترجمة)، ودوران، Deltaحدث هو raهوed. يستخدم معالج لهذا حدث قيم دلتا تمرير الوسيطات في حدث لتعديل موضع واستدارة Game قطعة.

إذا نتج عن الإحداثيات الجديدة قطعة اللعبة بنقل خارج حدود منفذ العرض، يتم عكس السرعة النسبية لمعالجة inertia. يؤدي ذلك Game قطعة وثب إيقاف الحد منفذ العرض صادف.

لا يمكنك تغيير خصائص InertiaProcessor2Dالكائن أثناء هو يستخدم الاستكمال الخارجي. ولذلك، عندما عكس السرعة س أو ص، معالج الأحداث أولاً يتوقف inertia بواسطة استدعاء Complete()أسلوب. يقوم بتعيين قيم جديدة للسرعة الأولية إلى تكون قيم السرعة الحالي (تعديل سلوك sponge)، ويقوم بتعيين processInertia يؤشر إلى true.

يلي تعليمات برمجية يظهر معالج الأحداث ل Deltaحدث.

#region OnInertiaDelta
private void OnInertiaDelta(object sender, Manipulation2DDeltaEventArgs e)
{
    // Adjust the position of the game piece.
    X += e.Delta.TranslationX;
    Y += e.Delta.TranslationY;
    rotation += e.Delta.Rotation;

    // Check to see if the piece has hit the edge of the view port.
    bool reverseX = false;
    bool reverseY = false;

    if (X > viewport.Width)
    {
        reverseX = true;
        X = viewport.Width;
    }

    else if (X < viewport.X)
    {
        reverseX = true;
        X = viewport.X;
    }

    if (Y > viewport.Height)
    {
        reverseY = true;
        Y = viewport.Height;
    }

    else if (Y < viewport.Y)
    {
        reverseY = true;
        Y = viewport.Y;
    }

    if (reverseX || reverseY)
    {
        // Get the current velocities, reversing as needed.
        // If reversing, apply sponge factor to slow the piece slightly.
        float velocityX = e.Velocities.LinearVelocityX * ((reverseX) ? -spongeFactor : 1.0f);
        float velocityY = e.Velocities.LinearVelocityY * ((reverseY) ? -spongeFactor : 1.0f);
        // Must stop inertia processing before changing parameters.
        if (inertiaProcessor.IsRunning)
        {
            inertiaProcessor.Complete(Timestamp);
        }
        // Assign the new velocities.
        inertiaProcessor.TranslationBehavior.InitialVelocityX = velocityX;
        inertiaProcessor.TranslationBehavior.InitialVelocityY = velocityY;
        // Set flag so that inertia processing will continue.
        processInertia = true;
    }
}
#endregion

عند معالجة inertia هو إكمال raهوes المعالج inertia Completedحدث. يعين معالج لهذا حدث processInertia يؤشر إلى false.

#region OnInertiaCompleted
private void OnInertiaCompleted(object sender, Manipulation2DCompletedEventArgs e)
{
    processInertia = false;
}
#endregion

بلا منطق المقدمة حتى الآن يتسبب بالفعل الاستكمال الخارجي inertia إلى تحدث. Th هو هو accomplهوhed في ProcessInertia الأسلوب. Th هو الأسلوب، الذي هو تسمى تكرار من تكرار حلقي تحديث الألعاب ( Game.تحديث الطريقة) يقوم بالتأكد إذا علامة processInertia هو معينة إلى true، وإذا كان الأمر كذلك، باستدعاء Process()الأسلوب. استدعاء هذا الأسلوب يؤدي الاستكمال الخارجي إلى تحدث، ورفع Deltaحدث.

#region ProcessInertia
public void ProcessInertia()
{
    if (processInertia)
    {
        inertiaProcessor.Process(Timestamp);
    }
}
#endregion

قطعة اللعبة هو تقديم لا فعلياً إلى أن واحد التحميلات الزائدة أسلوب رسم هو المسمى. التحميل الزائد أول من القيم بالموضع هو أسلوب هو تسمى بشكل متكرر من حلقة اللعبة التعادل ( Game.Draw الأسلوب). يعرض هذا Game قطعة بالموضع الحالي واستدارة العوامل المقياس.

#region Draw
public void Draw()
{
    spriteBatch.Draw(
        texture, position,
        null, pieceColor, rotation,
        origin, scale,
        SpriteEffects.None, 1.0f);
}

public void Draw(Rectangle bounds)
{
    spriteBatch.Draw(texture, bounds, pieceColor);
}
#endregion

خصائص إضافى

تستخدم ثلاثة خصائص خاصة بواسطة من GamePiece فئة.

  1. timestamp $ $ $ $ – يحصل على القيمة طابع زمني إلى ليتم استخدامه بواسطة معالجات المعالجة و inertia.

  2. X-الحصول أو قم بتعيين علامة X إحداثيات لقطعة اللعبة. عند تعيين هذا الخيار، يقوم بضبط الحدود المستخدمة لاختبار الدخول و الموقع المحوري المعالج معالجة.

  3. Y-الحصول أو قم بتعيين الإحداثي ص Game قطعة. عند تعيين هذا الخيار، يقوم بضبط الحدود المستخدمة لاختبار الدخول و الموقع المحوري المعالج معالجة.

#region PrivateProperties
private long Timestamp
{
    get 
    {
        // Get timestamp in 100-nanosecond units.
        double nanosecondsPerTick = 1000000000.0 / System.Diagnostics.Stopwatch.Frequency;
        return (long)(System.Diagnostics.Stopwatch.GetTimestamp() / nanosecondsPerTick / 100.0);
    }
}

private float X
{
    get { return position.X; }
    set
    {
        position.X = value;
        manipulationProcessor.Pivot.X = value;
        bounds.X = (int)(position.X - (origin.X * scale));
    }
}

private float Y
{
    get { return position.Y; }
    set
    {
        position.Y = value;
        manipulationProcessor.Pivot.Y = value;
        bounds.Y = (int)(position.Y - (origin.Y * scale));
    }
}
#endregion

راجع أيضًا:

موارد أخرى

manipulations و Inertia

استخدام Manipulations و Inertia في تطبيق XNA

إنشاء في فئة GamePieceCollection

إنشاء في فئة Game1