⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 frmplay.frm

📁 也是坦克大战
💻 FRM
字号:
VERSION 5.00
Begin VB.Form frmPlay 
   BorderStyle     =   0  'None
   Caption         =   "Tank War"
   ClientHeight    =   3195
   ClientLeft      =   0
   ClientTop       =   0
   ClientWidth     =   4680
   ControlBox      =   0   'False
   Icon            =   "frmPlay.frx":0000
   LinkTopic       =   "Form1"
   ScaleHeight     =   3195
   ScaleWidth      =   4680
   ShowInTaskbar   =   0   'False
   StartUpPosition =   3  'Windows Default
End
Attribute VB_Name = "frmPlay"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = False
Option Explicit

Dim DirectX As DirectX7
Dim DDraw As DirectDraw7
Dim DSound As DirectSound
Dim DInput As DirectInput

Dim diDevice As DirectInputDevice

Dim Primary As DirectDrawSurface7
Dim BackBuffer As DirectDrawSurface7

Dim Sounds As Collection    ' Store DirectSoundBuffer objects in this.

Dim tank1 As cTank
Dim tank2 As cTank
Dim Stars As Collection     ' Store cSprite Star in this.

Dim ddsd1 As DDSURFACEDESC2, ddsdScreen As DDSURFACEDESC2

Dim Surfaces As Collection  ' Store all other DirectDrawSurfaces in this.

Dim blnInitialized As Boolean

Dim intWinner As Integer

Dim Score(1 To 2) As Integer

Dim GameState As PlayStates

Private Enum PlayStates
    psStartUp = 0
    psPlaying = 1
    psEnd = 2
End Enum

Sub Init()
    On Local Error GoTo ErrHandler
    
    Set DirectX = New DirectX7
    Set DDraw = DirectX.DirectDrawCreate("")
    Set DSound = DirectX.DirectSoundCreate("")
    Set DInput = DirectX.DirectInputCreate
    
    ' ----- Direct Draw -------
    With DDraw
        .SetCooperativeLevel Me.hWnd, DDSCL_ALLOWMODEX Or DDSCL_EXCLUSIVE Or DDSCL_FULLSCREEN
        .SetDisplayMode 640, 480, 16, 0, DDSDM_DEFAULT
    End With
    
    ' ------- Direct Sound -----
    DSound.SetCooperativeLevel Me.hWnd, DSSCL_PRIORITY
    
    ' ------ Direct Input -----
    Set diDevice = DInput.CreateDevice("GUID_SysKeyBoard")
    
    diDevice.SetCommonDataFormat DIFORMAT_KEYBOARD
    diDevice.SetCooperativeLevel Me.hWnd, DISCL_BACKGROUND Or DISCL_NONEXCLUSIVE
    
    diDevice.Acquire
    
    ' -------- Primary ---------
    With ddsd1
        .lFlags = DDSD_CAPS Or DDSD_BACKBUFFERCOUNT
        .ddsCaps.lCaps = DDSCAPS_COMPLEX Or DDSCAPS_FLIP Or DDSCAPS_PRIMARYSURFACE
        .lBackBufferCount = 1
    End With
    
    Set Primary = DDraw.CreateSurface(ddsd1)
    
    ' ------- Backbuffer ------
    Dim caps As DDSCAPS2
    
    caps.lCaps = DDSCAPS_BACKBUFFER
    Set BackBuffer = Primary.GetAttachedSurface(caps)
    
    BackBuffer.GetSurfaceDesc ddsdScreen
    BackBuffer.SetFontTransparency True
    BackBuffer.SetForeColor 0
    With Me.Font
        .Name = "Courier New"
        .Size = 14
        .Bold = True
    End With
    BackBuffer.SetFont Me.Font
    
    InitSounds
    initSurfaces
    
    blnInitialized = True
    
    Exit Sub    ' Don't crash into ErrHandler!
    
ErrHandler:
    Debug.Print "Error init"
    Debug.Print Err.Description
    ' If we can't initialize DirectX then quit.
    EndIt
End Sub

