!0.......^.........^.........^..
!B
\H11\H07     \H10\H02SPRITE HIGH, \H10\H00NO LIMIT      

!2.......^.........^.........^.........^.........^.........^....
 Calling all loony tunesmiths! Chris Wood is gonna show you how
 to create cartoon sized sprites and get 'em moving. Well, he's
            smarter than the average programmer ...
!1.......^.........^.........^.........^........

Yabbadubbadoo! It's cartoon time. That's  right,
if  you've  been dying to create your own  games
featuring   favourite  cartoon  characters,  the
waiting  is  now  over.  How'd  you  like  Wally
waddling around your games? Or you could  create
your own Celtic cartoon to rival Dun Darach.  Or
even the Flintstones?

!0.......^.........^.........^..
SHAPIN' UP
!1.......^.........^.........^.........^........
How  big  do  you  want  your sprite? Well,  the
routine will let you handle sprites up to  31x24
character squares, but the designer program only
has  room  for  7x7  on  screen. Anyhow, do  you
really  want  sprites much bigger than that?  It
makes playing Space Invaders a bit pointless  if
they're bigger than barn doors when you come  to
blast  'em! And you can still create sprites  as
large as those in Dun Darach.
  Attributes are another problem associated with
sprites.  You can get round this by having  your
characters  the  same  colour as the  background
like those in Dun Darach or Tir na Nog. But with
this program, sprites can have their own  attri-
butes  like Wally and the gang, in Everyone's  a
Wally.  Or,  chameleon-like,  they can turn  the
colour  of  whatever  is  behind  them  just  as
Frankie does.

!0.......^.........^.........^..
!B
OLD MASKERS
!1.......^.........^.........^.........^........
To  mask or not to mask - this program lets  you
decide. A mask is merely a shape that masks  out
the  part  of the screen to which the sprite  is
moving before slotting the sprite into the  hole
left  by  the  mask. Say you had a black  sprite
with  a  lot  of  white in it, without a mask  -
print  it in front of a detailed background  and
you'd be able to see through the white areas  of
the sprite.
  Now  if you have a mask exactly the same  size
as  your chosen sprite, it'll clear exactly  the
right area on the screen. Well, that's how  it's
done  in  Dun Darach. Of course, you can  always
choose a mask one pixel bigger than your  sprite
all the way round for extra emphasis - the tech-
nique used in Everyone's a Wally.

!0.......^.........^.........^..
!B
ROUTINE PROCEDURE
!1.......^.........^.........^.........^........
The sprite routine holds a copy of the screen in
high memory - that way all the work of  printing
the  sprites  is done out of sight - then  down-
loads  it to the normal screen memory where  you
can  see  it.  Next it erases all the copy  from
high memory before handing back control to  you.
So, if you want to wipe out all the sprites from
the  screen,  you can download the empty  screen
and bingo, they're gone!

!0.......^.........^.........^..
!B
PULLING RANK
!1.......^.........^.........^.........^........
You'll have noticed how sprites in  professional
games pass over each other without getting  into
a  rare  old mess. It's all down to priority,  a
sort  of  sprite pecking order. The sprite  with
the  highest  priority  is the last one  printed
onto  the  screen and appears to be in front  of
all  the  others  when it passes over them.  Any
sprites  added  to  the  list will have a  lower
priority  than the others as the data block  for
each  sprite  is added lower down in memory  and
the  front  of  the  sprite queue is lowered  to
point to it.
  Those of you who are up on your games have  no
doubt got your objections ready. How, I hear you
ask,  do  the  sprites in The Rocky Horror  Show
manage  to go behind the scenery? Thought  you'd
catch me out, eh? Phah! Take a lamp post.  Found
one? Right now, say you've got five sprites  you
want to pass behind or in front of it. OK  then,
design  the  sprites and the lamp post but  tell
the  Data  Block  program  that you want  eleven
sprites  -  that's  one  lamp post, five  normal
sprites  and  five identical, inactive  sprites.
The  lamp  post  has a higher priority than  the
normal sprites so they appear to move behind it.
But  switch  to  the  inactive  sprites and  the
priorities swap around so the sprites now appear
in  front. Clever, innit? Now you can have  some
behind,  some in front and others turning  cart-
wheels around it, for all I care!
  You've probably sussed that you're never going
