This exciting and interactive app brings the thrill of tank battles to your screen, combining strategic gameplay with dynamic graphics and responsive controls. This project showcases a robust architecture that handles everything from turret mechanics to projectile management and audio integration.
In this app, users can control a tank, rotate its turret, fire projectiles, and navigate through a beautifully rendered environment. With support for Xbox controllers, the gameplay experience is enhanced, making it accessible for both keyboard enthusiasts and gamepad users.
Whether you’re a developer looking to explore game design principles or a gamer eager for a fun challenge, this repository offers a comprehensive look into the mechanics of game development. Dive in, explore the code, and unleash your creativity as you modify and expand upon this foundational project!
Join us on this journey to create an engaging tank battle experience!
Public Class Form1
- Public Class Form1: This line declares a new class named
Form1
. In Visual Basic, a class is a blueprint for creating objects. Here,Form1
will represent the main window of our application.
Private DeltaTime As New DeltaTimeStructure(Now, Now, TimeSpan.Zero)
- Private DeltaTime: This declares a variable named
DeltaTime
that will track the time between frames in the game. - New DeltaTimeStructure(Now, Now, TimeSpan.Zero): It creates a new instance of the
DeltaTimeStructure
, initializing it with the current time (Now
) and a zero time span.
Private OffScreen As New BufferManager(Me, BackColor)
- Private OffScreen: This variable handles off-screen rendering to reduce flickering during drawing operations.
- New BufferManager(Me, BackColor): It creates a new
BufferManager
object that takes the current form (Me
) and its background color (BackColor
) as parameters.
Private Player As AudioPlayer
- Private Player: This variable will manage audio playback in the game. It will be initialized later in the code.
Private Turret As Turret
- Private Turret: This variable will hold an instance of the
Turret
class, which manages the tank's turret.
Private Projectiles As New ProjectileManager(Brushes.Red, New Drawing.Size(10, 10), 200, 100, 9)
- Private Projectiles: This initializes a
ProjectileManager
to handle the game's projectiles. - Brushes.Red: Sets the projectile color to red.
- New Drawing.Size(10, 10): Sets the size of each projectile to 10x10 pixels.
- 200, 100, 9: These parameters define other behaviors of the projectiles, such as their speed and lifespan.
Private Controllers As XboxControllers
- Private Controllers: This variable will manage input from Xbox controllers.
Private ClientCenter As Point = New Point(ClientSize.Width / 2, ClientSize.Height / 2)
- Private ClientCenter: This calculates the center point of the client area (the drawable area) of the form, which is used for positioning objects.
Private Body As New Body(Brushes.Gray, New PointF(500, 500), 128, 64, 0, 0, 150, 30)
- Private Body: This creates an instance of the
Body
class, representing the tank's body. - Brushes.Gray: Sets the tank's color to gray.
- New PointF(500, 500): Sets the initial position of the tank to (500, 500).
- 128, 64, 0, 0, 150, 30: These parameters define the tank's dimensions and physics properties.
Dim Arrow As New ArrowVector(New Pen(Color.Black, 10), New PointF(640, 360), 0, 60, 70, 10, 15, 0, Body.MaxVelocity, 30)
- Dim Arrow: This defines an
ArrowVector
that visually represents the direction and velocity of the tank. - New Pen(Color.Black, 10): Initializes the arrow with a black pen of width 10.
- New PointF(640, 360): Sets the starting point of the arrow.
- 0, 60, 70, 10, 15, 0, Body.MaxVelocity, 30: Various parameters that define the arrow's behavior.
Private RelativeTurretAngle As Single
- Private RelativeTurretAngle: This variable will store the angle difference between the turret and the body of the tank.
Private ADown As Boolean
Private DDown As Boolean
Private WDown As Boolean
Private SDown As Boolean
Private EDown As Boolean
Private F1Down As Boolean
Private F1DownHandled As Boolean
Private F2Down As Boolean
Private F2DownHandled As Boolean
Private XDown As Boolean
Private LeftArrowDown As Boolean
Private RightArrowDown As Boolean
Private SpaceDown As Boolean
- Each of these variables tracks whether specific keys are currently pressed down. For example:
- ADown: Tracks if the 'A' key is pressed.
- WDown: Tracks if the 'W' key is pressed for moving forward.
- SpaceDown: Tracks if the spacebar is pressed for firing.
Private TimeToNextRotation As TimeSpan = TimeSpan.FromMilliseconds(1)
Private LastRotationTime As DateTime = Now
- Private TimeToNextRotation: Sets a minimal time interval for turret rotation.
- Private LastRotationTime: Records the last time the turret was rotated.
Private InstructionsFont As New Font("Segoe UI", 14)
Private InstructionsLocation As New Point(0, 0)
Private F1NoticeLocation As New PointF(0, 0)
- Private InstructionsFont: Defines the font used for displaying instructions.
- Private InstructionsLocation: Sets where the instruction text will appear on the screen.
Private HiddenHints As New String("Show / Hide Keyboard Hints > F1" & Environment.NewLine)
- Private HiddenHints: A string containing hints for keyboard controls.
Private KeyboardHintsText As New String("Show / Hide Keyboard Hints > F1" & Environment.NewLine & "Rotate Turret CounterClockwise > Left Arrow" & Environment.NewLine & ...)
- Private KeyboardHintsText: Provides detailed instructions for keyboard controls.
Private ControllerHintsText As New String("Show / Hide Keyboard Hints > F1" & Environment.NewLine & "Rotate Turret CounterClockwise > Right Thumbstick Left" & Environment.NewLine & ...)
- Private ControllerHintsText: Similar to the keyboard hints, this provides instructions for using a controller.
Private HintsText As String = KeyboardHintsText
- Private HintsText: This variable holds the current hints text to be displayed, initially set to keyboard hints.
Public Sub New()
InitializeComponent()
InitializeForm()
InitializeTimer()
Controllers.Initialize()
InitializeSounds()
Body.TimeToNextRotation = TimeSpan.FromMilliseconds(25)
Turret = New Turret(New Pen(Color.Black, 10), 50, Body.Center, 75, 0, TimeSpan.FromMilliseconds(100))
RelativeTurretAngle = Turret.AngleInDegrees - Body.AngleInDegrees
End Sub
- Public Sub New(): This is the constructor for the
Form1
class. It runs when an instance of the form is created. - InitializeComponent(): Sets up the form's components (like buttons, labels, etc.).
- InitializeForm(): Custom method to set additional properties for the form.
- InitializeTimer(): Sets up a timer for updating the game state.
- Controllers.Initialize(): Initializes the Xbox controllers for input.
- InitializeSounds(): Loads and prepares sound files for playback.
- Body.TimeToNextRotation = TimeSpan.FromMilliseconds(25): Sets the rotation interval for the tank body.
- Turret = New Turret(...): Creates a new turret instance with specified properties.
- RelativeTurretAngle = Turret.AngleInDegrees - Body.AngleInDegrees: Calculates the initial angle difference between the turret and the tank body.
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
DeltaTime.Update()
HandleUserInput()
Projectiles.UpdateProjectiles(DeltaTime.ElapsedTime)
Body.CheckWallBounce(Body.Body, ClientSize.Width, ClientSize.Height)
Body.Update(DeltaTime.ElapsedTime)
Turret.AngleInDegrees = (Body.AngleInDegrees + RelativeTurretAngle + 360) Mod 360
Arrow.Center = Body.Center
Arrow.AngleInDegrees = Body.AngleInDegrees
Arrow.Velocity = Body.Velocity
Arrow.Update(DeltaTime.ElapsedTime)
Turret.Center = Body.Center
HandleAudioPlayback()
Invalidate()
End Sub
- Private Sub Timer1_Tick(...): This method is called at regular intervals defined by the timer. It updates the game state.
- DeltaTime.Update(): Updates the elapsed time since the last frame.
- HandleUserInput(): Calls a method to process user input from the keyboard or controller.
- Projectiles.UpdateProjectiles(DeltaTime.ElapsedTime): Updates the state of all projectiles based on the elapsed time.
- Body.CheckWallBounce(...): Checks if the tank has hit any walls and adjusts its position accordingly.
- Body.Update(DeltaTime.ElapsedTime): Updates the tank's position and physics based on the elapsed time.
- Turret.AngleInDegrees = (Body.AngleInDegrees + RelativeTurretAngle + 360) Mod 360: Calculates the turret's angle based on the tank's current angle and the relative angle.
- Arrow.Center = Body.Center: Updates the arrow's center position to match the tank's position.
- Arrow.AngleInDegrees = Body.AngleInDegrees: Sets the arrow's angle to match the tank's angle.
- Arrow.Velocity = Body.Velocity: Updates the arrow's velocity based on the tank's current velocity.
- Arrow.Update(DeltaTime.ElapsedTime): Updates the arrow's position based on the elapsed time.
- Turret.Center = Body.Center: Sets the turret's position to match the tank's position.
- HandleAudioPlayback(): Manages the audio playback based on the tank's movement.
- Invalidate(): Requests to repaint the form, triggering the
OnPaint
method.
Protected Overrides Sub OnPaint(e As PaintEventArgs)
MyBase.OnPaint(e)
DrawFrame()
OffScreen.Buffered?.Render(e.Graphics)
OffScreen.EraseFrame()
End Sub
- Protected Overrides Sub OnPaint(...): This method is called when the form needs to be repainted.
- MyBase.OnPaint(e): Calls the base class's paint method to ensure proper rendering.
- DrawFrame(): Calls a custom method to draw the game elements.
- OffScreen.Buffered?.Render(e.Graphics): Renders the off-screen buffer onto the form's graphics.
- OffScreen.EraseFrame(): Clears the buffer for the next frame.
Protected Overrides Sub OnKeyDown(e As KeyEventArgs)
MyBase.OnKeyDown(e)
Select Case e.KeyCode
Case Keys.A
ADown = True
Case Keys.D
DDown = True
Case Keys.W
WDown = True
Case Keys.S
SDown = True
Case Keys.E
EDown = True
Case Keys.F1
F1Down = True
Case Keys.F2
F2Down = True
Case Keys.X
XDown = True
Case Keys.Left
LeftArrowDown = True
Case Keys.Right
RightArrowDown = True
Case Keys.Space
SpaceDown = True
End Select
End Sub
- Protected Overrides Sub OnKeyDown(...): This method handles key presses.
- Select Case e.KeyCode: Checks which key was pressed and sets the corresponding boolean variable to
True
.
Protected Overrides Sub OnKeyUp(e As KeyEventArgs)
MyBase.OnKeyUp(e)
Select Case e.KeyCode
Case Keys.A
ADown = False
Case Keys.D
DDown = False
Case Keys.W
WDown = False
Case Keys.S
SDown = False
Case Keys.E
EDown = False
Case Keys.F1
F1Down = False
F1DownHandled = False
Case Keys.F2
F2Down = False
F2DownHandled = False
Case Keys.X
XDown = False
Case Keys.Left
LeftArrowDown = False
Case Keys.Right
RightArrowDown = False
Case Keys.Space
SpaceDown = False
End Select
End Sub
- Protected Overrides Sub OnKeyUp(...): This method handles key releases.
- Select Case e.KeyCode: Checks which key was released and sets the corresponding boolean variable to
False
.
Private Sub Form1_Resize(sender As Object, e As EventArgs) Handles Me.Resize
If Not WindowState = FormWindowState.Minimized Then
ClientCenter = New Point(ClientSize.Width / 2, ClientSize.Height / 2)
Body.Center = ClientCenter
OffScreen.DisposeBuffer()
Timer1.Enabled = True
Else
Timer1.Enabled = False
End If
End Sub
- Private Sub Form1_Resize(...): This method handles resizing the form.
- If Not WindowState = FormWindowState.Minimized: Checks if the window is not minimized.
- ClientCenter = New Point(ClientSize.Width / 2, ClientSize.Height / 2): Updates the center based on the new size.
- Body.Center = ClientCenter: Centers the tank body to the new client center.
- OffScreen.DisposeBuffer(): Disposes of the current off-screen buffer to prepare for a new one.
- Timer1.Enabled = True: Starts the timer if the window is not minimized.
- Else Timer1.Enabled = False: Stops the timer if the window is minimized.
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles Me.Load
ClientCenter = New Point(ClientSize.Width / 2, ClientSize.Height / 2)
End Sub
- Private Sub Form1_Load(...): This method runs when the form is loaded.
- ClientCenter = New Point(ClientSize.Width / 2, ClientSize.Height / 2): Initializes the center point of the client area.
Private Sub DrawFrame()
OffScreen.AllocateBuffer(Me)
OffScreen.Buffered.Graphics.DrawString(HintsText, InstructionsFont, Brushes.Black, InstructionsLocation)
Body.Draw(OffScreen.Buffered.Graphics, ClientSize)
Arrow.Draw(OffScreen.Buffered.Graphics)
Projectiles.DrawProjectiles(OffScreen.Buffered.Graphics)
Turret.Draw(OffScreen.Buffered.Graphics)
End Sub
- Private Sub DrawFrame(): This method handles drawing the game elements.
- OffScreen.AllocateBuffer(Me): Allocates a new buffer for off-screen drawing.
- OffScreen.Buffered.Graphics.DrawString(...): Draws the hints text on the screen.
- Body.Draw(...), Arrow.Draw(...), Projectiles.DrawProjectiles(...), Turret.Draw(...): Calls the draw methods for each game element to render them onto the buffer.
Private Sub HandleUserInput()
Controllers.Update()
HandleKeyPresses()
HandleControllerInput()
End Sub
- Private Sub HandleUserInput(): This method processes user input.
- Controllers.Update(): Updates the state of the controllers.
- HandleKeyPresses(): Calls a method to handle keyboard input.
- HandleControllerInput(): Calls a method to handle controller input.
Private Sub HandleKeyPresses()
If ADown Then
Body.RotateCounterClockwise()
End If
If DDown Then
Body.RotateClockwise()
End If
If WDown Then
If Body.Velocity < Body.MaxVelocity Then
Body.Velocity += 1
Else
Body.Velocity = Body.MaxVelocity
End If
ElseIf SDown Then
If Body.Velocity > -Body.MaxVelocity Then
Body.Velocity += -1
Else
Body.Velocity = -Body.MaxVelocity
End If
Else
Body.Decelerate(DeltaTime.ElapsedTime)
End If
If EDown Then
Body.EmergencyStop(DeltaTime.ElapsedTime)
If Body.Velocity <> 0 Then
If Not Player.IsPlaying("emergencystop") Then
Player.PlaySound("emergencystop")
End If
Else
If Player.IsPlaying("emergencystop") Then
Player.PauseSound("emergencystop")
End If
End If
ElseIf Not Controllers.B(0) Then
If Player.IsPlaying("emergencystop") Then
Player.PauseSound("emergencystop")
End If
End If
If F1Down Then
If Body.ShowControllerHints Then Body.ShowControllerHints = False
If Body.ShowKeyboardHints Then
If Not F1DownHandled Then
Body.ShowKeyboardHints = False
HintsText = HiddenHints
F1DownHandled = True
End If
Else
If Not F1DownHandled Then
Body.ShowKeyboardHints = True
HintsText = KeyboardHintsText
F1DownHandled = True
End If
End If
End If
If F2Down Then
If Body.ShowKeyboardHints Then Body.ShowKeyboardHints = False
If Body.ShowControllerHints Then
If Not F2DownHandled Then
Body.ShowControllerHints = False
HintsText = HiddenHints
F2DownHandled = True
End If
Else
If Not F2DownHandled Then
Body.ShowControllerHints = True
HintsText = ControllerHintsText
F2DownHandled = True
End If
End If
End If
If XDown OrElse SpaceDown Then
FireProjectile()
End If
If LeftArrowDown Then
RotateTurretCounterClockwise()
End If
If RightArrowDown Then
RotateTurretClockwise()
End If
End Sub
- Private Sub HandleKeyPresses(): This method processes the state of the tank based on key presses.
- If ADown Then Body.RotateCounterClockwise(): If the 'A' key is pressed, the tank rotates counterclockwise.
- If DDown Then Body.RotateClockwise(): If the 'D' key is pressed, the tank rotates clockwise.
- If WDown Then: If the 'W' key is pressed, the tank accelerates.
- If Body.Velocity < Body.MaxVelocity Then: Checks if the tank's velocity is less than its maximum speed.
- Body.Velocity += 1: Increases the tank's velocity by 1.
- Else Body.Velocity = Body.MaxVelocity: Sets the velocity to the maximum if it exceeds it.
- ElseIf SDown Then: If the 'S' key is pressed, the tank reverses.
- Similar logic checks if the velocity can be decreased or sets it to the maximum reverse speed.
- Else Body.Decelerate(DeltaTime.ElapsedTime): If neither 'W' nor 'S' is pressed, the tank decelerates based on the elapsed time.
- If EDown Then: If the 'E' key is pressed, it triggers an emergency stop.
- Body.EmergencyStop(DeltaTime.ElapsedTime): Stops the tank immediately.
- Checks if the emergency stop sound is playing and plays or pauses it accordingly.
- If F1Down Then: If the 'F1' key is pressed, it toggles the visibility of keyboard hints.
- If F2Down Then: If the 'F2' key is pressed, it toggles the visibility of controller hints.
- If XDown OrElse SpaceDown Then FireProjectile(): If either the 'X' key or spacebar is pressed, it triggers the firing of a projectile.
- If LeftArrowDown Then RotateTurretCounterClockwise(): If the left arrow key is pressed, it rotates the turret counterclockwise.
- If RightArrowDown Then RotateTurretClockwise(): If the right arrow key is pressed, it rotates the turret clockwise.
Private Sub RotateTurretClockwise()
Dim TimeSinceLastRotation As TimeSpan = Now - LastRotationTime
If TimeSinceLastRotation > TimeToNextRotation Then
Dim AngleInDegrees = (Turret.AngleInDegrees + 1) Mod 360
RelativeTurretAngle = (AngleInDegrees - Body.AngleInDegrees + 360) Mod 360
LastRotationTime = Now
End If
End Sub
- Private Sub RotateTurretClockwise(): This method handles the clockwise rotation of the turret.
- Dim TimeSinceLastRotation As TimeSpan = Now - LastRotationTime: Calculates the time since the last rotation.
- If TimeSinceLastRotation > TimeToNextRotation Then: Checks if enough time has passed to allow another rotation.
- Dim AngleInDegrees = (Turret.AngleInDegrees + 1) Mod 360: Increments the turret's angle by 1 degree, ensuring it stays within a 0-359 degree range using modulo 360.
- RelativeTurretAngle = (AngleInDegrees - Body.AngleInDegrees + 360) Mod 360: Updates the relative angle of the turret compared to the body.
- LastRotationTime = Now: Updates the last rotation time to the current time.
Private Sub RotateTurretCounterClockwise()
Dim TimeSinceLastRotation As TimeSpan = Now - LastRotationTime
If TimeSinceLastRotation > TimeToNextRotation Then
Dim AngleInDegrees = (Turret.AngleInDegrees - 1 + 360) Mod 360
RelativeTurretAngle = (AngleInDegrees - Body.AngleInDegrees + 360) Mod 360
LastRotationTime = Now
End If
End Sub
- Private Sub RotateTurretCounterClockwise(): This method handles the counterclockwise rotation of the turret.
- The logic is similar to the clockwise rotation method, but it decrements the angle instead.
Private Sub FireProjectile()
If Now - Turret.LastFireTime > Turret.TimeToNextFire Then
Player.PlayOverlapping("gunshot")
Projectiles.FireProjectile(Turret.Center, Turret.AngleInDegrees)
Turret.LastFireTime = Now
End If
End Sub
- Private Sub FireProjectile(): This method handles firing a projectile from the turret.
- If Now - Turret.LastFireTime > Turret.TimeToNextFire Then: Checks if enough time has passed since the last shot.
- Player.PlayOverlapping("gunshot"): Plays the gunshot sound effect.
- Projectiles.FireProjectile(Turret.Center, Turret.AngleInDegrees): Fires a projectile from the turret's center at its current angle.
- Turret.LastFireTime = Now: Updates the last fire time to the current time.
Private Sub HandleControllerInput()
If Controllers.LeftThumbstickLeft(0) Then
Body.RotateCounterClockwise()
End If
If Controllers.LeftThumbstickRight(0) Then
Body.RotateClockwise()
End If
If Controllers.A(0) OrElse Controllers.LeftStick(0) Then
If Body.Velocity < Body.MaxVelocity Then
Body.Velocity += 1
Else
Body.Velocity = Body.MaxVelocity
End If
ElseIf Controllers.Y(0) Then
If Body.Velocity > -Body.MaxVelocity Then
Body.Velocity += -1
Else
Body.Velocity = -Body.MaxVelocity
End If
Else
Body.Decelerate(DeltaTime.ElapsedTime)
End If
If Controllers.B(0) Then
Body.EmergencyStop(DeltaTime.ElapsedTime)
If Body.Velocity <> 0 Then
If Not Player.IsPlaying("emergencystop") Then
Player.PlaySound("emergencystop")
End If
Controllers.TimeToVibe = 50
Controllers.VibrateRight(0, 32000)
Else
If Player.IsPlaying("emergencystop") Then
Player.PauseSound("emergencystop")
End If
End If
ElseIf Not EDown Then
If Player.IsPlaying("emergencystop") Then
Player.PauseSound("emergencystop")
End If
End If
If Controllers.X(0) OrElse Controllers.RightTrigger(0) Then
FireProjectile()
End If
If Controllers.RightThumbstickLeft(0) Then
RotateTurretCounterClockwise()
End If
If Controllers.RightThumbstickRight(0) Then
RotateTurretClockwise()
End If
End Sub
- Private Sub HandleControllerInput(): This method processes input from the Xbox controller.
- If Controllers.LeftThumbstickLeft(0): If the left thumbstick is moved left, the tank rotates counterclockwise.
- If Controllers.LeftThumbstickRight(0): If the left thumbstick is moved right, the tank rotates clockwise.
- If Controllers.A(0) OrElse Controllers.LeftStick(0): If button A is pressed or the left stick is pushed forward, it accelerates the tank.
- If Controllers.Y(0): If button Y is pressed, it reverses the tank.
- Else Body.Decelerate(DeltaTime.ElapsedTime): If neither button is pressed, the tank decelerates.
- If Controllers.B(0): If button B is pressed, the tank performs an emergency stop.
- If Body.Velocity <> 0: If the tank is moving, it plays the emergency stop sound and vibrates the controller.
- If Controllers.X(0) OrElse Controllers.RightTrigger(0): If button X or the right trigger is pressed, it fires a projectile.
- If Controllers.RightThumbstickLeft(0): If the right thumbstick is moved left, it rotates the turret counterclockwise.
- If Controllers.RightThumbstickRight(0): If the right thumbstick is moved right, it rotates the turret clockwise.
Private Sub HandleAudioPlayback()
If Body.Velocity <> 0 Then
If Not Player.IsPlaying("running") Then
Player.LoopSound("running")
End If
If Player.IsPlaying("idle") Then
Player.PauseSound("idle")
End If
Else
If Not Player.IsPlaying("idle") Then
Player.LoopSound("idle")
End If
If Player.IsPlaying("running") Then
Player.PauseSound("running")
End If
End If
End Sub
- Private Sub HandleAudioPlayback(): This method manages the background sounds based on the tank's movement state.
- If Body.Velocity <> 0: If the tank is moving, it plays the running sound.
- If Not Player.IsPlaying("running"): Ensures the running sound is not already playing before looping it.
- If Player.IsPlaying("idle"): If the idle sound is playing, it pauses it.
- Else: If the tank is not moving, it plays the idle sound and pauses the running sound if it’s playing.
Private Sub InitializeForm()
CenterToScreen()
SetStyle(ControlStyles.UserPaint, True)
SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True)
Text = "Tank - Code with Joe"
WindowState = FormWindowState.Maximized
End Sub
- Private Sub InitializeForm(): This method sets up the form's properties.
- CenterToScreen(): Centers the form on the screen.
- SetStyle(ControlStyles.UserPaint, True): Allows custom painting on the form.
- SetStyle(ControlStyles.OptimizedDoubleBuffer Or ControlStyles.AllPaintingInWmPaint, True): Enables double buffering to reduce flickering during rendering.
- Text = "Tank - Code with Joe": Sets the window title.
- WindowState = FormWindowState.Maximized: Starts the form in a maximized state.
Private Sub InitializeTimer()
Timer1.Interval = 15
Timer1.Start()
End Sub
- Private Sub InitializeTimer(): This method sets up the game timer.
- Timer1.Interval = 15: Sets the timer to tick every 15 milliseconds.
- Timer1.Start(): Starts the timer.
Private Sub InitializeSounds()
CreateSoundFiles()
Dim FilePath As String = Path.Combine(Application.StartupPath, "idle.mp3")
Player.AddSound("idle", FilePath)
Player.SetVolume("idle", 300)
Player.LoopSound("idle")
FilePath = Path.Combine(Application.StartupPath, "running.mp3")
Player.AddSound("running", FilePath)
Player.SetVolume("running", 400)
FilePath = Path.Combine(Application.StartupPath, "emergencystop.mp3")
Player.AddSound("emergencystop", FilePath)
Player.SetVolume("emergencystop", 1000)
FilePath = Path.Combine(Application.StartupPath, "gunshot.mp3")
Player.AddOverlapping("gunshot", FilePath)
Player.SetVolume("gunshot", 1000)
End Sub
- Private Sub InitializeSounds(): This method initializes all sound effects used in the game.
- CreateSoundFiles(): Calls a method to create sound files from resources.
- Dim FilePath As String = Path.Combine(Application.StartupPath, "idle.mp3"): Defines the path to the sound files.
- Player.AddSound("idle", FilePath): Loads the idle sound into the audio player.
- Player.SetVolume(...): Sets the volume for each sound effect.
- Player.LoopSound("idle"): Loops the idle sound when the game starts.
Private Sub CreateSoundFiles()
Dim FilePath As String = Path.Combine(Application.StartupPath, "idle.mp3")
CreateFileFromResource(FilePath, My.Resources.Resource1.idle)
FilePath = Path.Combine(Application.StartupPath, "running.mp3")
CreateFileFromResource(FilePath, My.Resources.Resource1.running)
FilePath = Path.Combine(Application.StartupPath, "emergencystop.mp3")
CreateFileFromResource(FilePath, My.Resources.Resource1.emergencystop)
FilePath = Path.Combine(Application.StartupPath, "gunshot.mp3")
CreateFileFromResource(FilePath, My.Resources.Resource1.gunshot003)
End Sub
- Private Sub CreateSoundFiles(): This method creates sound files from embedded resources.
- CreateFileFromResource(...): Calls a helper method to create the file if it doesn't exist.
Private Sub CreateFileFromResource(filepath As String, resource As Byte())
Try
If Not IO.File.Exists(filepath) Then
IO.File.WriteAllBytes(filepath, resource)
End If
Catch ex As Exception
Debug.Print($"Error creating file: {ex.Message}")
End Try
End Sub
- Private Sub CreateFileFromResource(...): This method creates a file from a byte array resource.
- If Not IO.File.Exists(filepath): Checks if the file already exists.
- IO.File.WriteAllBytes(filepath, resource): Writes the resource to a file.
- Catch ex As Exception: Catches any exceptions that occur during file creation and prints an error message to the debug output.
- Understanding how to manage game state using timers and events.
- Learning how to handle user input from both keyboard and controllers.
- Implementing basic game mechanics like movement, rotation, and firing.
- Managing audio playback for a more immersive experience.
Feel free to explore the code further and modify it to enhance your understanding of game development principles. Happy coding!
-
Open Visual Studio:
- Launch Visual Studio on your computer.
-
Go to the Start Window:
- If you're on the start window, look for the "Clone a repository" option. If you have a project open, you can access this by going to File > Open > Clone....
-
Enter Repository URL:
- In the "Clone a repository" dialog, enter the URL of the repository you want to clone in the "Repository location" field.
-
Select Local Path:
- Choose the local path where you want to clone the repository by clicking the "Browse" button.
-
Click Clone:
- After entering the URL and selecting the local path, click the "Clone" button.
-
Open the Cloned Repository:
- Once cloning is complete, Visual Studio will open the cloned repository, and you can start working on it.
Watch Cloning a repo video.