Clicking and dragging sprites

Just starting out? Need help? Post your questions and find answers here.
c4
New User
New User
Posts: 8
Joined: Mon May 19, 2008 2:25 pm
Location: South Florida

Clicking and dragging sprites

Post 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.
c4
New User
New User
Posts: 8
Joined: Mon May 19, 2008 2:25 pm
Location: South Florida

Post by c4 »

Nothing?

Did I ask something completely stupid? If so, I apologize. I'm new to PB programming.
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post 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
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
Trond
Always Here
Always Here
Posts: 7446
Joined: Mon Sep 22, 2003 6:45 pm
Location: Norway

Post 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.
c4
New User
New User
Posts: 8
Joined: Mon May 19, 2008 2:25 pm
Location: South Florida

Post 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?
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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.
oh... and have a nice day.
User avatar
IceSoft
Addict
Addict
Posts: 1699
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Post by IceSoft »

Search to 'PBpuzzle' can help you to find an example ;-)
Belive! C++ version of Puzzle of Mystralia
Bug Planet
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
User avatar
tinman
PureBasic Expert
PureBasic Expert
Posts: 1102
Joined: Sat Apr 26, 2003 4:56 pm
Location: Level 5 of Robot Hell
Contact:

Post 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
If you paint your butt blue and glue the hole shut you just themed your ass but lost the functionality.
(WinXPhSP3 PB5.20b14)
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post 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.
oh... and have a nice day.
Post Reply