Sub InitSounds()
    Set Sounds = New Collection
    
    Dim dsb As DirectSoundBuffer
    Dim bufferDesc As DSBUFFERDESC
    Dim waveFormat As WAVEFORMATEX
    Dim strFile As String
    
    bufferDesc.lFlags = DSBCAPS_CTRLFREQUENCY Or DSBCAPS_CTRLPAN Or DSBCAPS_CTRLVOLUME Or DSBCAPS_STATIC
    
    With waveFormat
        .nFormatTag = WAVE_FORMAT_PCM
        .nChannels = 1
        .lSamplesPerSec = 22050
        .nBitsPerSample = 16
        .nBlockAlign = .nBitsPerSample / 8 * .nChannels
        .lAvgBytesPerSec = .lSamplesPerSec * .nBlockAlign
    End With
    
    strFile = App.Path & "\explode.wav"
    Set dsb = DSound.CreateSoundBufferFromFile(strFile, bufferDesc, waveFormat)
    Sounds.Add dsb, "Explode1"
    Sounds.Add dsb, "Explode2"
    
    strFile = App.Path & "\score.wav"
    Set dsb = DSound.CreateSoundBufferFromFile(strFile, bufferDesc, waveFormat)
    Sounds.Add dsb, "Score"
End Sub

Sub initSurfaces()
    Dim dds As DirectDrawSurface7
    Dim key As DDCOLORKEY
    
    key.high = 0
    key.low = 0
    
    On Error Resume Next
    Surfaces.Remove "Tank"
    Surfaces.Remove "Bullet"
    Surfaces.Remove "Back"
    Surfaces.Remove "Star"
    Surfaces.Remove "StartUp"
    On Error GoTo 0
    
    ' ------ Back Ground ------
    With ddsd1
        .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
        .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
        .lWidth = 640
        .lHeight = 480
    End With
    Set dds = DDraw.CreateSurfaceFromFile(App.Path & "\back.bmp", ddsd1)
    Surfaces.Add dds, "Back"
    
    ' ------- Tank ----------
    With ddsd1
        .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
        .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
        .lWidth = 116
        .lHeight = 64
    End With
    Set dds = Nothing
    Set dds = DDraw.CreateSurfaceFromFile(App.Path & "\tank01.bmp", ddsd1)
    dds.SetColorKey DDCKEY_SRCBLT, key
    
    Surfaces.Add dds, "Tank"
    
    ' ------ Bullet -------
    Set dds = Nothing
    With ddsd1
        .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
        .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
        .lWidth = 20
        .lHeight = 5
    End With
    Set dds = DDraw.CreateSurfaceFromFile(App.Path & "\bullet01.bmp", ddsd1)
    dds.SetColorKey DDCKEY_SRCBLT, key
    
    Surfaces.Add dds, "Bullet"
    
    ' ------ Star ---------
    Set dds = Nothing
    With ddsd1
        .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
        .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
        .lWidth = 9
        .lHeight = 8
    End With
    Set dds = DDraw.CreateSurfaceFromFile(App.Path & "\Star01.bmp", ddsd1)
    dds.SetColorKey DDCKEY_SRCBLT, key
    
    Surfaces.Add dds, "Star"
    
    ' ------ StartUp -------
    Set dds = Nothing
    With ddsd1
        .lFlags = DDSD_CAPS Or DDSD_WIDTH Or DDSD_HEIGHT
        .ddsCaps.lCaps = DDSCAPS_OFFSCREENPLAIN
        .lWidth = 640
        .lHeight = 480
    End With
    Set dds = DDraw.CreateSurfaceFromFile(App.Path & "\startup.bmp", ddsd1)
    
    Surfaces.Add dds, "StartUp"
    
    
    initTanks
    initStars
End Sub

Sub initStars()
    Set Stars = New Collection
    
    Dim oStar As cSprite
    Dim i As Integer
    Randomize
    
    For i = 1 To 41
        Set oStar = New cSprite
        
        With oStar
            .LoadData App.Path & "\Star01.spr"
            .x = (Rnd * 520) + 100
            .Y = (Rnd * 440) + 20
            .Direction = dirUp
            Set .ddsBackBuffer = BackBuffer
            Set .ddsBitmap = Surfaces("Star")
        End With
        
        Stars.Add oStar
    Next i