to  have the normal and inactive sprites on  the
screen  at  the  same time. That means they  can
share the same storage area and you'll only need
one  copy  of  the  shape and mask data. It's  a
great way of saving space. Say you've got  fifty
sprites  but  only ten are on the screen at  any
one  time,  then  provided they're all the  same
size,  you  can  get  away with having only  ten
storage  areas.  By  the  same token, one  large
sprite  can  provide a storage area for  several
smaller  ones when it's off the screen. And  all
the different versions of the same sprite - left
leg in, right leg out, shake it all about and so
on - need only one storage area.
  If  you fancy having a crack at 3D games  like
Knight Lore, then this technique's going to come
in very handy. Each room in these games is  made
up  of eight by eight large squares. That  means
that  each sprite needs eight different  version
of  its Data Block for the eight distances  that
it can be away from you - one row away, two rows
and  so  on.  And  depending  on how far up  the
screen objects and sprites are from each  other,
that  alters the priorities you should allot  to
them.

!0.......^.........^.........^..
!B
MAKING YOUR MOVES
!1.......^.........^.........^.........^........
Right, eyes down and away we go. Your first  job
is to design your screen background. It may be a
loading  screen or perhaps you've got a  program
that prints platforms and ladders. Whatever  you
choose, save it with RANDOMIZE USR 57813. That's
plonked  the whole lot safely up in high  memory
where it can be worked on. But say you only want
to use part of the screen, remembering that  the
less  that  has to move, the faster the  routine
runs.  That's  why  old  clever  clogs  himself,
Matthew Smith only used the top two thirds.  You
can  choose any combination you want using  POKE
57478,length of screen (24=full, 16=two  thirds,
8=one third).
  If you want to use an area other than the top,
POKE  57481,start of screen (64=top,  72=middle,
80=bottom): POKE 57484,PEEK (57481)+165.
  You haven't forgotten the attributes, I  hope!
Use POKE 57484,length of attributes = 3, 2 or  1
third. And then there's the starting point: POKE
57492,starting    point    (88=top,   89=middle,
90=bottom): POKE 57495,PEEK (57492)+165.
  When  you change the starting point,  remember
to change the length as well or you run the risk
of going off the bottom of the screen and wiping
out Basic. Nasty!
  Stringing  it all together, here's an  example
that  uses the bottom two-thirds of the  screen,
leaving the top free for scores or whatever:
!0.......^.........^.........^..
  POKE 57478,16: POKE 57481,72:
  POKE 57484,PEEK (57481)+165:
  POKE 57489,2: POKE 57492,89:
  POKE 57495,PEEK (57492)+165
!1.......^.........^.........^.........^........
Finally,  to  call back your picture and  effec-
tively wipe all your sprites off the face of the
screen, use RANDOMIZE USR 57836.
  And  I don't know why you're sitting there  as
though  you've  got  all day - you'd jolly  well
better start typing in the listings. Like now!

!0.......^.........^.........^..
!B
\H11\H06\H10\H00WALK THIS WAY                   
!2.......^.........^.........^.........^.........^.........^....
If you're confused about your next step as you try your hand  at
cartoon   creation,  this  easy-to-follow  guide  will  see  you
through.
!1.......^.........^.........^.........^........
!P\H11\H06\H10\H00

Step 1. First   create   the  scenery  for  your
sprites. You'll find it easy with a package like
Melbourne Draw or The Artist.

Step 2. Draw  your  sprites  with  the  Designer
program.  But  don't forget that you'll have  to
amend  the  old  sprite  for  each new frame  of
animation.

Step 3. Design  a  mask  for  each frame  you've
drawn.  This  feature is optional, but it  stops
the background from showing through your sprites
- unless you're writing a ghost story!

Step 4. Load  in  the  Data  Block  program  and
answer  all  the  questions  it asks about  your
sprites.  When  that's  done,  save the code  it
creates.

