How to erase without flicker?

The place for codemasters or beginners to talk about programming any language for the Spectrum.
llewelyn
Dizzy
Posts: 94
Joined: Thu Feb 22, 2018 3:27 pm
Location: virginias eastern shore
Contact:

How to erase without flicker?

Post by llewelyn » Fri May 11, 2018 4:33 pm

I'm experimenting with a character that moves by itself.
Using CLS is causing the character to flicker, is there a way to avoid this?
I have a vague idea that OVER may be the answer I need but I havent used it before.

Heres the test program.

5 FOR x = 0 to 20 step 1
10 PRINT AT 0, x; "A"
20 CLS
30 NEXT X
1 x

User avatar
PeterJ
Site Admin
Posts: 1347
Joined: Thu Nov 09, 2017 7:19 pm
Location: Surrey, UK

Re: How to erase without flicker?

Post by PeterJ » Fri May 11, 2018 4:47 pm

I would try printing a space in the previous character position on each iteration of the loop, rather than clearing the screen each time.
1 x

llewelyn
Dizzy
Posts: 94
Joined: Thu Feb 22, 2018 3:27 pm
Location: virginias eastern shore
Contact:

Re: How to erase without flicker?

Post by llewelyn » Fri May 11, 2018 5:35 pm

Thankyou Peter, I tried that and it sort of worked but then it caused another effect that was unexpected, lots of A 's briefly following the original. So I added more spaces and that reduced the 'ghosts' but what I found was the character moved too quickly so I slowed it down with a PAUSE statement and that got rid of the ghosts!
0 x

Joefish
Manic Miner
Posts: 634
Joined: Tue Nov 14, 2017 10:26 am

Re: How to erase without flicker?

Post by Joefish » Fri May 11, 2018 5:58 pm

CLS takes its time because it clears the screen, both pixels and atributes.
If you're not averse to a little bit of machine code, you can have a routine that simply sets the attributes of all characters so that their INK and PAPER are the same, so the screen appears empty. It's a lot quicker.

Code: Select all

org 65368
ld hl,22528
ld de,22529
ld (hl),0
ld bc,735
ldir
ret
This translates into 14 bytes:

Code: Select all

DATA 33,0,88,17,1,88,54,0,1,223,2,237,176,201
Just POKE these bytes in wherever you want in memory and do RANDOMIZE USER nnnn or LET Z=USR nnnnn with the address you poked them to to activate it. For example, to POKE it in just below the UDGs in memory, do CLEAR 65353 (to tell BASIC to reserve the memory above this address) then POKE these 14 numbers in from 65354-65367 and call it with LET Z=USR 65354 (here Z is just some throwaway variable because calls like this always return a number. You may have seen RANDOMIZE USR before, but if you kept using that in a game it would keep resetting the random number generator).

The eighth byte (the second appearance of a zero) is the key one - this is the attribute byte that gets applied to the whole screen. Use 0 for Black. 127 for Bright White. Use Colour * 9 and add 64 if you want BRIGHT. e.g. 6*9 + 64 = 118 for Bright Yellow, 5*9 = 45 for Dull Cyan.

Another byte you might want to fiddle with is that 223 - subtract 32 or 64 bytes (or more x32) off this number to leave one or two (or more) rows at the bottom of the screen untouched, for scores etc.

Also a good idea to do PAUSE 1 at some point in your main game loop. That will synch you up to the TV refresh.
3 x

llewelyn
Dizzy
Posts: 94
Joined: Thu Feb 22, 2018 3:27 pm
Location: virginias eastern shore
Contact:

Re: How to erase without flicker?

Post by llewelyn » Fri May 11, 2018 6:16 pm

Thanks Joe but thats way above my head, I can barely manage Basic as it is! However I appreciate your feedback and I've saved this post and will have a go at it a little later. What I've got so far works and is:-

