Author Topic: [SOLVED]Sprite Clipping Issue??  (Read 4526 times)

0 Members and 1 Guest are viewing this topic.

Offline Omnikam

  • Atari ST
  • ***
  • Posts: 121
  • Karma: 4
    • View Profile
[SOLVED]Sprite Clipping Issue??
« on: November 09, 2015 »
Hey guy  ;D I`m having a crazy time tying to understand why the following code doesn't work as i expect it should
It should display a ship, a ball and a record, but in the following it just shows 3 records, if i comment out the record clipping and it`s display it will show 2 ships and so on. I spent 2 days trying to solve the problem but no luck ,is anyone familiar with my problem and have a solution? :-\
When i try to debug it i notice that both c64, ball, ship and happydays have the same identifier number
I would have thought that ball, ship and happydays being unique identifiers would hold separate values? Since they each hold separate clipping coordinates
Code: [Select]
InitSprite()
      xres=800
      yres=600
      InitKeyboard()
     
      windows=  OpenScreen(xres,yres,32,"(C) Omnikam 2015")
       
  UsePNGImageDecoder()
  UseJPEGImageDecoder()
    c64=  LoadSprite(#PB_Any, "pirate.png",#PB_Sprite_AlphaBlending )
   
   ball=ClipSprite(c64,0, 0, 500, 500)
   ship=ClipSprite(c64,501, 0, 500, 500)
   happydays=ClipSprite(c64,   0, 501, 480 ,480  )                                 

   
    Repeat
    ClearScreen(0)
    DisplayTransparentSprite(ball,0,0,255)
    DisplayTransparentSprite(ship,100,40,255)
    DisplayTransparentSprite(happydays,10,300,255)
   FlipBuffers()
   ExamineKeyboard()
   Until KeyboardPushed (#PB_Key_Escape)
« Last Edit: November 09, 2015 by Omnikam »

Offline Omnikam

  • Atari ST
  • ***
  • Posts: 121
  • Karma: 4
    • View Profile
Re: Sprite Clipping Issue??
« Reply #1 on: November 09, 2015 »
Okay i seemed to have got it to work with the following code
It will only work correctly if the clipped image is displayed straight after it`s clipping, That seems limited and probably even a bug?
I guess i solved my problem, although i cant understand why its so ???
Thought I`d add that using rotate sprite on a given sprite will rotate them all, i think it has everything to do with the clipped sprites sharing the same number
Code: [Select]
      InitSprite()
      xres=800
      yres=600
      InitKeyboard()
     
      windows=  OpenScreen(xres,yres,32,"(C) Omnikam 2015")
       
  UsePNGImageDecoder()
  UseJPEGImageDecoder()
    c64=  LoadSprite(#PB_Any, "pirate.png",#PB_Sprite_AlphaBlending )
   Repeat
      ClearScreen(0)
      ball=ClipSprite(c64,0, 0, 500, 500)
     DisplayTransparentSprite(ball,0,0,255)
     ship=ClipSprite(c64,501, 0, 500, 500)
     DisplayTransparentSprite(ship,100,40,255)
     happydays=ClipSprite(c64,   0, 501, 480 ,480  )                                 
     DisplayTransparentSprite(happydays,10,300,100)
    FlipBuffers()
   ExamineKeyboard()
   Until KeyboardPushed (#PB_Key_Escape)
   
« Last Edit: November 09, 2015 by Omnikam »

Offline ~Ar-S~

  • C= 64
  • **
  • Posts: 61
  • Karma: 26
  • Demo RuleZ
    • View Profile
Re: [SOLVED]Sprite Clipping Issue??
« Reply #2 on: November 10, 2015 »
It's strange you're wright.

Anyway, I prefer to use GrabSprite anyway the free the original "big" sprite.

Code: [Select]
UsePNGImageDecoder()

Enumeration
  #C64
  #BALL
  #SHIP
  #HAPPYDAYS
EndEnumeration

InitSprite() : InitKeyboard()
xres=1280
yres=768

If OpenScreen(xres,yres,32,"(C) Omnikam 2015")

LoadSprite(#C64, "pirate.png",#PB_Sprite_AlphaBlending )
CopySprite(#C64,#BALL,#PB_Sprite_AlphaBlending)
CopySprite(#C64,#SHIP,#PB_Sprite_AlphaBlending)
CopySprite(#C64,#HAPPYDAYS,#PB_Sprite_AlphaBlending)

GrabSprite(#BALL,   17, 15, 477, 477,#PB_Sprite_AlphaBlending)
GrabSprite(#SHIP,   500, 17, 500, 420,#PB_Sprite_AlphaBlending)
GrabSprite(#HAPPYDAYS,   0, 500, 486 ,480,#PB_Sprite_AlphaBlending)

Debug #BALL
Debug #SHIP
Debug #HAPPYDAYS

FreeSprite(#C64)
x = 1280

Repeat
  ExamineKeyboard()
  ClearScreen(0)
  x-4
  DisplayTransparentSprite(#ball,     x     , 50,255)
  DisplayTransparentSprite(#ship,     30 + x, 50,255)
  DisplayTransparentSprite(#happydays,80 + x, 50,255)
 
  If x < -500
    x = 1280
  EndIf
 
  FlipBuffers()
Until KeyboardPushed (#PB_Key_Escape)

EndIf

~ Ar-S ~

Offline Omnikam

  • Atari ST
  • ***
  • Posts: 121
  • Karma: 4
    • View Profile
Re: [SOLVED]Sprite Clipping Issue??
« Reply #3 on: November 11, 2015 »
Your code doesnt work on my computer, shows nothing
How rude of me  :telloff:
A BIG thanks for sharing  :cheers:
« Last Edit: November 12, 2015 by Omnikam »

Offline emook

  • C= 64
  • **
  • Posts: 94
  • Karma: 12
    • View Profile
Re: [SOLVED]Sprite Clipping Issue??
« Reply #4 on: November 12, 2015 »
Hi,

Its because you are mis-using ClipSprite. It doesn't clip an image like a traditional image editing package, it applies a clipping windows to the sprite. It also does not have a return value.

So, when you code :
Code: [Select]
c64=  LoadSprite(#PB_Any, "pirate.png",#PB_Sprite_AlphaBlending )     ; you load the sprite and assign its ID to c64
ball=ClipSprite(c64,0, 0, 500, 500)   ; ball= does nothing, but you apply the clipping window to c64 at 0,0,500,500
ship=ClipSprite(c64,501, 0, 500, 500) ; ship = does nothing, but you move the clipping window to c64 at 501,0,500,500
happydays=ClipSprite(c64,   0, 501, 480 ,480  ) ; happydays = does nothing, but you move the clipping window to c64 at 0, 501, 480 ,480

What you need to do it copy the sprite to a new sprite, then clip that sprite. I've tried to keep the code most close to how you have been coding - eg :

Code: [Select]
c64=  LoadSprite(#PB_Any, "pirate.png",#PB_Sprite_AlphaBlending ) ; load the sprite ID and place in c64

ball=CopySprite(c64,#PB_Any)  ; copy the sprite c64 to ball
ship=CopySprite(c64,#PB_Any)  ; copy the sprite c64 to ship
happydays=CopySprite(c64,#PB_Any)  ; copy the sprite c64 to happydays

ClipSprite(ball,0, 0, 500, 500)   ; clip ball
ClipSprite(ship,501,0,500,500) ; clip ship
ClipSprite(happydays,0, 501, 480 ,480  ) ; clip happydays

If you use grab sprite, you need a screen large enough to grab from. If I change Ar-S screen size to 800x600 I get unpredictable results, so I would clip c64, paste at 0,0 then grab :)

The only thing you have to remember here is that clipping a sprite will not remove any of the image. So every copy of c64 we make and clip, will be exactly the same size and take the same amount of memory as c64.

Code: [Select]
InitSprite()
xres=800
yres=600
InitKeyboard()

win=OpenWindow(0,50,50,800,600,"")
windows=  OpenWindowedScreen(win,0,0,xres,yres)

UsePNGImageDecoder()
UseJPEGImageDecoder()

c64=  LoadSprite(#PB_Any, "pirate.png",#PB_Sprite_AlphaBlending )

ball=CopySprite(c64,#PB_Any)
ship=CopySprite(c64,#PB_Any)
happydays=CopySprite(c64,#PB_Any)

ClipSprite(ball,0, 0, 500, 500)
ClipSprite(ship,501,0,500,500)
ClipSprite(happydays,0, 501, 480 ,480  )                                 


Repeat
  ClearScreen(0)
  DisplayTransparentSprite(ball,0,0,255)
  DisplayTransparentSprite(ship,100,40,255)
  DisplayTransparentSprite(happydays,10,300,255)
 
  FlipBuffers()
  ExamineKeyboard()
Until KeyboardPushed (#PB_Key_Escape)

Another way to do it using clip sprite and then freeing up memory would be :

Code: [Select]
tmp=CopySprite(c64,#PB_Any,#PB_Sprite_AlphaBlending)

ClipSprite(tmp,0, 0, 500, 500)
DisplayTransparentSprite(tmp,0,0)
ball=GrabSprite(#PB_Any,0, 0, 500, 500,#PB_Sprite_AlphaBlending)
ClearScreen(0)

ClipSprite(tmp,501,0,500,500)
DisplayTransparentSprite(tmp,0,0)
ship=GrabSprite(#PB_Any,0, 0, 500, 500,#PB_Sprite_AlphaBlending)
ClearScreen(0)

ClipSprite(tmp,0, 501, 480 ,480)
DisplayTransparentSprite(tmp,0,0)
happydays=GrabSprite(#PB_Any,0, 0, 500, 500,#PB_Sprite_AlphaBlending)

FreeSprite(c64)

But I would hate repeating code an create a procedure to handle the sprite grabbing, something like :
Code: [Select]
InitSprite()
xres=800
yres=600
InitKeyboard()

win=OpenWindow(0,50,50,800,600,"")
windows=  OpenWindowedScreen(win,0,0,xres,yres)

UsePNGImageDecoder()
UseJPEGImageDecoder()

c64=  LoadSprite(#PB_Any, "pirate.png",#PB_Sprite_AlphaBlending )

Procedure Grab_Sp(tmp,x,y,w,h)
  ClearScreen(0)
  ClipSprite(tmp,x, y, w, h)
  DisplayTransparentSprite(tmp,0,0)
  ProcedureReturn GrabSprite(#PB_Any,0, 0, 500, 500,#PB_Sprite_AlphaBlending)
EndProcedure

ball=Grab_Sp(c64,0, 0, 500, 500)

ship=Grab_Sp(c64,501,0,500,500)

happydays=Grab_Sp(c64,0, 501, 480 ,480)

FreeSprite(c64)

Repeat
  ClearScreen(0)
  DisplayTransparentSprite(ball,0,0,255)
  DisplayTransparentSprite(ship,100,40,255)
  DisplayTransparentSprite(happydays,10,300,255)
 
  FlipBuffers()
  ExamineKeyboard()
Until KeyboardPushed (#PB_Key_Escape)

Hope that helps in understanding how clipsprite works. Also remember grab sprite grabs from the screen, so if your screen is only 800 wide but the image you are loading is wider you wont be able to grab the sprite...
----

R Tape loading error, 0:1

Offline Omnikam

  • Atari ST
  • ***
  • Posts: 121
  • Karma: 4
    • View Profile
Re: [SOLVED]Sprite Clipping Issue??
« Reply #5 on: November 12, 2015 »
Thanks a lot Emook, i finally understand ClipSprite and grabsprite ;D
Does it matter that i use openscreen and not openwindows?
I'm very new to programing and tend to just jump in and learn from creating rather than study the manual, although i do look at the reference help, for function's and parameters
Would be nice  if  naively ,clipping a sprite created a new sprite with just the clipped dimensions, don't you think? Seems like id have to build that function with a procedure, which if I'm not mistaken one of your examples did

[Question] Emook, I changed your script to Open screen 800x600 and used your sprite clippingGrab Procedure, the strange thing is that Pirate.png is larger than the screen res, yet it still works perfectly?
[Question 2] Emook, In your above example All grabbed sprites will have a pixel count of 500x500, no mater what size is clipped. Is that right? If so can i alter the procedure so it creates a sprite based on the actual clipped dimensions?
Code: [Select]
ProcedureReturn GrabSprite(#PB_Any,0, 0, 500, 500,#PB_Sprite_AlphaBlending)I get my assumption from the above line, It creates a sprite from grabbing the screen starting at 0,0 and covering 500x500 pixels, Is that right? Would be wastfull if i had small sprites on the spriteboard
Could i do this?
Code: [Select]
ProcedureReturn GrabSprite(#PB_Any,0, 0, w, h,#PB_Sprite_AlphaBlending)Wouldnt that grab the sprite based on actual clipped dimensions?
I tried  it and it seems to work  :updance:
Verified working using spritehight, spritewidth and debug output
Now the grabbed sprite will only be as big as it`s needed
Thanks again Emook, You will be credited in my next demo
« Last Edit: November 12, 2015 by Omnikam »