Questo sito utilizza cookies solo per scopi di autenticazione sul sito e nient'altro. Nessuna informazione personale viene tracciata. Leggi l'informativa sui cookies.
Username: Password: oppure
GN TankBattle - GameEngine.vb

GameEngine.vb

Caricato da: GN
Scarica il programma completo

  1. Imports Microsoft.DirectX
  2. Imports Microsoft.DirectX.Direct3D
  3. Imports Microsoft.DirectX.DirectInput
  4. Imports Microsoft.DirectX.DirectSound
  5. Imports System.Threading
  6.  
  7. Public Class GameEngine
  8.     Dim DispGrafico As Direct3D.Device
  9.     Dim SchermoIntero As Boolean
  10.     Dim Tastiera As DirectInput.Device
  11.     Dim Suoni As DirectSound.Device
  12.     Dim th As Thread
  13.     Dim Livello As Integer
  14.     Dim CarroNemico As oggX
  15.     Dim Nemici As New List(Of Nemico)
  16.     Dim Proiettili As New List(Of Proiettile)
  17.     Dim Giocatore As oggX
  18.     Dim Terreno As oggX
  19.     Dim AngoloGiocatore As Integer = 0
  20.     Dim Tempo As Integer
  21.     Dim Sparo As SecondaryBuffer
  22.     Dim FineLivello As SecondaryBuffer
  23.     Dim TempoScaduto As SecondaryBuffer
  24.  
  25.     Sub New()
  26.         InitializeComponent()
  27.         SchermoIntero = (MsgBox("Schermo intero?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes)
  28.     End Sub
  29.  
  30.     Sub New(ByVal s As Boolean)
  31.         InitializeComponent()
  32.         SchermoIntero = s
  33.     End Sub
  34.  
  35.     Private Sub GameEngine_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  36.         Dim ParametriGrafici As New PresentParameters()
  37.         If SchermoIntero = True Then
  38.             ParametriGrafici.BackBufferCount = 2
  39.             ParametriGrafici.AutoDepthStencilFormat = DepthFormat.D16
  40.             ParametriGrafici.EnableAutoDepthStencil = True
  41.             ParametriGrafici.DeviceWindowHandle = Me.Handle
  42.             ParametriGrafici.SwapEffect = SwapEffect.Flip
  43.             ParametriGrafici.Windowed = False
  44.             ParametriGrafici.BackBufferWidth = My.Computer.Screen.Bounds.Width
  45.             ParametriGrafici.BackBufferHeight = My.Computer.Screen.Bounds.Height
  46.             ParametriGrafici.BackBufferFormat = Format.X8R8G8B8
  47.         Else
  48.             ParametriGrafici.BackBufferCount = 2
  49.             ParametriGrafici.AutoDepthStencilFormat = DepthFormat.D16
  50.             ParametriGrafici.EnableAutoDepthStencil = True
  51.             ParametriGrafici.DeviceWindowHandle = Me.Handle
  52.             ParametriGrafici.SwapEffect = SwapEffect.Flip
  53.             ParametriGrafici.Windowed = True
  54.         End If
  55.         DispGrafico = New Direct3D.Device(0, Direct3D.DeviceType.Hardware, Me.Handle, CreateFlags.HardwareVertexProcessing, ParametriGrafici)
  56.         Tastiera = New DirectInput.Device(SystemGuid.Keyboard)
  57.         Tastiera.SetDataFormat(DeviceDataFormat.Keyboard)
  58.         Tastiera.SetCooperativeLevel(Me, CooperativeLevelFlags.Background Or CooperativeLevelFlags.NonExclusive)
  59.         Tastiera.Acquire()
  60.         Suoni = New DirectSound.Device
  61.         Suoni.SetCooperativeLevel(Me, CooperativeLevel.Priority)
  62.         Sparo = Me.CaricaSuono(Application.StartupPath & "\Audio\Sparo.wav")
  63.         FineLivello = Me.CaricaSuono(Application.StartupPath & "\Audio\FineLivello.wav")
  64.         TempoScaduto = Me.CaricaSuono(Application.StartupPath & "\Audio\TempoScaduto.wav")
  65.         Me.GeneraLivello()
  66.         Me.Show()
  67.         Me.Focus()
  68.         th = New Thread(AddressOf MainLoop)
  69.         th.Start()
  70.     End Sub
  71.  
  72.     Sub MainLoop()
  73.         Do
  74.             Dim a As Double = Rad(AngoloGiocatore)
  75.             Tastiera.Poll()
  76.             Dim t As KeyboardState = Tastiera.GetCurrentKeyboardState()
  77.             DispGrafico.Clear(ClearFlags.Target Or ClearFlags.ZBuffer, Color.Blue, 1, 0)
  78.             DispGrafico.BeginScene()
  79.             DispGrafico.SamplerState(0).MinFilter = TextureFilter.Linear
  80.             If t.Item(Key.F1) = True Then
  81.                 Process.Start(Application.StartupPath & "\Comandi.txt")
  82.                 If SchermoIntero = True Then
  83.                     Application.Exit()
  84.                 End If
  85.             End If
  86.             If t.Item(Key.F2) = True Then
  87.                 DispGrafico.Transform.View = Matrix.LookAtLH(New Vector3(0, 3000, 5), New Vector3(0, 0, 0), New Vector3(0, 1, 0))
  88.             Else
  89.                 DispGrafico.Transform.View = Matrix.LookAtLH(Giocatore.pos + New Vector3(Math.Sin(a) * 200, 0, Math.Cos(a) * 200), Giocatore.pos, New Vector3(0, 1, 0))
  90.             End If
  91.             DispGrafico.Transform.Projection = Matrix.PerspectiveFovLH(CSng(Math.PI / 16), 4 / 3, 1, 4000)
  92.             DispGrafico.RenderState.Lighting = True
  93.             DispGrafico.RenderState.Ambient = Color.White
  94.             Me.AggiungiMesh(Terreno)
  95.             Dim Casuale As New Random()
  96.             For i As Integer = 0 To Nemici.Count - 1
  97.                 Dim CorrNemico As Nemico = Nemici.Item(i)
  98.                 Dim PrecPosNemico As Vector3 = CorrNemico.mesh.pos
  99.                 Dim PrecRotNemico As Vector3 = CorrNemico.mesh.rot
  100.                 With CorrNemico
  101.                     If .IANemico_Azione = 0 Then
  102.                         .IANemico_Azione = Casuale.Next(1, 13)
  103.                         Select Case .IANemico_Azione
  104.                             Case 1, 2, 3, 4
  105.                                 .IANemico_Obiettivo = Casuale.NextDouble()
  106.                             Case 5, 6, 7, 8, 9
  107.                                 .IANemico_Obiettivo = Casuale.Next(1, 50)
  108.                                 .IANemico_PrecPos = .mesh.pos
  109.                             Case 10, 11, 12
  110.                                 .IANemico_Obiettivo = Casuale.Next(5, 50)
  111.                         End Select
  112.                     Else
  113.                         Select Case .IANemico_Azione
  114.                             Case 1, 2
  115.                                 If .mesh.rot.Y > .IANemico_Obiettivo Then
  116.                                     .IANemico_Azione = 0
  117.                                 Else
  118.                                     .mesh.rot.Y += 0.1
  119.                                 End If
  120.                             Case 3, 4
  121.                                 If .mesh.rot.Y > .IANemico_Obiettivo Then
  122.                                     .IANemico_Azione = 0
  123.                                 Else
  124.                                     .mesh.rot.Y -= 0.1
  125.                                 End If
  126.                             Case 5, 6
  127.                                 If Me.DistanzaPunti(.IANemico_PrecPos, .mesh.pos) > .IANemico_Obiettivo Then
  128.                                     .IANemico_Azione = 0
  129.                                 Else
  130.                                     .mesh.pos.X += 5 * Math.Sin(.mesh.rot.Y)
  131.                                     .mesh.pos.Z += 5 * Math.Cos(.mesh.rot.Y)
  132.                                 End If
  133.                             Case 7, 8, 9
  134.                                 If Me.DistanzaPunti(.IANemico_PrecPos, .mesh.pos) > .IANemico_Obiettivo Then
  135.                                     .IANemico_Azione = 0
  136.                                 Else
  137.                                     .mesh.pos.X -= 5 * Math.Sin(.mesh.rot.Y)
  138.                                     .mesh.pos.Z -= 5 * Math.Cos(.mesh.rot.Y)
  139.                                 End If
  140.                             Case 10, 11, 12
  141.                                 If .IANemico_Passaggio = .IANemico_Obiettivo Then
  142.                                     .IANemico_Azione = 0
  143.                                 Else
  144.                                     .IANemico_Passaggio += 1
  145.                                 End If
  146.                         End Select
  147.                     End If
  148.                 End With
  149.                 If CollisioneNemico(i) = True Then
  150.                     CorrNemico.mesh.pos = PrecPosNemico
  151.                     CorrNemico.mesh.rot = PrecRotNemico
  152.                 End If
  153.                 Nemici.Item(i) = CorrNemico
  154.                 Me.AggiungiMesh(CorrNemico.mesh)
  155.                 If t.Item(Key.Space) = True Then
  156.                     Dim MinGioc As New Vector3()
  157.                     Dim MaxGioc As New Vector3()
  158.                     Me.BoundingBox(Giocatore, MinGioc, MaxGioc)
  159.                     Dim MinNemico As New Vector3()
  160.                     Dim MaxNemico As New Vector3()
  161.                     Me.BoundingBox(CorrNemico.mesh, MinNemico, MaxNemico)
  162.                     Proiettili.Add(New Proiettile(Me, Giocatore.pos, New Vector3(0, Me.Rad(AngoloGiocatore), 0)))
  163.                 End If
  164.                 Dim e As Boolean = False
  165.                 For p As Integer = 0 To Proiettili.Count - 1
  166.                     If Me.CollisioneOggetto(Proiettili(p).mesh, CorrNemico.mesh) Then
  167.                         Sparo.Play(0, BufferPlayFlags.Default)
  168.                         Nemici.RemoveAt(i)
  169.                         e = True
  170.                         Exit For
  171.                     End If
  172.                 Next
  173.                 If Nemici.Count = 0 Then
  174.                     My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\Livello.txt", Livello + 1, False)
  175.                     FineLivello.Play(0, BufferPlayFlags.Default)
  176.                     TimerTempo.Stop()
  177.                     Me.GeneraLivello()
  178.                 End If
  179.                 If e = True Then
  180.                     Exit For
  181.                 End If
  182.             Next
  183.             Dim PrecPosGiocatore As Vector3 = Giocatore.pos
  184.             Dim PrecRotGiocatore As Vector3 = Giocatore.rot
  185.             If t.Item(Key.Right) = True Then
  186.                 If AngoloGiocatore <> 360 Then
  187.                     AngoloGiocatore += 2.5
  188.                 Else
  189.                     AngoloGiocatore = 0
  190.                 End If
  191.             ElseIf t.Item(Key.Left) = True Then
  192.                 If AngoloGiocatore <> 0 Then
  193.                     AngoloGiocatore -= 2.5
  194.                 Else
  195.                     AngoloGiocatore = 360
  196.                 End If
  197.             End If
  198.             If t.Item(Key.Up) = True Then
  199.                 Giocatore.pos.X -= 5 * Math.Sin(a)
  200.                 Giocatore.pos.Z -= 5 * Math.Cos(a)
  201.             ElseIf t.Item(Key.Down) = True Then
  202.                 Giocatore.pos.X += 5 * Math.Sin(a)
  203.                 Giocatore.pos.Z += 5 * Math.Cos(a)
  204.             End If
  205.             Giocatore.rot.Y = (AngoloGiocatore * 2 * Math.PI) / 360
  206.             If CollisioneGiocatore() = True Then
  207.                 Giocatore.pos = PrecPosGiocatore
  208.                 Giocatore.rot = PrecRotGiocatore
  209.             End If
  210.             Me.AggiungiMesh(Giocatore)
  211.             For p As Integer = 0 To Proiettili.Count - 1
  212.                 Try
  213.                     Proiettili(p).mesh.pos.X -= 5 * Math.Sin(Proiettili(p).mesh.rot.Y)
  214.                     Proiettili(p).mesh.pos.Z -= 5 * Math.Cos(Proiettili(p).mesh.rot.Y)
  215.                     Me.AggiungiMesh(Proiettili(p).mesh)
  216.                     Proiettili(p).s += 1
  217.                     If Proiettili(p).s = 100 Then
  218.                         Proiettili.RemoveAt(p)
  219.                     End If
  220.                 Catch ex As Exception
  221.                 End Try
  222.             Next
  223.             If t.Item(Key.Escape) Then
  224.                 Application.Exit()
  225.             End If
  226.             DispGrafico.EndScene()
  227.             DispGrafico.Present()
  228.             Application.DoEvents()
  229.             If SchermoIntero = False Then
  230.                 Dim s As String = "i"
  231.                 If Tempo = 1 Then
  232.                     s = "o"
  233.                 End If
  234.                 Me.Text = "GN TankBattle - tempo rimanente:" & Tempo.ToString & " second" & s & " - Nemici rimanenti:" & Nemici.Count
  235.             End If
  236.             If Tempo = 0 Then
  237.                 TimerTempo.Stop()
  238.                 TempoScaduto.Play(0, BufferPlayFlags.Default)
  239.                 Me.GeneraLivello()
  240.             End If
  241.         Loop
  242.     End Sub
  243.  
  244.     Function Rad(ByVal grad As Double) As Double
  245.         Return (grad * 2 * Math.PI) / 360
  246.     End Function
  247.  
  248.     Function NuovaMesh(ByVal fileSrc As String, ByVal materialiOn As Boolean, ByVal textureOn As Boolean, ByVal TexPath As String, ByVal pos As Vector3, ByVal rot As Vector3) As oggX
  249.         With NuovaMesh
  250.             Dim materiali() As ExtendedMaterial = Nothing
  251.             .mesh = Mesh.FromFile(fileSrc, MeshFlags.Dynamic, DispGrafico, materiali)
  252.             .numX = UBound(materiali)
  253.             ReDim .tex(.numX)
  254.             ReDim .mat(.numX)
  255.             Dim i As Integer
  256.             For i = 0 To .numX
  257.                 If textureOn Then
  258.                     If materiali(i).TextureFilename <> "" Then
  259.                         .tex(i) = TextureLoader.FromFile(DispGrafico, TexPath & "\" & materiali(i).TextureFilename)
  260.                     End If
  261.                 End If
  262.                 If materialiOn Then
  263.                     .mat(i) = materiali(i).Material3D
  264.                     .mat(i).Ambient = .mat(i).Diffuse
  265.                 End If
  266.             Next
  267.             .pos = pos
  268.             .rot = rot
  269.         End With
  270.     End Function
  271.  
  272.     Sub AggiungiMesh(ByVal Modello As oggX)
  273.         DispGrafico.Transform.World = Me.generaMatWorld(Modello)
  274.         For i As Integer = 0 To Modello.numX
  275.             DispGrafico.Material = Modello.mat(i)
  276.             DispGrafico.SetTexture(0, Modello.tex(i))
  277.             Modello.mesh.DrawSubset(i)
  278.         Next
  279.     End Sub
  280.  
  281.     Function generaMatWorld(ByVal m As oggX) As Matrix
  282.         Dim pos As Matrix = Matrix.Translation(m.pos)
  283.         Dim rot As Matrix = Matrix.RotationYawPitchRoll(m.rot.Y, m.rot.X, m.rot.Z)
  284.         Return Matrix.Multiply(rot, pos)
  285.     End Function
  286.  
  287.     Function CaricaSuono(ByVal src As String) As SecondaryBuffer
  288.         Dim d As New BufferDescription()
  289.         d.Flags = BufferDescriptionFlags.ControlPan Or BufferDescriptionFlags.ControlFrequency Or BufferDescriptionFlags.ControlVolume
  290.         Return New SecondaryBuffer(src, d, Suoni)
  291.     End Function
  292.  
  293.     Private Sub GameEngine_FormClosing(ByVal sender As System.Object, ByVal e As System.Windows.Forms.FormClosingEventArgs) Handles MyBase.FormClosing
  294.         End
  295.     End Sub
  296.  
  297.     Private Function DistanzaPunti(ByVal pt1 As Vector3, ByVal pt2 As Vector3) As Double
  298.         Dim dx As Double = pt2.X - pt1.X
  299.         Dim dy As Double = pt2.Z - pt1.Z
  300.         Dim d As Double = Math.Sqrt((dx ^ 2) + (dy ^ 2))
  301.         Return d
  302.     End Function
  303.  
  304.     Sub GeneraLivello()
  305.         Try
  306.             Livello = CInt(My.Computer.FileSystem.ReadAllText(Application.StartupPath & "\Livello.txt"))
  307.         Catch ex As Exception
  308.             If MsgBox("Impossibile leggere dal file livello.txt. Iniziare dal livello 1?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then
  309.                 Livello = 1
  310.                 My.Computer.FileSystem.WriteAllText(Application.StartupPath & "\Livello.txt", 1, False)
  311.             Else
  312.                 Application.Exit()
  313.             End If
  314.         End Try
  315.         If SchermoIntero = False Then
  316.             Control.CheckForIllegalCrossThreadCalls = False
  317.         End If
  318.         Tempo = 60
  319.         Nemici.Clear()
  320.         Proiettili.Clear()
  321.         CarroNemico = Me.NuovaMesh(Application.StartupPath & "\Grafica\Carro_Armato_Nemico\Mesh.x", True, True, Application.StartupPath & "\Grafica\Carro_Armato_Nemico\", New Vector3(0, 0, 0), New Vector3(0, 0, 0))
  322.         Dim Casuale As New Random()
  323.         For i As Integer = 1 To Livello
  324.             Dim pos As New Vector3()
  325.             Do
  326.                 pos = New Vector3(Casuale.Next(-100, 100), 0, Casuale.Next(-100, 100))
  327.                 CarroNemico.pos = pos
  328.                 If Nemici.Count <> 0 Then
  329.                     If Me.Collisione(CarroNemico, listaMesh(Nemici)) = False Then
  330.                         Nemici.Add(New Nemico(CarroNemico))
  331.                         Exit Do
  332.                     End If
  333.                 Else
  334.                     Nemici.Add(New Nemico(CarroNemico))
  335.                     Exit Do
  336.                 End If
  337.             Loop
  338.         Next
  339.         Giocatore = Me.NuovaMesh(Application.StartupPath & "\Grafica\Carro_Armato_Giocatore\Mesh.x", True, True, Application.StartupPath & "\Grafica\Carro_Armato_Giocatore\", New Vector3(Casuale.Next(-100, 100), 0, Casuale.Next(-100, 100)), New Vector3(0, 0, 0))
  340.         Terreno = Me.NuovaMesh(Application.StartupPath & "\Grafica\Terreno\Mesh.x", True, True, Application.StartupPath & "\Grafica\Terreno\", New Vector3(0, -9.5, 0), New Vector3(0, 0, 0))
  341.         TimerTempo.Start()
  342.     End Sub
  343.  
  344.     Function CollisioneGiocatore() As Boolean
  345.         Return Me.Collisione(Giocatore, listaMesh(Nemici))
  346.     End Function
  347.  
  348.     Function CollisioneNemico(ByVal i As Integer) As Boolean
  349.         Dim m1 As oggX = Nemici.Item(i).mesh
  350.         Dim m2 As New List(Of oggX)(listaMesh(Nemici))
  351.         m2.RemoveAt(i)
  352.         m2.Add(Giocatore)
  353.         Return Collisione(m1, m2)
  354.     End Function
  355.  
  356.     Function Collisione(ByVal mesh1 As oggX, ByVal mesh2 As List(Of oggX)) As Boolean
  357.         For Each i As oggX In mesh2
  358.             If CollisioneOggetto(mesh1, i) Then
  359.                 Return True
  360.                 Exit Function
  361.             End If
  362.         Next
  363.         Return False
  364.     End Function
  365.  
  366.     Sub BoundingBox(ByVal corrMesh As oggX, ByRef min As Vector3, ByRef max As Vector3)
  367.         Dim descr As VertexBufferDescription = corrMesh.mesh.VertexBuffer.Description
  368.         Dim vertexData As GraphicsStream = corrMesh.mesh.VertexBuffer.Lock(0, 0, LockFlags.ReadOnly)
  369.         Geometry.ComputeBoundingBox(vertexData, corrMesh.mesh.NumberVertices, descr.VertexFormat, min, max)
  370.         corrMesh.mesh.VertexBuffer.Unlock()
  371.         Dim t As Matrix = Me.generaMatWorld(corrMesh)
  372.         Return
  373.     End Sub
  374.  
  375.     Function CollisioneOggetto(ByVal m1 As oggX, ByVal m2 As oggX) As Boolean
  376.         Dim min1 As New Vector3()
  377.         Dim max1 As New Vector3()
  378.         Me.BoundingBox(m1, min1, max1)
  379.         Dim min2 As New Vector3()
  380.         Dim max2 As New Vector3()
  381.         Me.BoundingBox(m2, min2, max2)
  382.         Dim w As Double = max2.X - min2.X
  383.         Dim h As Double = max2.Z - min2.Z
  384.         Return m1.pos.X >= m2.pos.X AndAlso m1.pos.X <= m2.pos.X + w AndAlso m1.pos.Z >= m2.pos.Z AndAlso m1.pos.Z <= m2.pos.Z + h
  385.     End Function
  386.  
  387.     Private Sub TimerTempo_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TimerTempo.Tick
  388.         Tempo -= 1
  389.         Me.Text = "GN TankBattle - tempo rimanente:" & Tempo.ToString & " secondi - Nemici rimanenti:" & Nemici.Count
  390.     End Sub
  391.  
  392.     Function listaMesh(ByVal n As List(Of Nemico)) As List(Of oggX)
  393.         Dim m As New List(Of oggX)
  394.         For Each i As Nemico In n
  395.             m.Add(i.mesh)
  396.         Next
  397.         Return m
  398.     End Function
  399. End Class