Click here to Skip to main content
12,692,778 members (36,681 online)
Click here to Skip to main content

Tagged as

Stats

266.3K views
5.5K downloads
176 bookmarked
Posted

WPF Grand Prix

, 14 Dec 2010 CPOL
An article showing how to create a race game using the powerful WPF capabilities
GrandPrix.exe
GrandPrix.exe.manifest
GrandPrix.pdb
GrandPrix.vshost.application
GrandPrix.vshost.exe
GrandPrix.vshost.exe.manifest
Images
ChequerLine.PNG
Grass.png
GrandPrix.application
GrandPrix
bin
Debug
GrandPrix.application
GrandPrix.exe
GrandPrix.exe.manifest
GrandPrix.vshost.application
GrandPrix.vshost.exe
GrandPrix.vshost.exe.manifest
Images
ChequerLine.PNG
Grass.png
Thumbs.db
Release
GrandPrix.application
GrandPrix.exe
GrandPrix.exe.manifest
GrandPrix.pdb
Images
ChequerLine.PNG
Grass.png
Circuits
F1.csproj.user
GrandPrix.csproj.user
GrandPrix_TemporaryKey.pfx
Images
Asphalt.png
ChequeredFlag.PNG
ChequerLine.PNG
CodeProject.gif
Grass.png
Icon.png
StartingGrid.png
Properties
TrackSegments
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
//using System.Windows.Media.Effects;
using GrandPrix.TrackSegments;

namespace GrandPrix
{
    /// <summary>
    /// Interaction logic for Kart.xaml
    /// </summary>
    public partial class Kart : UserControl
    {
        #region attributes
        public static DependencyProperty WheelAngleProperty = DependencyProperty.Register("WheelAngle", typeof(double), typeof(Kart), new PropertyMetadata(new PropertyChangedCallback(WheelAngleChanged)));
        public static DependencyProperty BodyColor1Property = DependencyProperty.Register("BodyColor1", typeof(Color), typeof(Kart), new PropertyMetadata(new PropertyChangedCallback(BodyColor1Changed)));
        public static DependencyProperty BodyColor2Property = DependencyProperty.Register("BodyColor2", typeof(Color), typeof(Kart), new PropertyMetadata(new PropertyChangedCallback(BodyColor2Changed)));
        public static DependencyProperty BodyColor3Property = DependencyProperty.Register("BodyColor3", typeof(Color), typeof(Kart), new PropertyMetadata(new PropertyChangedCallback(BodyColor3Changed)));
        public static DependencyProperty MaxSpeedProperty = DependencyProperty.Register("MaxSpeed", typeof(double), typeof(Kart), new PropertyMetadata(new PropertyChangedCallback(MaxSpeedChanged)));
        double maxSpeed = 10.0;

        #endregion attributes

        #region ctor
        public Kart()
        {
            InitializeComponent();

            CarToTrackDistanceList = new List<double>();
            ShortestDistance = 10000.0;
            LastDistance = 10000.0;
            CarGroundType = GroundType.Asphalt;
            RangeEllipseList = new List<Ellipse>();

            //ShadowEffect = new DropShadowBitmapEffect()
            //{
            //    Color = Colors.Black,
            //    Direction = 0,
            //    ShadowDepth = 25,
            //    Softness = 2,
            //    Opacity = 0.5
            //};

            //this.BitmapEffect = ShadowEffect;

            CurrentSegmentOffset = 0.0;

            Speed = 0.0;
            Velocity2D = new Vector(0.0, 0.0);
            Laps = 0;
        }
        #endregion ctor

        #region properties
        public double WheelAngle
        {
            get { return (double)GetValue(WheelAngleProperty); }
            set { SetValue(WheelAngleProperty, value); }
        }

        public double MaxSpeed
        {
            get { return (double)GetValue(MaxSpeedProperty); }
            set { SetValue(MaxSpeedProperty, value); }
        }

        public Color BodyColor1
        {
            get { return (Color)GetValue(BodyColor1Property); }
            set { SetValue(BodyColor1Property, value); }
        }

        public Color BodyColor2
        {
            get { return (Color)GetValue(BodyColor2Property); }
            set { SetValue(BodyColor2Property, value); }
        }

        public Color BodyColor3
        {
            get { return (Color)GetValue(BodyColor3Property); }
            set { SetValue(BodyColor3Property, value); }
        }

        public ScaleTransform CarScaleTransform { get; set; }
        public TranslateTransform CarTranslateTransform { get; set; }
        public RotateTransform CarRotateTransform { get; set; }
        public double Acceleration { get; set; }
        public double Speed { get; set; }
        public Vector Velocity2D { get; set; }
        //public DropShadowBitmapEffect ShadowEffect { get; set; }
        public List<double> CarToTrackDistanceList { get; set; }
        public List<Ellipse> RangeEllipseList { get; set; }
        public TrackLineSegment LastNearestTrackLineSegment { get; set; }
        public TrackLineSegment NearestTrackLineSegment { get; set; }
        public double ShortestDistance { get; set; }
        public double LastDistance { get; set; }
        public GroundType CarGroundType { get; set; }

