none
Best Way to Add Enemies? RRS feed

  • Question

  • Hello,

    I have a question regarding coding a game. What would you suggest is the best way to add enemies to it? I have considered using an array of sprites but do not have the coding expertise to know how to do it.

    Thanks,

    The Visual Basic N00B

    Friday, February 16, 2018 9:50 PM

Answers

  • Hello,

    I have a question regarding coding a game. What would you suggest is the best way to add enemies to it? I have considered using an array of sprites but do not have the coding expertise to know how to do it.

    Thanks,

    The Visual Basic N00B

    This question is really just a small part of the larger question, "how do I design a game engine?" and the answer to that question is to follow proven game engine design techniques.  The following is a brief explanation of the general high-level design skeleton behind most modern game engines (including Unreal Engine and Unity).  Of course each engine is unique and there are different ways to implement the general principles; this explanation is meant to provide a loosely defined framework to follow.

    First you need to define some kind of GameObject class that will represent anything and everything in the game.  Similar to how the Object class in VB represents the base type of all other classes.  Generally a GameObject has some kind of unique identifier, a position in the game world, functionality to initialize itself and functionality to update itself (usually called once per frame).  It may also have some kind of collision information, though this could be deferred to a descendant class or add-on behavior.

    While various engines will handle it differently, there will generally be a way to extend the generic GameObject into more specific objects such as Sprites, which are GameObjects with a visual component.  As mentioned, collision as well as rigid-body physics are functionality which would typically be provided by some extension of the generic GameObject class. These extensions might come in the form of child-classes deriving from GameObject or as componentized behaviors which can be added to GameObject instances.

    The second primary component is the main game engine loop.  Again, there are many ways to implement it but every game engine needs to run a loop of code to continuously process the game.  In general, this loop will take the following steps:

    1. Update world-time
    2. Clear the graphics state
    3. Clean up dead game objects
    4. Update the state of each game object
    5. Update collision between objects
    6. Draw each visible object to the graphics state
    7. Render the current graphics frame
    8. Update user input

    The GameEngine just needs to maintain an active list of GameObjects that will be managed and executed on each pass of the game loop.

    Hopefully this makes it clear how your game's enemy instances would just be more GameObjects being handled on each iteration of the game loop.

    If you'd like to peruse an example of a game engine implementation in code, you can view the PuppyBreath code on GitHub and look at the GameObject and RenderCanvas implementations.  This code is in development and I have some changes that have not been pushed out yet (the collision on GameObject has changed), but the currently published version can still be reviewed as an example implementation of a game engine.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Sunday, February 18, 2018 5:56 PM
    Moderator

