Posts Tagged with Elastic Collision

Confined collisions with a dose of gravity

Over the past few months I have created a handful of Silverlight 2 examples that demonstrate basic physics. In this example I am going to demonstrate containment of a variable number of spheres with gravity causing deceleration.  Below you see a simple Grid which I will place a set number of spheres within.  Each sphere will be inserted into the grid at a randomized X position, within the top 20 pixels of the container.  Each sphere drop immediately and react to any collision with the container or other spheres elastically.

If you run this a few times you are bound to find it freak out. I am still in the process of tracking down why on a occasion it appears get lost and the spheres disapear.

Code: GravitationalCollisions.zip

Silverlight 2 MVC Game Framework

Last week I presented a session at DesertCodeCamp 2008 on Developing Casual Games with Silverlight 2. Excluding some technical difficulties, getting my MacBook to connect to dual projectors, the presentation went well. There is certainly interest in the community to begin using Silverlight as a casual gaming platform.

The goal of this presentation was to create a more “developer” focused exploration into a development architecture one could use for building a casual game. In this example, one which leverages pixel-based movement. As with everything in development, there is no real right or wrong architecture, just proven patterns, that have proven scalability, flexibility and efficiency.

Concept

Build a simple game where a player has to move around a box and avoid a series of randomly moving spheres. Each sphere can collide with both the bounds of the box, each other and the player. The player can only be collided with 5 times or the game is over. Player movement is controlled by hitting a combination of arrow keys which changes the vector angle of the players movement. The players speed is consistent, until that player collides with one of the spheres. The behavior of the collision will change based on the element being collided with..

Framework

Last fall Microsoft released its first version of the Model-View-Controller (MVC) framework for ASP.NET as a way to help developers implement this proven separation pattern into ASPX site design. If you have not got a chance to use I strongly recommend giving it a try.

VS 2008 SolutionAt a very high level MVC divides an application’s implementation into three components: models, views, and controller. This “separation” is used specifically as a way to improve a developers ability to decouple the presentation layer from the business logic. In game development, MVC is an excellent way to build a foundation which simplifies a developers ability to control state such as movement and collision detection. Unfortunately a formal MVC framework does not exist for Silverlight 2, but implementing the pattern is pretty simple. The image to left illustrates how I have implemented the MCV pattern in my example project.

Exploring further you will see that I do not consider “page.xaml” a view. This is intentional. page.xaml is simply a way to get my controller instantiated. All game elements will be inserted into my “Shell.xaml” view by my controller, and this UserControl will be inserted into the page’s LayoutRoot after the page’s xaml has been loaded. My controller will get a reference to this root UIElement via constructor dependency injection, a common approach seen in MVC implementations. Here is the code found within page.xaml.cs.


public partial class Page : UserControl
{
    private Controllers.Controller _controller
    private Views.Shell _shell = new Views.Shell()
    public Views.Shell Shell
    {
        get { return _shell }
        set { _shell = value }
    }
 
    public Page()
    {
        InitializeComponent()
        this.Loaded += new RoutedEventHandler(Page_Loaded)
    }
 
    void Page_Loaded(object sender, RoutedEventArgs e)
    {
        LayoutRoot.Children.Add(_shell)
        _controller = new Controllers.Controller(this)
        _controller.Initialize()
    }
}

Controller

In this game I have a single controller which acts as the central nervous system of my game. It controls the following:

  • Primary game timer (tick)
    • Moves Player, Balls and checks for Collisions
  • Inserts the appropriate dialogs and listens to events from each
    • Start, End, Next Level
  • Listening for events from my primary model
    • Collision, NextLevel, GameOver and StopMovement
  • Captures the approriate keyboard inputs
    • Left, Right, Up, Down, Left-Up, Left-Down, Right-Up, Right-Down

Game Model

The controller instantiates and holds a reference to my primary game model which will maintain the games state and expose any methods used to interact with the “Player” and “Hazards” [ball]). The model is the single places that knows how to start a level, insert the player and place each of the balls into a level. When events occur like the player collides with a ball, the model fires an event to the controller indicating what transpired. The controller decides what this means visually to the game play (updates the “Shell” to indicate a new Hit count). The model maintains state so it will be responsible for deciding when the game is over. A game is over when either time has expired (15 seconds) or five collisions have occurred. As with a collision, the model will fire an event to the controller when the game is over.

Behaviors

Part of building this sample was to build upon some of the previous work I have done on spherical collisions. Is previous posts, I have shown how to react to both an elastic and inelastic collision. In this example I refer to elastic behavior as “Deflect” and inelastic as “Bump”. The idea is that if I build an object oriented methodology of defining collision behavior, one based on inheritance, I can expand the types of hazards as I develop new behaviors. For example, the next behavior I intend to develop is one which hazards chases the player, when the hazard gets within a specified proximity of the player.

Here is the game and source.

Code: CodeCampGame.zip

Spherical elastic and inelastic collisions in Silverlight

