Click here to Skip to main content
Click here to Skip to main content

Air Hockey: A fun game with two and single player mode for Ultrabooks.

By , 22 Oct 2012
 

Please note

This article is an entry in our AppInnovation Contest. Articles in this sub-section are not required to be full articles so care should be taken when voting.

Disclaimer

This article is an entry in our AppInnovation Contest. Articles in this sub-section are not required to be full articles so care should be taken when voting. 

Introduction 

Idea 

Air hockey is a game for two competing players trying to score points in the opposing player's goal.It is a multi touch game supporting both two player mode and Single player mode.Since the Ultrabooks provide a responsive touch experience so I decided to create a game which can take the benefit of the touch input not just only for  tapping  or dragging the mallets but as if playing on a real Air Hockey Table.  

 

 

Development Platform 

Here I have used C# ,  Farseer Physics Engine  and Visual Studio. As Windows 8 doesn't support XNA finding a proper physics engine in C# for Windows 8 was difficult. So I used Physics Helper XAML which uses Farseer Physics engine as its backbone.

Gameplay 

The mallet is gripped by touching and pressing in fingertips on top of it. this  helps the player to move the mallet around the table faster.

For basic defense, the mallet is kept near to the goal. In this position, very slight movements to the left and right will block virtually all straight shots. To block bank shots, one pulls back quickly to the corners of the goal. This is known as the "triangle defense".

Shots are often hit out of "drifts", where the puck travels in set patterns designed to throw off the opponent's expectations and timing. The First person to score 8 goals in opposite players goal becomes the winner.

 

 Ultrabook Features Used 

Ambient light sensor - for in-game visual change  

Touch sensor – for movement/interaction  

Location sensor - for social sharing in facebook.  

Background 

 To understand the code snippet and its use some knowledge with XNA and Farseer Physics Engine Can be Very Useful.

Creating physics bodies using Physics Helper( Whic uses Farseer Physics Engine) is very simple. 

To use Physics helper give the reference like in your XAML file  

    xmlns:ph="using:Spritehand.FarseerHelper"
    xmlns:local="using:*My.Project.Here*" 

 Then use the below code to create a physics Canvas and a static ground of darkgreen color 

and a rectangular body of physics sprite . 

 <Canvas x:Name="cnvGameOuter"  >
 
    <ph:PhysicsCanvas x:Name="cnvGame" Background="Blue"  Width="1366" Height="768" MousePickEnabled="true">
 
        <ph:PhysicsSprite x:Name="block" Canvas.Left="200" Canvas.Top="0"  Width="100" Height="100" >
            <Rectangle Width="100" Height="100" Fill="Red" />
        </ph:PhysicsSprite>
 
        <ph:PhysicsSprite x:Name="ground" Background="DarkGreen"  Canvas.Left="0" Canvas.Top="648"  Width="1366" Height="120" IsStatic="True" />
 
    </ph:PhysicsCanvas>
 
</Canvas>

In our game the main game screen is rendered on a Physics canvas Similar to the above one and other objects like Mallets and Puck has been designed using The Physics Sprite of Physics helper. 

To have a more detail knowledge I suggest to go through the documentation of physic helper at:

http://physicshelperxaml.codeplex.com/documentation 

Using the code

Once all the elements ( Physics Sprites) on your canvas( Physics canvas Mentioned above) are placed properly 

then We need to add interactivity like collisions and Control of the mallets and puck, like their movement ,speed 

and response.

So we will be writing codes  to manipulate the above tasks in C#.  

like 

