Results 1 to 20 of 20

Thread: How to make the ship move smoothly??Look in for details.

  1. #1

    Thread Starter
    Hyperactive Member toughcoder's Avatar
    Join Date
    Nov 2002
    Location
    Near, Very Near
    Posts
    340

    Unhappy How to make the ship move smoothly??Look in for details.

    Hello Every1 and herez wishing u all a VERY HAPPY & PROSPEROUS NEW YEAR.
    Well, coming straight to the point, i'm trying to make a shoot'em sort of a game like the classic Invaders. I have made a scrolling background, it works fine and i can even draw the ship on the background. So far so good. This drawing part is inside a loop which exits once the escape key is pressed. The ship moves left or right depending on the respective key pressed. So far everything is fine, the only problem is that the ship when moving jerks a little bit and doesnt signs of smooth moving. I want to make the ship move smoothly on the background. I'm ncluding the source, can anyone plz help.

    N.B:::: Form.Autoredraw is set to true. The ship sprite and the mask for the ship are loaded into a pictureBox. Whereas for the background i have used LoadImage. Plz copy the code and help me. I cannot post the background image but mind u its dimension is 600x600 and its a bitmap. U guys just make any bitmap of 600x600 and load it. Plz help me. Thanq u. Below is the code
    -------------------------------------------------------------------------------------------------

    Private Declare Function BitBlt Lib "gdi32" (ByVal hDestDC As Long, ByVal X As Long, ByVal Y As Long, ByVal nWidth As Long, ByVal nHeight As Long, ByVal hSrcDC As Long, ByVal xSrc As Long, ByVal ySrc As Long, ByVal dwRop As Long) As Long
    Private Declare Function GetKeyState Lib "user32" (ByVal nVirtKey As Long) As Integer
    Private Declare Function SelectObject Lib "gdi32" (ByVal hdc As Long, ByVal hObject As Long) As Long
    Private Declare Function CreateCompatibleDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function DeleteDC Lib "gdi32" (ByVal hdc As Long) As Long
    Private Declare Function LoadImage Lib "user32" Alias "LoadImageA" (ByVal hInst As Long, ByVal lpsz As String, ByVal un1 As Long, ByVal n1 As Long, ByVal n2 As Long, ByVal un2 As Long) As Long
    Private Declare Function DeleteObject Lib "gdi32" (ByVal hObject As Long) As Long

    Const KEY_TOGGLED As Integer = &H1
    Const KEY_PRESSED As Integer = &H1000
    Dim Left_EdgeTouched As Boolean, Right_EdgeTouched As Boolean

    Const IMAGE_BITMAP As Long = 0
    Const LR_LOADFROMFILE As Long = &H10
    Const LR_CREATEDIBSECTION As Long = &H2000
    '****************************************

    Dim BackDC As Long

    'Back ground dimensions
    Const BackHeight As Long = 600
    Const BackLength As Long = 600

    'The width of the scrolling screen
    Const ScrollHeight As Long = 600

    Private Sub Form_Click()
    End
    End Sub

    Private Sub Form_Load()
    BackDC = GenerateDC(App.Path & "\space.bmp")
    BitBlt Me.hdc, 20, ((Screen.Height / Screen.TwipsPerPixelY) - (picSprite.Height + 50)), picMask.ScaleWidth, picMask.ScaleHeight, picMask.hdc, 0, 0, vbSrcAnd
    BitBlt Me.hdc, 20, ((Screen.Height / Screen.TwipsPerPixelY) - (picSprite.Height + 50)), picMask.ScaleWidth, picMask.ScaleHeight, picSprite.hdc, 0, 0, vbSrcPaint
    Me.Refresh
    GameLoop
    End Sub

    Private Sub GameLoop()
    Static Ship_Position As Integer
    Me.Show
    Do
    Background (Ship_Position)
    If (GetKeyState(vbKeyLeft) And KEY_PRESSED) And Left_EdgeTouched = False Then
    If Ship_Position <= 10 Then
    Ship_Position = 10
    Right_EdgeTouched = False
    Left_EdgeTouched = True
    Else
    Ship_Position = Ship_Position - 5
    Right_EdgeTouched = False
    End If
    End If
    If (GetKeyState(vbKeyRight) And KEY_PRESSED) And Right_EdgeTouched = False Then
    If Ship_Position > Me.ScaleWidth - picSprite.Width Then
    Ship_Position = Me.ScaleWidth - picSprite.Width
    Right_EdgeTouched = True
    Left_EdgeTouched = False
    Else
    Ship_Position = Ship_Position + 5
    Left_EdgeTouched = False
    End If
    End If
    If (GetKeyState(vbKeyEscape) And KEY_PRESSED) Then End
    DoEvents
    BitBlt Me.hdc, Ship_Position, ((Screen.Height / Screen.TwipsPerPixelY) - (picSprite.Height + 50)), picMask.ScaleWidth, picMask.ScaleHeight, picMask.hdc, 0, 0, vbSrcAnd
    BitBlt Me.hdc, Ship_Position, ((Screen.Height / Screen.TwipsPerPixelY) - (picSprite.Height + 50)), picMask.ScaleWidth, picMask.ScaleHeight, picSprite.hdc, 0, 0, vbSrcPaint

    Me.Refresh
    Loop
    End Sub

    Public Function GenerateDC(FileName As String) As Long
    Dim DC As Long
    Dim hBitmap As Long

    DC = CreateCompatibleDC(0)
    If DC < 1 Then
    GenerateDC = 0
    Exit Function
    End If
    hBitmap = LoadImage(0, FileName, IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE Or LR_CREATEDIBSECTION)
    If hBitmap = 0 Then 'Failure in loading bitmap
    DeleteDC DC
    GenerateDC = 0
    Exit Function
    End If
    SelectObject DC, hBitmap
    GenerateDC = DC
    DeleteObject hBitmap
    End Function

    Private Function DeleteGeneratedDC(DC As Long) As Long

    If DC > 0 Then
    DeleteGeneratedDC = DeleteDC(DC)
    Else
    DeleteGeneratedDC = 0
    End If
    End Function

    Private Sub Background(Ship_Position As Integer)
    Static Y As Long
    Dim GlueHeight As Long, EndScroll As Long

    If Y + ScrollHeight > BackHeight Then
    GlueHeight = Y + ScrollHeight - BackHeight
    EndScroll = ScrollHeight - GlueHeight

    'Blit the Background
    BitBlt Me.hdc, 0, 0, BackLength, EndScroll, BackDC, 0, Y, vbSrcCopy
    BitBlt Me.hdc, 0, EndScroll, BackLength, GlueHeight, BackDC, 0, 0, vbSrcCopy
    Else
    BitBlt Me.hdc, 0, 0, BackLength, ScrollHeight, BackDC, 0, Y, vbSrcCopy
    End If
    Y = (Y Mod BackHeight) + 5
    End Sub
    If Not VB Then Exit
    ------------------------------------------------
    visit me @ http://mzubair.50g.com/

  2. #2
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    The reason is you are moving by 5 or 10 pixels a second - a huge amount if you want smooth scrolling. You'll need to increase the speed of your loop and decrease the rate of movement.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  3. #3
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    make it move 1 pixel each frame...and the change framerate to see what looks good...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  4. #4

    Thread Starter
    Hyperactive Member toughcoder's Avatar
    Join Date
    Nov 2002
    Location
    Near, Very Near
    Posts
    340

    How to increase the loop speed then??

    Well, i considered both the options - move the ship 1 pixel at a time, but can any1 plz tell me how to increase the speed of the loop as sastraxi have entioned. Thanq
    If Not VB Then Exit
    ------------------------------------------------
    visit me @ http://mzubair.50g.com/

  5. #5
    Addicted Member
    Join Date
    Dec 2001
    Location
    Great White North, ey?
    Posts
    202

    Question

    Hi, I too need to know how to speed up a loop. Anyone? This is because after I switched from Win 98 to 2k, my game started running 40fps less then before. On 98 it ran at about 100fps, now with 2k it runs at 60fps even though the performace of my computer significantly increased after installing 2k.....wierd.

    Please help, thanks.

  6. #6
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    hmmm...i dont know if you've just set the framerate too low or if it's lagging...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  7. #7
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    use GetTickCount to set the speed of the loop
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  8. #8
    Addicted Member
    Join Date
    Dec 2001
    Location
    Great White North, ey?
    Posts
    202

    Unhappy

    Originally posted by cyborg
    hmmm...i dont know if you've just set the framerate too low or if it's lagging...

    I didn't SET the framerate, it just happens to be like that. If it is possible to set a framerate, maybe I should just set it to 100fps so that it doesn't go above or below providing the player the same game experience on different machines. Do you know of any references, links on setting framerate? Thanks.

  9. #9
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    VB Code:
    1. Private Declare Function GetTickCount Lib "kernel32" () As Long
    2. Const Fps As Single = 100
    3. Dim Running As Boolean
    4.  
    5. Private Sub Form_Load()
    6.     Me.Show
    7.     Running = True
    8.     GameLoop
    9. End Sub
    10.  
    11.  
    12. Sub GameLoop()
    13.     Dim TempTime As Long
    14.     While Running = True
    15.         If TempTime < GetTickCount Then
    16.             TempTime = GetTickCount + 1 / Fps * 1000 '(1s / 30frames/s = 33ms)
    17.             'GameCode
    18.         End If
    19.         DoEvents
    20.     Wend
    21. End Sub
    22.  
    23. Private Sub Form_Unload(Cancel As Integer)
    24.     Running = False
    25. End Sub

    Try this....not tested but i think it will work...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  10. #10
    Addicted Member
    Join Date
    Dec 2001
    Location
    Great White North, ey?
    Posts
    202

    Smile

    Hey, thanks for the code. It works somewhat, I can set a lower fps, but nothing I do can make it go over 60. Maybe this is a Win 2000 thing. I'm yet to try it on XP.....

  11. #11
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    that depends on how much processing it is in the game code...
    try to onle run the loop without any calculations...
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  12. #12
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    try changing this line:
    TempTime = GetTickCount + 1 / Fps * 1000
    to this:
    TempTime = GetTickCount + 1 / (Fps * 1000)
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  13. #13
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    no! that wont solve anything! my mistake!
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  14. #14
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    ahh! now i think i found out what was wrong...
    change:
    If TempTime < GetTickCount Then
    to:
    vIf TempTime <= GetTickCount Then
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  15. #15
    Good Ol' Platypus Sastraxi's Avatar
    Join Date
    Jan 2000
    Location
    Ontario, Canada
    Posts
    5,134
    Your machine is probably set to a lower refresh rate (hz) than it was previously (windows 98). Before, you may have had 100hz (thus, 100fps), but now you have 60hz [default], and thus 60fps. This is called Blitting on VSync.

    You shoulnd't *need* to get around this, as the game should blit as many times as possible in a second (to get the smoothest framerate), but the objects should only UPDATE when they're supposed to. So, in your loop (psuedocode), you should have something like this:
    Code:
    gettime()
    loop {
    delta = (gettime() - lasttime) / 1000
    blittoscreen()
    
    shipx = shipx + pixelspersecond * delta
    
    gettime()
    } end
    Delta is used so that it moves at the same rate, in this case x pixels per second, no matter what the speed of the loop is.
    All contents of the above post that aren't somebody elses are mine, not the property of some media corporation.
    (Just a heads-up)

  16. #16
    Addicted Member
    Join Date
    Dec 2001
    Location
    Great White North, ey?
    Posts
    202

    Thumbs up

    Thanks for the suggestions, but I still can't get over 60fps. Sastraxi is probably right, but the reason I want to get around this is because the game goes and looks much slower then what I planned it to be, if I increase the speed of everything by increasing the number of pixels everything moves, then the game will go too fast on win 95/98.

    Is there a way of manually changing your refresh rate? If there is, there is probably code on changing it as well .

  17. #17
    Addicted Member
    Join Date
    Dec 2001
    Location
    Great White North, ey?
    Posts
    202

    Exclamation

    I just found the refresh rate settings under the monitor settings and I switched it to 100hz and my game goes 100fps now! But I can't tell people to change their refresh rates if they want to play my game, and as I mentioned before I need to get around this because the game plays slow if it runs at 60fps. Hmm..any ideas, how do you guys get around this?

  18. #18
    Frenzied Member cyborg's Avatar
    Join Date
    May 2000
    Location
    Sweden
    Posts
    1,755
    if you're using a geforce graphics card you can disable the vsync (dont know how to do it with other cards).
    go to desktop properties > settings > advanced > look around for vsync....
    Check out the FAQ and do a search before you post.
    My tutorials: Anti-Alias Pixels, Accurate Game Loop, Resource File

  19. #19
    Ex-Super Mod'rater Electroman's Avatar
    Join Date
    Sep 2000
    Location
    Newcastle, England
    Posts
    4,349
    Let me get this straight, your games running at 60fps instead of 100fps, yea? well anyone that plays your game is going to have the same problem unless you make it so that your game doesn't depend on the fps. The best way I know, and use everytime, is if you use GetTickCount to calc how long its been, in milliseconds, between this and the last loop, eg:
    Code:
    lngTick = GetTickCount()
    Do
        lstlngTick = lngTick
        lngTick = GetTickCount()
        intTickDif = lngTick - lstlngTick
        If intTickDif <= 0 then intTickDif = 1  'Prevents Division by zero
        If intTickDif > 1000 then intTickDif = 100  'Incase very long delay(1fps), normally an error
        
        '[Game Code here]
    Loop Until ...
    Then in your game code instead of just doing:
    Code:
    PlayerXPos = PlayerXPos + PlayerXSpeed
    Do:
    Code:
    PlayerXPos = PlayerXPos + (PlayerXSpeed * (intTickDif /10))
    The 10 could be a different number for example if you make it "1000" then PlayerXSpeed would be in Pixels per second.

    This way if the fps is different the game is run at the same speed, very low fps will make it flicker tho.

    Hope that helps.
    When your thread has been resolved please edit the original post in the thread ()
    and amend "-[RESOLVED]-" to the end of the title and change the icon to , Thank you.

    When posting Code use the [VBCode]Code Here[/VBCode] tags to be able to use the code highlighting.

  20. #20
    Addicted Member
    Join Date
    Dec 2001
    Location
    Great White North, ey?
    Posts
    202

    Talking

    Hey Electroman, that works great, thank you so much for that!

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