I recently took an interest in using some very basic physics within Silverlight 2. I took physics nearly 12 years ago and am certainly rusty, but thought it would be fun to simulate he effect two spheres have when they collide. Their are two types of collision; a perfectly elastic collision where there is no lose in kinetic energy and an inelastic collision where some or all of the kinetic energy is converted into internal energy.   In the example below I try to demonstrate both types of collision along with a form of inelastic collision I call magnetic where upon collision energy is transferred in the direction of the collision and the sphere attaches itself to the object it is colliding with.

I am pretty certain I am taking some liberties with accuracy of each collision, but nonetheless one can see the effect two spheres have on momentum.  Interestingly, if you allow the demo to run long enough most if not all of the balls will stop colliding. The first thing I needed to do to create my sample was to create a UserControl that would represent my sphere. Within this control I created a series of properties and two public Method: “Move()” and “Collision()”. Since each sphere will move through my container the same way, I can encapsulate this logic within the control itself. Here is that code.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public void Move(Rect bounds)
{
    //add the current vector to each X/Y 
    this.X += this.VX
    this.Y += this.VY
 
    //check to see if this sphere has collided with an adjacent wall
    //if so, then reverse its vector.  Since my bounding box is definable 
    //pass in a Rect struct
 
    //check the left and the right of the bound box
    if (this.X &lt bounds.X &amp&amp this.VX &lt 0)
        this.VX = -this.VX
 
    if(this.X &gt (bounds.Right-this.Distance) &amp&amp this.VX &gt 0)
        this.VX = -this.VX
 
    //check the top and the bottom
    if (this.Y &lt bounds.Y &amp&amp this.VY &lt 0)
        this.VY = -this.VY
 
    if(this.Y &gt (bounds.Bottom-this.Distance) &amp&amp this.VY &gt 0)
        this.VY = -this.VY
 
    //move this sphere to its new X,Y position
    _translate.X = this.X
    _translate.Y = this.Y
}

Since my container floats in the center of my Page.xaml I use a “Rect” struct to hold the X,Y, Width and Height of the UIElement that that will confine the spheres. I pass this “Rect” as an argument. Depending on the surface that the object is colliding with, I move the sphere and reverse the vector by either adding or subtracting itself from VX or VY. In addition to determining how itself moves, the sphere I also determines the effect of a collision. This method is pretty big, but is broken down into four sections. The first determines the time in which the two spheres collide where is the remaining determine the effect of each type of collision.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
public bool Collision(Sphere s)
{
    // find the time when the two spheres really collide with each other.
    double dx = (this.X + this._radius) - (s.X + s.Radius)
    double dy = (this.Y + this._radius) - (s.Y + s.Radius)
 
    //calculate the distance between two balls 
    double distance = dx * dx + dy * dy
    double distanceSqrt = Math.Sqrt(distance)
 
    double dvx = this.VX - s.VX
    double dvy = this.VY - s.VY
 
    if (distanceSqrt &gt (this._radius + s.Radius))
        return false
    //There are two basic kinds of collisions, elastic and inelastic:
    //if an elastic collision occurs send both spheres rebounding backwards
    //with no loss in total kinetic energy.
 
    //Note: since both of our spheres have the same mass the only way to determine 
    //which type of collision will occur is to look at velocity.
    double collision = 0.0
    if (this.CollisionType == CollisionTypes.Elastic  
	s.CollisionType == CollisionTypes.Elastic)
    {
        collision = dvx * dx + dvy * dy
        if (collision &gt 0)
            return false
 
        collision /= distance
 
        double deltaVX = dx * collision
        double deltaVY = dy * collision
 
        //deflect this sphere
        this._vx -= deltaVX
        this._vy -= deltaVY
        //deflect the sphere that was part of the collision
        s.VX += deltaVX
        s.VY += deltaVY
    }
    //if a partial inelastic collision occurs the spheres collide and some 
    //kinetic energy is lost...both masses decelerate
    else if(this.CollisionType == CollisionTypes.Inelastic  
	s.CollisionType == CollisionTypes.Inelastic)
    {
        collision = dvx * dx + dvy * dy
        if (collision &gt 0)
            return false
 
        collision /= distance*2
 
        double deltaVX = dx * collision
        double deltaVY = dy * collision
 
        //deflect this sphere
        this._vx -= deltaVX
        this._vy -= deltaVY
        //deflect the sphere that was part of the collision
        s.VX += deltaVX
        s.VY += deltaVY
    }
    //if a magnetic collision occurs we would have a perfectly inelastic collision
    else if (this.CollisionType == CollisionTypes.Magnetic &amp&amp 
	s.CollisionType == CollisionTypes.Magnetic)
    {
        //the sphere causing the collision will continue its forward momentum 
        //attaching itself to the adjacent sphere
        s.VX = this.VX
        s.VY = this.VY
    }
    return true
}

Code: SphericalCollision.zip