Results 1 to 29 of 29

Thread: Falling Game

  1. #1

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Falling Game

    I'm making a game, where objects fall and you have to try to evade them. I'm using pictureboxes and they fall, and the object is able to move horizontally. The question I had was how do I make a loop so then once the pictureboxes fall off the form, they can spawn randomly (the pictureboxes have different set speeds) at the top and fall again?

    Another problem I had was how do I have it so once a powerbar falls down to zero, the game ends, so say the object at the bottom gets hit 4 times, then the power bar falls to zero and the game ends. Those are the last two steps I need to finish the game.

    Thanks,
    Cheekson

  2. #2
    Fanatic Member
    Join Date
    Feb 2013
    Posts
    985

    Re: Falling Game

    Hi

    first off
    are you counting how many picture boxes you have are just throwing them down randomly, if you want another to appear when 1 has disappeared at the bottom then you need to keep a count.

    Example,
    you randomly spawn boxes at random speeds until you reach 10 total boxes, then after your collision detection detects a box has left the screen(collided with an invisible line under the play area) then remove the box, decrement the box count
    on the next frame loop do a check if the number is not maximum if its not then add a box and start the process again

    Second
    you need to set conditions for pausing the game, bringing up menus, scores, continues etc
    inside the main game loop you put a controllable infinite loop inside an if statment.

    example
    while gameon = true
    ------
    --Game Code
    ------
    if energybar = 0 then
    ShowScoreForm = true
    end if

    while showscoreform = true
    if scoreform.visible=false then
    scoreform.visible = true
    end if
    ------------
    ------------
    -----------
    loop

    loop

    you would have a button on the form which would stop the wholegame loop, or just the showscoreform loop and continue game after resetting it or something
    and best put all codes into subs to keep your loop tidy, if yourusing a timer and not a loop then just change it as necessary

    hope this helps
    Yes!!!
    Working from home is so much better than working in an office...
    Nothing can beat the combined stress of getting your work done on time whilst
    1. one toddler keeps pressing your AVR's power button
    2. one baby keeps crying for milk
    3. one child keeps running in and out of the house screaming and shouting
    4. one wife keeps nagging you to stop playing on the pc and do some real work.. house chores
    5. working at 1 O'clock in the morning because nobody is awake at that time
    6. being grossly underpaid for all your hard work


  3. #3
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,380

    Re: Falling Game

    The answer to your first question is simple, check if the PictureBox.Bottom is greater than or equal to the Form's height or bottom. If it is, then set the PictureBox.Location equal to a random x and a constant y:
    Code:
    Option Strict On
    Option Explicit On
    Public Class Form1
        'Declare a new instance of the random object here,
        'or declare it here, and set it as a new instance at the form load
        Private r As New Random
    
        Private Sub check_pb()
            For Each pb As PictureBox In Me.Controls.OfType(Of PictureBox)()
                If pb.Bottom >= Me.Bottom Then
                    pb.Location = New Point(r.Next(0, Me.Width), 5)
                End If
            Next
        End Sub
    
    
    End Class
    As for your second question, I'm not sure I understand your question. Is it: if the picturebox hits the bottom 4 times, the game ends? If so, then declare an integer variable and increment it by 1 when you set the PictureBox.Location:
    Code:
    Option Strict On
    Option Explicit On
    Public Class Form1
        'Declare a new instance of the random object here,
        'or declare it here, and set it as a new instance at the form load
        Private r As New Random
        Private bottom_hit As Integer = 1
    
        Private Sub check_pb()
            For Each pb As PictureBox In Me.Controls.OfType(Of PictureBox)()
                If pb.Bottom >= Me.Bottom AndAlso bottom_hit < 3 Then
                    pb.Location = New Point(r.Next(0, Me.Width), 5)
                    bottom_hit += 1
                ElseIf pb.Bottom >= Me.Bottom AndAlso bottom_hit = 4 Then
                    'End the game here
    
                End If
            Next
        End Sub
    
    
    End Class
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  4. #4
    Fanatic Member
    Join Date
    Feb 2013
    Posts
    985

    Re: Falling Game

    Code:
    while gameon = true
        ------
        --Game Code
        ------
        if energybar = 0 then
            ShowScoreForm = true
        end if
    
        while showscoreform = true
            if scoreform.visible=false then
                scoreform.visible = true
            end if
            ------------
            ------------
            -----------
        loop
    
    loop
    thats a little tidier, dont forget to let your system breath, ill say put doevents method in all your tight loops, with something liki this performance wont be an issue.
    no doubt 50 people will jump in here and shout all the better ways to do it
    Yes!!!
    Working from home is so much better than working in an office...
    Nothing can beat the combined stress of getting your work done on time whilst
    1. one toddler keeps pressing your AVR's power button
    2. one baby keeps crying for milk
    3. one child keeps running in and out of the house screaming and shouting
    4. one wife keeps nagging you to stop playing on the pc and do some real work.. house chores
    5. working at 1 O'clock in the morning because nobody is awake at that time
    6. being grossly underpaid for all your hard work


  5. #5
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Falling Game

    Quote Originally Posted by dday9 View Post
    The answer to your first question is simple, check if the PictureBox.Bottom is greater than or equal to the Form's height or bottom. If it is, then set the PictureBox.Location equal to a random x and a constant y
    I would actually select to have a random Y as well, a negative value so it doesn't immediately appear on screen again after its fallen down. Something like:
    -rand.Next(10) * PictureBox.Height

  6. #6
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,380

    Re: Falling Game

    Quote Originally Posted by Joacim Andersson View Post
    I would actually select to have a random Y as well, a negative value so it doesn't immediately appear on screen again after its fallen down. Something like:
    -rand.Next(10) * PictureBox.Height
    That's true, it'd look kind of jumpy if it were to just appear on the screen.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  7. #7
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,380

    Re: Falling Game

    no doubt 50 people will jump in here and shout all the better ways to do it
    GBeats, I want you to take a look at this article.... When WinForms met the game loop that really helped me out that I think people should read when deciding when to use a 'game' loop and when to just draw in 'WinForm' fashion. In this case, I believe that it should be in a 'WinForm' fashion.
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  8. #8
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: Falling Game

    This should be in the games and graphics section as we got game experts here.

    It is generally not wise to use a bunch of pictureboxes for games, let alone timers. There are graphical functions built in to vb.net, but if you want better graphics, you can use APIs such as BitBlt, StretchBlt, and TransparentBlt, all of which allow transparency which remove the background from an image, or if you wanna take advantage of the video hardware for either 2D / 3D theres DirectX and XNA.

    You are also gonna need a gameloop locked at 60 frames per second. Im gonna be home shortly from work so Ill copy and paste code showing you how. And if you want real falling physics, Ill show you around that time as well.

  9. #9
    Fanatic Member
    Join Date
    Feb 2013
    Posts
    985

    Re: Falling Game

    there's pros and conns like it says dday9, like i say if your going to do it, might as well do it right, even if its not necessary its good practice.
    Yes!!!
    Working from home is so much better than working in an office...
    Nothing can beat the combined stress of getting your work done on time whilst
    1. one toddler keeps pressing your AVR's power button
    2. one baby keeps crying for milk
    3. one child keeps running in and out of the house screaming and shouting
    4. one wife keeps nagging you to stop playing on the pc and do some real work.. house chores
    5. working at 1 O'clock in the morning because nobody is awake at that time
    6. being grossly underpaid for all your hard work


  10. #10

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    At the bottom of the screen, there is a picturebox that you, the player controls and it moves souly on the x axis. As the pictureboxes from above fall, you have to move left or right to evade them. So if the object the player controls is hit 4 times by the falling object then the game is over.

  11. #11

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    Quote Originally Posted by Jacob Roman View Post
    This should be in the games and graphics section as we got game experts here.

    It is generally not wise to use a bunch of pictureboxes for games, let alone timers. There are graphical functions built in to vb.net, but if you want better graphics, you can use APIs such as BitBlt, StretchBlt, and TransparentBlt, all of which allow transparency which remove the background from an image, or if you wanna take advantage of the video hardware for either 2D / 3D theres DirectX and XNA.

    You are also gonna need a gameloop locked at 60 frames per second. Im gonna be home shortly from work so Ill copy and paste code showing you how. And if you want real falling physics, Ill show you around that time as well.
    I would love to see that, but for the moment it's just a simple game. I've never used the hardware you're talking about and I'm relatively new to programming. I'd like to look at it and learn about it though.

  12. #12
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,380

    Re: Falling Game

    Quote Originally Posted by cheekson View Post
    At the bottom of the screen, there is a picturebox that you, the player controls and it moves souly on the x axis. As the pictureboxes from above fall, you have to move left or right to evade them. So if the object the player controls is hit 4 times by the falling object then the game is over.
    Ahh I gotcha know! What you want to do is declare an integer variable like I did above, only check if the picturebox.Bounds intersects with the picturebox the user's controlling:
    Code:
    Option Strict On
    Option Explicit On
    Public Class Form1
        'Declare a new instance of the random object here,
        'or declare it here, and set it as a new instance at the form load
        Private r As New Random
        Private hit As Integer = 1
    
        Private Sub check_pb()
            For Each pb As PictureBox In Me.Controls.OfType(Of PictureBox)()
                If pb.Bottom >= Me.Bottom AndAlso hit < 3 Then
                    'Falling pb hits the bottom
                    pb.Location = New Point(r.Next(0, Me.Width), -5 - pb.Height)
                ElseIf pb.Bounds.IntersectsWith(player_picturebox.Bounds) Then
                    'Hit
                    hit += 1
                ElseIf hit = 4 Then
                    'end game
                End If
            Next
        End Sub
    
    End Class
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  13. #13

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    Code:
    Public Class Form1
            Dim RainDrops As Integer
    
        Private Sub Form1_KeyDown(ByVal sender As System.Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
            If e.KeyValue = Keys.Left Then
                picCharmander.Left = picCharmander.Left - 10
            End If
    
    
            If e.KeyValue = Keys.Right Then
                picCharmander.Left = picCharmander.Left + 10
    
            End If
        End Sub
        Private Sub Timer1_Tick(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Timer1.Tick
            PictureBox2.Top = PictureBox2.Top + 6
            PictureBox3.Top = PictureBox3.Top + 4
            PictureBox4.Top = PictureBox4.Top + 5
            PictureBox5.Top = PictureBox5.Top + 7
            PictureBox6.Top = PictureBox6.Top + 5
            PictureBox7.Top = PictureBox7.Top + 4.5
            PictureBox8.Top = PictureBox8.Top + 3
            PictureBox9.Top = PictureBox9.Top + 5
            PictureBox10.Top = PictureBox10.Top + 5.7
    
    
        End Sub
        End Class
    This is what I have right now, like I said, and if I didn't I'm sorry, but pretty basic. The pictures fall and the picture at the bottom moves. Also if there is a more efficient way to have this written, that would be nice. This is the only way I know to write it.
    Last edited by cheekson; May 13th, 2013 at 02:20 PM.

  14. #14

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    Quote Originally Posted by dday9 View Post
    Ahh I gotcha know! What you want to do is declare an integer variable like I did above, only check if the picturebox.Bounds intersects with the picturebox the user's controlling:
    Code:
    Option Strict On
    Option Explicit On
    Public Class Form1
        'Declare a new instance of the random object here,
        'or declare it here, and set it as a new instance at the form load
        Private r As New Random
        Private hit As Integer = 1
    
        Private Sub check_pb()
            For Each pb As PictureBox In Me.Controls.OfType(Of PictureBox)()
                If pb.Bottom >= Me.Bottom AndAlso hit < 3 Then
                    'Falling pb hits the bottom
                    pb.Location = New Point(r.Next(0, Me.Width), -5 - pb.Height)
                ElseIf pb.Bounds.IntersectsWith(player_picturebox.Bounds) Then
                    'Hit
                    hit += 1
                ElseIf hit = 4 Then
                    'end game
                End If
            Next
        End Sub
    
    End Class
    Ok, so how would I implament that into my game, with the names I have for things?

  15. #15
    Super Moderator dday9's Avatar
    Join Date
    Mar 2011
    Posts
    12,380

    Re: Falling Game

    A few things:
    1) You don't have to type out every picturebox like that
    2) you don't have to set the Top like that as well

    From what you gave me there I'd do something like this:
    Code:
    Option Strict On
    Option Explicit On
    Public Class Form1
        'Declare a new instance of the random object here,
        'or declare it here, and set it as a new instance at the form load
        Private r As New Random
        Private hit As Integer = 1
        Private pbList As New List(Of PictureBox)
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            pbList.AddRange({PictureBox2, PictureBox4, PictureBox5, PictureBox6, PictureBox7, PictureBox2, PictureBox8, PictureBox9, PictureBox10})
    
            Timer1.Start()
        End Sub
    
        Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
            For Each pb As PictureBox In pbList
                pb.Top += 5
    
                If pb.Bottom >= Me.Bottom Then
                    'Hit the bottom
                    pb.Location = New Point(r.Next(0, Me.Width), -r.Next(0, 10))
                ElseIf pb.Bounds.IntersectsWith(picCharmander.Bounds) Then
                    'Hit charmander
                    hit += 1
                    pb.Location = New Point(r.Next(0, Me.Width), -r.Next(0, 10) - Me.Height)
                ElseIf hit = 4 Then
                    'end game
                    Timer1.Stop()
                End If
            Next
        End Sub
    
        Private Sub Form1_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
            If e.KeyCode = Keys.Left Then
                picCharmander.Left -= 10
            ElseIf e.KeyCode = Keys.Right Then
                picCharmander.Left += 10
            End If
        End Sub
    End Class
    "Code is like humor. When you have to explain it, it is bad." - Cory House
    VbLessons | HtmlLessons | CssLessons | Code Tags | Sword of Fury - Jameram

  16. #16
    Fanatic Member
    Join Date
    Feb 2013
    Posts
    985

    Re: Falling Game

    if you are familiar with classes and even if not, this would be a perfect opportunity to learn.

    turn your pictureboxes into objects with falling speed, position, and picture properties with a contructor

    just something simple like

    class box
    private FSpeed as single
    private PosX as long
    private PosY as Long


    public sub New()
    'for speed use 3+ a random number between 0 and 5 say
    posy = top of course
    posX = random numberbetween Left and width
    end sub

    create some functions to get the fspeed, posx,y inside the class

    then you can create a list of boxes

    public boxes as new list(of box)

    then with every tick event if theres less then 10 in the list add a new one

    boxes.add and it will calculate everything for you

    then just handle the movement using the functions in the class
    Yes!!!
    Working from home is so much better than working in an office...
    Nothing can beat the combined stress of getting your work done on time whilst
    1. one toddler keeps pressing your AVR's power button
    2. one baby keeps crying for milk
    3. one child keeps running in and out of the house screaming and shouting
    4. one wife keeps nagging you to stop playing on the pc and do some real work.. house chores
    5. working at 1 O'clock in the morning because nobody is awake at that time
    6. being grossly underpaid for all your hard work


  17. #17

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    Quote Originally Posted by GBeats View Post
    if you are familiar with classes and even if not, this would be a perfect opportunity to learn.

    turn your pictureboxes into objects with falling speed, position, and picture properties with a contructor

    just something simple like

    class box
    private FSpeed as single
    private PosX as long
    private PosY as Long


    public sub New(iPicture as object)
    'for speed use 3+ a random number between 0 and 5 say
    posy = top of course
    posX = random numberbetween Left and width
    end sub

    create some functions to get the fspeed, posx,y inside the class

    then you can create a list of boxes

    public boxes as new list(of box)

    then with every tick event if theres less then 10 in the list add a new one

    boxes.add and it will calculate everything for you

    then just handle the movement using the functions in the class
    I'm vaguely familiar with classes. I'll look into that and when I get the chance, I'll try it out. I'm learning a lot here, Thanks.

  18. #18

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    Quote Originally Posted by dday9 View Post
    A few things:
    1) You don't have to type out every picturebox like that
    2) you don't have to set the Top like that as well

    From what you gave me there I'd do something like this:
    Code:
    Option Strict On
    Option Explicit On
    Public Class Form1
        'Declare a new instance of the random object here,
        'or declare it here, and set it as a new instance at the form load
        Private r As New Random
        Private hit As Integer = 1
        Private pbList As New List(Of PictureBox)
    
        Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
            pbList.AddRange({PictureBox2, PictureBox4, PictureBox5, PictureBox6, PictureBox7, PictureBox2, PictureBox8, PictureBox9, PictureBox10})
    
            Timer1.Start()
        End Sub
    
        Private Sub Timer1_Tick(sender As System.Object, e As System.EventArgs) Handles Timer1.Tick
            For Each pb As PictureBox In pbList
                pb.Top += 5
    
                If pb.Bottom >= Me.Bottom Then
                    'Hit the bottom
                    pb.Location = New Point(r.Next(0, Me.Width), -r.Next(0, 10))
                ElseIf pb.Bounds.IntersectsWith(picCharmander.Bounds) Then
                    'Hit charmander
                    hit += 1
                    pb.Location = New Point(r.Next(0, Me.Width), -r.Next(0, 10) - Me.Height)
                ElseIf hit = 4 Then
                    'end game
                    Timer1.Stop()
                End If
            Next
        End Sub
    
        Private Sub Form1_KeyDown(sender As System.Object, e As System.Windows.Forms.KeyEventArgs) Handles MyBase.KeyDown
            If e.KeyCode = Keys.Left Then
                picCharmander.Left -= 10
            ElseIf e.KeyCode = Keys.Right Then
                picCharmander.Left += 10
            End If
        End Sub
    End Class
    I think this is the last question, how do I change the speed and number of pictureboxes falling. This is for harder or easier levels. Before, when I had all the pictureboxes typed out I could see and change what their falling speeds were, how do I do that with the new code written here?
    Last edited by cheekson; May 13th, 2013 at 03:24 PM.

  19. #19
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,104

    Re: Falling Game

    To change the speed, you have two options. Either decrease the timer interval so that they move more often, or increase the distance they move each time. The performance will be better if you choose the latter, but motion will be better if you choose the former. If you move too far in each interval, the motion will become jerky.

    To add more pictureboxes, wouldn't you just add them to the pbList that you already have? You could create a bunch of them with visibility set to False, then move them in and out of the list to add more or less of them.
    My usual boring signature: Nothing

  20. #20

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    Quote Originally Posted by Shaggy Hiker View Post
    To change the speed, you have two options. Either decrease the timer interval so that they move more often, or increase the distance they move each time. The performance will be better if you choose the latter, but motion will be better if you choose the former. If you move too far in each interval, the motion will become jerky.

    To add more pictureboxes, wouldn't you just add them to the pbList that you already have? You could create a bunch of them with visibility set to False, then move them in and out of the list to add more or less of them.
    That's what I was thinking, just wasn't sure if there was some specific way to go about doing it.

  21. #21
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,104

    Re: Falling Game

    Probably not, unless you start running into performance issues. There are many possible ways to do any part of that, some are a bit more efficient than others. Try whatever feels good to you, and if that proves to be too slow, then you can change it. I'd suggest altering the timer interval, first, as that will tend to have the best visual result. If you get enough pictureboxes, and they are falling fast enough, then the display might appear to stutter, in which case it is time to try something else.

    One thing you might consider is that each control has a .Tag property that you can use for whatever you want. Suppose you put an integer into the .Tag property for each of your PB controls. Then, when the timer ticks, you might do something like this:

    PB.Top += CInt(PB.Tag) * someFactor

    The larger the integer in PB.Tag, the faster the PB will move down the screen. someFactor can start out at 1 for the first level, then become 1.1, 1.2, etc, for each subsequent level, and the PB will appear to move faster and faster as someFactor increases. However, this is changing the rate of change of the PB rather than changing the timer interval, so it could get ugly fast. Decreasing the interval rather than increasing someFactor would have the same result, but a smoother motion.
    My usual boring signature: Nothing

  22. #22

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    Quote Originally Posted by Shaggy Hiker View Post
    Probably not, unless you start running into performance issues. There are many possible ways to do any part of that, some are a bit more efficient than others. Try whatever feels good to you, and if that proves to be too slow, then you can change it. I'd suggest altering the timer interval, first, as that will tend to have the best visual result. If you get enough pictureboxes, and they are falling fast enough, then the display might appear to stutter, in which case it is time to try something else.

    One thing you might consider is that each control has a .Tag property that you can use for whatever you want. Suppose you put an integer into the .Tag property for each of your PB controls. Then, when the timer ticks, you might do something like this:

    PB.Top += CInt(PB.Tag) * someFactor

    The larger the integer in PB.Tag, the faster the PB will move down the screen. someFactor can start out at 1 for the first level, then become 1.1, 1.2, etc, for each subsequent level, and the PB will appear to move faster and faster as someFactor increases. However, this is changing the rate of change of the PB rather than changing the timer interval, so it could get ugly fast. Decreasing the interval rather than increasing someFactor would have the same result, but a smoother motion.
    What's "Cint"? Also, what if I want them to move at different speeds? I don't see how that would change.

  23. #23
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: Falling Game

    But my point is, is that you should avoid using pictureboxes to make games with.

    I'll start you off with built in graphics functions in vb.net. This is some source code that will allow you to load an image from file in memory, and display it with a game loop locked at 60 FPS and improved controls, so you don't get that lag of holding down the key:

    vb.net Code:
    1. Option Explicit On
    2. Option Strict On
    3.  
    4. Public Class Form1
    5.  
    6.     Private Declare Function QueryPerformanceCounter Lib "Kernel32" (ByRef X As Long) As Integer
    7.     Private Declare Function QueryPerformanceFrequency Lib "Kernel32" (ByRef X As Long) As Integer
    8.  
    9.     Private Structure Sprite_Type
    10.         Public X As Integer
    11.         Public Y As Integer
    12.         Public Width As Integer
    13.         Public Height As Integer
    14.     End Structure
    15.  
    16.     'Key Functions
    17.     Private Const P1_UP As Keys = Keys.Up
    18.     Private Const P1_DOWN As Keys = Keys.Down
    19.     Private Const P1_LEFT As Keys = Keys.Left
    20.     Private Const P1_RIGHT As Keys = Keys.Right
    21.  
    22.     'Key Flags (MUST BE IN BINARY FORMAT THE MORE KEYS YOU USE: ex. 1, 2, 4, 8, 16, 32, 64, 128, etc.
    23.     Private Const P1_UP_FLAG As Integer = 1
    24.     Private Const P1_DOWN_FLAG As Integer = 2
    25.     Private Const P1_LEFT_FLAG As Integer = 4
    26.     Private Const P1_RIGHT_FLAG As Integer = 8
    27.  
    28.     Private Ticks_Per_Second As Long
    29.     Private Start_Time As Long
    30.  
    31.     Private Milliseconds As Integer
    32.     Private Get_Frames_Per_Second As Integer
    33.     Private Frame_Count As Integer
    34.  
    35.     Private Keystate As Integer
    36.     Private Running As Boolean
    37.  
    38.     Private Texture As Image
    39.     Private Texture_Graphics As Graphics
    40.     Private newGraphics As Graphics
    41.  
    42.     Dim Backbuffer As Bitmap
    43.     Dim Backbuffer_Graphics As Graphics
    44.  
    45.     Private Sprite As Sprite_Type
    46.  
    47.     Private Function Hi_Res_Timer_Initialize() As Boolean
    48.  
    49.         If QueryPerformanceFrequency(Ticks_Per_Second) = 0 Then
    50.             Hi_Res_Timer_Initialize = False
    51.         Else
    52.             QueryPerformanceCounter(Start_Time)
    53.             Hi_Res_Timer_Initialize = True
    54.         End If
    55.  
    56.     End Function
    57.  
    58.     Private Function Get_Elapsed_Time() As Single
    59.  
    60.         Dim Last_Time As Long
    61.         Dim Current_Time As Long
    62.  
    63.         QueryPerformanceCounter(Current_Time)
    64.         Get_Elapsed_Time = Convert.ToSingle((Current_Time - Last_Time) / Ticks_Per_Second)
    65.         QueryPerformanceCounter(Last_Time)
    66.  
    67.     End Function
    68.  
    69.     Private Sub Lock_Framerate(ByVal Target_FPS As Long)
    70.  
    71.         Static Last_Time As Long
    72.         Dim Current_Time As Long
    73.         Dim FPS As Single
    74.  
    75.         Do
    76.             QueryPerformanceCounter(Current_Time)
    77.             FPS = Convert.ToSingle(Ticks_Per_Second / (Current_Time - Last_Time))
    78.         Loop While (FPS > Target_FPS)
    79.  
    80.         QueryPerformanceCounter(Last_Time)
    81.  
    82.     End Sub
    83.  
    84.     Private Function Get_FPS() As String
    85.  
    86.         Frame_Count = Frame_Count + 1
    87.  
    88.         If Get_Elapsed_Time - Milliseconds >= 1 Then
    89.             Get_Frames_Per_Second = Frame_Count
    90.             Frame_Count = 0
    91.             Milliseconds = Convert.ToInt32(Get_Elapsed_Time)
    92.         End If
    93.  
    94.         Get_FPS = "Frames Per Second: " & Get_Frames_Per_Second
    95.  
    96.     End Function
    97.  
    98.     Private Function Check_Key(ByVal Keyflag As Integer) As Integer
    99.  
    100.         Check_Key = Keystate And Keyflag
    101.  
    102.     End Function
    103.  
    104.     Private Sub Keyboard_Control()
    105.  
    106.         If Check_Key(P1_LEFT_FLAG) > 0 Then Sprite.X -= 5
    107.         If Check_Key(P1_RIGHT_FLAG) > 0 Then Sprite.X += 5
    108.  
    109.     End Sub
    110.  
    111.     Private Sub Load_Texture()
    112.         Texture = Image.FromFile(Application.StartupPath() & "\Link.bmp")
    113.         Texture_Graphics = Me.CreateGraphics()
    114.         newGraphics = Graphics.FromImage(Texture)
    115.     End Sub
    116.  
    117.     Private Sub Unload_Texture()
    118.         newGraphics.Dispose()
    119.         Texture_Graphics.Dispose()
    120.     End Sub
    121.  
    122.     Private Sub Setup_Sprite()
    123.         With Sprite
    124.             .Width = 54
    125.             .Height = 69
    126.             .X = CInt(Me.Width / 2) - CInt(Sprite.Width / 2)
    127.             .Y = 490
    128.         End With
    129.     End Sub
    130.  
    131.     Private Sub Clear_Screen()
    132.         Backbuffer_Graphics.Clear(Color.FromArgb(0, 0, 0, 0))
    133.     End Sub
    134.  
    135.     Private Sub Render()
    136.  
    137.         Clear_Screen()
    138.         Texture_Graphics.DrawImage(Texture, New RectangleF(Sprite.X, Sprite.Y, Sprite.Width, Sprite.Height))
    139.  
    140.     End Sub
    141.  
    142.     Private Sub Game_Loop()
    143.  
    144.         Do While Running = True
    145.             Keyboard_Control()
    146.             Render()
    147.             Lock_Framerate(60)
    148.             Me.Text = Get_FPS()
    149.             Application.DoEvents()
    150.         Loop
    151.  
    152.     End Sub
    153.  
    154.     Private Sub Main()
    155.  
    156.         With Me
    157.             .Show()
    158.             .Focus()
    159.             .DoubleBuffered = True
    160.             .KeyPreview = True
    161.         End With
    162.  
    163.         Backbuffer_Graphics = Me.CreateGraphics()
    164.         Load_Texture()
    165.         Setup_Sprite()
    166.         Hi_Res_Timer_Initialize()
    167.         Running = True
    168.         Game_Loop()
    169.  
    170.     End Sub
    171.  
    172.     Private Sub Shutdown()
    173.  
    174.         Running = False
    175.         Application.Exit()
    176.  
    177.     End Sub
    178.  
    179.     Private Sub Form1_KeyDown(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyDown
    180.  
    181.         Select Case e.KeyCode
    182.             Case P1_UP
    183.                 Keystate = Keystate Or P1_UP_FLAG
    184.             Case P1_DOWN
    185.                 Keystate = Keystate Or P1_DOWN_FLAG
    186.             Case P1_LEFT
    187.                 Keystate = Keystate Or P1_LEFT_FLAG
    188.             Case P1_RIGHT
    189.                 Keystate = Keystate Or P1_RIGHT_FLAG
    190.         End Select
    191.  
    192.     End Sub
    193.  
    194.     Private Sub Form1_KeyUp(ByVal sender As Object, ByVal e As System.Windows.Forms.KeyEventArgs) Handles Me.KeyUp
    195.  
    196.         Select Case e.KeyCode
    197.             Case P1_UP
    198.                 Keystate = Keystate And (Not P1_UP_FLAG)
    199.             Case P1_DOWN
    200.                 Keystate = Keystate And (Not P1_DOWN_FLAG)
    201.             Case P1_LEFT
    202.                 Keystate = Keystate And (Not P1_LEFT_FLAG)
    203.             Case P1_RIGHT
    204.                 Keystate = Keystate And (Not P1_RIGHT_FLAG)
    205.         End Select
    206.  
    207.     End Sub
    208.  
    209.     Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
    210.  
    211.         Main()
    212.  
    213.     End Sub
    214.  
    215.     Private Sub Form1_FormClosing(ByVal sender As Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles MyBase.FormClosing
    216.  
    217.         Shutdown()
    218.  
    219.     End Sub
    220.  
    221. End Class

    Its a rushed project but it works. I have the image you can download as an example, which is Link from Legend of Zelda. No pictureboxes or timers used :P

    Now for falling physics, you just don't wanna have it go at a constant speed and hit the ground. You wanna make it interesting. The formula for gravity is F = MG which is force = mass * gravity. This is used in acceleration. Acceleration can equal this force. You are also gonna wanna integrate it. Im gonna start you off with the Forward Euler integrator:

    Code:
    Acceleration.X = Force.X * One_Over_Mass
    Acceleration.Y = Force.Y * One_Over_Mass
    
    Position.X = Position.X + Velocity.X * dt
    Velocity.X = Velocity.X + Acceleration.X * dt
    
    Position.Y = Position.Y + Velocity.Y * dt
    Velocity.Y = Velocity.Y + Acceleration.Y * dt
    Where dt is your time step. A basic time step would be 1 / 100, which are typically used in physics engines. Although there are more advanced integrators out there, this is the easiest to understand. The gravity constant youll need for earth gravity is 9.80665. Mass is measured in kilograms, however, if you want pounds, youll have to have your mass in pounds be converted to kilograms by this formula:

    Code:
    Dim POUNDS_TO_KG As Single = 0.45359237
    Dim Mass as Single
    Mass = 10 * POUNDS_TO_KG
    To get these physics going, this is the code I use to update physics:

    Code:
    Private Sub Update_Physics
            Delta_Time = Get_Elapsed_Time_Per_Frame
            If Delta_Time > 0.25 Then Delta_Time = 0.25
            Accumulator = Accumulator + Delta_Time
            
            While (Accumulator >= Time_Step)
                Accumulator = Accumulator - Time_Step
                Integrate2D Obj, Time_Step
                Time = Time + Time_Step
            Wend
    End Sub
    And then it hits you. You need collision detection. So a basic box to box collision detection would be something like this:

    Code:
    Public Structure Box
        X As Single
        Y As Single
        W As Single
        H As Single
        VX As Single
        VY As Single
    End Structure
    
    Public Function AABBCheck(B1 As Box, B2 As Box) As Boolean
        'returns true if the boxes are colliding (velocities are not used)
        Dim B1 As Box
        Dim B2 As Box
        
        Return Not (((B1.X + B1.W < B2.X) Or (B1.X > B2.X + B2.W) Or (B1.Y + B1.H < B2.Y) Or (B1.Y > B2.Y + B2.H)))
    End Function
    And if you have any more questions, let me know
    Attached Images Attached Images  

  24. #24

    Thread Starter
    New Member
    Join Date
    Apr 2013
    Posts
    12

    Re: Falling Game

    At the moment, I don't really get this, I haven't learned a lot of what you have written up there. I'd like to learn it, eventually. I'll look at it later this week and respond.

  25. #25
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: Falling Game

    What do you not understand?

  26. #26
    Fanatic Member AceInfinity's Avatar
    Join Date
    May 2011
    Posts
    696

    Re: Falling Game

    Yeah, I would avoid the use of Pictureboxes as well. And especially creating a new instance of one for every falling object. If you're going to be using Pictureboxes you should be trying to reuse them as much as possible for each "new" falling object. Create a max number of Picturebox instances, and then for how many you want to appear on screen, you'll need a way to measure that, which could be from a counter variable. A class could encapsulate the Picturebox itself, along with properties for direction, and speed (in case you wanted them to fall on angles perhaps). From here, the variables would stay constant, and be set to random values upon reset time; when they hit the bottom and are ready in the queue to become placed at the top again to "fall." These values would not be reset again, until the object has hit the bottom, giving the illusion that you have a new object falling each time because of a different in speed, and perhaps direction, image, or whatever else you decide to change...

    That's if you use Pictureboxes though. You don't want to have to deal with creating new instances and managing each new instance all the time if you can avoid doing that.
    <<<------------
    Improving Managed Code Performance | .NET Application Performance
    < Please if this helped you out. Any kind of thanks is gladly appreciated >


    .NET Programming (2012 - 2018)
    ®Crestron - DMC-T Certified Programmer | Software Developer
    <<<------------

  27. #27
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    40,104

    Re: Falling Game

    The worst possible solution is to create new pictureboxes each time. That's about the most costly thing you can do, so do as AceInfinity said, or even better, figure out what JR is on about....then figure out what his post was about....and if you figure out the first part, let the rest of the world know. Still, the point is a good one. Manipulating controls can take you a fair distance, but you can only do a certain amount of that before you run up against the performance limits. I'm not quite sure where those limits are, but they aren't very far up. Eventually, the cost entailed in moving the controls around is going to make further performance improvements impossible. For a small number of PB, you should have no problems. Above that number the game will cease to function smoothly no matter what you do. The key question is: Where is that limit? It's probably in the vicinity of a dozen controls, but could be lower or higher. Creating new pictureboxes each time will drop the limit, reusing a collection of them will increase the limit.

    CInt is the fastest way to convert a string or object into an Integer, but it only works if the item really can be converted (because it IS an integer, in the case of an Object, or because it is a string representation of an Integer in the case of a string).
    My usual boring signature: Nothing

  28. #28
    Elite Hacker Jacob Roman's Avatar
    Join Date
    Aug 2004
    Location
    Miami Beach, FL
    Posts
    5,349

    Re: Falling Game

    You are only limited to 255 controls on the form at once. I hit that limit before.

  29. #29
    I'm about to be a PowerPoster! Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Falling Game

    Quote Originally Posted by Jacob Roman View Post
    You are only limited to 255 controls on the form at once. I hit that limit before.
    VB6 had that limitation but not VB.Net.

    In all honesty for a very simple game like this when you have some objects "falling" down the screen and one playable object that you move left and right using picture boxes is fine. As soon as one of the picture boxes fall below the the Form bottom just move it up again as suggested earlier in this thread. Learning more about graphics and DirectX is fine if you want to do more advanced stuff. Depending on the size of the falling object you probably don't need much more than 10 to 15 picture boxes and that is really nothing to worry about. Just reuse them by moving them to the top when they have fallen down. Doing anything else is just overkill.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Click Here to Expand Forum to Full Width