Step 5. Load up the Motion Picture program, your
Sprite Code, Mask Code and the Data Block  code.
And remember you'll have to clear enough room in
memory  for  that  lot.  You'll find that  30000
should be ridiculously adequate.

Step 6. Run the program and up'll come your very
own cartoon. Use the cursor keys to control your
chosen  character.  And as we movie people  say,
That's All Folks!

!0.......^.........^.........^..
!B
DRAW NEAR
!1.......^.........^.........^.........^........
Have you decided which cartoon hero you're going
to  breathe life into? As soon as you're  ready,
this  is  the  screen that'll greet you.  You're
asked for the width of your sprite in characters
(bytes) - the maximum is seven - and its  height
in  pixels - maximum fifty-six. As you can  see,
your life-size sprite appears in the top left of
the screen as you draw on the nine times  larger
one  in the middle. Use the cursor keys (or  5-8
on the Speccy+) to control the flashing  cursor.
The zero key turns a pixel on or off, or if  you
prefer you can take a line for a walk by  press-
ing  the  four  key.  The  other important  keys
you'll need are as follows:
R  recalls  a  sprite for retouching after  it's
been loaded into 47000 where it's stored in  the
Designer.
S as soon as you're satisfied with your  sprite,
this stores it in memory. You'll be asked  "save
width?",  so  that  if  you  need to change  its
width,  the program will rearrange the data  for
the  sprite. If you reckon it ought to grow  up,
just press Break and enter a larger height, then
press  R  when you return to the design  screen.
Each  sprite is saved with the name  "SPRDATnnn"
where nnn is its length in bytes.
F  when  you're  ready  to  finish and save  the
sprite to tape.
Things  start to get a bit hairy when you  start
slapping  a  mask  onto your sprite. It's OK  if
you're  just doing a same size mask like in  Dun
Darach as you only have to fill in the holes  in
the original sprite.
  Your  problems  start when you try to  outline
masks - you fill in all the gaps easily  enough,
but when it comes to going round the edges, oops
you're going all over the shop. That's why  I've
incorporated  the  command C for "check mask"  -
did you think I'd let you down? First load  your
sprite  into 47000 and another copy into  48000.
Next  fill in the gaps and start off around  the
edge,  When  you get lost, press C and the  mask
and  sprite  will  be  printed  together in  the
bottom left of the screen.

!2.......^.........^.........^.........^.........^.........^....
!B
Here's  the  Sprite  Designer  in  action. The large box in  the
middle  of the screen is your editing window. While you  create,
the life-size sprite is shown taking shape in the box top left.
!0.......^.........^.........^..

!Spopeye

!B
\H11\H07\H10\H00DECIMAL LOADER                  
!2.......^.........^.........^.........^.........^.........^....
Type in this loader and use it to enter the two blocks of  code,
one  for  the  Designer and one for the Sprite code. Enter  STOP
when you've finished.
!0.......^.........^.........^..

 100 INPUT "Start Address? ";s
 110 FOR n=s TO 1e9 STEP 8: PRIN
T n
 120 LET tot=0: FOR b=0 TO 7: IN
PUT "number? ";a: PRINT a;",";:
POKE n+b,a: LET tot=tot+a: NEXT
b
 130 INPUT "checksum? ";c: IF c<
>tot THEN  PRINT : BEEP .1,0: PR
INT "WRONG": GO TO 120
 140 PRINT : NEXT n

!B
\H11\H07\H10\H00DESIGNER BASIC                  
!2.......^.........^.........^.........^.........^.........^....
Type  in  the  Designer  program  and  then  save  it with  SAVE
"DESIGNER"  LINE  9999 with the code after it on the tape.  That
way it'll load the code and run it.
  The  Designer  tells  you  the amount of room taken up by  the
sprite  or  its mask and the storage area. Each sprite needs  14
bytes  of  data, 12 of which tell it where it is on the  screen,
whether  it  has  a  mask or attributes, and where its shape  is
stored.  The  other  two bytes contain a pointer to the area  of
memory telling it where it can store a copy of the background on
which it sits.
  If  you  don't  give your sprite a mask, you needn't  reserve