End Sub

Sub Blt()
    Static Paused(1 To 2) As Integer
    
    If Not blnInitialized Then Exit Sub ' DirectX must be ready...
    
    On Local Error GoTo ErrHandler
    
    Dim blnRestore As Boolean
    Dim rc As RECT          ' Multi-use variable.
    
    blnRestore = False
    Do Until ExModeActive
        blnRestore = True
        DoEvents
    Loop
    
    DoEvents
    
    If blnRestore Then
        blnRestore = False
        DDraw.RestoreAllSurfaces
        Call initSurfaces
    End If
    
    ' Do drawing here...
    rc = AssignRect(0, 0, 640, 480)
    BackBuffer.BltFast 0, 0, Surfaces("Back"), rc, DDBLTFAST_WAIT
    'Debug.Print "Checking stars...";
    checkStars tank1
    checkStars tank2
    'Debug.Print "done"
    drawStars
    
    If Paused(1) = 0 Then
        tank1.moveTank
    Else
        Paused(1) = Paused(1) - 1
        tank1.MoveBullets
    End If
    If Paused(2) = 0 Then
        tank2.moveTank
    Else
        Paused(2) = Paused(2) - 1
        tank2.MoveBullets
    End If
    If tank1.Collsion(tank2) And Paused(2) = 0 Then
        PlaySound "Explode1"
        tank2.x = 620
        tank2.Y = 460
        tank2.Direction = dirLeft
        Paused(2) = 30
        tank1.Score = tank1.Score + tank2.Score
        tank2.Score = 0
    End If
    If tank2.Collsion(tank1) And Paused(1) = 0 Then
        PlaySound "Explode2"
        tank1.x = 120
        tank1.Y = 20
        tank1.Direction = dirRight
        Paused(1) = 30
        tank2.Score = tank2.Score + tank1.Score
        tank1.Score = 0
    End If
    tank1.drawTank
    tank2.drawTank
    drawScores
    
    Primary.Flip Nothing, DDFLIP_WAIT
    
    If Stars.Count = 0 Then intWinner = IIf(tank1.Score > tank2.Score, 1, 2)
    
    Exit Sub
ErrHandler:
    ' Just don't draw.
    Debug.Print Err.Number, Err.Description
End Sub

Sub EndIt()
    If Not (DDraw Is Nothing) Then
        With DDraw
            .RestoreAllSurfaces
            .SetCooperativeLevel Me.hWnd, DDSCL_NORMAL
        End With
    End If
    
    diDevice.Unacquire
    
    Set DInput = Nothing
    Set diDevice = Nothing
    Set DSound = Nothing
    Set Sounds = Nothing
    Set Surfaces = Nothing
    Set Stars = Nothing
    Set Primary = Nothing
    Set BackBuffer = Nothing
    Set DDraw = Nothing
    Set DirectX = Nothing
    
    ShowCursor True
    Unload Me
    End
End Sub

Function ExModeActive() As Boolean
    Dim lngVal As Long
    
    lngVal = DDraw.TestCooperativeLevel
    
    ExModeActive = (lngVal = DD_OK)
End Function