void controller_Initialized(object source)
        {
            _playerPaddle = _physicsController.PhysicsObjects[_elemPaddlePlayer]; // "paddlePlayer"
            _cpuPaddle = _physicsController.PhysicsObjects[_elemPaddleCpu];       // "paddleCpu"
            _puck = _physicsController.PhysicsObjects[_elemPuck];                 // "puck"

            _playerPaddle.BodyObject.LinearDamping = 30.0f;
            _playerPaddle.BodyObject.AngularDamping = 30.0f;
           
            _cpuPaddle.BodyObject.LinearDamping = 1.0f;
            _playerPaddle.BodyObject.AngularDamping = 30.0f;
           
            _playerPaddle.ManipulationStarted += new EventHandler<ManipulationStartedEventArgs>(Paddle_ManipulationStarted);
            _playerPaddle.ManipulationCompleted += new EventHandler<ManipulationCompletedEventArgs>(Paddle_ManipulationCompleted);
            _cnvGame.MouseMove += new MouseEventHandler(cnvTable_MouseMove);


            _levelManager = new LevelManager(_physicsController, _cnvGame);
            _levelManager.LoadLevel(LevelManager.LevelCurrentNum);
            
            _soundManager = new SoundManager(_cnvGame);
            _scoreManager = new ScoreManager(_tbPlayerScore, _tbCpuScore);

            _enemyAIManager = new EnemyAIManager(_physicsController, _cpuPaddle, _puck, _physicsController.PhysicsObjects["goalPlayer"]);

        }

        void controller_TimerLoop(object source)
        {
            _enemyAIManager.ProcessAI();
            
        }


void controller_Collision(PhysicsSprite sprite1, PhysicsSprite sprite2)
        {
            // puck collisions
            if (sprite1 == _puck)
            {
                if (sprite2 == _playerPaddle)
                    _soundManager.PlaySound(SoundManager.SoundList.PaddleHitsPuck);
                else
                    if (sprite2 == _cpuPaddle)
                        _enemyAIManager.HandlePuckCollision();
                    else
                        if (sprite2.Name.StartsWith("boundary"))
                            _soundManager.PlaySound(SoundManager.SoundList.PaddleHitsWall);
                        else
                            if (sprite2.Name.ToLower().StartsWith("goalplayer"))
                            {
                                _scoreManager.PlayerScore++;
                                _soundManager.PlaySound(SoundManager.SoundList.Score);
                                _soundManager.PlaySound(SoundManager.SoundList.Applause);
                                ResetPuck();
                            }
                            else
                                if (sprite2.Name.ToLower().StartsWith("goalcpu"))
                                {
                                    _scoreManager.CpuScore++;
                                    _soundManager.PlaySound(SoundManager.SoundList.Score);
                                    ResetPuck();
                                }
            }

          
        }

What the above code Does: 

In void controller_Initialized(object source){...} , all the controls for the Player as well as Enemy and the puck is initialized then the a timer loop is created for the enemey AI processing when played in single player mode against CPU.

Then in the next we detect the collision among physics sprites and update the scores of each player .

In the code we have used some other classes like  

evelManager : for defining levels such as Easy , Normal and Hard  

soundManager : For Game Play sound

enemyAiManager: Ai for CPU opponent used for the complete development of the game. 

Points of Interest

Developing  a 2d game with physics properties which uses the device sensor data for Windows 8 in C# is little  challenging then I imagined, before I started coding for this  Game.I wish Windows 8 supported XNA, but any way I was able to solve all the physics issues using Physics helper which is very light weight and easy to integration. And at the end of the development of this game I was also able to port a windows phone game I originally wrote using C# And Physics Helper in the same way integrating the Physics helper XAML.

I believe these links may interest you:

http://physicshelperxaml.codeplex.com/documentation

http://msdn.microsoft.com/library/windows/apps/

http://msdn.microsoft.com/en-us/library/windows/apps/hh465136.aspx 

 

Thank you for reading this article. Hope you are benefited by reading it. Ratings and Feedback are most welcome for improvements in future.

Thank you again.   

License

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

About the Author

Sanjay_Kumar Jena
Software Developer
India India
Member
No Biography provided

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
GeneralMy vote of 5 PinmemberSanjay_Kumar Jena23 Oct '12 - 3:49 
QuestionAir Hockey is a Windows Metro App PinmemberSanjay_Kumar Jena22 Oct '12 - 20:32 
QuestionWhich flavour? PinadminChris Maunder22 Oct '12 - 19:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 22 Oct 2012
Article Copyright 2012 by Sanjay_Kumar Jena
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid