Rotate image fast? (wheel of fortune like)

Just starting out? Need help? Post your questions and find answers here.
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Rotate image fast? (wheel of fortune like)

Post by ricardo »

hello

I want to rotate a simple image (something like the wheel of fortune):

Image

Its just for a small game i want to code for my kids (wheel of fortune with very simple phrases, all downloable games in spanish have phrases very complicated for them)

I do not nothing about sprites, dont know if its possible or using bmp, jpg.

Any help are welcome :)
ARGENTINA WORLD CHAMPION
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Re: Rotate image fast? (wheel of fortune like)

Post by ricardo »

ricardo wrote:hello

I want to rotate a simple image (something like the wheel of fortune):

Image

Its just for a small game i want to code for my kids (wheel of fortune with very simple phrases, all downloable games in spanish have phrases very complicated for them)

I do not nothing about sprites, dont know if its possible or using bmp, jpg. avoiding sprites, because i want the rest of the app to be a simple interface since i dont want to spend much time coding it. Just want something fast to code.

Any help are welcome :)
ARGENTINA WORLD CHAMPION
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Post by ricardo »

Maybe drawing it to make it rotate?
ARGENTINA WORLD CHAMPION
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

513x513 is just 1 pix too big. make it 512x512.

then load it as a sprite, create a Sprite3D from it, and use RotateSprite3D.
http://www.purebasic.com/documentation/ ... prite.html
http://www.purebasic.com/documentation/ ... ite3d.html
http://www.purebasic.com/documentation/ ... ite3d.html

using sprite and screen is the easiest approach.

you can create buttons etc. on the screen itself, using sprites for fancy skinned look.

or you use a WindowedScreen in the middle for the wheel only, and create the rest of the GUI in boring standard buttons.


... doing the same with Images surely is possible, but you would need ASM routines to rotate the Image, there is nothing native for this in PB.
oh... and have a nice day.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

...but you would need ASM routines to rotate the Image...
No, lots of options. Here's one:

Code: Select all

;================================================== 
;  Program:     GDIPlus Rotation Demo 
;  Author:      netmaestro 
;  Date:        July 2, 2009
;================================================== 

CompilerIf Defined(GdiplusStartupInput, #PB_Structure) = 0 
  Structure GdiplusStartupInput 
    GdiPlusVersion.l 
    *DebugEventCallback.Debug_Event 
    SuppressBackgroundThread.l 
    SuppressExternalCodecs.l 
  EndStructure 
CompilerEndIf  

#background = 0 ; image# for background 

Prototype GdiplusStartup( *token, *input, mode ) 
Prototype GdipCreateBitmapFromFile(filename.p-bstr, *image)
Prototype GdipCreateFromHDC( hdc, *gfx) 
Prototype GdipRotateWorldTransform( *gfx, angle.f, mode)
Prototype GdipResetWorldTransform( *gfx)
Prototype GdipTranslateWorldTransform( *gfx, wmidf.f, hmidf.f, mode)
Prototype GdipDrawImageRectI( *gfx, *image, x, y, Width, Height ) 
Prototype GdipDeleteGraphics( *gfx ) 
Prototype GdipDisposeImage( *image ) 
Prototype GdiplusShutdown( *token ) 

OpenLibrary(0, "gdiplus.dll") 
  
Global GdiplusStartup.GdiplusStartup                           = GetFunction( 0, "GdiplusStartup" )          
Global GdipCreateBitmapFromFile.GdipCreateBitmapFromFile       = GetFunction( 0, "GdipCreateBitmapFromFile")
Global GdipCreateFromHDC.GdipCreateFromHDC                     = GetFunction( 0, "GdipCreateFromHDC" )      
Global GdipDrawImageRectI.GdipDrawImageRectI                   = GetFunction( 0, "GdipDrawImageRectI" )      
Global GdipRotateWorldTransform.GdipRotateWorldTransform       = GetFunction( 0, "GdipRotateWorldTransform" )      
Global GdipTranslateWorldTransform.GdipTranslateWorldTransform = GetFunction( 0, "GdipTranslateWorldTransform" )      
Global GdipResetWorldTransform.GdipResetWorldTransform         = GetFunction( 0, "GdipResetWorldTransform" ) 
Global GdipDeleteGraphics.GdipDeleteGraphics                   = GetFunction( 0, "GdipDeleteGraphics" )      
Global GdipDisposeImage.GdipDisposeImage                       = GetFunction( 0, "GdipDisposeImage" )        
Global GdiplusShutdown.GdiplusShutdown                         = GetFunction( 0, "GdiplusShutdown" )  

Procedure InitGDIPlus() 
  input.GdiplusStartupInput 
  input\GdiPlusVersion = 1 
  GdiplusStartup( @*token, @input, #Null) 
  ProcedureReturn *token 
EndProcedure 

Procedure ShutDownGDIPlus(*token) 
  GdiplusShutdown(*token) 
  CloseLibrary(0) 
EndProcedure 

Procedure RotateImage(*image, bkgimage, angle.f) 
  width=ImageWidth(bkgimage) 
  height=ImageHeight(bkgimage) 
  wmidf.f = width/2 
  hmidf.f = height/2 
  wmid.l = height/2 
  hmid.l = height/2  
  hdc=StartDrawing(ImageOutput(bkgimage)) 
    GdipCreateFromHDC( hdc, @*surface) 
    GdipRotateWorldTransform( *surface, angle, 1) 
    GdipTranslateWorldTransform( *surface, wmidf, hmidf, 1) 
    GdipDrawImageRectI( *surface, *image, wmid, hmid, -width, -height) 
    GdipResetWorldTransform( *surface)                                      
  StopDrawing() 
  GdipDeleteGraphics( *surface)  
EndProcedure 

*token = InitGDIPlus() 

GdipCreateBitmapFromFile("513pxwheeloffortuneseas.png", @*wheeldisc) 
CreateImage(0,513,513,32) 

OpenWindow(0,0,0,540,570,"Rotation Demo",#PB_Window_ScreenCentered|#PB_Window_SystemMenu) 
SetWindowColor(0,0)
ImageGadget(0,15,15,0,0,0) 
ButtonGadget(1,220,540,100,20,"Spin!") 

RotateImage(*wheeldisc, #background, 0) 
SetGadgetState(0,ImageID(#background)) 
      
Repeat 
  EventID = WindowEvent() 
  Select EventID
    Case #PB_Event_Gadget
      Select EventGadget()
        Case 1
          inc.d = (500+Random(200))/100
      EndSelect
  EndSelect
        
  If inc
    inc - 0.01
    If inc<=0
      inc=0:spinning=0
      intangle=Int(angle.d) 
      offset=intangle%15
      If offset > 7 : angle+(15-offset) : Else : angle-offset : EndIf
    Else
      angle.d+inc.d:If angle >=360:angle=0:EndIf 
    EndIf
    RotateImage(*wheeldisc, #background, angle) 
    SetGadgetState(0,ImageID(#background)) 
  EndIf  
 
Until EventID = #WM_CLOSE 

ShutDownGDIPlus(*token)  
BERESHEIT
ricardo
Addict
Addict
Posts: 2438
Joined: Fri Apr 25, 2003 7:06 pm
Location: Argentina

Post by ricardo »

Thanks for you answers!! :)

But now i found a problem i was not aware... how do i know which is the area pointing up when i stop the rotation? This is getting more complicated that what i was thinking about! :P

Best Regards
ARGENTINA WORLD CHAMPION
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

It isn't difficult. Make a Select/Case block with upper and lower limits (remember you're dealing with floats) where the result is decided by the finishing angle. 0=900, 15 (or better 14 to 16, floats remember) = 300, etc.
BERESHEIT
User avatar
Kaeru Gaman
Addict
Addict
Posts: 4826
Joined: Sun Mar 19, 2006 1:57 pm
Location: Germany

Post by Kaeru Gaman »

@netmaestro

ok, you're right... why write everything again when GDI+ already has all you need.

just would have taken weeks for me to import all the stuff and learn how to use it. :mrgreen:

with Sprite3D, would have been a one hour job for me.
oh... and have a nice day.
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Sprite3D may be smoother, not sure. It probably is.
BERESHEIT
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Post by netmaestro »

Interesting, if you resize the .png to 512*512 it runs smoother. A nice multiple of 2 is probably a lot easier on the gdiplus algos.
BERESHEIT
User avatar
IceSoft
Addict
Addict
Posts: 1695
Joined: Thu Jun 24, 2004 8:51 am
Location: Germany

Post by IceSoft »

Kaeru Gaman wrote: ... why write everything again when GDI+ already has all you need.
Why not?
GDI+ is only for Microsoft OSes.

Using the Sprite3D functions ... and your source works also on Linux and MACOS.
Belive! C++ version of Puzzle of Mystralia
Bug Planet
<Wrapper>4PB, PB<game>, =QONK=, PetriDish, Movie2Image, PictureManager,...
+18
Enthusiast
Enthusiast
Posts: 228
Joined: Fri Oct 24, 2008 2:07 pm

Post by +18 »

why this occurred for me?

Image
User avatar
Michael Vogel
Addict
Addict
Posts: 2807
Joined: Thu Feb 09, 2006 11:27 pm
Contact:

Post by Michael Vogel »

+18 wrote:why this occurred for me?...
Is *wheeldisk already a pointer var? Then it is equal the reference address already, adding an additional "@" would be a little bit to much here :wink:

If you are not sure, just insert some debug lines like...

Code: Select all

Debug *wheeldisk
Debug @*wheeldisk
Michael
infratec
Always Here
Always Here
Posts: 7619
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Post by infratec »

Hi,

since I like it crossplatform compatible:

I simply modified the example of the PureBASIC helpfile
(10 minutes work)


But than I needed to convert the picture to bmp.
UsePNG... was not working, don't know why.

PNG is working now

So I reduced the sice to 512x512 and set the cornercolour to 255,0,255.

Code: Select all

UsePNGImageDecoder()

If InitSprite() = 0 Or InitKeyboard() = 0
  MessageRequester("Error", "Sprite system can't be initialized", 0)
  End
EndIf

If InitSprite3D() = 0
  MessageRequester("Error", "Sprite3D system can't be initialized correctly", 0)
  End
EndIf


If OpenWindow(0, 0, 0, 800, 600, "Wheel V1.01", #PB_Window_ScreenCentered|#PB_Window_SystemMenu)

 If OpenWindowedScreen(WindowID(0), 0, 0, 800, 600, 0, 0, 0)

  ; Load our 16 bit sprite (which is a 24 bit picture in fact, as BMP doesn't support 16 bit format)
  ; 
  LoadSprite(0, "Wheel.png", #PB_Sprite_Texture)
  CreateSprite3D(0, 0)
  
  Sprite3DQuality(1)
  
  TransparentSpriteColor(0, RGB(255, 0, 255)) ; Our pink is transparent :)

  x = 0

  Repeat
    
    ; Inverse the buffers (the back become the front (visible)... And we can do the rendering on the back)
    
    FlipBuffers()
    
    ClearScreen(RGB(0,50,128))
    
    ; Draw our sprite
    ;
    If Start3D()
      DisplaySprite3D(0, 144, 44)
      RotateSprite3D(0, x, 0)
      Stop3D()
    EndIf
    
    Delay(10)  ; to reduce the cpu load from 100 to 10%  :)

    ExamineKeyboard()
    
    x + 1 ; to speed it up, increase this value
    If x > 359: x = 0 : EndIf
  Until KeyboardPushed(#PB_Key_Escape) Or WindowEvent() = #PB_Event_CloseWindow
  
 Else
   MessageRequester("Error", "Can't open windowed screen!", 0)
 EndIf
 
Else
 MessageRequester("Error", "Can't open window!", 0)
EndIf

End
Best regards,

Bernd
Last edited by infratec on Fri Jul 03, 2009 6:35 pm, edited 6 times in total.
User avatar
Psychophanta
Always Here
Always Here
Posts: 5153
Joined: Wed Jun 11, 2003 9:33 pm
Location: Anare
Contact:

Post by Psychophanta »

@ricardo, can't help, as i am so anti-capitalist.
To me that wheel is like a latin cross to Count Dracula. :P

Sorry, if not help i should be just shuted up :oops:
http://www.zeitgeistmovie.com

while (world==business) world+=mafia;
Post Reply