memory for it but you'll always need a storage area for the part
of  the screen that's printed over. This must be one byte  wider
than the sprite and the same depth.
!0.......^.........^.........^..

   1 INPUT "WIDTH in bytes? ";q:
 POKE 45010,q: POKE 45151,q: INP
UT "HEIGHT in pixels? ";p: POKE
45007,p: POKE 45134,p
!2.......^.........^.........^.........^.........^.........^....
Line 1           This finds out what sort of dimensions you want
                 for the sprite. You can change the width during
                 program running, but you can't change the
                 height - so make your choices carefully.
!0.......^.........^.........^..

   5 POKE 23658,0: PRINT AT 7,0;
"PEN OFF";AT 9,0;" SIZE"'q;" x "
;p'" =";q*p''"STORAGE"'" =";(q+1
)*p
   8 LET pl=0: BORDER 6: LET x=0
: LET y=175: PLOT 71,175: DRAW 2
4*q+1,0: DRAW 0,-3*p-1: DRAW -24
*q-1,0: DRAW 0,3*p+1
   9 RANDOMIZE USR 45000
!2.......^.........^.........^.........^.........^.........^....
Lines 5-9        This prints the pen information down the side
                 of the editing window and then draws the window
                 itself to the required size.
!0.......^.........^.........^..

  10 LET x=x+(INKEY$="8" AND x<>
q*8-1)-(INKEY$="5" AND x<>0)
  20 LET y=y+(INKEY$="7" AND y<>
175)-(INKEY$="6" AND y<>176-p)
  25 IF INKEY$="s" THEN  BEEP .1
,20: INPUT "Save width ? ";q: PO
KE 45010,q: POKE 45151,q: POKE 4
5159,235: POKE 45149,235: RANDOM
IZE USR 45124: GO TO 50
  26 IF INKEY$="r" THEN  BEEP .1
,30: GO TO 50
  30 IF INKEY$="4" THEN  BEEP .0
1,20: LET pl=1-pl: PRINT AT 7,0;
"PEN ";("ON " AND pl=1);("OFF" A
ND pl=0)
  32 IF pl=1 THEN  PLOT  OVER 1;
x,y: GO SUB 900
  35 IF INKEY$="0" THEN  BEEP .0
1,20: PLOT  OVER 1;x,y: GO SUB 9
00
  36 IF INKEY$="c" THEN  POKE 45
159,235: POKE 45149,235: RANDOMI
ZE USR 45124: POKE 45159,0: POKE
 45149,0: POKE 45153,47: POKE 45
129,120: RANDOMIZE USR 45124: BE
EP .1,0: POKE 45153,182: POKE 45
125,128: POKE 45126,187: RANDOMI
ZE USR 45124: POKE 45153,0: POKE
 45125,152: POKE 45126,183: POKE
 45129,0
  38 IF INKEY$="f" THEN  SAVE "S
PRDAT "+STR$ (p*q)CODE 47000,p*q
  40 PLOT  OVER 1;x,y: PLOT  OVE
R 1;x*3+73,173-((175-y)*3)
  41 BEEP .01,-28: PLOT  OVER 1;
x,y: PLOT  OVER 1;x*3+73,173-((1
75-y)*3): GO TO 10
!2.......^.........^.........^.........^.........^.........^....
Lines 10-41      This is the main loop. Most of this is just
                 IF ... INKEY$ stuff, calling the other parts of
                 the program. If you don't like the small cursor
                 you can change lines 40 and 41 to read:
                 40 PLOT OVER 1;x,y: GO SUB 900
                 41 PLOT OVER 1;x,y: GO SUB 900: GO TO 10
                 but if you do, it'll be a fair bit slower. If
                 you like the cursor, but don't like the
                 constant beeping you could change the beep in
                 line 41 to -30.
!0.......^.........^.........^..

  50 CLS : POKE 45159,0: POKE 45
