Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Graphics
Imports Microsoft.DirectX.AudioVideoPlayback
Imports DistortionPipeline
Imports DistortionSample
Public Class Breakout
Inherits Microsoft.Xna.Framework.Game
Private Enum BonusType
LongBat
BigBall
QuickBat
SlowBall
DoubleBall
Super
End Enum
Public Const DefaultWidth As Int32 = 1024
Public Const DefaultHeight As Int32 = 768
Private BatSpeed As Single = 4
Private BallSpeed As Single = 4
Private Graphics As GraphicsDeviceManager
Private Batch As SpriteBatch
Private SubTitle As GameText
Private Title As GameObject
Private Background As GameObject
Private BackgroundMusic As Audio
Private Level As Int16 = 0
Private Lives As Int16 = 3
Private LevelCompleted As Boolean = True
Private GameCompleted As Boolean = False
Private Bat As GameObject
Private Ball As GameObject
Private Blocks As New List(Of Block)
Private Super As Boolean = False
Private Angle As Single = 0
Private _BonusTime(5) As Int16
Private Property BonusTime(ByVal Type As BonusType) As Int16
Get
Return _BonusTime(Type)
End Get
Set(ByVal value As Int16)
_BonusTime(Type) = value
End Set
End Property
Sub New()
Me.Graphics = New GraphicsDeviceManager(Me)
Me.Content.RootDirectory = "content"
End Sub
Private Function GetTexture(ByVal Name As String) As Texture2D
Return Texture2D.FromFile(Me.Graphics.GraphicsDevice, My.Application.Info.DirectoryPath & "\" & Name)
End Function
Private Function GetBounds(ByVal Obj As GameObject) As Rectangle
Return New Rectangle(Obj.Position.X - (Obj.Sprite.Width / 2), Obj.Position.Y - (Obj.Sprite.Height / 2), Obj.Sprite.Width, Obj.Sprite.Height)
End Function
Private Sub PlaySound(ByVal Name As String)
My.Computer.Audio.Play(My.Application.Info.DirectoryPath & "\" & Name, AudioPlayMode.Background)
End Sub
Private Sub CalculateBallVelocity(ByVal Obj As GameObject)
Dim DeltaX As Single = Ball.Position.X - Obj.Position.X
Dim DevAngle As Single = Math.Abs(DeltaX) * ((Math.PI / 3) / (Obj.Sprite.Width / 2))
Dim AngleOnX As Single = MathHelper.PiOver2 - Math.Abs(DevAngle)
Dim YComponent As Single = BallSpeed * Math.Sin(AngleOnX)
Dim XComponent As Single = BallSpeed * Math.Cos(AngleOnX)
If DeltaX < 0 Then
XComponent = -XComponent
End If
If Ball.Position.Y <= Obj.Position.Y Then
Ball.Velocity = New Vector2(XComponent, -YComponent)
Else
Ball.Velocity = New Vector2(XComponent, YComponent)
End If
End Sub
Private Sub CollisionCheck()
Dim BallRect As Rectangle = GetBounds(Ball)
Dim BatRect As Rectangle = GetBounds(Bat)
Dim Bounced As Boolean = False
If BallRect.Intersects(BatRect) Then
CalculateBallVelocity(Bat)
PlaySound("Boink1.wav")
End If
If ((Ball.Position.X < 5) Or (Ball.Position.X > Me.Graphics.GraphicsDevice.Viewport.Width - 5)) _
And (Ball.Position.Y < Me.Graphics.GraphicsDevice.Viewport.Height - 5) Then
Ball.Velocity = New Vector2(-Ball.Velocity.X, Ball.Velocity.Y)
PlaySound("Boink1.wav")
End If
If Ball.Position.Y < 5 Then
Ball.Velocity = New Vector2(Ball.Velocity.X, -Ball.Velocity.Y)
PlaySound("Boink1.wav")
End If
If Ball.Position.Y > Me.Graphics.GraphicsDevice.Viewport.Height Then
If (Not Super) Then
PlaySound("Beep.wav")
Lives -= 1
Ball.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2, Me.Graphics.GraphicsDevice.Viewport.Height / 2)
Ball.Velocity = New Vector2(0, 1)
Else
Ball.Velocity = New Vector2(Ball.Velocity.X, -Ball.Velocity.Y)
PlaySound("Boink1.wav")
End If
End If
Dim HitBlocks As New List(Of Block)
For Each Block As Block In Blocks
Dim BlockRect As Rectangle = GetBounds(Block)
If BallRect.Intersects(BlockRect) And (Not Bounced) Then
If (Ball.Position.X > Block.Position.X + Block.Sprite.Width / 2) Or _
(Ball.Position.X < Block.Position.X - Block.Sprite.Width / 2) Then
Ball.Velocity = New Vector2(-Ball.Velocity.X, Ball.Velocity.Y)
Else
Ball.Velocity = New Vector2(Ball.Velocity.X, -Ball.Velocity.Y)
End If
Bounced = True
Block.Life -= 1
PlaySound("Boink1.wav")
If Block.Life = 0 Then
Block.Enabled = False
HitBlocks.Add(Block)
If Block.Name.Contains("Bonus") Then
ActivateBonus(Block.Name)
End If
Else
Block.Sprite = GetTexture("Block" & Block.Life.ToString.PadLeft(2, "0") & ".png")
End If
End If
Next
For Each Block As Block In HitBlocks
Blocks.Remove(Block)
Next
If Lives = 0 Then
SubTitle.Text = "Peccato! Hai perso!"
SubTitle.CreateSprite(Me.Graphics.GraphicsDevice)
SubTitle.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2 - SubTitle.Sprite.Width / 2, 300)
LevelCompleted = True
GameCompleted = True
End If
End Sub
Private Sub KeyboardCheck()
Dim KeyState As KeyboardState = Keyboard.GetState
If KeyState.IsKeyDown(Keys.Right) Then
If Bat.Position.X + Bat.Sprite.Width / 2 < Me.GraphicsDevice.Viewport.Width Then
Bat.Position += New Vector2(BatSpeed, 0)
End If
End If
If KeyState.IsKeyDown(Keys.Left) Then
If Bat.Position.X - Bat.Sprite.Width / 2 > 0 Then
Bat.Position += New Vector2(-BatSpeed, 0)
End If
End If
If KeyState.IsKeyDown(Keys.Escape) Then
Me.Exit()
End If
If KeyState.IsKeyDown(Keys.F2) Then
'Blocks.Clear()
End If
End Sub
Private Sub AdvanceLevel()
Level += 1
LevelCompleted = False
If Level = 1 Then
SubTitle.Text = "Premi invio per continuare"
SubTitle.CreateSprite(Me.Graphics.GraphicsDevice)
SubTitle.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2 - SubTitle.Sprite.Width / 2, 300)
'BackgroundMusic = New Audio(My.Application.Info.DirectoryPath & "\Rapsodia.mp3")
'BackgroundMusic.Volume = 0
'BackgroundMusic.Play()
'Togliete i commenti per avviare la musica. Il file NON č incluso nel paccheto
'perchč pesa troppo. Potete comunque usarne uno voi
End If
Try
Dim Reader As New IO.StreamReader(My.Application.Info.DirectoryPath & "\Level" & Level & ".lvl")
Dim Line As String
Do While Not Reader.EndOfStream
Line = Reader.ReadLine
If String.IsNullOrEmpty(Line) Then
Continue Do
End If
Dim Vals() As String = Line.Split("=")
Dim Name As String = Vals(0).Trim
Dim Arg As String = Vals(1).Trim
If Arg.Contains(",") Then
Dim Coords() As String = Arg.Split(",")
Dim CoX As String = Coords(0).Trim
Dim CoY As String = Coords(1).Trim
Dim Area As New Rectangle
If CoX.Contains(">") Then
Dim Xs() As String = CoX.Split(">")
Dim MinX As Int16 = CInt(Xs(0).Trim)
Dim MaxX As Int16 = CInt(Xs(1).Trim)
Area.X = MinX
Area.Width = MaxX - MinX
Else
Area.X = CInt(CoX)
Area.Width = 0
End If
If CoY.Contains(">") Then
Dim Ys() As String = CoY.Split(">")
Dim MinY As Int16 = CInt(Ys(0).Trim)
Dim MaxY As Int16 = CInt(Ys(1).Trim)
Area.Y = MinY
Area.Height = MaxY - MinY
Else
Area.Y = CInt(CoY)
Area.Height = 0
End If
For X As Int16 = Area.X To (Area.X + Area.Width) Step 35
For Y As Int16 = Area.Y To (Area.Y + Area.Height) Step 19
Dim B As New Block(GetTexture(Name & ".png"))
B.Position = New Vector2(X, Y)
B.Name = Name
If Name.StartsWith("Block") Then
B.Life = CInt(Name.Remove(0, Name.Length - 2))
End If
Blocks.Add(B)
Next
Next
End If
Loop
Reader.Close()
Catch FNFE As IO.FileNotFoundException
GameCompleted = True
SubTitle.Text = "Complimenti! Hai finito il gioco!"
SubTitle.CreateSprite(Me.Graphics.GraphicsDevice)
SubTitle.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2 - SubTitle.Sprite.Width / 2, 300)
End Try
End Sub
Private Sub UpdateBonus()
For I As Int16 = 0 To 5
If BonusTime(I) = 1 Then
Select Case I
Case BonusType.LongBat
Bat.Scale = 1
Case BonusType.BigBall
Ball.Scale = 1
Case BonusType.QuickBat
BatSpeed = 4
Case BonusType.SlowBall
BallSpeed = 4
Case BonusType.DoubleBall
Case BonusType.Super
BatSpeed = 4
BallSpeed = 4
Super = False
For Each B As Block In Blocks
B.Rotation = 0
Next
Bat.Rotation = 0
Ball.Rotation = 0
End Select
Ball.Velocity = Vector2.Transform(Ball.Velocity, Matrix.CreateScale(BatSpeed / 4))
End If
If BonusTime(I) > 0 Then
BonusTime(I) -= 1
End If
Next
End Sub
Private Sub ActivateBonus(ByVal Name As String)
Select Case Name
Case "Bonus01"
Bat.Scale = 2
BonusTime(BonusType.LongBat) = 1000
Case "Bonus02"
Ball.Scale = 2
BonusTime(BonusType.BigBall) = 1000
Case "Bonus03"
BatSpeed = 6
BonusTime(BonusType.QuickBat) = 1000
Case "Bonus04"
BallSpeed = 2
BonusTime(BonusType.SlowBall) = 1000
Case "Bonus05"
BonusTime(BonusType.DoubleBall) = 1000
Case "Bonus06"
BatSpeed = 9
BallSpeed = 9
Super = True
BonusTime(BonusType.Super) = 500
End Select
Ball.Velocity = Vector2.Transform(Ball.Velocity, Matrix.CreateScale(BatSpeed / 4))
End Sub
''' <summary>
''' Inizializza gli oggetti della classe.
''' </summary>
Protected Overrides Sub Initialize()
Batch = New SpriteBatch(Me.Graphics.GraphicsDevice)
MyBase.Initialize()
End Sub
''' <summary>
''' Carica tutte le risorse che occorrono (texture, modelli 3D, suoni, ecc...).
''' </summary>
Protected Overrides Sub LoadContent()
Background = New GameObject(GetTexture("Background.png"))
Background.Position = Background.Center
Dim Size As New Viewport
Size.Width = Background.Sprite.Width
Size.Height = Background.Sprite.Height
Size.X = 0
Size.Y = 0
Me.Graphics.GraphicsDevice.Viewport = Size
Me.Graphics.PreferredBackBufferHeight = Size.Height
Me.Graphics.PreferredBackBufferWidth = Size.Width
Me.Graphics.ApplyChanges()
Title = New GameObject(GetTexture("Title.png"))
Title.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2, 100)
SubTitle = New GameText()
SubTitle.Font = New Drawing.Font("Monotype Corsiva", 30, Drawing.FontStyle.Italic)
SubTitle.Text = "Premi invio per iniziare"
SubTitle.CreateSprite(Me.Graphics.GraphicsDevice)
SubTitle.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2 - SubTitle.Sprite.Width / 2, 300)
Bat = New GameObject(GetTexture("Bat.png"))
Bat.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2, Me.Graphics.GraphicsDevice.Viewport.Height - 40)
Ball = New GameObject(GetTexture("Ball.png"))
Ball.Position = New Vector2(Me.Graphics.GraphicsDevice.Viewport.Width / 2, Me.Graphics.GraphicsDevice.Viewport.Height / 2)
Ball.Velocity = New Vector2(0, 3)
MyBase.LoadContent()
End Sub
''' <summary>
''' Rilascia tutte le risorse che non servono pių.
''' </summary>
Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
End Sub
''' <summary>
''' Aggiorna la situazione di gioco (tutti gli oggetti vengono aggiornati).
''' </summary>
Protected Overrides Sub Update(ByVal GameTime As GameTime)
If GamePad.GetState(PlayerIndex.One).Buttons.Back = ButtonState.Pressed Then
Me.Exit()
End If
If (Not LevelCompleted) Then
KeyboardCheck()
Else
If Keyboard.GetState().IsKeyDown(Keys.Enter) Then
AdvanceLevel()
End If
End If
CollisionCheck()
UpdateBonus()
If (Not LevelCompleted) Or ((LevelCompleted) And (Level = 0)) Then
Ball.UpdatePosition()
End If
If Blocks.Count = 0 Then
LevelCompleted = True
End If
If Super Then
Angle += 0.02
End If
MyBase.Update(GameTime)
End Sub
''' <summary>
''' Disegna tutti gli oggetti visibili sullo schermo.
''' </summary>
Protected Overrides Sub Draw(ByVal gameTime As Microsoft.Xna.Framework.GameTime)
Me.Graphics.GraphicsDevice.Clear(Color.CornflowerBlue)
Batch.Begin()
If Super Then
For Each B As Block In Blocks
B.Rotation = Angle
Next
Bat.Rotation = Angle
Ball.Rotation = Angle
End If
Background.Draw(Batch)
Bat.Draw(Batch)
Ball.Draw(Batch)
If LevelCompleted Then
If (Level = 0) Or (GameCompleted) Then
Title.Draw(Batch)
End If
SubTitle.Draw(Batch)
End If
For Each Block As GameObject In Blocks
Block.Draw(Batch)
Next
Batch.End()
MyBase.Draw(gameTime)
End Sub
End Class