public WheelMenu( MenuScreen screen, Camera camera, float wheelScale, float screenScale, float startX, float activeX, float finishX, float y) : base(screen, Vector2.Zero) { this.wheelScale = wheelScale; scaleMatrix = Matrix.CreateScale( wheelScale ); this.camera = camera; angle = MathHelper.PiOver4; TransitionOnPosition = new Vector2( startX, y ); Position = new Vector2( activeX, y ); TransitionOffPosition = new Vector2( finishX, y ); rotateSpring = new SpringInterpolater( 1, 50, SpringInterpolater.GetCriticalDamping( 50 ) ); lastX = startX; ContentManager content = screen.ScreenManager.Game.Content; entryEffect = content.Load<Effect>( "Effects/basic" ).Clone( Screen.ScreenManager.GraphicsDevice ); entryEffect.CurrentTechnique = entryEffect.Techniques["DiffuseColor"]; entryEffect.Parameters["LightingEnabled"].SetValue( false ); entryWorldEffectParameter = entryEffect.Parameters["World"]; entryViewEffectParameter = entryEffect.Parameters["View"]; entryProjectionEffectParameter = entryEffect.Parameters["Projection"]; entryDiffuseEffectParameter = entryEffect.Parameters["DiffuseMap"]; wheelModel = content.Load<CustomModel>( "Models/hamsterWheel" ); foreach ( CustomModel.ModelPart part in wheelModel.ModelParts ) { part.Effect.CurrentTechnique = part.Effect.Techniques["Color"]; part.Effect.Parameters["Color"].SetValue( new Color( Color.LightGray, 0 ).ToVector4() ); } }
WheelMenu wheel; // the parent wheel #endregion Fields #region Constructors public WheelMenuEntry( WheelMenu wheel, Texture2D texture ) { this.wheel = wheel; this.texture = texture; segments = 10; extendedSpring = new SpringInterpolater( 1, 800, SpringInterpolater.GetCriticalDamping( 800 ) ); extendedSpring.SetSource( 0 ); extendedSpring.SetDest( 0 ); extendedSpring.Active = true; growSpring = new SpringInterpolater( 1, 700, .25f * SpringInterpolater.GetCriticalDamping( 700 ) ); growSpring.SetSource( 0 ); growSpring.SetDest( 0 ); growSpring.Active = true; float height = WheelMenu.EntryIdleSize; float width = height * (float)texture.Width / (float)texture.Height; GenerateVerts( width, height, segments, out idleVerts ); GenerateVerts( width * WheelMenu.EntryActiveScale, height * WheelMenu.EntryActiveScale, segments, out activeVerts ); vertexBuffer = new VertexPositionNormalTexture[( segments + 1 ) * 2]; vertexDeclaration = new VertexDeclaration( wheel.Screen.ScreenManager.GraphicsDevice, VertexPositionNormalTexture.VertexElements ); }
public PlayerTag( Player player, SpriteFont font ) { this.player = player; this.font = font; ss = GameCore.Instance.GraphicsDevice.Viewport.Height / 1080f; color = GameCore.Instance.PlayerColors[player.PlayerNumber]; device = player.Screen.ScreenManager.GraphicsDevice; camera = player.Screen.Camera; spriteBatch = player.Screen.ScreenManager.SpriteBatch; tagOffset *= device.Viewport.Height / 1080f; nearHeightOver2 = camera.Near * (float)Math.Tan( camera.Fov / 2 ); nearWidthOver2 = camera.Aspect * nearHeightOver2; screenPos = Vector2.Zero; origin = font.MeasureString( player.HUD.Name ) / 2; spring = new SpringInterpolater( 1, 700, .3f * SpringInterpolater.GetCriticalDamping( 700 ) ); spring.SetSource( 0 ); spring.SetDest( 1 ); }
public GameTimer( TimeSpan fullTime ) : base(GameplayScreen.Instance) { this.fullTime = fullTime; this.timeLeft = fullTime; GraphicsDevice device = Screen.ScreenManager.GraphicsDevice; ss = device.Viewport.Height / 1080f; clockTimeString = new StringBuilder( "XX:XX:XX" ); clockPosition = new Vector2( device.Viewport.Width / 2, 50 * ss ); clockScaleSpring = new SpringInterpolater( 1, 700, .3f * SpringInterpolater.GetCriticalDamping( 700 ) ); clockScaleSpring.SetSource( 0f ); clockScaleSpring.SetDest( 1f ); clockFont = Screen.Content.Load<SpriteFont>( "Fonts/clockFont" ); timeUpText = Screen.Content.Load<Texture2D>( "Textures/timeUpText" ); Viewport viewport = GameCore.Instance.GraphicsDevice.Viewport; timeUpPosition = new Vector2( viewport.Width / 2, viewport.Height / 2 ); timeUpOrigin = new Vector2( timeUpText.Width, timeUpText.Height ) / 2; timeUpSpring = new SpringInterpolater( 1, 700, .3f * SpringInterpolater.GetCriticalDamping( 700 ) ); timeUpSpring.SetSource( 0 ); timeUpSpring.SetDest( 1 ); spriteBatch = Screen.ScreenManager.SpriteBatch; }
public PopupText( float size, Vector2 showPos, Vector2 hidePos, float timeout ) { this.size = size; this.showPos = showPos; this.hidePos = hidePos; this.timeout = timeout; this.text = new StringBuilder( 4 ); PositionSpring = new SpringInterpolater( 2, 300f, SpringInterpolater.GetCriticalDamping( 300f ) ); ScaleSpring = new SpringInterpolater( 1, 700f, .25f * SpringInterpolater.GetCriticalDamping( 700f ) ); ResetSprings(); }
public MenuEntry( MenuScreen screen, Vector2 position, string text ) : base(screen, position) { this.text = text; if ( text.Length == 0 ) this.Dimensions = new Vector2( 0f, (float)Screen.ScreenManager.Font.LineSpacing ); else this.Dimensions = Screen.ScreenManager.Font.MeasureString( text ); scaleSpring = new SpringInterpolater( 1, 700, .4f * SpringInterpolater.GetCriticalDamping( 700 ) ); scaleSpring.SetSource( 1 ); scaleSpring.SetDest( 1 ); scaleSpring.Active = true; }
public BooleanMenuItem( MenuScreen screen, Vector2 position, bool value ) : base(screen, position) { this.value = value; spriteBatch = screen.ScreenManager.SpriteBatch; font = Screen.ScreenManager.Font; Origin = new Vector2( 0, font.LineSpacing / 2 ); scaleSpring = new SpringInterpolater( 1, 700, .4f * SpringInterpolater.GetCriticalDamping( 700 ) ); scaleSpring.SetSource( 1 ); scaleSpring.SetDest( 1 ); scaleSpring.Active = true; Color = Color.White; }
public StaticImageMenuItem( MenuScreen screen, Vector2 position, Texture2D texture ) : base(screen, position) { this.texture = texture; TransitionOffPosition = position; TransitionOnPosition = position; spriteBatch = Screen.ScreenManager.SpriteBatch; Dimensions = new Vector2( texture.Width, texture.Height ); Origin = Dimensions / 2; Tint = Color.White; Fade = true; scaleSpring = new SpringInterpolater( 1, 700, .35f * SpringInterpolater.GetCriticalDamping( 700 ) ); scaleSpring.SetSource( 1 ); scaleSpring.SetDest( 1 ); scaleSpring.Active = true; }
private Powerup( GameplayScreen screen ) : base(screen) { Body = new PhysCircle( 1f, Vector2.Zero, 1f ); Body.Flags = BodyFlags.Anchored | BodyFlags.Ghost; Body.Parent = this; Oscillator = new SpringInterpolater( 1, 10, 0 ); SizeSpring = new SpringInterpolater( 1, 200, .15f * SpringInterpolater.GetCriticalDamping( 200 ) ); LockToPlayerSpring = new SpringInterpolater( 2, 100, SpringInterpolater.GetCriticalDamping( 100 ) ); RotationSpring = new SpringInterpolater( 1, 15, SpringInterpolater.GetCriticalDamping( 15 ) ); Oscillator.Active = true; SizeSpring.Active = true; LockToPlayerSpring.Active = true; RotationSpring.Active = true; DrawOrder = 6; }
public ImageMenuEntry( MenuScreen screen, Vector2 position, Texture2D texture, Vector2? dimensions ) : base(screen, position) { this.texture = texture; if ( dimensions != null ) Dimensions = (Vector2)dimensions; else Dimensions = new Vector2( texture.Width, texture.Height ); scaleSpring = new SpringInterpolater( 1, 700f, .35f * SpringInterpolater.GetCriticalDamping( 700f ) ); scaleSpring.SetSource( idleScale ); scaleSpring.SetDest( idleScale ); scaleSpring.Active = true; spriteBatch = Screen.ScreenManager.SpriteBatch; Tint = Color.White; Fade = true; }
private void LoadTitleContent() { GraphicsDevice device = ScreenManager.Game.GraphicsDevice; ContentManager content = ScreenManager.Game.Content; Viewport viewport = ScreenManager.GraphicsDevice.Viewport; vertArray = new VertexPositionTexture[4]; vertArray[0].TextureCoordinate = new Vector2( 0, 0 ); vertArray[1].TextureCoordinate = new Vector2( 1, 0 ); vertArray[2].TextureCoordinate = new Vector2( 1, 1 ); vertArray[3].TextureCoordinate = new Vector2( 0, 1 ); vertexDeclaration = new VertexDeclaration( device, VertexPositionTexture.VertexElements ); screenEffect = content.Load<Effect>( "Effects/screenAlignedEffect" ).Clone( device ); screenEffect.CurrentTechnique = screenEffect.Techniques["Texture"]; screenEffect.Parameters["ScreenWidth"].SetValue( viewport.Width ); screenEffect.Parameters["ScreenHeight"].SetValue( viewport.Height ); screenTextureParameter = screenEffect.Parameters["Texture"]; // 'Avatar' avatarTexture = content.Load<Texture2D>( "Textures/avatarText" ); avatarVertSprings = new SpringInterpolater[4]; for ( int i = 0; i < 4; ++i ) { float k = i < 2 ? 125 : 220; float bs = i < 2 ? .7f : 1f; avatarVertSprings[i] = new SpringInterpolater( 3, k, bs * SpringInterpolater.GetCriticalDamping( k ) ); } // 'Hamster' hamsterTexture = content.Load<Texture2D>( "Textures/hamsterText" ); hamsterVertSprings = new SpringInterpolater[4]; for ( int i = 0; i < 4; ++i ) { float k = i < 2 ? 145 : 250; float bs = i < 2 ? .8f : 1f; hamsterVertSprings[i] = new SpringInterpolater( 3, k, bs * SpringInterpolater.GetCriticalDamping( k ) ); } // 'Panic' panicTexture = content.Load<Texture2D>( "Textures/panicText" ); panicPositionSpring = new SpringInterpolater( 2, 120, SpringInterpolater.GetCriticalDamping( 120 ) ); panicSizeSpring = new SpringInterpolater( 1, 750, .75f * SpringInterpolater.GetCriticalDamping( 200 ) ); }
public PlayerHUD( Player player, SignedInGamer gamer ) { GameplayScreen screen = player.Screen; if ( gamer != null ) { profile = gamer.GetProfile(); Name = gamer.Gamertag; } else Name = "CPU"; Player = player; Score = 0; Boost = 1f; Rectangle safeRect = ScreenRects.SafeRegion; screenScale = GameCore.Instance.GraphicsDevice.Viewport.Height / 1080f; float ss = screenScale; // base hud object hudCageTexture = screen.Content.Load<Texture2D>( "Textures/playerHUDCage" ); hudTexture = screen.Content.Load<Texture2D>( "Textures/playerHUD" ); int hudWidth = (int)( hudTexture.Width * screenScale ); int hudHeight = (int)( hudTexture.Height * screenScale ); int x0 = xPadding + safeRect.X + Player.PlayerNumber * ( safeRect.Width - hudWidth - 2 * xPadding ) / 3; int y0 = -(int)( yPadding * screenScale + .5f ) + safeRect.Y + safeRect.Height - hudHeight; hudRect = new Rectangle( x0, y0, hudWidth, hudHeight ); // profile picture profileRect = new Rectangle( x0 + (int)( 88 * ss + .5f ), y0 + (int)( 26 * ss + .5f ), (int)( 60 * ss + .5f ), (int)( 60 * ss + .5f ) ); // boost meter boostRect = new Rectangle( x0 + (int)( 90 * ss + .5f ), y0 + (int)( 111 * ss + .5f ), (int)( 142 * ss + .5f ), (int)( 18 * ss + .5f ) ); boostEffect = screen.Content.Load<Effect>( "Effects/meterEffect" ); boostEffect.CurrentTechnique = boostEffect.Techniques[0]; boostEffectParamBoost = boostEffect.Parameters["Boost"]; boostEffectParamBoosting = boostEffect.Parameters["Boosting"]; boostEffectParamTime = boostEffect.Parameters["Time"]; boostTexture = new Texture2D( screen.ScreenManager.GraphicsDevice, boostRect.Width, boostRect.Height ); // name namePos = new Vector2( x0 + 162 * ss, y0 + 12 * ss ); nameFont = screen.Content.Load<SpriteFont>( "Fonts/HUDNameFont" ); nameOrigin = nameFont.MeasureString( Name ) / 2; float nameLength = nameOrigin.X * 2; nameScale = ss * Math.Min( 150f / nameLength, 1f ); // score scorePos = new Vector2( x0 + 230 * ss, y0 + 100 * ss ); scoreFont = screen.Content.Load<SpriteFont>( "Fonts/HUDScoreFont" ); scoreSpring = new SpringInterpolater( 1, 700f, .25f * SpringInterpolater.GetCriticalDamping( 700f ) ); scoreSpring.SetSource( 1f ); scoreSpring.SetDest( 1f ); scoreSpring.Active = true; scoreString = new StringBuilder( 1 ); //// score popup //scorePopup = new PopupText( ss, scorePos + new Vector2( -25f, -120f ) * screenScale, // scorePos + new Vector2( -15f, -15f ) * screenScale, 1f ); // score popup //float yMax = GameCore.Instance.DisplayGamertags ? -50f : -10f; //float yMin = GameCore.Instance.DisplayGamertags ? 0f : 40f; float yMax = -50f; float yMin = 0f; scorePopup = new PopupText( ss, new Vector2( 0f, yMax ) * screenScale, new Vector2( 0, yMin ) * screenScale, 1f ); // place placePos = new Vector2( x0 + 36 * ss, y0 + 91 * ss ); placeFont = screen.Content.Load<SpriteFont>( "Fonts/HUDPlaceFont" ); placeSmallFont = screen.Content.Load<SpriteFont>( "Fonts/HUDPlaceTagFont" ); placeNumber = new StringBuilder( "0" ); placeSpring = new SpringInterpolater( 1, 700f, .25f * SpringInterpolater.GetCriticalDamping( 700f ) ); placeSpring.SetSource( 1f ); placeSpring.SetDest( 1f ); placeSpring.Active = true; Place = 1; }
public Player( GameplayScreen screen, int playerNumber, PlayerIndex playerIndex, Avatar avatar, Vector2 pos, uint id ) : base(screen) { WheelModel = screen.Content.Load<CustomModel>( "Models/hamsterBall" ); foreach ( CustomModelSample.CustomModel.ModelPart part in WheelModel.ModelParts ) { part.Effect.CurrentTechnique = part.Effect.Techniques["Color"]; part.Effect.Parameters["Color"].SetValue( new Vector4( .8f, .7f, 1f, .225f ) ); part.Effect.Parameters["SpecularPower"].SetValue( 400 ); part.Effect.Parameters["Mask"].SetValue( MaskHelper.MotionBlur( 1 ) ); } DrawOrder = 8; WinState = PlayerWinState.None; soundPosition = Vector3.Zero; soundVelocity = Vector3.Zero; float depth = screen.Camera.Position.Z; DeathLine = depth * (float)Math.Tan( screen.Camera.Fov / 2f ); RespawnTime = float.MaxValue; shrinkBegin = 0; Scale = 1f; ScaleSpring = new SpringInterpolater( 1, 200, SpringInterpolater.GetCriticalDamping( 200 ) ); ScaleSpring.Active = true; ScaleSpring.SetSource( Scale ); ScaleSpring.SetDest( Scale ); PlayerIndex = playerIndex; PlayerNumber = playerNumber; BoostBurnRate = 1f; BoostRechargeRate = .25f; Avatar = avatar; BoundingCircle = new PhysCircle( Size / 2f, pos, 10f ); BoundingCircle.Parent = this; BoundingCircle.Elasticity = .4f; BoundingCircle.Friction = .5f; BoundingCircle.Collided += HandleCollision; BoundingCircle.Responded += HandleCollisionResponse; screen.PhysicsSpace.AddBody( BoundingCircle ); walkAnim = CustomAvatarAnimationData.GetAvatarAnimationData( "Walk", Screen.Content ); runAnim = CustomAvatarAnimationData.GetAvatarAnimationData( "Run", Screen.Content ); // pre-load animations for podium screen avatar.SetAnimation( AvatarAnimationPreset.Celebrate ); avatar.SetAnimation( AvatarAnimationPreset.Clap ); avatar.SetAnimation( AvatarAnimationPreset.FemaleAngry ); avatar.SetAnimation( AvatarAnimationPreset.MaleCry ); standAnim = (AvatarAnimationPreset)( (int)AvatarAnimationPreset.Stand0 + random.Next( 8 ) ); avatar.SetAnimation( standAnim ); if ( playerIndex >= PlayerIndex.One ) { HUD = new PlayerHUD( this, SignedInGamer.SignedInGamers[playerIndex] ); } else { HUD = new PlayerHUD( this, null ); playerAI = new PlayerAI( this ); } vertexDeclaration = new VertexDeclaration( screen.ScreenManager.GraphicsDevice, VertexPositionNormalTexture.VertexElements ); boosterSound = GameCore.Instance.AudioManager.Play2DCue( "booster", 1f ); boosterSound.Pause(); glow = new CircularGlow( new Vector3( BoundingCircle.Position, 0 ), Color.OrangeRed, Size ); glow.Player = this; screen.ObjectTable.Add( glow ); glowSpring = new SpringInterpolater( 1, 500, .75f * SpringInterpolater.GetCriticalDamping( 500 ) ); glowSpring.Active = true; glowSpring.SetSource( 0 ); glowSpring.SetDest( 0 ); Tag = new PlayerTag( this, screen.Content.Load<SpriteFont>( "Fonts/playerTagFont" ) ); SetID( id ); }
/// <summary> /// Load graphics content for the game. /// </summary> public override void LoadContent() { if ( Content == null ) Content = new ContentManager( ScreenManager.Game.Services, "Content" ); Game game = ScreenManager.Game; // initialize physics PhysicsSpace = new PhysicsSpace(); PhysicsSpace.Gravity = new Vector2( 0f, -8f ); // render targets GraphicsDevice device = ScreenManager.GraphicsDevice; PostProcessor.Initialize( device, ScreenManager.SpriteBatch, Content ); PresentationParameters pars = device.PresentationParameters; basicSceneRenderTarget = new RenderTarget2D( device, pars.BackBufferWidth, pars.BackBufferHeight, 1, pars.BackBufferFormat ); maskRenderTarget = new RenderTarget2D( device, pars.BackBufferWidth, pars.BackBufferHeight, 1, SurfaceFormat.Bgr32 ); screenRectangle = new Rectangle( 0, 0, pars.BackBufferWidth, pars.BackBufferHeight ); // this prevents the game from pausing after the player presses start to exit the loading screen firstFrame = true; // load fonts gameFont = Content.Load<SpriteFont>( "Fonts/gamefont" ); Content.Load<SpriteFont>( "Fonts/HUDNameFont" ); // load screens ahead of time scoreboardMenuScreen = new ScoreboardMenuScreen( ScreenManager, initSlotInfo ); pauseScreen = new PauseMenuScreen( ScreenManager ); // model explosion particles ParticleManager = new ParticleManager( game, Content ); ParticleManager.Initialize(); components.Add( ParticleManager ); // other particles PixieParticleSystem = new PixieParticleSystem( game, Content ); SparkParticleSystem = new SparkParticleSystem( game, Content ); PinkPixieParticleSystem = new PinkPixieParticleSystem( game, Content ); components.Add( PixieParticleSystem ); components.Add( SparkParticleSystem ); components.Add( PinkPixieParticleSystem ); foreach ( DrawableGameComponent component in components ) component.Initialize(); // pre-load LaserBeam.Initialize(); Content.Load<CustomAvatarAnimationData>( "Animations/Walk" ); Content.Load<CustomAvatarAnimationData>( "Animations/Run" ); backgroundTexture = Content.Load<Texture2D>( "Textures/gameBackground" ); int left = -( backgroundTexture.Width - ScreenManager.GraphicsDevice.Viewport.Width ) / 2; Viewport viewport = ScreenManager.GraphicsDevice.Viewport; if ( left > 0 ) backgroundRect = new Rectangle( 0, 0, viewport.Width, viewport.Height ); else backgroundRect = new Rectangle( left, 0, backgroundTexture.Width, viewport.Height ); // init game stuff ObjectTable = new ObjectTable<GameObject>(); // ready, go! ObjectTable.Add( new ReadyGo( this, new Vector2( viewport.Width / 2, viewport.Height / 2 ) ) ); float fov = MathHelper.ToRadians( 30f ); float aspect = ScreenManager.GraphicsDevice.DisplayMode.AspectRatio; Camera = new Camera( fov, aspect, 1f, 100f, new Vector3( 0f, 0f, cameraDistance ), Vector3.Zero ); winnerSpring = new SpringInterpolater( 1, 10, SpringInterpolater.GetCriticalDamping( 10 ) ); winnerSpring.SetSource( 1 ); winnerSpring.SetDest( 0 ); FloorBlock.Initialize( this ); Powerup.Initialize( this ); lastRowY = rowSpacing - Player.Size * 1.5f; InitSafeRectangle(); InitStage(); CountdownTime = 0f; CountdownEnd = 3f; lastCamY = Camera.Position.Y; SpawnRows(); // spawn additional rows before loading screen is over gameClock = new GameTimer( TimeSpan.FromMinutes( 2 ) ); ObjectTable.Add( gameClock ); ScreenManager.Game.ResetElapsedTime(); }
private void SetSpringDests( Texture2D texture, Vector2 position, float scale, SpringInterpolater[] springs ) { float halfWidth = scale * texture.Width / 2; float height = scale * texture.Height; springs[0].SetDest( new Vector3( -halfWidth + position.X, position.Y, 0 ) ); springs[1].SetDest( new Vector3( halfWidth + position.X, position.Y, 0 ) ); springs[2].SetDest( new Vector3( halfWidth + position.X, height + position.Y, 0 ) ); springs[3].SetDest( new Vector3( -halfWidth + position.X, height + position.Y, 0 ) ); springs[0].SetSource( new Vector3( -halfWidth + position.X, position.Y, 0 ) ); springs[1].SetSource( new Vector3( halfWidth + position.X, position.Y, 0 ) ); springs[2].SetSource( new Vector3( halfWidth + position.X, height + position.Y, 0 ) ); springs[3].SetSource( new Vector3( -halfWidth + position.X, height + position.Y, 0 ) ); }
private void SetVertexBuffer( SpringInterpolater[] springs ) { int index = 0; foreach ( SpringInterpolater spring in springs ) { float[] vert = spring.GetSource(); vertArray[index++].Position = new Vector3( vert[0], vert[1], 0 ); } }
public Shelves( GameplayScreen screen ) : base(screen) { int nCages = nMaxPlayers * nCagesPerBox; cagePieces = new CagePiece[nCages]; DrawOrder = 4; for ( int i = 0; i < nCages; ++i ) cagePieces[i] = new CagePiece(); hingeTransforms = new Matrix[4]; angleSpring = new SpringInterpolater( 1, 50, SpringInterpolater.GetCriticalDamping( 50 ) ); cageModel = screen.Content.Load<InstancedModel>( "Models/cage" ); hingeModel = screen.Content.Load<InstancedModel>( "Models/cageHinge" ); // determine transforms for each piece boundary = screen.ObjectTable.GetObjects<Boundary>()[0]; if ( boundary == null ) throw new InvalidOperationException( "boundary must be initialized before shelf" ); float totalLength = boundary.Right - boundary.Left - size - 2f * offsetFromWall; spacing = totalLength / 3f; Camera camera = Screen.Camera; float tanFovOver2 = (float)Math.Tan( camera.Fov / 2f ); float depth = camera.Position.Z + size / 2f; float height = depth * tanFovOver2; topLine = height - size / 2f; depth = camera.Position.Z - size / 2f; height = depth * tanFovOver2; deathLine = Screen.Camera.Position.Y - height; // cage bottoms stored in first four indices for ( int i = 0; i < nMaxPlayers; ++i ) { Vector3 pos = new Vector3( boundary.Left + offsetFromWall + i * spacing, topLine - size / 2f, 0f ); cagePieces[i].Translation = Matrix.CreateTranslation( pos ); cagePieces[i].Rotation = bottomStart; cagePieces[i].Transform = scale * bottomStart * cagePieces[i].Translation; cagePieces[i].Body = new PhysPolygon( size, .014f * size, new Vector2( pos.X + size / 2f, pos.Y ), 1f ); cagePieces[i].Body.Friction = 1.75f; cagePieces[i].Body.SetPivotPoint( new Vector2( -size / 2, 0f ) ); cagePieces[i].Body.Flags = BodyFlags.Anchored; cagePieces[i].Body.Parent = this; Screen.PhysicsSpace.AddBody( cagePieces[i].Body ); hingeTransforms[i] = Matrix.CreateScale( size ) * Matrix.CreateTranslation( new Vector3( cagePieces[i].Body.Position, 0 ) ); } // all other cage pieces won't change for ( int i = nMaxPlayers; i < nCages; ++i ) { int box = ( i - nMaxPlayers ) / 2; int side = i % 2; float x = boundary.Left + offsetFromWall + box * spacing + side * size; Vector3 pos = new Vector3( x, topLine, 0f ); Matrix translation = Matrix.CreateTranslation( pos ); Matrix rotation = side == 0 ? rotateL : rotateR; cagePieces[i].Translation = translation; cagePieces[i].Rotation = rotation; cagePieces[i].Transform = scale * rotation * translation; cagePieces[i].Body = new PhysPolygon( .014f, size, new Vector2( pos.X, pos.Y ), 1f ); cagePieces[i].Body.Flags = BodyFlags.Anchored; cagePieces[i].Body.Parent = this; Screen.PhysicsSpace.AddBody( cagePieces[i].Body ); } }