149,0: RANDOMIZE USR 45124: GO T
O 5
!2.......^.........^.........^.........^.........^.........^....
Line 50          This line clears the screen ready for a redraw.
!0.......^.........^.........^..

 900 PLOT  OVER 1;x*3+72,174-((1
75-y)*3): DRAW  OVER 1;2,0
 901 PLOT  OVER 1;x*3+72,172-((1
75-y)*3): DRAW  OVER 1;2,0
 902 PLOT  OVER 1;x*3+72,173-((1
75-y)*3): DRAW  OVER 1;2,0
 904 PLOT  OVER 1;x*3+73,173-((1
75-y)*3)
 910 RETURN
!2.......^.........^.........^.........^.........^.........^....
Lines 900-910    This subroutine draws the window 'box'.
!0.......^.........^.........^..

9999 CLEAR 44999: LOAD ""CODE 45
000: RUN
!2.......^.........^.........^.........^.........^.........^....
Line 9999        This is the set-up line to load in the machine
                 code from tape.
!0.......^.........^.........^..

!B
\H11\H07\H10\H00DESIGNER CODE                   
!2.......^.........^.........^.........^.........^.........^....
Use  the  Decimal  Loader  to  enter this code. Enter the  start
address,  45000,  when  you're  asked, then type in the  numbers
eight  at a time followed by the checksum for each line. If  you
make a mistake, just enter the line again. When you've finished,
save the code with SAVE "DES CODE" CODE 45000,164 - but you must
save it after Designer Basic on your tape.

45000:   33,  0,  0, 34,249,175,  6, 16, =513
45008:  197,  6,  2,197,237, 75,249,175, =1138
45016:  120,205,177, 34,  6,  8,126,197, =873
45024:   23,245,205,251,175,241,193, 16, =1349
45032:  246,193, 16,231, 42,249,175, 46, =1198
45040:    0, 36, 34,249,175,193, 16,216, =919
45048:  201,  0,  0, 56, 13,205, 41,176, =692
45056:   12,  4,120,205,177, 34,195,236, =983
45064:   34,201,205, 41,176, 62,  3,245, =967
45072:  197, 62,  3,245,197,120,205,177, =1206
45080:   34,205,236, 34,193, 12,241, 61, =1016
45088:   32,241,193,  4,241, 61, 32,231, =1035
45096:  201,237, 75,249,175, 12,237, 67, =1253
45104:  249,175, 13,237, 75,249,175, 42, =1215
45112:  249,175, 41,  9,  1, 69,  0,  9, =553
45120:   68, 77,  4,201, 17,152,183, 33, =735
45128:    0,  0, 34,249,175,  6, 16,197, =677
45136:  237, 75,249,175,120, 60, 50,250, =1216
45144:  175, 61,205,177, 34,235,  6,  2, =895
45152:   26,  0,119, 19, 35, 16,249,235, =699
45160:  193, 16,228,201,  0,  0,  0,  0, =638
!0.......^.........^.........^..

!B
\H11\H07\H10\H00SPRITE CODE                     
!2.......^.........^.........^.........^.........^.........^....
Sprites  here  we come! Again using the loader program, type  in
the code in the same way as you did with the Designer code. Done
that? Now save it with SAVE "SPR CODE" CODE 57270,584.

