Image falls to pieces, revealing another one. - Dav - 05-17-2022
I've been trying to come up with some interesting transitions for an image slideshow (family album thing). I have the regular fades and slides and swaps worked out, trying to get something fancier. Here's something I thought of using rotozoom - break image up to pieces and drop them off the screen, revealing the other one.
It's a mess. Seems to work but thought I'd share it now to get some feedback/help with making it better. Perhaps there's a better way to do this? (There's 2 rotozoom subs in the code to compare them)
- Dav
Code: (Select All) '===============
'IMAGEPIECES.BAS
'===============
'Coded by Dav, MAY/2022
RANDOMIZE TIMER
'=== make 1st image to use (background one)
image1& = _NEWIMAGE(1000, 650, 32)
_DEST image1&
FOR y = 0 TO _HEIGHT
LINE (0, y)-(_WIDTH, y), _RGB(RND * 255, RND * 255, RND * 255), B
NEXT
'=== make 2nd image to use (will fall to pieces)
image2& = _NEWIMAGE(1000, 650, 32)
_DEST image2&
FOR y = 0 TO _HEIGHT
LINE (0, y)-(_WIDTH, y), _RGB(0, 0, RND * 196), B
NEXT
row = 15: col = 10 '15x10 grid of pieces
xsize = _WIDTH / row: ysize = _HEIGHT / col
DIM SHARED piece&(row * col), piecex(row * col), piecey(row * col)
DIM dropspeed(row * col), rotatespeed(row * col)
DIM xwobble(row * col), xwobblespeed(row * col)
'====
main:
'====
bc = 1
FOR c = 1 TO col
FOR r = 1 TO row
'int x/y values for each piece
x1 = (r * xsize) - xsize: x2 = x1 + xsize
y1 = (c * ysize) - ysize: y2 = y1 + ysize
piecex(bc) = x1: piecey(bc) = y1
'make pieces images from image2& screen
piece&(bc) = _NEWIMAGE(ABS(x2 - x1) + 1, ABS(y2 - y1) + 1, 32)
_PUTIMAGE (0, 0), image2&, piece&(bc), (x1, y1)-(x2, y2)
'int random values for each piece
dropspeed(bc) = RND * 2 + 1
rotatespeed(bc) = RND * 2 + 1
xwobble(bc) = INT(RND * 3) + 1 'x move piece (1=none,2=left,3=right)
xwobblespeed(bc) = INT(RND * 2) + .5 'how fast to wobble it
bc = bc + 1
NEXT
NEXT
'make main screen
_DEST 0
SCREEN _NEWIMAGE(1000, 650, 32)
CLS
'=== show 1st image on screen that will fall to pieces
FOR t = 1 TO row * col
RotoZoom piecex(t) + (xsize / 2), piecey(t) + (ysize / 2), piece&(t), 1, 0
NEXT
PRINT "Press enter to break up screen and reveal image behind...";
_DISPLAY
SLEEP
drop = 0: wob = 0
DO
_PUTIMAGE (0, 0), image1& 'background image
'show 1st image breaking up
FOR t = 1 TO row * col
tx = piecex(t): tx2 = piecex(t) + xsize
ty = piecey(t): ty2 = piecey(t) + ysize
SELECT CASE xwobble(t)
CASE 1
'RotoZoom piecex(t) + (xsize / 2), piecey(t) + (ysize / 2) + (drop * dropspeed(t)), piece&(t), 1, (ang * rotatespeed(t))
RotoZoom3 piecex(t) + (xsize / 2), piecey(t) + (ysize / 2) + (drop * dropspeed(t)), piece&(t), 1, 1, (ang * rotatespeed(t))
CASE 2
'RotoZoom piecex(t) + (xsize / 2) - wob, piecey(t) + (ysize / 2) + (drop * dropspeed(t)), piece&(t), 1, (ang * rotatespeed(t))
RotoZoom3 piecex(t) + (xsize / 2) - wob, piecey(t) + (ysize / 2) + (drop * dropspeed(t)), piece&(t), 1, 1, (ang * rotatespeed(t))
wob = wob - xwobblespeed(t)
CASE 3
'RotoZoom piecex(t) + (xsize / 2) + wob, piecey(t) + (ysize / 2) + (drop * dropspeed(t)), piece&(t), 1, (ang * rotatespeed(t))
RotoZoom3 piecex(t) + (xsize / 2) + wob, piecey(t) + (ysize / 2) + (drop * dropspeed(t)), piece&(t), 1, 1, (ang * rotatespeed(t))
wob = wob + xwobblespeed(t)
END SELECT
drop = drop + .1: ang = ang + .1
_LIMIT 3500
NEXT
_DISPLAY
'see if all pieces off screen
done = 1
FOR d = 1 TO row * col
IF piecey(d) + drop < _HEIGHT THEN done = 0
NEXT
IF done = 1 THEN EXIT DO
LOOP
'release pieces from memory
FOR p = 1 TO row * col
_FREEIMAGE piece&(p)
NEXT
GOTO main
SUB RotoZoom (X AS LONG, Y AS LONG, Image AS LONG, Scale AS SINGLE, Rotation AS SINGLE)
DIM px(3) AS SINGLE: DIM py(3) AS SINGLE
W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
px(0) = -W& / 2: py(0) = -H& / 2: px(1) = -W& / 2: py(1) = H& / 2
px(2) = W& / 2: py(2) = H& / 2: px(3) = W& / 2: py(3) = -H& / 2
sinr! = SIN(-Rotation / 57.2957795131): cosr! = COS(-Rotation / 57.2957795131)
FOR i& = 0 TO 3
x2& = (px(i&) * cosr! + sinr! * py(i&)) * Scale + X: y2& = (py(i&) * cosr! - px(i&) * sinr!) * Scale + Y
px(i&) = x2&: py(i&) = y2&
NEXT
_MAPTRIANGLE _SEAMLESS(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
_MAPTRIANGLE _SEAMLESS(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image& TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
END SUB
SUB RotoZoom3 (X AS LONG, Y AS LONG, Image AS LONG, xScale AS SINGLE, yScale AS SINGLE, radianRotation AS SINGLE)
' This assumes you have set your drawing location with _DEST or default to screen.
' X, Y - is where you want to put the middle of the image
' Image - is the handle assigned with _LOADIMAGE
' xScale, yScale - are shrinkage < 1 or magnification > 1 on the given axis, 1 just uses image size.
' These are multipliers so .5 will create image .5 size on given axis and 2 for twice image size.
' radianRotation is the Angle in Radian units to rotate the image
' note: Radian units for rotation because it matches angle units of other Basic Trig functions
' and saves a little time converting from degree.
' Use the _D2R() function if you prefer to work in degree units for angles.
DIM px(3) AS SINGLE: DIM py(3) AS SINGLE ' simple arrays for x, y to hold the 4 corners of image
DIM W&, H&, sinr!, cosr!, i&, x2&, y2& ' variables for image manipulation
W& = _WIDTH(Image&): H& = _HEIGHT(Image&)
px(0) = -W& / 2: py(0) = -H& / 2 'left top corner
px(1) = -W& / 2: py(1) = H& / 2 ' left bottom corner
px(2) = W& / 2: py(2) = H& / 2 ' right bottom
px(3) = W& / 2: py(3) = -H& / 2 ' right top
sinr! = SIN(-radianRotation): cosr! = COS(-radianRotation) ' rotation helpers
FOR i& = 0 TO 3 ' calc new point locations with rotation and zoom
x2& = xScale * (px(i&) * cosr! + sinr! * py(i&)) + X: y2& = yScale * (py(i&) * cosr! - px(i&) * sinr!) + Y
px(i&) = x2&: py(i&) = y2&
NEXT
_MAPTRIANGLE _SEAMLESS(0, 0)-(0, H& - 1)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(1), py(1))-(px(2), py(2))
_MAPTRIANGLE _SEAMLESS(0, 0)-(W& - 1, 0)-(W& - 1, H& - 1), Image TO(px(0), py(0))-(px(3), py(3))-(px(2), py(2))
END SUB
RE: Image falls to pieces, revealing another one. - James D Jarvis - 05-17-2022
I don't think you'd have to do much more than just break it into sperate triangles (as opposed to keeping the pieces as rectangles) and it would look better.
RE: Image falls to pieces, revealing another one. - bplus - 05-17-2022
Looks good to me @Dav. When I first read the title, I just imaged all the pixels dropping, maybe accelerating with gravity...
but yours works, there are plenty of ways this could be done. Did you need both RotoZoom subs?
With RotoZoom3 you could spin the images on all 3 axis, scale x and y from -1 to 1, different stages for each piece in the falling loop.
You could make it slower and have individual pieces start the fall-out.
RE: Image falls to pieces, revealing another one. - Coolman - 05-17-2022
excellent. i may do a speed test on this code if i have time.
|