        public double CircuitOffset { get; set; }
        public int CurrentSegmentIndex { get; set; }
        public double CurrentSegmentOffset { get; set; }

        public bool IsTurningLeft { get; set; }
        public bool IsTurningRight { get; set; }
        public bool IsSpeedingUp { get; set; }
        public bool IsSlowingDown { get; set; }

        public int Index { get; set; }
        public int Laps { get; set; }
        public string PilotName { get; set; }

        #endregion properties

        #region methods
        public bool IsColliding(Kart other)
        {
            bool ret = false;

            var dX = other.CarTranslateTransform.X - this.CarTranslateTransform.X;
            var dY = other.CarTranslateTransform.Y - this.CarTranslateTransform.Y;
            var h = Math.Sqrt(dX * dX + dY * dY);

            ret = (h < 40);

            return ret;
        }

        public void ResolveCollision(Kart other)
        {
            Vector position = new Vector(this.CarTranslateTransform.X, this.CarTranslateTransform.Y);
            Vector otherPosition = new Vector(other.CarTranslateTransform.X, other.CarTranslateTransform.Y);

            // get the mtd
            Vector delta = (position - otherPosition);
            double d = delta.Length;
            // minimum translation distance to push balls apart after intersecting
            var radius = 40.0;

            Vector mtd = delta * ((float)(((radius + 1.0 + radius + 1.0) - d) / d));

            // resolve intersection --
            // inverse mass quantities
            float im1 = 0.1f;
            float im2 = 0.1f;

            // push-pull them apart based off their mass
            position = position + ((mtd * (im1 / (im1 + im2))));
            otherPosition = otherPosition - (mtd * (im2 / (im1 + im2)));

            // impact speed
            var rad = (this.CarRotateTransform.Angle % 360.0) / (2.0 * Math.PI);
            var translateVelocity = new Vector(this.Speed * Math.Cos(rad) + this.Velocity2D.X, this.Speed * Math.Sin(rad) + this.Velocity2D.Y);
            var otherTranslateVelocity = new Vector(other.Speed * Math.Cos(rad) + other.Velocity2D.X, other.Speed * Math.Sin(rad) + other.Velocity2D.Y);
            Vector v = (translateVelocity - (otherTranslateVelocity));
            Vector mtdNormalize = new Vector(mtd.X, mtd.Y);
            mtdNormalize.Normalize();
            double vn = Vector.CrossProduct(v, mtdNormalize);

            // collision impulse
            Vector impulse = mtd * (0.05);

            // change in momentum
            translateVelocity = translateVelocity + (impulse * (im1));
            otherTranslateVelocity = otherTranslateVelocity - (impulse * (im2));


            this.CarTranslateTransform.X = position.X;
            this.CarTranslateTransform.Y = position.Y;
            other.CarTranslateTransform.X = otherPosition.X;
            other.CarTranslateTransform.Y = otherPosition.Y;

            this.Velocity2D = translateVelocity;
            other.Velocity2D = otherTranslateVelocity;

            var angleDiff = this.CarRotateTransform.Angle - other.CarRotateTransform.Angle;

            this.CarRotateTransform.Angle += angleDiff;
            other.CarRotateTransform.Angle += angleDiff;
        }

        #endregion methods

        #region events
        public static void WheelAngleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Kart kart = d as Kart;
            kart.LeftWheelRotation.Angle =
            kart.RightWheelRotation.Angle = (double)e.NewValue;
        }
        public static void MaxSpeedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Kart kart = d as Kart;
            kart.MaxSpeed = (double)e.NewValue;
        }
                
        public static void BodyColor1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Kart kart = d as Kart;
            kart.bodyColorGradient1.Color = (Color)e.NewValue;
            kart.bodyColorGradient5.Color = (Color)e.NewValue;
        }

        public static void BodyColor2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Kart kart = d as Kart; 
            kart.bodyColorGradient2.Color = (Color)e.NewValue;
            kart.bodyColorGradient4.Color = (Color)e.NewValue;
        }

        public static void BodyColor3Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            Kart kart = d as Kart;
            kart.bodyColorGradient3.Color = (Color)e.NewValue;
            kart.mirrors.Fill = new SolidColorBrush((Color)e.NewValue);
        }
        #endregion events
    }
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author


You may also be interested in...

| Advertise | Privacy | Terms of Use | Mobile
Web01 | 2.8.170118.1 | Last Updated 15 Dec 2010
Article Copyright 2010 by Marcelo Ricardo de Oliveira
Everything else Copyright © CodeProject, 1999-2017
Layout: fixed | fluid