57270:   16, 16,  6,  1,  0,  2,  0, 16, =57
57278:   64,156,136,156,240,210,135,131, =1228
57286:  153,130,152,147, 20, 20,  6,  1, =629
57294:    0,  2,  0, 16, 64,156,136,156, =530
57302:  240,210,  0,  0, 20, 20, 88,255, =833
57310:   88,255,  1,243,221, 33,182,223, =1246
57318:  237, 75,223,223,197,221,229,225, =1630
57326:    1, 14,  0,221,  9, 17,202,223, =687
57334:  237,176, 58,205,223,167,202,127, =1395
57342:  224, 42,212,223, 34,222,223, 42, =1222
57350:  210,223, 34,220,223, 42,202,223, =1377
57358:   34,218,223,237, 75,218,223,120, =1348
57366:  205,177, 34, 34,216,223, 50,206, =1145
57374:  223,217,237, 91,214,223,217,237, =1659
57382:   75,208,223,197,237, 75,218,223, =1456
57390:  120, 60, 50,219,223, 61,230,  7, =970
57398:   40,  6, 42,216,223, 36, 24,  5, =592
57406:  120,205,177, 34, 36, 34,216,223, =1045
57414:   37, 62,165,132,103,229,205, 13, =946
57422:  225, 58,208,223,167, 32, 19, 50, =982
57430:   95,225, 33, 47,166, 34,102,225, =927
57438:   17, 32, 91,225,229,205, 89,225, =1113
57446:   62,  6, 61, 50, 95,225, 33,182, =714
57454:    0, 34,102,225, 17,  0, 91,225, =694
57462:  205, 89,225,193, 16,173,205,131, =1237
57470:  225,193,  5,194,234,223,  1,  0, =1075
57478:   24, 17,  0, 64, 33,  0,229,237, =604
57486:  176,  1,  0,  3, 17,  0, 88, 33, =318
57494:    0,253,237,176,  1,  0,  3, 17, =687
57502:    0,253, 33,  0,226,237,176,237, =1162
57510:   75,223,223,197,221,229,225,  1, =1394
57518:   14,  0,183,237, 66,229,221,225, =1175
57526:   17,202,223,237,176, 58,205,223, =1341
57534:  167, 40, 71,237, 75,202,223,237, =1252
57542:   67,218,223,120,205,177, 34, 34, =1078
57550:  216,223,237, 75,208,223,237, 91, =1510
57558:  214,223,197,237, 75,218,223,120, =1507
57566:   60, 50,219,223, 61,230,  7, 40, =890
57574:    6, 42,216,223, 36, 24,  5,120, =672
57582:  205,177, 34, 36, 34,216,223, 37, =962
57590:  237, 75,207,223, 12,  6,  0,235, =995
57598:   62,165,130, 87,237,176,235,193, =1285
57606:   16,208,193, 16,158,251,201,175, =1218
57614:  237, 75,207,223, 71,197, 42,220, =1272
57622:  223, 17,  0, 91,237,176, 18, 34, =796
57630:  220,223,193, 58,208,223,167, 32, =1324
57638:   12, 42,222,223, 17, 32, 91,237, =876
57646:  176, 18, 34,222,223, 58,206,223, =1160
57654:  167,200, 33,  0, 91,205, 70,225, =991
57662:   58,208,223,167,192, 33, 32, 91, =1004
57670:  237, 75,206,223,  4,229,197,167, =1338
57678:  203, 30, 35, 16,251,193, 13,225, =966
57686:   32,243,201,237, 75,206,223,  4, =1221
57694:   24,  5,126,217, 18, 19,217, 26, =652
57702:    0,  0,119, 19, 35, 16,241,201, =631
57710:  147,152,130,153,131,135,205,177, =1230
57718:   34,124, 15, 15, 15,230,  3,246, =682
57726:   88,198,165,103,201, 58,204,223, =1240
57734:  167,200,237, 75,202,223,120,205, =1429
57742:  116,225,237, 75,206,223, 58,202, =1342
57750:  223,230,  7, 40,  1,  4, 58,203, =766
57758:  223,230,  7, 95, 58,209,223,131, =1176
57766:   31, 31, 31,230, 31, 79, 58,209, =700
57774:  223,230,  7, 40,  1, 12, 58,203, =774
57782:  223,230,  7, 40,  1, 12,120, 50, =683
57790:  206,223, 17, 32,  0,229, 58,206, =971
57798:  223, 71, 58,204,223,119, 35, 16, =949
57806:  252,225, 25, 13, 32,239,201, 17, =1004
57814:    0,229, 33,  0, 64,  1,  0, 27, =354
57822:  237,176, 17,  0,226, 33,  0, 88, =777
57830:    1,  0,  3,237,176,201,  1,  0, =619
57838:   27, 17,  0, 64, 33,  0,229,237, =607
57846:  176,201,  0,  0,  0,  0,  0,  0, =377
!0.......^.........^.........^..