Private Sub Form_Load()
    Dim rc As RECT
    Dim diState As DIKEYBOARDSTATE
    Dim blnRestore As Boolean
    Dim blnJustQuit As Boolean
    Dim l As Single
    
    Set Surfaces = New Collection
    
    ShowCursor False
    
    Me.Show
    DoEvents
    Init
    
    rc = AssignRect(0, 0, 640, 480)
    
    'On Error GoTo ErrStop
    
    Do
        diDevice.GetDeviceStateKeyboard diState
        
        Select Case GameState
        Case psStartUp
        
            Do Until ExModeActive
                blnRestore = True
                DoEvents
            Loop
            If blnRestore Then initSurfaces
            
            If Not blnJustQuit Then
                If diState.key(DIK_ESCAPE) Then
                    Exit Do
                End If
                If diState.key(DIK_RETURN) Then
                    initTanks
                    initStars
                    intWinner = 0
                    GameState = psPlaying
                End If
            Else
                If Timer > l + 0.2 Then blnJustQuit = False
            End If
            
            BackBuffer.BltFast 0, 0, Surfaces("StartUp"), rc, DDBLTFAST_WAIT
            Primary.Flip Nothing, DDFLIP_WAIT
            
            DoEvents
            
        Case psPlaying
            With diState
                If .key(DIK_UP) Then tank1.Direction = dirUp
                If .key(DIK_RIGHT) Then tank1.Direction = dirRight
                If .key(DIK_DOWN) Then tank1.Direction = dirDown
                If .key(DIK_LEFT) Then tank1.Direction = dirLeft
                If .key(DIK_RCONTROL) Then tank1.Fire
                
                If .key(DIK_W) Then tank2.Direction = dirUp
                If .key(DIK_D) Then tank2.Direction = dirRight
                If .key(DIK_S) Then tank2.Direction = dirDown
                If .key(DIK_A) Then tank2.Direction = dirLeft
                If .key(DIK_LCONTROL) Then tank2.Fire
            End With
            
            Blt
            
            If intWinner > 0 Then GameState = psEnd
            
            If diState.key(DIK_ESCAPE) Then
                DoEvents
                GameState = psStartUp
                l = Timer
                blnJustQuit = True
            End If
            
        Case psEnd
            BackBuffer.SetForeColor vbWhite
            BackBuffer.BltColorFill rc, 0
            BackBuffer.DrawText 200, 200, "Well Done Player " & CStr(intWinner), False
            BackBuffer.DrawText 200, 300, "Press Space to continue...", False
            Primary.Flip Nothing, DDFLIP_WAIT
            
            With diState
                If .key(DIK_SPACE) Then
                    GameState = psStartUp
                End If
            End With
            
        End Select
        
        DoEvents
    Loop Until False
    
ErrStop:
    If Err.Number <> 0 Then Debug.Print Err.Description
    
    DoEvents
    
    EndIt
End Sub

Private Sub Form_Paint()
    Blt
End Sub

Private Sub Form_Unload(Cancel As Integer)
    Set frmPlay = Nothing
End Sub

Sub drawScores()
    BackBuffer.DrawText 50, 70, CStr(tank1.Score), False
    BackBuffer.DrawText 50, 119, CStr(tank2.Score), False
End Sub

Sub drawStars()
    Dim oStar As cSprite
    
    For Each oStar In Stars
        oStar.drawSprite
    Next
End Sub

Sub checkStars(tank As cTank)
    Dim oStar As cSprite
    Dim tmp As Collection
    Dim i As Integer
    Dim blnRemoved As Boolean
    Set tmp = Stars
    
    For i = tmp.Count To 1 Step -1
        Set oStar = tmp(i)
        If RectCollision(oStar.RectOnScreen, tank.RectOnScreen) Then
            'Debug.Print "Removing " & i
            Stars.Remove i
            'Debug.Print "done"
            tank.Score = tank.Score + 100
            blnRemoved = True
        End If
    Next i
    
    If blnRemoved Then PlaySound "Score"
End Sub

Sub PlaySound(strKey As String)
    Dim dsb As DirectSoundBuffer
    
    Set dsb = Sounds(strKey)
    dsb.Play DSBPLAY_DEFAULT
End Sub

Sub initTanks()
    Set tank1 = New cTank
    With tank1
        .initTank Surfaces("Tank"), BackBuffer, Surfaces("Bullet")
        .x = 120
        .Y = 20
        .Group = 1
        .Speed = 10
        .ClearBullets
        .Score = 0
    End With
    
    Set tank2 = New cTank
    With tank2
        .initTank Surfaces("Tank"), BackBuffer, Surfaces("Bullet")
        .x = 620
        .Y = 460
        .Group = 2
        .Speed = 10
        .Direction = dirLeft
        .ClearBullets
        .Score = 0
    End With
End Sub

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -