Mouse cursor on image on screen

Just starting out? Need help? Post your questions and find answers here.
shaker
User
User
Posts: 38
Joined: Wed Aug 12, 2009 4:41 pm
Location: Bristol/Bath UK

Mouse cursor on image on screen

Post by shaker »

I have searched the forum and PureArea and can't find how to make a mouse cursor appear on top of an image on a screen.

From the examples I've seen, it appears that the normal MS mouse cursor is not available for use on screens, and people seem to use a Sprite. When I do this in the following code, the token cursor (large white square top left) doesn't show - except briefly when I exit the program.

Is there a solution?

Hope you can help, even if to say it can't be done.

Code: Select all

Enumeration
#IMAGE_SMALL
#SPRITE_MAIN = 1
EndEnumeration

Declare SetValveColours()
Declare ToggleValveColoursByKeyboard(Valve)

Global Started,Dim Colour(5),Dim x(5), Dim y(5)

;valve locations
x(1)=150 :y(1)=355
x(2)=450 :y(2)=445 
x(3)=343 :y(3)=144
x(4)=572 :y(4)=335
x(5)=785 :y(5)=546    

LoadImage(#IMAGE_SMALL, "c:\users\rex\pictures\ProcessPlant1.bmp")
LoadedImageWidth = ImageWidth(#IMAGE_SMALL)
LoadedImageHeight = ImageHeight(#IMAGE_SMALL)
InitSprite()  :InitKeyboard() :InitMouse()

OpenScreen(1024,768,32,"")
CreateSprite(#SPRITE_MAIN, 64, 64)
StartDrawing(SpriteOutput(#SPRITE_MAIN))
  Box(0, 0, 64, 64, RGB(255, 255, 255))
StopDrawing()


StartDrawing(ScreenOutput())  
  SetValveColours()
StopDrawing():FlipBuffers()

;======================================================================================================

;MAIN LOOP
;==========

Repeat 
DisplaySprite(#SPRITE_MAIN,100,100)

  Select ExamineKeyboard()
    Case KeyboardReleased(#PB_Key_1 ) :    ToggleValveColoursByKeyboard(1)
    Case KeyboardReleased(#PB_Key_2 ) :    ToggleValveColoursByKeyboard(2)
    Case KeyboardReleased(#PB_Key_3 ) :    ToggleValveColoursByKeyboard(3)
    Case KeyboardReleased(#PB_Key_4 ) :    ToggleValveColoursByKeyboard(4)
    Case KeyboardReleased(#PB_Key_5 ) :    ToggleValveColoursByKeyboard(5)
  EndSelect
  
  If KeyboardPushed(#PB_Key_Escape )   :Quit = 1 :EndIf 
  
Until Quit = 1

End

Procedure SetValveColours()

;Set valve colours to those last displayed
;============================= 
Box(0, 0,1024, 768, RGB(255, 255, 255))
DrawImage(ImageID(#IMAGE_SMALL), 0, 0)

For i = 1 To 5
  Circle(x(i), y(i), 8 ,RGB(0,0,0))
   If Started = 0 
    Circle(x(i), y(i), 5 ,$00FF00)
   Else 
    Circle(x(i), y(i), 5 ,Colour(i))
   EndIf   
  DrawText (x(i)+12,y(i)-8,"V"+Str(i))
  Colour(i) = Point(x(i),y(i))
Next

Started = 1

EndProcedure

Procedure ToggleValveColoursByKeyboard(Valve)
StartDrawing(ScreenOutput())
    Box(0, 0,1024, 768, RGB(255, 255, 255))
    DrawImage(ImageID(#IMAGE_SMALL), 0, 0)    
    SetValveColours()   
    If Red(Colour(Valve)) =  255
      Colour(Valve) = RGB(0,255,0)  
      Circle(x(Valve), y(Valve), 5 ,RGB(0,255,0))
    Else
     Colour(Valve) = RGB(255,0,0)
     Circle(x(Valve), y(Valve), 5 ,RGB(255,0,0))
    EndIf
  StopDrawing() :FlipBuffers()
EndProcedure
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Mouse cursor on image on screen

Post by Kaeru Gaman »

Sprites are like brushes, they get painted over each other every frame.
if you display the cursor first, it will be covered by the other output.

btw. you should preferably only change values in the conditioned branches, and display the drawings unconditioned.
and don't use select but If on the keys....
and use a sprite for the back not an image...

there's a whole bunch of crackles...
oh... and have a nice day.
shaker
User
User
Posts: 38
Joined: Wed Aug 12, 2009 4:41 pm
Location: Bristol/Bath UK

Re: Mouse cursor on image on screen

Post by shaker »

I've changed the select to if's. but have two queries

"if you display the cursor first, it will be covered by the other output."

Sorry, I don't understand. I display the cursor only after the other stuff has been drawn - which seems to be what you are telling me to do.

"and use a sprite for the back not an image..."

Does this mean that the sprite can't be used on an image on a screen?
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Mouse cursor on image on screen

Post by Kaeru Gaman »

Sorry, I don't understand. I display the cursor only after the other stuff has been drawn

no.
in your loop, you first display your #SPRITE_MAIN, then you do the other stuff.
you do all your displaying in procedures and condition branches, it's hard to see what happens where and how.
Does this mean that the sprite can't be used on an image on a screen?
no.
this just means that drawing a large image is way way way slower than displaying a sprite.


you whole code needed straight clearing, sorry.

I messed around with it a bit...

Code: Select all

Enumeration
#IMAGE_SMALL
#SPRITE_MAIN
EndEnumeration


Global Started,Dim Colour(5),Dim x(5), Dim y(5)

;valve locations
x(1)=150 :y(1)=355
x(2)=450 :y(2)=445
x(3)=343 :y(3)=144
x(4)=572 :y(4)=335
x(5)=785 :y(5)=546   

InitSprite()  
InitKeyboard() 
InitMouse()

OpenScreen(1024,768,32,"")

;LoadSprite(#IMAGE_SMALL, "c:\users\rex\pictures\ProcessPlant1.bmp")

;======================================================================================================
; Creating on-the-fly-background to replace the back image
;======================================================================================================
CreateSprite( #IMAGE_SMALL, 1024,768 )
  StartDrawing( SpriteOutput( #IMAGE_SMALL ) )
    Box( 0,0, 1024,768, $008000 )
    For n=1 To 4
      For t = n+1 To 5
        LineXY( x(n),y(n), x(t),y(t), $0FF0FF )
      Next
    Next
  StopDrawing()
;======================================================================================================

LoadedImageWidth = SpriteWidth(#IMAGE_SMALL)
LoadedImageHeight = SpriteHeight(#IMAGE_SMALL)

CreateSprite(#SPRITE_MAIN, 64, 64)
StartDrawing(SpriteOutput(#SPRITE_MAIN))
  LineXY( 0,0, 64, 64, $FF0000 )
  LineXY( 0,0, 32, 16, $FF0000 )
  LineXY( 0,0, 16, 32, $FF0000 )
StopDrawing()

; SetValveColour
For i=1 To 5
  Colour( i ) = $00FF00
Next

;======================================================================================================

;MAIN LOOP
;==========

Repeat

;==========
; Input
;==========

  ExamineKeyboard()
  ExamineMouse()

  Valve = 0 ; erase number to make none toggled if no key is pressed
  ; if 1-5 is pressed, set the valve number to toggle
  If  KeyboardReleased(#PB_Key_1 ) :    Valve = 1 : EndIf
  If  KeyboardReleased(#PB_Key_2 ) :    Valve = 2 : EndIf
  If  KeyboardReleased(#PB_Key_3 ) :    Valve = 3 : EndIf
  If  KeyboardReleased(#PB_Key_4 ) :    Valve = 4 : EndIf
  If  KeyboardReleased(#PB_Key_5 ) :    Valve = 5 : EndIf
 
  If KeyboardPushed(#PB_Key_Escape )   :Quit = 1 :EndIf

  MX = MouseX()
  MY = MouseY()

;==========
; Processing
;==========

  ; ToggleValveColoursByKeyboard
  If Valve > 0
    If Colour( Valve ) = $00FF00  ; if green
      Colour( Valve ) = $0000FF   ; make it red
    Else                          ; else
      Colour( Valve ) = $00FF00   ; make it green
    EndIf
  EndIf

;==========
; Display
;==========

  ClearScreen( $FFFFFF )  ; way way way faster than drawing a big box
  
  DisplaySprite( #IMAGE_SMALL, 0, 0 ) ; background as sprite is faster than image
  
  ; Show Valves
  StartDrawing( ScreenOutput() )
    For i=1 To 5
      Circle( x(i), y(i), 8 , $000000 )
      Circle( x(i), y(i), 5 , Colour(i) )
      DrawingMode( #PB_2DDrawing_Transparent )      ; make text transparent back
      DrawText (x(i)+12,y(i)-8,"V"+Str(i), $FF0000) ; chose a colour that fits to your back image
    Next
  StopDrawing()
  
  DisplayTransparentSprite(#SPRITE_MAIN, MX, MY) ; display cursor on top of all with transparent back
  
  FlipBuffers()

Until Quit = 1

End
mind the structure: Input - Processing - Output
especially for screen operations it's better to keep to that line.

and only do in conditions what is necessary to be in conditions.
here only the changing of the colour need to be conditioned,
and only of that one colour of the valve that was changed.
all the other stuff remains unconditioned in the MainLoop.

with a screen it's just totally the other way round than with a window.
in an EventLoop for a Window you will place as few actions as possible unconditioned into the mainloop.
oh... and have a nice day.
shaker
User
User
Posts: 38
Joined: Wed Aug 12, 2009 4:41 pm
Location: Bristol/Bath UK

Re: Mouse cursor on image on screen

Post by shaker »

Many thanks! I was totally at sea. I'll study what you have done in the example, learn the lessons, and apply it to my program.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Mouse cursor on image on screen

Post by Kaeru Gaman »

you're welcome.
come back with any question you may have.
oh... and have a nice day.
shaker
User
User
Posts: 38
Joined: Wed Aug 12, 2009 4:41 pm
Location: Bristol/Bath UK

Re: Mouse cursor on image on screen

Post by shaker »

I had imported a .bmp to save coding to give the same result.

Your solution achieves the required end by coding. But would it work if you tried to show the curson on an imported image as I did? In other words does a mouse cursor on an image on a screen work?
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Mouse cursor on image on screen

Post by Kaeru Gaman »

sure it does.

first try to keep it a sprite:
comment the creation I introduced out, uncomment the LoadSprite.
it should completely replace your LoadImage:DrawImage

you can try it to do it with an image:
just put the Image into the Drawing block, as the first action, comment the according DisplaySprite out.

Code: Select all

 ; DisplaySprite( #IMAGE_SMALL, 0, 0 ) ; background as sprite is faster than image
  ; Show Image and Valves
  StartDrawing( ScreenOutput() )
    DrawImage(ImageID(#IMAGE_SMALL), 0, 0)
    For i=1 To 5
      Circle( x(i), y(i), 8 , $000000 )
      Circle( x(i), y(i), 5 , Colour(i) )
      DrawingMode( #PB_2DDrawing_Transparent )      ; make text transparent back
      DrawText (x(i)+12,y(i)-8,"V"+Str(i), $FF0000) ; chose a colour that fits to your back image
    Next
  StopDrawing()
oh... and have a nice day.
shaker
User
User
Posts: 38
Joined: Wed Aug 12, 2009 4:41 pm
Location: Bristol/Bath UK

Re: Mouse cursor on image on screen

Post by shaker »

Many thanks. I will study what you have told me.
shaker
User
User
Posts: 38
Joined: Wed Aug 12, 2009 4:41 pm
Location: Bristol/Bath UK

Re: Mouse cursor on image on screen

Post by shaker »

But aren't you still coding the image? I wanted to avoid that by importing a fairly complex .bmp. Is it possible to show the sprite on the .bmp? Please forgive my denseness.
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Re: Mouse cursor on image on screen

Post by Kaeru Gaman »

I just drawed the Image because I have no fitting image to load.

comment this whole block out:

Code: Select all

;======================================================================================================
; Creating on-the-fly-background to replace the back image
;======================================================================================================
CreateSprite( #IMAGE_SMALL, 1024,768 )
  StartDrawing( SpriteOutput( #IMAGE_SMALL ) )
    Box( 0,0, 1024,768, $008000 )
    For n=1 To 4
      For t = n+1 To 5
        LineXY( x(n),y(n), x(t),y(t), $0FF0FF )
      Next
    Next
  StopDrawing()
;======================================================================================================
and uncomment this one line I left in the code:

Code: Select all

LoadSprite(#IMAGE_SMALL, "c:\users\rex\pictures\ProcessPlant1.bmp")
then the only thing changed from your image to my sprite is,
that I loaded ProcessPlant1.bmp as a sprite not as image,
and that sprites are displayed and images are drawn.


PS:
depending on what your project is to become, you should not hardcode the patchs of the content.
load the image from a relative path, e.g. a subfolder of your exe's folder, make sure to adjust currect directory first.
but you can take care of this later, don't get puzzled for now.
oh... and have a nice day.
shaker
User
User
Posts: 38
Joined: Wed Aug 12, 2009 4:41 pm
Location: Bristol/Bath UK

Re: Mouse cursor on image on screen

Post by shaker »

Kaeru,

Very many thanks. I would have struggled for days without your detailed help. And you have given me valuable advice beyond that to get the program working as I wanted.
Post Reply