!B
\H11\H07\H10\H00DATA BLOCK PROGRAM              
!2.......^.........^.........^.........^.........^.........^....
When you've designed all your sprites and worked out where  they
should be in memory, you can type in this program. It'll ask you
how  many sprites you want for the coordinates of each one,  the
attributes  and  whether  they have a mask. After the block  for
each  sprite's  been  worked  out,  it'll print the info on  the
screen - it's an idea to jot it down or take a print-out of  the
screen  for  later. The number printed above each tells you  the
priority of the sprite.
  Whatever  you  do,  note  down the first location printed,  as
you'll  have to POKE this into the sprite code to tell it  where
the data starts. Use:
  INPUT n: POKE 57317,INT (n/256): POKE 57316,n-(PEEK 57317*256)
after  you've  loaded  the  Sprite  code.  When you've  finished
entering  all  the  data,  the  program  is saved with the  name
"BLOCKSnnn" where nnn is the number of sprite blocks.
  If  you  want to add a sprite to your data block, load it  in,
run  the  program  and  tell it the new number of sprites.  Once
you've  entered  the first one, enter STOP and then GO TO 150  -
the program will then save the new block.
  When  all  your cartoon characters are in the bag, POKE  57312
with  the number of your sprites and after saving the screen  to
high memory, you can type RANDOMIZE USR 57313 to print them  all
onto  the  screen. So, wassup Doc? Oh, you want animation?  Keep
movin' then!
!0.......^.........^.........^..

  10 INPUT "Number of sprites? "
;n
  15 LET r=n*14: LET s=57284-r
  20 FOR p=1 TO n
!2.......^.........^.........^.........^.........^.........^....
Lines 10-20      This sets up the number of sprites and then 
                 starts off the For ... Next loop.
!0.......^.........^.........^..

  30 INPUT "x coord? ";x: POKE s
,x
  40 INPUT "y coord? ";y: POKE s
+1,y
!2.......^.........^.........^.........^.........^.........^....
Lines 30-40      These lines collect the x and y coordinates of
                 the sprite.
!0.......^.........^.........^..

  50 INPUT "attribute? ";a: POKE
 s+2,a
!2.......^.........^.........^.........^.........^.........^....
Line 50          This line collects the colour of the sprite.
!0.......^.........^.........^..

  60 INPUT "active? ";a: POKE s+
3,a
!2.......^.........^.........^.........^.........^.........^....
Line 60          This line asks whether the sprite is active or
                 not. This should normally be set to zero and
                 then turned on (ie. set) when needed.
!0.......^.........^.........^..

  70 INPUT "width in bytes? ";w:
 POKE s+5,w
  80 INPUT "height in pixels? ";
h: POKE s+7,h
!2.......^.........^.........^.........^.........^.........^....
Lines 70-80      These lines collect the dimensions of the 
                 sprite.
!0.......^.........^.........^..

  90 INPUT "mask? (y or n)";a$:
POKE s+6,1: IF a$="y" THEN  POKE
 s+6,0
!2.......^.........^.........^.........^.........^.........^....
Line 90          Is your sprite wearing a mask? This line will
                 find out.
!0.......^.........^.........^..

 100 INPUT "shape data address?
";sd: LET a=INT (sd/256): LET d=
sd-(a*256): POKE s+8,d: POKE s+9
,a
!2.......^.........^.........^.........^.........^.........^....
Line 100         This line collects the address at which you
                 want to store the data for the shape of your
                 sprite.
!0.......^.........^.........^..

 110 INPUT "mask data address? "
;sd: LET a=INT (sd/256): LET d=s
d-(a*256): POKE s+10,d: POKE s+1
1,a
!2.......^.........^.........^.........^.........^.........^....
Line 110         If you've got a mask, tell this line where 
                 you've put it in memory. If you haven't, simply
                 enter zero.
!0.......^.........^.........^..

 120 INPUT "storage area address
? ";sd: LET a=INT (sd/256): LET
d=sd-(a*256): POKE s+12,d: POKE
s+13,a: CLS
!2.......^.........^.........^.........^.........^.........^....
Line 120         The storage area address is the bit of memory
                 where you have to put a copy of the screen that
                 your sprite is obliterating - component frames
                 of a sprite, ie. its animations, can use the
                 same area of memory to store the screen.
!0.......^.........^.........^..

 130 PRINT "SPRITE ";n-p+1: PRIN
T : FOR q=s TO s+13: PRINT PEEK
q,q: NEXT q
 140 LET s=s+14: NEXT p
 150 SAVE "BLOCK"+STR$ nCODE 572
84-r,r
!2.......^.........^.........^.........^.........^.........^....
Lines 130-150    This last block prints out the data information
                 for the user, loops back if necessary and then
                 saves the code.
!0.......^.........^.........^..

!B
\H11\H07\H10\H00MOTION PICTURES                 
!2.......^.........^.........^.........^.........^.........^....
Right, we're on the move. If you've followed the instructions up
to  now,  you're ready to turn your sprites into real  cartoons.
You'd better make a start on this program, then load and run it.
You'll  be asked the total number of frames for all the  sprites
and  then the number of animations for each. It'll then  animate
all the sprites and allow you to move the first one under cursor
control.  Remember  this  is a sprite you're moving, not just  a
frame,  so  if sprite one has four frames they'll all be  recog-
nised as sprite one.
  Press  Break and you can change the sprite you're  controlling
by  altering  the  value  of SP to any number up to the  maximum
number  of  your sprites. If you change the value of P, also  in
line 80, you can amend the number of pixels you control.
!0.......^.........^.........^..

  10 INPUT "Total No. of frames?
";n: DIM a(n): DIM b(n): DIM c(n
): POKE 57312,n
  20 LET r=n*14: LET s=57284-r:
LET b=n: LET num=0: LET q=INT (s
/256): POKE 57317,q: POKE 57316,
s-(q*256)
!2.......^.........^.........^.........^.........^.........^....
Lines 10-20      These lines ask the user exactly how many 
                 sprites he wants to animate in total (that is,
                 how many frames there are) and then sets up the
                 dimensions and control routines accordingly.
!0.......^.........^.........^..

  30 INPUT "Number of animations
?";a: IF a>b OR a=0 THEN  GO TO
30
  40 LET a(num+1)=b-a+1: LET b(n
um+1)=b+1: LET c(num+1)=b-a+1
  50 FOR q=b TO b-a+1 STEP -1: P
RINT q;",";: NEXT q: PRINT : PRI
NT : LET b=b-a: LET num=num+1
!2.......^.........^.........^.........^.........^.........^....
Lines 30-50      This part of the program finds out how many
                 animations are to be used for each sprite.
!0.......^.........^.........^..

  60 IF b<>0 THEN  GO TO 30
!2.......^.........^.........^.........^.........^.........^....
Line 60          After the program has checked to see how many
                 frames have been "used", it then goes back to
                 find out what else needs animating if there are
                 any frames unaccounted for.
!0.......^.........^.........^..

  80 LET sp=1: LET x=20: LET y=2
0: LET p=2
!2.......^.........^.........^.........^.........^.........^....
Line 80          This line sets up the basic control variables
                 for the sprites. The SP variable tells the
                 program which sprite is current, the X and Y
                 variables are the coordinates for the sprite,
                 and the P variable is the sprite's priority.
!0.......^.........^.........^..

 200 FOR n=1 TO num
 210 LET g=a(n)
 220 LET s=57284-(g*14)
 230 POKE s+3,0: LET g=g+1
 240 LET l=b(n)
 250 IF g=l THEN  LET a(n)=c(n):
 LET g=a(n)
 260 LET a(n)=g: LET s=57284-(g*
14)
 270 IF n=sp THEN  LET x=x+p*((I
NKEY$="8")-(INKEY$="5")): LET y=
y+p*((INKEY$="6")-(INKEY$="7")):
 POKE s,x: POKE s+1,y
 280 POKE s+3,1: NEXT n
 290 RANDOMIZE USR 57313: GO TO
200
!2.......^.........^.........^.........^.........^.........^....
Lines 200-290    This is the main loop of the program. Line 270
                 is the interesting line which you might want to
                 rip out for use in your own programs - this
                 actually moves the sprites while the rest of 
                 this section deals with animating them.
!1.......^.........^.........^.........^........

!B
--
from Your Spectrum #19 (Oct.1985)
--
!$
