├── Licence.txt ├── README.md ├── WPDrumkit.sln ├── WPDrumkit ├── WPDrumkit │ ├── AnimatedToggleButton.cs │ ├── Background.png │ ├── Button.cs │ ├── Cymbal.cs │ ├── Drum.cs │ ├── DrummingView.cs │ ├── DrumsetView.cs │ ├── Game.ico │ ├── GameThumbnail.png │ ├── InfoOverlay.cs │ ├── InputState.cs │ ├── Main.cs │ ├── Pad.cs │ ├── PadView.cs │ ├── PercussionItem.cs │ ├── PercussionMenu.cs │ ├── Program.cs │ ├── Properties │ │ ├── AppManifest.xml │ │ ├── AssemblyInfo.cs │ │ └── WMAppManifest.xml │ ├── Recorder.cs │ ├── ToggleButton.cs │ ├── View.cs │ ├── Visual.cs │ └── WPDrumkit.csproj └── WPDrumkitContent │ ├── Audio │ ├── china.wav │ ├── cowbell.wav │ ├── crash.wav │ ├── hihat1.wav │ ├── hihat2.wav │ ├── kick.wav │ ├── ride1.wav │ ├── ride2.wav │ ├── snare.wav │ ├── splash.wav │ ├── tom1.wav │ ├── tom2.wav │ └── tom3.wav │ ├── Images │ ├── Buttons │ │ ├── drumset.png │ │ ├── drumset_pressed.png │ │ ├── exit.png │ │ ├── exit_pressed.png │ │ ├── info.png │ │ ├── info_pressed.png │ │ ├── pads.png │ │ ├── pads_pressed.png │ │ ├── play.png │ │ ├── play_pressed.png │ │ ├── record.png │ │ ├── record_pressed.png │ │ ├── recording.png │ │ ├── stop.png │ │ └── stop_pressed.png │ ├── Drumset │ │ ├── background.png │ │ ├── china.png │ │ ├── cowbell.png │ │ ├── crash.png │ │ ├── hihat_closed.png │ │ ├── hihat_open_lower.png │ │ ├── hihat_open_upper.png │ │ ├── kick.png │ │ ├── locks.png │ │ ├── ride1.png │ │ ├── ride2.png │ │ ├── snare.png │ │ ├── splash.png │ │ ├── tom1.png │ │ ├── tom2.png │ │ └── tom3.png │ ├── Menu │ │ ├── china.png │ │ ├── china_highlight.png │ │ ├── close.png │ │ ├── cowbell.png │ │ ├── cowbell_highlight.png │ │ ├── crash.png │ │ ├── crash_highlight.png │ │ ├── hihat1.png │ │ ├── hihat1_highlight.png │ │ ├── hihat2.png │ │ ├── hihat2_highlight.png │ │ ├── kick.png │ │ ├── kick_highlight.png │ │ ├── ride1.png │ │ ├── ride1_highlight.png │ │ ├── ride2.png │ │ ├── ride2_highlight.png │ │ ├── snare.png │ │ ├── snare_highlight.png │ │ ├── splash.png │ │ ├── splash_highlight.png │ │ ├── tom1.png │ │ ├── tom1_highlight.png │ │ ├── tom2.png │ │ ├── tom2_highlight.png │ │ ├── tom3.png │ │ └── tom3_highlight.png │ ├── bg_pads.png │ └── splash.png │ ├── SegoeWPText.spritefont │ └── WPDrumkitContent.contentproj ├── WPDrumkit_v1_2.xap └── doc ├── drumkit.png ├── screenshot1.png ├── screenshot2.png ├── sprite.png └── wheel.png /Licence.txt: -------------------------------------------------------------------------------- 1 | Copyright © 2012-2014 Microsoft Mobile Oy. All rights reserved. 2 | 3 | Microsoft is a registered trademark of Microsoft Corporation. Nokia and HERE are 4 | trademarks and/or registered trademarks of Nokia Corporation. Other product and 5 | company names mentioned herein may be trademarks or trade names of their 6 | respective owners. 7 | 8 | 9 | License 10 | 11 | Subject to the conditions below, you may use, copy, modify and/or merge copies 12 | of this software and associated content and documentation files (the ”Software”) 13 | to test, develop, publish, distribute, sub-license and/or sell new software 14 | derived from or incorporating the Software, solely in connection with Microsoft 15 | Mobile devices (however branded). Some of the documentation, content and/or 16 | software may be licensed under open source software or other licenses. To the 17 | extent such documentation, content and/or software are included, those licenses 18 | and/or other terms and conditions shall apply in addition and/or instead of this 19 | notice. The exact terms of the licenses, disclaimers, acknowledgements and 20 | notices are reproduced in the materials provided, or in other obvious locations. 21 | No other license to any other intellectual property rights is granted herein. 22 | 23 | This file, unmodified, shall be included with all copies or substantial portions 24 | of the Software that are distributed in source code form. 25 | 26 | The Software cannot constitute the primary value of any new software derived 27 | from or incorporating the Software. 28 | 29 | Any person dealing with the Software shall not misrepresent the source of the 30 | Software. 31 | 32 | 33 | Disclaimer 34 | 35 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 36 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 37 | FOR A PARTICULAR PURPOSE, QUALITY AND NONINFRINGEMENT. IN NO EVENT SHALL THE 38 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES (INCLUDING, 39 | WITHOUT LIMITATION, DIRECT, SPECIAL, INDIRECT, PUNITIVE, CONSEQUENTIAL, 40 | EXEMPLARY AND/ OR INCIDENTAL DAMAGES) OR OTHER LIABILITY, WHETHER IN AN ACTION 41 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 42 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 43 | 44 | Microsoft Mobile Oy retains the right to make changes to this document at any 45 | time, without notice. 46 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Drumkit XNA 2 | =========== 3 | 4 | Drumkit XNA is a virtual drumkit that lets you play percussion sounds by 5 | tapping sound pads. The application contains two views for playing, a simple 6 | view with 2D pads and a whole 3D like drumset to play with. You can record 7 | your beats and play them back afterwards. It is also possible to play the 8 | drums on top of your last recording. The application has been developed purely 9 | on top of XNA with Microsoft Visual Studio 2010 Express for Windows Phone and 10 | tested to work on Nokia Lumia 800. 11 | 12 | Even though XNA Framework apps cannot be compiled or upgraded to target 13 | Windows Phone OS 8.0, XNA Game Studio 4.0 apps that target Windows Phone 14 | OS 7.1 remain fully supported and continue to run on Windows Phone 8 devices. 15 | Compatibility with Windows Phone 8 has been verified using Microsoft Visual 16 | Studio Express 2012 for Windows Phone and Nokia Lumia 820 and Nokia Lumia 920 17 | devices. 18 | 19 | ![Combined screenshots](doc/drumkit.png?raw=true) 20 | 21 | The application has been ported from Java Drumkit example, available at 22 | http://www.developer.nokia.com/info/sw.nokia.com/id/1fe81968-abbf-48d1-a137-a203094611b2/MIDP_Java_Drumkit_Example_v1_0_en.zip.html 23 | At the same time, also a Qt version has been developed for Symbian and Nokia 24 | N9 devices, available at: 25 | http://www.developer.nokia.com/info/sw.nokia.com/id/57f87a44-0408-41c5-9d60-e2491d6793fb/Drumkit.html 26 | 27 | This example application is hosted in GitHub: 28 | https://github.com/Microsoft/drumkit-wp 29 | 30 | For more information on implementation and porting, visit the wiki pages: 31 | https://github.com/Microsoft/drumkit-wp/wiki 32 | 33 | This project is compatible with Windows Phone 7 and Windows Phone 8 devices. 34 | 35 | 36 | What's new in version 1.2 37 | ------------------------- 38 | 39 | * Removed dependency to Nokia Pure Text font. 40 | 41 | 42 | 1. Instructions 43 | -------------------------------------------------------------------------------- 44 | 45 | Before building the project, make sure you have the following installed: 46 | * Windows 7 or later 47 | * Microsoft Visual Studio 2010 Express for Windows Phone 48 | * The Windows Phone Developer Tools January 2011 Update: 49 | http://download.microsoft.com/download/6/D/6/6D66958D-891B-4C0E-BC32-2DFC41917B11/WindowsPhoneDeveloperResources_en-US_Patch1.msp 50 | * Windows Phone Developer Tools Fix: 51 | http://download.microsoft.com/download/6/D/6/6D66958D-891B-4C0E-BC32-2DFC41917B11/VS10-KB2486994-x86.exe 52 | * Compatibility with Windows 8 and Microsoft Visual Studio Express 2012 for 53 | Windows Phone has been verified 54 | 55 | **Building:** 56 | 57 | 1. Open the SLN file: File > Open Project, select the file `WPDrumkit.sln`. 58 | 2. Select the target, for example 'Windows Phone 7 Emulator'. 59 | 3. Press F5 to build the project and run it on the Windows Phone Emulator. 60 | 61 | **Deploying to phone:** 62 | 63 | Please see official documentation for deploying and testing applications on 64 | Windows Phone devices: 65 | http://msdn.microsoft.com/en-us/library/gg588378%28v=vs.92%29.aspx 66 | 67 | 68 | 2. Implementation 69 | -------------------------------------------------------------------------------- 70 | 71 | **Folders:** 72 | 73 | * The root folder contains the project file, the license information and this file (README.md). 74 | * `WPDrumkit`: Root folder for the implementation files. 75 | * `Properties`: Application property files. 76 | * `WPDrumkitContent`: Root folder for the application content, font file. 77 | * `Audio`: Audio files. 78 | * `Images`: Root folder for images, background & splash screen. 79 | * `Buttons`: Button graphics 80 | * `Drumset`: Drumset graphics 81 | * `Menu`: Menu graphics 82 | 83 | **Important files and classes:** 84 | 85 | | File | Description | 86 | | ---- | ----------- | 87 | | `PadView.cs` | Class that controls the functionality of pad view. | 88 | | `DrumsetView.cs` | Class that controls the functionality of drumset view. | 89 | | `Pad.cs` | Class responsible of playing the sounds. | 90 | | `Recorder.cs` | Records the drum strokes. | 91 | 92 | 93 | 3. License 94 | -------------------------------------------------------------------------------- 95 | 96 | See the license text file delivered with this project. The license file is also 97 | available online at 98 | https://github.com/Microsoft/drumkit-wp/blob/master/Licence.txt 99 | 100 | 101 | 4. Version history 102 | ------------------------------------------------------------------------------- 103 | 104 | * Version 1.2.0: Removed dependency to Nokia Pure Text font 105 | * Version 1.1.0: First publication at developer.nokia.com based on 1.0.1 release 106 | * Version 1.0.1: Refactoring, comments and some minor bug fixes 107 | * Version 1.0.0: First version with both pad view and drumset view 108 | * Version 0.2.0: Pad view 109 | -------------------------------------------------------------------------------- /WPDrumkit.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 Express for Windows Phone 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WPDrumkit", "WPDrumkit\WPDrumkit\WPDrumkit.csproj", "{54669492-97BF-47E9-A199-AEB7F3B624A5}" 5 | EndProject 6 | Project("{96E2B04D-8817-42C6-938A-82C39BA4D311}") = "WPDrumkitContent", "WPDrumkit\WPDrumkitContent\WPDrumkitContent.contentproj", "{EFABC865-B5C5-4AF8-9973-7558C0E94CC1}" 7 | EndProject 8 | Global 9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 10 | Debug|Windows Phone = Debug|Windows Phone 11 | Release|Windows Phone = Release|Windows Phone 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {54669492-97BF-47E9-A199-AEB7F3B624A5}.Debug|Windows Phone.ActiveCfg = Debug|Windows Phone 15 | {54669492-97BF-47E9-A199-AEB7F3B624A5}.Debug|Windows Phone.Build.0 = Debug|Windows Phone 16 | {54669492-97BF-47E9-A199-AEB7F3B624A5}.Debug|Windows Phone.Deploy.0 = Debug|Windows Phone 17 | {54669492-97BF-47E9-A199-AEB7F3B624A5}.Release|Windows Phone.ActiveCfg = Release|Windows Phone 18 | {54669492-97BF-47E9-A199-AEB7F3B624A5}.Release|Windows Phone.Build.0 = Release|Windows Phone 19 | {54669492-97BF-47E9-A199-AEB7F3B624A5}.Release|Windows Phone.Deploy.0 = Release|Windows Phone 20 | {EFABC865-B5C5-4AF8-9973-7558C0E94CC1}.Debug|Windows Phone.ActiveCfg = Debug|Windows Phone 21 | {EFABC865-B5C5-4AF8-9973-7558C0E94CC1}.Release|Windows Phone.ActiveCfg = Release|Windows Phone 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /WPDrumkit/WPDrumkit/AnimatedToggleButton.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Microsoft Mobile. All rights reserved. 3 | * See the license file delivered with this project for more information. 4 | */ 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using Microsoft.Xna.Framework.Graphics; 11 | using Microsoft.Xna.Framework; 12 | 13 | namespace WPDrumkit 14 | { 15 | /// 16 | /// Extends a toggle button with animated ON state. 17 | /// 18 | public class AnimatedToggleButton : ToggleButton 19 | { 20 | private float timePerFrame; 21 | private float totalElapsed; 22 | private int frameCount; 23 | private int frame; 24 | private int frameWidth; 25 | private int frameHeight; 26 | 27 | /// 28 | /// Constructor 29 | /// 30 | /// Image shown while toggle button is up 31 | /// Image shown while toggle button is pressed 32 | /// Sprite image shown while toggle button is down and animated 33 | /// Number of frames in sprite image 34 | /// Animation speed (frames per second) 35 | public AnimatedToggleButton(Texture2D off, Texture2D pressed, Texture2D on, int frames, int fps) 36 | : base(off, pressed, on) 37 | { 38 | frameCount = frames; 39 | timePerFrame = (float)1 / fps; 40 | // Animation works only with vertically lined up sprite image 41 | frameWidth = on.Width; 42 | frameHeight = on.Height / frameCount; 43 | } 44 | 45 | override public void Draw(SpriteBatch spriteBatch) 46 | { 47 | if (Visible) 48 | { 49 | if (On && !pressed) 50 | { 51 | // Select current frame from sprite image 52 | Rectangle sourceRect = new Rectangle(0, frameHeight * frame, frameWidth, frameHeight); 53 | spriteBatch.Draw(onImg, rect, sourceRect, Color.White * opacity); 54 | } 55 | else 56 | { 57 | base.Draw(spriteBatch); 58 | } 59 | } 60 | } 61 | 62 | /// 63 | /// Updates the frame position according to the elapsed time. 64 | /// 65 | /// The time elapsed since last update 66 | public void UpdateFrame(float elapsed) 67 | { 68 | if (On) 69 | { 70 | totalElapsed += elapsed; 71 | if (totalElapsed > timePerFrame) 72 | { 73 | frame++; 74 | frame = frame % frameCount; 75 | totalElapsed -= timePerFrame; 76 | } 77 | } 78 | } 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /WPDrumkit/WPDrumkit/Background.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/microsoft/drumkit-wp/fcc2c79732b3d60b1472216dcdb214a1fe1e30e4/WPDrumkit/WPDrumkit/Background.png -------------------------------------------------------------------------------- /WPDrumkit/WPDrumkit/Button.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Microsoft Mobile. All rights reserved. 3 | * See the license file delivered with this project for more information. 4 | */ 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using Microsoft.Xna.Framework; 11 | using Microsoft.Xna.Framework.Graphics; 12 | using Microsoft.Xna.Framework.Input.Touch; 13 | 14 | namespace WPDrumkit 15 | { 16 | /// 17 | /// Implements a basic button 18 | /// 19 | public class Button 20 | { 21 | public event EventHandler Clicked = delegate { }; 22 | 23 | protected Texture2D releasedImg; 24 | protected Texture2D pressedImg; 25 | protected Rectangle rect; 26 | // A big button can be pressed with multiple fingers at the same time 27 | // so we need to keep track of every individual touch point 28 | protected List touchIds; 29 | protected bool pressed = false; 30 | protected bool animated = false; 31 | protected float opacity = 1.0f; 32 | 33 | public bool Enabled { get; set; } 34 | public bool Visible { get; set; } 35 | 36 | /// 37 | /// Returns the 38 | /// 39 | public Point Location 40 | { 41 | get { return rect.Location; } 42 | set { rect.Location = value; } 43 | } 44 | 45 | public Point Center 46 | { 47 | get { return rect.Center; } 48 | set 49 | { 50 | rect.X = value.X - rect.Width / 2; 51 | rect.Y = value.Y - rect.Height / 2; 52 | } 53 | } 54 | 55 | /// 56 | /// Gets or sets the opacity of the button. 57 | /// 58 | public float Opacity 59 | { 60 | get { return opacity; } 61 | set 62 | { 63 | opacity = value; 64 | Visible = opacity > 0.0f; 65 | } 66 | } 67 | 68 | /// 69 | /// Initializes a new instance of Button 70 | /// 71 | /// Image shown when the button is up 72 | /// Image shown when the button is down 73 | public Button(Texture2D released, Texture2D pressed) 74 | { 75 | releasedImg = released; 76 | pressedImg = pressed; 77 | rect = released.Bounds; 78 | Location = new Point(0, 0); 79 | touchIds = new List(); 80 | Enabled = true; 81 | Visible = true; 82 | } 83 | 84 | /// 85 | /// Enables the button 86 | /// 87 | public void Enable() 88 | { 89 | Enabled = true; 90 | opacity = 1.0f; 91 | } 92 | 93 | /// 94 | /// Disables the button 95 | /// 96 | public void Disable() 97 | { 98 | Enabled = false; 99 | opacity = 0.5f; 100 | } 101 | 102 | /// 103 | /// Determines whether a point is inside the button area 104 | /// 105 | /// Coordinates 106 | public bool Contains(Point position) 107 | { 108 | return rect.Contains(position); 109 | } 110 | 111 | /// 112 | /// Determines whether a point is inside the button area 113 | /// 114 | /// Coordinates 115 | public bool Contains(Vector2 position) 116 | { 117 | return Contains(new Point((int)position.X, (int)position.Y)); 118 | } 119 | 120 | /// 121 | /// Draws an image representing the current state of the button. 122 | /// 123 | /// Batch to add the sprite into 124 | public virtual void Draw(SpriteBatch spriteBatch) 125 | { 126 | if (Visible) 127 | // Choose and draw image accoriding to the state of the button and visibility 128 | spriteBatch.Draw(pressed ? pressedImg : releasedImg, rect, Color.White * opacity); 129 | } 130 | 131 | /// 132 | /// Handles the touch events 133 | /// 134 | /// Touch information concerning an individual touch point 135 | public void TouchEvent(TouchLocation touch) 136 | { 137 | switch (touch.State) 138 | { 139 | case TouchLocationState.Pressed: 140 | Pressed(touch); 141 | break; 142 | case TouchLocationState.Moved: 143 | Moved(touch); 144 | break; 145 | case TouchLocationState.Released: 146 | Released(touch); 147 | break; 148 | } 149 | } 150 | 151 | /// 152 | /// Handles the pressed (down) event if the touch postition is inside the button 153 | /// 154 | /// Contains the information about the touch event 155 | public void Pressed(TouchLocation touch) 156 | { 157 | if (!Enabled || !Visible) 158 | return; 159 | if (Contains(touch.Position)) 160 | { 161 | if (!touchIds.Contains(touch.Id)) 162 | touchIds.Add(touch.Id); 163 | pressed = true; 164 | } 165 | } 166 | 167 | /// 168 | /// Handles the moved (drag) event. Checks whether the touch position enters or leaves the button area 169 | /// 170 | /// Contains the information about the touch event 171 | public void Moved(TouchLocation touch) 172 | { 173 | if (!Enabled || !Visible) 174 | return; 175 | if (Contains(touch.Position)) 176 | { 177 | pressed = true; 178 | if (!touchIds.Contains(touch.Id)) 179 | touchIds.Add(touch.Id); 180 | } 181 | else if (touchIds.Contains(touch.Id)) 182 | { 183 | pressed = false; 184 | touchIds.Remove(touch.Id); 185 | } 186 | } 187 | 188 | /// 189 | /// Handles the released (up) event. 190 | /// Triggers Clicked event if released event happens inside the button and 191 | /// none of the other existing pointer is still holding the button down 192 | /// 193 | /// Contains the information about the touch event 194 | public void Released(TouchLocation touch) 195 | { 196 | if (!Enabled || !Visible) 197 | return; 198 | if (touchIds.Contains(touch.Id)) 199 | { 200 | pressed = false; 201 | touchIds.Remove(touch.Id); 202 | if (Contains(touch.Position) && touchIds.Count == 0) 203 | { 204 | Clicked(this, new EventArgs()); 205 | } 206 | } 207 | } 208 | } 209 | } 210 | -------------------------------------------------------------------------------- /WPDrumkit/WPDrumkit/Cymbal.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Microsoft Mobile. All rights reserved. 3 | * See the license file delivered with this project for more information. 4 | */ 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using Microsoft.Xna.Framework.Audio; 11 | using Microsoft.Xna.Framework; 12 | using Microsoft.Xna.Framework.Graphics; 13 | using System.Threading; 14 | 15 | namespace WPDrumkit 16 | { 17 | /// 18 | /// Extends Pad with cymbal swinging animation 19 | /// 20 | class Cymbal : Pad 21 | { 22 | private Timer animator; 23 | private TimerCallback rotate; 24 | private const float dt = 0.1f; 25 | private float dampening = 0.96f; 26 | private float angle = 0f; 27 | private float acceleration = 0f; 28 | private float velocity = 0f; 29 | 30 | /// 31 | /// Maximum swinging angle 32 | /// 33 | public float MaxAngle { get; set; } 34 | 35 | /// 36 | /// Constructor 37 | /// 38 | /// Percussion enumeration 39 | /// Cymbal sound 40 | /// Bounding box 41 | /// List of rectangular touch areas 42 | /// Cymbal image 43 | public Cymbal(Percussion percussion, SoundEffect sound, Rectangle boundaries, List touchAreas, Texture2D image) : 44 | base(percussion, sound, boundaries, touchAreas, image) 45 | { 46 | MaxAngle = 0.26f; // Default for max angle (~15 degrees) 47 | rotate = new TimerCallback(RotateCallback); 48 | Played += new EventHandler(Cymbal_Played); 49 | } 50 | 51 | override public void Draw(SpriteBatch spriteBatch) 52 | { 53 | if (image != null) 54 | spriteBatch.Draw(image, Position, null, Color.White, angle, Origin, 1.0f, SpriteEffects.None, 0f); 55 | 56 | } 57 | 58 | /// 59 | /// Triggers the animation when cymbal gets played 60 | /// 61 | private void Cymbal_Played(object sender, EventArgs e) 62 | { 63 | if (sender == this) 64 | { 65 | angle = MaxAngle; 66 | if (animator != null) animator.Dispose(); 67 | AutoResetEvent reset = new AutoResetEvent(false); 68 | animator = new Timer(rotate, reset, 0L, 30L); 69 | } 70 | } 71 | 72 | /// 73 | /// Rotates the cymbal creating a swinging effect 74 | /// 75 | private void RotateCallback(Object stateInfo) 76 | { 77 | angle *= dampening; 78 | acceleration = -9.81f / (0.04f * Origin.X) * (float)Math.Sin(angle); 79 | velocity += acceleration * dt; 80 | angle += velocity * dt; 81 | 82 | if (Math.Abs(angle) < 0.01 && Math.Abs(velocity) < 0.01) 83 | animator.Dispose(); 84 | } 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /WPDrumkit/WPDrumkit/Drum.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Microsoft Mobile. All rights reserved. 3 | * See the license file delivered with this project for more information. 4 | */ 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using Microsoft.Xna.Framework.Audio; 11 | using Microsoft.Xna.Framework; 12 | using Microsoft.Xna.Framework.Graphics; 13 | using System.Threading; 14 | 15 | namespace WPDrumkit 16 | { 17 | /// 18 | /// Extends Pad with drum vibration animation 19 | /// 20 | class Drum : Pad 21 | { 22 | private Timer shaker; 23 | private TimerCallback shake; 24 | private float dampening = 0.8f; 25 | private float magnitude = 0f; 26 | 27 | public float MaxMagnitude { get; set; } 28 | 29 | /// 30 | /// Constructor 31 | /// 32 | /// Percussion enumeration 33 | /// Cymbal sound 34 | /// Bounding box 35 | /// List of rectangular touch areas 36 | /// Cymbal image 37 | public Drum(Percussion percussion, SoundEffect sound, Rectangle boundaries, List touchAreas, Texture2D image) : 38 | base(percussion, sound, boundaries, touchAreas, image) 39 | { 40 | MaxMagnitude = -0.04f; 41 | Origin = new Vector2(boundaries.Width / 2, boundaries.Height / 2); 42 | shake = new TimerCallback(ShakeCallback); 43 | Played += new EventHandler(Drum_Played); 44 | } 45 | 46 | override public void Draw(SpriteBatch spriteBatch) 47 | { 48 | if (image != null) 49 | spriteBatch.Draw(image, Position, null, Color.White, 0.0f, Origin, 1.0f + magnitude, SpriteEffects.None, 0f); 50 | 51 | } 52 | 53 | /// 54 | /// Triggers the animation when drum gets played 55 | /// 56 | private void Drum_Played(object sender, EventArgs e) 57 | { 58 | if (sender == this) 59 | { 60 | magnitude = MaxMagnitude; 61 | if (shaker != null) shaker.Dispose(); 62 | AutoResetEvent reset = new AutoResetEvent(false); 63 | shaker = new Timer(shake, reset, 0L, 30L); 64 | } 65 | } 66 | 67 | /// 68 | /// Scales the drum up and down creating a vibration effect 69 | /// 70 | private void ShakeCallback(Object stateInfo) 71 | { 72 | magnitude *= -dampening; 73 | if (Math.Abs(magnitude) < 0.01) 74 | shaker.Dispose(); 75 | } 76 | } 77 | } 78 | -------------------------------------------------------------------------------- /WPDrumkit/WPDrumkit/DrummingView.cs: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright (c) 2011-2014 Microsoft Mobile. All rights reserved. 3 | * See the license file delivered with this project for more information. 4 | */ 5 | 6 | using System; 7 | using System.Collections.Generic; 8 | using System.Linq; 9 | using System.Text; 10 | using Microsoft.Xna.Framework.Graphics; 11 | using Microsoft.Xna.Framework.Audio; 12 | using Microsoft.Xna.Framework.Content; 13 | using Microsoft.Xna.Framework; 14 | 15 | namespace WPDrumkit 16 | { 17 | /// 18 | /// Drumming base view. Contains things that are common to PadView and DrumsetView such as recording etc. 19 | /// 20 | abstract class DrummingView : View 21 | { 22 | protected Texture2D background; 23 | protected List