Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Got code snippets to share? This is the place for you!
Brani di codice da condividere? Questo è il posto per te!
Avez-vous des extraits de code à partager ? C'est l'endroit pour vous !
Post Reply
User avatar
ericomont
Posts: 29
Joined: Sun Oct 08, 2023 11:31 am

Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Post by ericomont »

It is not unusual that within 8bit computers, fast blitting graphics may have some form of position limitation.
On some machines you have a grid where to place bitmaps, like tiles. Others you are limited to certain horizontal positions.
One can shift bytes in memory to overcome these problems but that will slow things down.

The TRS-80 Color Computer is of the later kind, where bitmap can be placed anywhere vertically but horizontally only on the byte border.
The byte border changes through the various graphic resolutions. At 256x192-2 colors (pmode4), it happens every 8 pixels, at 64x64-4 colors, it happens every 4 pixels.

With the pmode4 at black and white (css) on an NTSC system, you get artifact colors. These happen by the TV blending and colorizing pixels.
On the NTSC case, to keep with the color you have to position your bitmap always every pixel horizontally, this means that while the byte border is at every 8 pixels, colored bitmaps will always be at every 2 pixels, so a pixel perfect horizontal motion needs only 4 positions to reach the next border.

I think the term people use is COMPILED SPRITES, when you create extra frames of your bitmaps to account for the position limitation.
So the idea here is to do just that, bounce a little artifact colored ball around pixel perfectly.
Image

I created a 16x16 white bitmap containing a 12x12 ball within, this means that if I move it in any direction, its blit is going to "automatically" erase its older version. Then I added a full byte to the bitmap by adding 8 pixels horizontally, getting a final size of 24x16 pixels.

At last, I moved the ball every 2 pixels horizontally within the bitmap to create a total of 4 frames.
Here is the thing:
Image

Saved the Atlas as a PNG and made a simple code to bounce it by flipping the X and Y speeds.
Here is the thing, the X can only move 8 frames.
So I created a variable F for frames from 0 to 3, so whenever you move sideways you increase or decrease that. If you overflow, it will flip to the other end and increase or decrease 8 pixels on your X.

Notice that on the screen side borders I'm not only checking for the X position but also for which frame before bouncing it back.
...and it runs way smoother than this GIF, also unwatchable if you remove the WAIT 50 MS for it is too fast :)
Last edited by ericomont on Fri Mar 07, 2025 5:00 am, edited 1 time in total.
User avatar
ericomont
Posts: 29
Joined: Sun Oct 08, 2023 11:31 am

Re: Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Post by ericomont »

Here is the commented code and needed assets.
I made a total of 8 different colored balls. Later I hope to make em all move.
Change the WAIT value at the end to control speed.
You can mess with F to see the other balls.

Image

Code: Select all

'Bouncing Balls v1.0

'--- BOOT
SCREEN #14:COLOR #0,#5:CLS			:'Set PMODE4 / COLOR B&W / Clear screen black
b:=LOAD ATLAS("ball.png") FRAME SIZE (24,16)	:'Load bitmap and frames

'---VARIABLES
x=112:y=84					:'Ball X and Y screen position
xs=1:ys=2					:'Ball X and Y speed
f=0						:'Ball frame

'--------------------------------------LOOP
DO

PUT BITMAP b FRAME f AT x,y			:'Blit bitmap frame

y=y+ys						:'Add speed to Y position
f=f+xs						:'Add speed to frame

IF f=4  THEN:f=0:x=x+8:ENDIF			:'Add frame to X position (right)
IF f=-1 THEN:f=3:x=x-8:ENDIF			:'Add frame to X position (left)

IF f=3 AND x=232 THEN xs=-1			:'Bounce from right wall
IF f=0 AND x=0 THEN xs=1			:'Bounce from left wall
IF y<0 THEN ys=2				:'Bounce from top wall
IF y>175 THEN ys=-2				:'Bounce from bottom wall

WAIT 50 MS					:'Pause for a while cause the coco is too fast

LOOP
User avatar
ericomont
Posts: 29
Joined: Sun Oct 08, 2023 11:31 am

Re: Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Post by ericomont »

MULTIBALL!
Go for the Jackpot! :)

Image
User avatar
ericomont
Posts: 29
Joined: Sun Oct 08, 2023 11:31 am

Re: Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Post by ericomont »

Here is the code with all balls moving over a white background.

Code: Select all

'Bouncing Balls v1.1

'--- BOOT
bo:
SCREEN #14:COLOR #0,#5:CLS 3							:'Set PMODE4 / COLOR B&W / Clear screen black
b:=LOAD ATLAS("ball.png") FRAME SIZE (24,16)					:'Load bitmap and frames

'---VARIABLES
DIM x(8):DIM y(8)								:'Ball X and Y screen position
DIM xs(8):DIM ys(8)								:'Ball X and Y speed
DIM f(8)									:'Ball frame

x(0)=8:y(0)=84:f(0)=0		:x(1)=40:y(1)=84:f(1)=4		
x(2)=72:y(2)=84:f(2)=8		:x(3)=104:y(3)=84:f(3)=12
x(4)=136:y(4)=84:f(4)=16	:x(5)=168:y(5)=84:f(5)=20
x(6)=200:y(6)=84:f(6)=24	:x(7)=232:y(7)=84:f(7)=28

k=-1:z=0									:'Key LAUNCH timer

FOR z=0 TO 7
	xs(z)=0:ys(z)=0
	PUT BITMAP b FRAME f(z) AT x(z),y(z)					:'Blit balls starting frame/position
NEXT
WAIT KEY

'--------------------------------------LOOP
DO