All replies

  • Hi

    The best way would be to add a Class called Enemy

    The Class would have a set of Properties that an Enemy could have.

    Then, for example, you could build a collection of Enemies such as Enemies = List(Of Enemy)

    To create the list, you could set up a loop of some sort, lets say a For ..... Next loop, and in the loop:

    Dim e as New Enemy, e.Property1 - "whatever", e.Property2 = 22, e.Property ="Very Bad Baddie", Enemies.add(e)


    Regards Les, Livingston, Scotland


    • Edited by leshay Friday, February 16, 2018 9:59 PM
    Friday, February 16, 2018 9:58 PM
  • The "best way" depends on the rest of your application.

    Here is one way similar to what Les described. See the sprite class and the list of sprites? I used the same class for the hunter and the target. You could use different classes, or have a basic object class that each type of character inherits. And on and on...

    Note how the public variable gamestate keeps track of the current game state as the action progresses.

    This example creates the controls all you have to do is paste it into an empty form and run.

    Public Class Form6
        Private WithEvents Timer1 As New Timer With {.Interval = 30}
        Private WithEvents Pic As New PictureBox With {.Parent = Me}    'add picturebox to the form
        Private GridSize As New Size(50, 50)    'square size in pixels
        Private GameMessage1 As String = "Press Spacebar to Begin Play..."
        Private GameMessage2 As String = "Left or Right keys to Move, Spacebar to Fire."
        Private GameMessage As String = GameMessage2
        Private GameState As Integer
    
        Private Class Sprite                    'define the sprite properties
            Public X As Integer
            Public Y As Integer
            Public Bmp As Bitmap
    
            Sub New(ByVal _Bmp As Bitmap, ByVal _X As Integer, ByVal _Y As Integer)
                X = _X
                Y = _Y
                Bmp = _Bmp
            End Sub
        End Class
    
        Private Sprites As New List(Of Sprite)
    
        Private Sub Form2_Load(sender As Object, e As EventArgs) Handles Me.Load
            DoubleBuffered = True
            BackColor = Color.DimGray
            KeyPreview = True
            ClientSize = New Size(400, 350)
            Pic.Dock = DockStyle.Fill
            Padding = New Padding(20, 50, 20, 20)
    
            'create a list of sprites- define an image and location on the game board
            'the first sprite is the player then two targets
            Sprites.AddRange({New Sprite(SystemIcons.Warning.ToBitmap(), 100, 200),
                             New Sprite(SystemIcons.Shield.ToBitmap(), 20, 10),
                             New Sprite(SystemIcons.Shield.ToBitmap(), 150, 50)})
            ResetGame()
    
            Timer1.Start()
    
        End Sub
    
        Private Sub Form6_Paint(sender As Object, e As PaintEventArgs) Handles Me.Paint
            'draw the message
            e.Graphics.DrawString(GameMessage, New Font("tahoma", 12, FontStyle.Bold), Brushes.AntiqueWhite, 20, 1)
        End Sub
    
        Private Sub Form2_KeyDown(sender As Object, e As KeyEventArgs) Handles Me.KeyDown
            'arrow keys move the sprite (form must have focus for key events)
            Select Case e.KeyCode
                Case Keys.Left
                    'move the first sprite
                    If GameState = 0 Then Sprites(0).X -= GridSize.Width
                Case Keys.Right
                    If GameState = 0 Then Sprites(0).X += GridSize.Width
                Case Keys.Space
                    Select Case GameState
                        Case 0
                            'lauch rocket
                            GameState = 1
                        Case Else
                            'new game
                            ResetGame()
                    End Select
                Case Else
                    Exit Sub
            End Select
    
            If Sprites(0).X > Pic.ClientRectangle.Width - GridSize.Width Then
                Sprites(0).X = Pic.ClientRectangle.Width - GridSize.Width
            End If
            If Sprites(0).X < 0 Then
                Sprites(0).X = 0
            End If
    
            Pic.Invalidate()
        End Sub
    
        Private Sub Pic_Paint(sender As Object, e As PaintEventArgs) Handles Pic.Paint
    
            With e.Graphics
                .Clear(Color.AliceBlue)
    
                Using p As New Pen(Color.Silver, 1),
                        br As New SolidBrush(Color.Gray),
                        f As New Font("arial", 10)
    
                    'draw grid
                    'determine the size of the total grid to be drawn in pixels based on viewport size
                    Dim gWidth As Single = CSng(GridSize.Width * Math.Ceiling(Pic.ClientSize.Width / GridSize.Width))
                    Dim gHeight As Single = CSng(GridSize.Height * Math.Ceiling(Pic.ClientSize.Width / GridSize.Height))
                    p.DashStyle = Drawing2D.DashStyle.Dot
    
                    For x As Single = 0 To gWidth Step GridSize.Width
                        .DrawLine(p, x, 0, x, 0 + gHeight)
                        .DrawString(x.ToString("f0"), f, br, x, 0)
                    Next
    
                    For y As Single = 0 To gHeight Step GridSize.Height
                        .DrawLine(p, 0, y, gWidth, y)
                        If y <> 0 Then .DrawString(y.ToString("f0"), f, br, 0, y)
                    Next
    
                    'draw sprites
                    For Each spt As Sprite In Sprites
                        .DrawImage(spt.Bmp, New Rectangle(spt.X, spt.Y,
                                                          GridSize.Width, GridSize.Height))
                    Next
    
                End Using
            End With
        End Sub
    
        Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles Timer1.Tick
            Static direction As Integer = 1
    
            If GameState < 2 Then
                'move the targets
                For i As Integer = 1 To Sprites.Count - 1
                    Sprites(i).X += direction * 2
                    If Sprites(i).X > Pic.ClientRectangle.Width - GridSize.Width Then direction = -direction
                    If Sprites(i).X < 0 Then direction = -direction
                Next
            End If
    
            Select Case GameState
                Case 1  'rocket launched
                    'check for collision
                    Dim rect As New Rectangle(Sprites(0).X, Sprites(0).Y, GridSize.Width, GridSize.Height)
    
                    For i As Integer = 1 To Sprites.Count - 1
                        If rect.Contains(New Point(CInt(Sprites(i).X + (GridSize.Width / 2)),
                                         CInt(Sprites(i).Y + (GridSize.Width / 2)))) Then
                            'hit target
                            GameState = 2
                        End If
                    Next
    
                    If GameState = 1 Then
                        'increment rocket
                        Sprites(0).Y -= 6
                        If Sprites(0).Y < 0 Then
                            'reached top missed target
                            GameState = 3
                        End If
                    End If
    
                    Select Case GameState
                        Case 3   'missed
                            GameMessage = "Missed! " & vbLf & GameMessage1
                            GameState = 5   'paused
                            Invalidate()
                        Case 2  'hit target
                            GameMessage = "Target Destroyed!" & vbLf & GameMessage1
                            GameState = 5
                            Invalidate()
                    End Select
            End Select
    
            Pic.Invalidate()
        End Sub
    
        Private Sub ResetGame()
            Sprites(0).X = 50
            Sprites(0).Y = 200
            GameState = 0
            GameMessage = GameMessage2
            Invalidate()
        End Sub
    End Class
    

    Saturday, February 17, 2018 11:22 AM
  • Hello,

    I have a question regarding coding a game. What would you suggest is the best way to add enemies to it? I have considered using an array of sprites but do not have the coding expertise to know how to do it.

    Thanks,

    The Visual Basic N00B

    Well if sprites are all the same and sprites are a type of image then clone the original sprite.

    La vida loca

    Saturday, February 17, 2018 1:27 PM
  • Hello,

    I have a question regarding coding a game. What would you suggest is the best way to add enemies to it? I have considered using an array of sprites but do not have the coding expertise to know how to do it.

    Thanks,

    The Visual Basic N00B

    This question is really just a small part of the larger question, "how do I design a game engine?" and the answer to that question is to follow proven game engine design techniques.  The following is a brief explanation of the general high-level design skeleton behind most modern game engines (including Unreal Engine and Unity).  Of course each engine is unique and there are different ways to implement the general principles; this explanation is meant to provide a loosely defined framework to follow.

    First you need to define some kind of GameObject class that will represent anything and everything in the game.  Similar to how the Object class in VB represents the base type of all other classes.  Generally a GameObject has some kind of unique identifier, a position in the game world, functionality to initialize itself and functionality to update itself (usually called once per frame).  It may also have some kind of collision information, though this could be deferred to a descendant class or add-on behavior.

    While various engines will handle it differently, there will generally be a way to extend the generic GameObject into more specific objects such as Sprites, which are GameObjects with a visual component.  As mentioned, collision as well as rigid-body physics are functionality which would typically be provided by some extension of the generic GameObject class. These extensions might come in the form of child-classes deriving from GameObject or as componentized behaviors which can be added to GameObject instances.

    The second primary component is the main game engine loop.  Again, there are many ways to implement it but every game engine needs to run a loop of code to continuously process the game.  In general, this loop will take the following steps:

    1. Update world-time
    2. Clear the graphics state
    3. Clean up dead game objects
    4. Update the state of each game object
    5. Update collision between objects
    6. Draw each visible object to the graphics state
    7. Render the current graphics frame
    8. Update user input

    The GameEngine just needs to maintain an active list of GameObjects that will be managed and executed on each pass of the game loop.

    Hopefully this makes it clear how your game's enemy instances would just be more GameObjects being handled on each iteration of the game loop.

    If you'd like to peruse an example of a game engine implementation in code, you can view the PuppyBreath code on GitHub and look at the GameObject and RenderCanvas implementations.  This code is in development and I have some changes that have not been pushed out yet (the collision on GameObject has changed), but the currently published version can still be reviewed as an example implementation of a game engine.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Sunday, February 18, 2018 5:56 PM
    Moderator