10 CLS
20 PRINT AT 10,10; "Press s to STOP"
30 REM perpetual motion experiment
40 REM
50 FOR x=0 TO 30 STEP 1
60 PRINT AT 0,x; " A"
65 REM adjust this for speed
70 PAUSE 5
80 IF x=30 THEN GOTO 10
85 REM emergency stop button
90 IF INKEY$="s" THEN STOP
100 NEXT x
0 x

User avatar
R-Tape
Site Admin
Posts: 2583
Joined: Thu Nov 09, 2017 11:46 am

Re: How to erase without flicker?

Post by R-Tape » Fri May 11, 2018 8:21 pm

It depends what you ultimately have in mind but if you're only moving a small number of characters at a time then CLS (BASIC or machine code) is a steamroller to crack a walnut IMO. I think Peter's suggestion of deleting the old position next time around looks best (though that can still have a slight flicker of the old position*). Here's another way, it's an example of a single # moving around the screen controlled by QAOP.

10 LET v=12: LET h=15: LET ov=v: LET oh=h
50 PAUSE 1: PRINT AT ov,oh;" ";AT v,h;"#";
55 LET ov=v: LET oh=h
60 IF INKEY$="o" AND h>0 THEN LET h=h-1
70 IF INKEY$="p" AND h<31 THEN LET h=h+1
80 IF INKEY$="q" AND v>0 THEN LET v=v-1
90 IF INKEY$="a" AND v<21 THEN LET v=v+1
100 GO TO 50

The critical bit is line 50. PAUSE 1 means the TV screen has only just started being drawn, then you delete the old (ov,oh) and redraw the new (v,h) as quickly as possible - before the TV is drawn. That way there is hardly any flicker. Line 55 updates the old position to delete next time around.

It gets a bit trickier the more you want to print.

*Your code has a bit of this, a quick flicker of the old A is usually present. It's rapid enough to get away with it tho.
2 x

User avatar
Seven.FFF
Manic Miner
Posts: 341
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: How to erase without flicker?

Post by Seven.FFF » Fri May 11, 2018 9:24 pm

*waves at Mike*
0 x
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
seven-fff.com/blog

llewelyn
Dizzy
Posts: 94
Joined: Thu Feb 22, 2018 3:27 pm
Location: virginias eastern shore
Contact:

Re: How to erase without flicker?

Post by llewelyn » Fri May 11, 2018 10:34 pm

Likewise Robin.
1 x

llewelyn
Dizzy
Posts: 94
Joined: Thu Feb 22, 2018 3:27 pm
Location: virginias eastern shore
Contact:

Re: How to erase without flicker?

Post by llewelyn » Fri May 11, 2018 10:48 pm

Thanks R-Tape I'll give that a try, took me a bit to figure it out. I wanted to understand how to achieve the move/erase starting with one block then I'll work up to doing it with 4 chrs until I eventually have a sprite move subroutine thats reliable and next after that is to design the character and then possibly a wee animation. Should keep me busy all summer!
1 x

User avatar
Seven.FFF
Manic Miner
Posts: 341
Joined: Sat Nov 25, 2017 10:50 pm
Location: USA

Re: How to erase without flicker?

Post by Seven.FFF » Fri May 11, 2018 10:59 pm

You can probably get away with printing spaces to clear your sprites, at least for a while. And if you’re moving in whole character jumps.

If you start exploring moving one pixel at a time, or your flicker gets too bad, then it might be worth exploring OVER. There’s two variants:

Think of OVER 1 as overprinting. Like if you hit backspace on a typewriter and typed a second letter on top of an existing one.

Think of OVER 0 as an unPRINT. Like using tippex paper on a typewriter. It’s similar to what you’re doing with spaces, but printing a space is more like a big blob of tippex fluid - an entire 8x8 block of pixels gets erased.

Which technique you use doesn't matter so much until you start having scenery that your sprites move over. Then being able to overprint and unprint more precisely gives you a lot more flexibility.
0 x
Robin Verhagen-Guest
SevenFFF / Threetwosevensixseven / colonel32
seven-fff.com/blog

Post Reply