Page 1 of 1

Clicking and dragging sprites

Posted: Wed May 21, 2008 4:00 pm
by c4
Is there an example somewhere which demonstrates clicking and dragging a sprite?

Perhaps someone could show a quick demonstration of how this could be done in PB.

Peace.

Posted: Thu May 22, 2008 1:06 pm
by c4
Nothing?

Did I ask something completely stupid? If so, I apologize. I'm new to PB programming.

Posted: Thu May 22, 2008 1:55 pm
by tinman
Here's one way to do it. But it's not very good as it uses Windows only functionality, it's not scalable, uses shared variables and there are missing things (like capturing the mouse).

Code: Select all

Define.l    quit
Define.l    ev

If InitSprite() = 0
    End
EndIf

If InitMouse() = 0 : End : EndIf

Define.l current_x : current_x = 100
Define.l current_y : current_y = 100
Define.l dragging : dragging = 0

Define.l old_mouse_x
Define.l old_mouse_y

Procedure DrawScreen()
    Shared current_x
    Shared current_y
    
    ClearScreen(RGB(0, 0, 0))
    DisplaySprite(0, current_x, current_y)
EndProcedure

If OpenWindow(0, 0, 0, 800, 600, "")
    If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, #False, 0, 0)
        SetRefreshRate(60)

        CreateSprite(0, 32, 32, #PB_Sprite_Memory)
        If StartDrawing(SpriteOutput(0))
            Box(0, 0, SpriteWidth(0), SpriteHeight(0), RGB(255, 0, 0))
            StopDrawing()
        Else
            CallDebugger
        EndIf

        DrawScreen()
        
        While quit=0
            ev = WaitWindowEvent()
            While ev<>0
                Select ev
                    Case #PB_Event_Repaint
                        DrawScreen()
                        
                    Case #PB_Event_CloseWindow
                        quit = 1
                    
                    Case #WM_LBUTTONDOWN
                        If WindowMouseX(0)>=current_x And WindowMouseX(0)<(current_x+SpriteWidth(0)) And WindowMouseY(0)>=current_y And WindowMouseY(0)<(current_y+SpriteHeight(0))
                            Debug "Starting drag"
                            
                            old_mouse_x = WindowMouseX(0)
                            old_mouse_y = WindowMouseY(0)
                            dragging = 1
                        EndIf
                        
                    Case #WM_MOUSEMOVE
                        If dragging
                            current_x = current_x + WindowMouseX(0) - old_mouse_x
                            current_y = current_y + WindowMouseY(0) - old_mouse_y
                            old_mouse_x = WindowMouseX(0)
                            old_mouse_y = WindowMouseY(0)
                            Debug "Dragging to "+Str(current_x)+", "+Str(current_y)
                            InvalidateRect_(WindowID(0), 0, 0)
                        EndIf
                        
                    Case #WM_LBUTTONUP
                        Debug "Stop dragging"
                        dragging = 0
                    
                EndSelect
                
                ev = WindowEvent()
            Wend
        Wend
    
        CloseScreen()
    EndIf
    CloseWindow(0)
EndIf
End

Posted: Thu May 22, 2008 5:25 pm
by Trond
c4 wrote:Nothing?

Did I ask something completely stupid? If so, I apologize. I'm new to PB programming.
You asked for multiple things instead of just one. First you need to detect mouse movement/presses. Then you need to draw the sprite. And you need to compare the mouse position to sprite position.

In general people will be much more keen to help when you try yourself first and then post your code, say what it does and say what you want it to do.

Posted: Thu May 22, 2008 5:49 pm
by c4
@Trond: You make a good point. I'll try to narrow down future questions.

@tinman: Thank you. Does the scaling problem you mentioned means I would have quite a few redundant variables if I added more sprites with dragging properties? Since only one sprite is being dragged at any given moment, it shouldn't matter how many are on the screen, no?

Or does the scaling problem relate to the fact that mouse positions are not captured in your example?

Posted: Thu May 22, 2008 6:49 pm
by Kaeru Gaman
when you want to drag a sprite, you will have a screen and use Examinemouse(),
so I see no use in messing around with windows' evenqueue, sorry tinman.

when you are working with sprites, you code your whole click-event handling from the scratch.
so, implementing some dragging in the end just means to add a Flag for
holding and adjusting the sprite-position parallel to the mouse-position.

Posted: Thu May 22, 2008 7:21 pm
by IceSoft
Search to 'PBpuzzle' can help you to find an example ;-)

