public Boundary( GameplayScreen screen, float left, float right, float rowStart, float rowSpacing ) : base(screen) { Left = left; Right = right; lastFrame = new GameTime( TimeSpan.FromSeconds( 0 ), TimeSpan.FromSeconds( 0 ), TimeSpan.FromSeconds( 1f / 30f ), TimeSpan.FromSeconds( 1f / 60 ) ); this.rowSpacing = rowSpacing; this.rowStart = rowStart; minHoleDist = ( FloorBlock.Height + Size ) / 2f; lastHole = rowStart; lastGoldenShake = 0; DrawOrder = 7; // this is for objects, such as powerups and players, so they can travel through the tubes objects = new List<BoundaryTubeObject>( 10 ); for ( int i = 0; i < 10; ++i ) objects.Add( new BoundaryTubeObject() ); // left polygon polyLeft = new PhysPolygon( polyWidth, 100f, new Vector2( left - halfPolyWidth, 0f ), 1f ); polyLeft.Elasticity = 1f; polyLeft.Friction = 1.5f; polyLeft.Flags = BodyFlags.Anchored; polyLeft.Parent = this; screen.PhysicsSpace.AddBody( polyLeft ); // right polygon polyRight = new PhysPolygon( polyWidth, 100f, new Vector2( right + halfPolyWidth, 0f ), 1f ); polyRight.Elasticity = 1f; polyRight.Friction = 1.5f; polyRight.Flags = BodyFlags.Anchored; polyRight.Parent = this; screen.PhysicsSpace.AddBody( polyRight ); // model cageModel = Screen.Content.Load<InstancedModel>( "Models/cageTile" ); cageHoleModel = Screen.Content.Load<InstancedModel>( "Models/cageHole" ); teeModel = Screen.Content.Load<InstancedModel>( "Models/tubeTee" ); cupModel = Screen.Content.Load<InstancedModel>( "Models/tubeCup" ); Camera camera = screen.Camera; float dist = camera.Position.Z + Size / 2f; float tanFovyOverTwo = (float)Math.Tan( camera.Fov / 2f ); deathLine = dist * tanFovyOverTwo + Size / 2f; topLine = camera.Position.Y + deathLine - Size; lastTopY = camera.Position.Y + deathLine; rows = (int)Math.Ceiling( 2f * deathLine / Size ); nTransforms = rows * 2; rotateL = new Matrix( 0, 0,-1, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1 ); rotateR = new Matrix( 0, 0, 1, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 1 ); rotateZ = new Matrix( 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); flip = new Matrix(-1, 0, 0, 0, 0,-1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 ); scale = Matrix.CreateScale( Size ); sidePieces = new SidePiece[nTransforms]; for ( int i = 0; i < nTransforms; ++i ) { sidePieces[i] = new SidePiece(); SidePiece piece = sidePieces[i]; int row = i % rows; bool onLeftSide = i / rows == 0; piece.Hole = false; piece.CagePosition = new Vector3( onLeftSide ? Left : Right, topLine - row * Size, 0f ); Matrix scaleRotate = scale * ( onLeftSide ? rotateL : rotateR ); piece.CageTransform = scaleRotate * Matrix.CreateTranslation( piece.CagePosition ); piece.TubePosition = piece.CagePosition + new Vector3( onLeftSide ? -Size / 2 : Size / 2, 0, 0 ); piece.TubeTransform = scale * Matrix.CreateTranslation( piece.TubePosition ); piece.Tube = TubePattern.Cup; } }
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 ); } }