INC k										:'Key LAUNCH ball control
IF k<113 THEN
	IF k=0 OR k=16 OR k=32 OR k=48 OR k=64 OR k=80 OR k=96 OR k=112 THEN
		IF RND(2)=0 THEN:xs(k/16)=1:ELSE:xs(k/16)=-1:ENDIF
		IF RND(2)=0 THEN:ys(k/16)=2:ELSE:ys(k/16)=-2:ENDIF		
	ENDIF
ENDIF
IF k=1000 THEN GOTO bo								:'Reset demo

FOR z=0 TO 7									:'DRAW and MOVE balls
 
	PUT BITMAP b FRAME f(z) AT x(z),y(z)					:'Blit bitmap frame
	
	y(z)=y(z)+ys(z)								:'Add speed to Y position
	f(z)=f(z)+xs(z)								:'Add speed to frame
	
	IF f(z)=4+z*4  THEN:f(z)=z*4	:x(z)=x(z)+8:ENDIF			:'Add frame to X position (right)
	IF f(z)=-1+z*4 THEN:f(z)=3+z*4	:x(z)=x(z)-8:ENDIF			:'Add frame to X position (left)
		
	IF f(z)=3+z*4 AND x(z)=232 THEN xs(z)=-1				:'Bounce from right wall
	IF f(z)=z*4 AND x(z)=0 THEN xs(z)=1					:'Bounce from left wall
	IF y(z)=0 THEN ys(z)=2							:'Bounce from top wall
	IF y(z)=176 THEN ys(z)=-2						:'Bounce from bottom wall
	
NEXT
LOOP
User avatar
ericomont
Posts: 29
Joined: Sun Oct 08, 2023 11:31 am

Re: Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Post by ericomont »

I also made one last version attempting to make the balls more properly bounce.
It works ok, but I just hacked the code.
Anyways, This is the result:
Image

And here this one final version:
Press any key to start.

Code: Select all

'Bouncing Balls v1.2

'--- BOOT
bo:
SCREEN #14:COLOR #0,#5:CLS 3		
b:=LOAD ATLAS("ball.png") FRAME SIZE (24,16)
'---VARIABLES
DIM x(8):DIM y(8)	
DIM xs(8):DIM ys(8)	AS INT		
DIM fa(8):DIM ya(8)	AS INT	
DIM f(8)  AS SIGNED BYTE		
DIM fl(8) AS SIGNED BYTE	
DIM z AS BYTE
DIM kk(8) AS BYTE
x(0)=8:y(0)=84:f(0)=0		:x(1)=40:y(1)=84:f(1)=4		
x(2)=72:y(2)=84:f(2)=8		:x(3)=104:y(3)=84:f(3)=12
x(4)=136:y(4)=84:f(4)=16	:x(5)=168:y(5)=84:f(5)=20
x(6)=200:y(6)=84:f(6)=24	:x(7)=232:y(7)=84:f(7)=28
k=-1:zt=0	
FOR z=0 TO 7
	xs(z)=0:'ys(z)=0		
	fa(z)=0:ya(z)=0				
	PUT BITMAP b FRAME f(z) AT x(z),y(z)	
	IF RND(2)=0 THEN:fl(z)=1:ELSE:fl(z)=-1:ENDIF
	ya(z)=RND(160)-80
NEXT
WAIT KEY
'--------------------------------------LOOP
DO
'--- KEY LAUNCH
INC k
IF k<113 THEN
	IF k=0 OR k=16 OR k=32 OR k=48 OR k=64 OR k=80 OR k=96 OR k=112 THEN
		IF RND(2)=0 THEN:xs(k/16)=1:ELSE:xs(k/16)=-1:ENDIF
		zt=k/16	
	ENDIF
ENDIF
'-------------------- BALL
FOR z=0 TO zt	
'--- DRAW BALL
	PUT BITMAP b FRAME f(z) AT x(z),y(z)	
'--- ADD ACCELERATION YA
	ya(z)=ya(z)+fl(z)
	ys(z)=ys(z)+ya(z)	
	IF ys(z)>40 THEN:ys(z)=0:y(z)=y(z)+2*fl(z):ENDIF
	If ys(z)<0 THEN:ys(z)=0:fl(z)=1:ENDIF
'--- ADD SPEED TO POS Y AND FRAME 
	INC kk(z)
	IF kk(z)=3 THEN:kk(z)=0: f(z)=f(z)+xs(z):ENDIF	
'--- EXECUTE POS X BYTE MOVE FROM FRAME LIMIT 
	IF f(z)=4+z*4  THEN:f(z)=z*4	:x(z)=x(z)+8:ENDIF
	IF f(z)=-1+z*4 THEN:f(z)=3+z*4	:x(z)=x(z)-8:ENDIF
'--- SCREEN BORDER COLLISION		
	IF f(z)=3+z*4 AND x(z)=232 THEN xs(z)=-1
	IF f(z)=z*4 AND x(z)=0 THEN xs(z)=1	
'	IF y(z)=0 THEN ys(z)=2	
	IF y(z)>=176 THEN fl(z)=-1
NEXT
LOOP
User avatar
Giovani_Gualdi
Posts: 6
Joined: Wed Mar 05, 2025 6:34 pm

Re: Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Post by Giovani_Gualdi »

Amazing Érico ! Now study and apply all this.
User avatar
ericomont
Posts: 29
Joined: Sun Oct 08, 2023 11:31 am

Re: Bouncing Balls - Pixel perfect motion blitting (non-sprites)

Post by ericomont »

Thanks Giovanni!
There are many ways to achieve smooth motion on position restricted blittings.
It all depends on what one wants to do or what the game needs to find the best appropriate technique.
My free-intention examples have downsides like objects going over others or a too big of a bitmap for the image size.
Both problems can be dealt with, but it is best to know what is the intended results so one codes precisely for that.
Post Reply