Posted: Thu May 22, 2008 11:33 pm
by tinman
c4 wrote:@tinman: Thank you. Does the scaling problem you mentioned means I would have quite a few redundant variables if I added more sprites with dragging properties? Since only one sprite is being dragged at any given moment, it shouldn't matter how many are on the screen, no?
Mainly this, because you will need to store x/y co-ordinates for each sprite, and then check against each one for the click hit-test. I've only used a variable for x/y whereas something like an array or list would obviously be better. And I think there are better hit tests than the multiple conditions in an If statement as I have used.
Kaeru Gaman wrote:when you want to drag a sprite, you will have a screen and use Examinemouse(),
so I see no use in messing around with windows' evenqueue, sorry tinman.
The original post asked how to move a sprite. A windowed screen is just as legitimate as a full screen.

But just for you I made this. It took less time to write than this reply. I'm sure you could have provided the same example sooner rather than making yet another condescending post.

Code: Select all

Define.l    quit
Define.l    ev

If InitSprite() = 0
    End
EndIf

If InitMouse() = 0 : End : EndIf
If InitKeyboard() = 0 : End : EndIf

Define.l current_x : current_x = 100
Define.l current_y : current_y = 100
Define.l dragging : dragging = 0

Define.l old_mouse_x
Define.l old_mouse_y

Procedure DrawScreen()
    Shared current_x
    Shared current_y
   
    ClearScreen(RGB(0, 0, 0))
    DisplaySprite(0, current_x, current_y)
    DisplaySprite(1, MouseX(), MouseY())
EndProcedure

If OpenScreen(800, 600, 32, "")

    CreateSprite(0, 32, 32, #PB_Sprite_Memory)
    If StartDrawing(SpriteOutput(0))
        Box(0, 0, SpriteWidth(0), SpriteHeight(0), RGB(255, 0, 0))
        StopDrawing()
    Else
        CallDebugger
    EndIf

    CreateSprite(1, 16, 16, #PB_Sprite_Memory)
    If StartDrawing(SpriteOutput(1))
        Line(SpriteWidth(1)/2, 0, 0, SpriteHeight(1), RGB(255, 255, 0))
        Line(0, SpriteHeight(1)/2, SpriteWidth(1), 0, RGB(255, 255, 0))
        StopDrawing()
    Else
        CallDebugger
    EndIf

    While quit=0
        ExamineKeyboard()
        
        If KeyboardPushed(#PB_Key_Escape)
            quit = 1
        EndIf
                   
        
        ExamineMouse()
        
        If MouseButton(#PB_MouseButton_Left)
            If dragging=0
                If MouseX()>=current_x And MouseX()<(current_x+SpriteWidth(0)) And MouseY()>=current_y And MouseY()<(current_y+SpriteHeight(0))
                    Debug "Starting drag"
                    dragging = 1
                EndIf
            Else
                current_x = current_x + MouseDeltaX()
                current_y = current_y + MouseDeltaY()
                Debug "Dragging to "+Str(current_x)+", "+Str(current_y)
            EndIf
        Else
            Debug "Stop dragging"
            dragging = 0
        EndIf
        
        DrawScreen()
        FlipBuffers(#True)
    Wend

    CloseScreen()
EndIf

End

Posted: Fri May 23, 2008 1:59 am
by Kaeru Gaman
tinman wrote:The original post asked how to move a sprite. A windowed screen is just as legitimate as a full screen.

But just for you I made this. It took less time to write than this reply. I'm sure you could have provided the same example sooner rather than making yet another condescending post.
for me a windowed screen is just another container for a screen,
I would handle a drag'n'drop of a sprite as hardcoded as on a fullscreen.
maybe a matter of taste. sure.

and fine if you code such example that quick, seems you were into coding today, and had an example in mind.
me not. only browsing forums for coffee break. dropping a remark was way quicker than getting into coding.