Значок ресурса

Sprite Designer

Нет прав на скачивание
Автор: Toni Baker
Год: 1984
Издатели: Your Spectrum
Языки: 🇬🇧 Английский
Формат: 📼 TAP лента
Требования: 🖥️ ZX Spectrum 48K

Ссылки:
Страница на ZXArt
Страница на World Of Spectrum
Страница на Spectrum Computing

Скриншоты:
SpriteDesigner_4.gif


!0.......^.........^.........^..


!B


\H11\H07\H10\H00 S P R I T E


\H11\H07\H10\H00 D E S I G N E R





!2.......^.........^.........^.........^.........^.........^....


User-defined sprites on the Spectrum? It's not that difficult!


Get things moving on-screen with more machine code magic from


Toni Baker.


!1.......^.........^.........^.........^........


This month's block of crafty code makes weird


shapes fly around all over the screen. In fact,


you shouldn't find it too hard to add a few bits


and pieces to the idea yourself. It's all basic-


ally very simple. You design up to five


different sprites - of any figure, shape, design


and so on - which in this case are 16 pixels


wide by 16 pixels high; imagine four user-


defined graphics characters glued together in a


square and you have the idea. But - and this is


where the story really begins - there's more to


this program than meets the eye, for it incorp-


orates a rather mind-blowing idea ...





!0.......^.........^.........^..


!B


MOTION PICTURES


!1.......^.........^.........^.........^........


You see, once you've defined a sprite, you can


then specify its coordinates on the screen and


its velocity across the screen. In other words,


they move! Curiouser and curiouser. Once a


sprite is set in motion, you can continue exe-


cuting more Basic or machine code. The sprites


will keep moving on-screen, simultaneously with


any other program.


One line of Basic can set a sprite in motion.


The next Basic line will, of course, be executed


in sequence - but it'll be executed whilst the


sprite is moving. Thus, the setting in motion in


the first place is all you have to worry about.


How it all works is quite intricate, so I'll


explain in a moment or two; if you find the


blurb a bit too heavy going, try quaffing a


cuppa or two before attempting to follow it. In


the meantime, I'll tell you how to integrate my


machine code with your Basic.





!0.......^.........^.........^..


!B


DOWN TO DESIGN


!1.......^.........^.........^.........^........


The first statement of your Basic program must


be a "DIM s$(x,8)"; where x is the maximum


number of things you want flying around on-


screen at any one time. Then, you'll want to


include the statements "LET on=33013" and "LET


off=33020". From here on in it's up to you. The


statement "RANDOMIZE USR on" will bring the


moving sprite facility into action, whereas the


statement "RANDOMIZE USR off"will bring things


back to normal.


The sprites themselves are defined using the


ordinary user-defined graphics. You can have up


to five different designs on-screen at once,


which are:


!0.......^.........^.........^..


Sprite 1=UDGs A,B,C,D


Sprite 2=UDGs E,F,G,H


Sprite 3=UDGs I,J,K,L


Sprite 4=UDGs M,N,O,P


Sprite 5=UDGs Q,R,S,T


!1.......^.........^.........^.........^........


You can define them yourself in the usual ways.


The array, s$, is the one that contains all


the information, however, and each element must


be precisely defined. Now ... it's "pay atten-


tion" time. Take a look at the box giving the


explanation of the sprite parameters. (Note that


in the explanations given, I've used the letter


'N' to represent one of the strings in s$; the


number is completely arbitrary.)


The element s$(N,8) is actually very import-


ant. If it contains any character whose code is


less than or equal to 64 (decimal), then the


sprite is said to be inactive - that is, it'll


not appear on the screen. You can make as many


alterations as you like to the other elements of


s$. Once all the alterations have been made, you


can then alter s$(N,8) and the sprite will be


active and will start moving across the screen.


If such a moving sprite collides with anything


on-screen, or if it hits the edges of the


screen, then it'll instantly stop


!0.......^.........^.........^..


!B


--------------------------------


\H11\H07\H10\H00 THE SPRITE PARAMETERS


--------------------------------


STRING | EXPLANATION


ELEMENT |


--------------------------------


s$(N,1) |CHR$ (the sprite number


| - between one & five)


--------------------------------


s$(N,2) |This must always be


|initialised to CHR$(1)


--------------------------------


s$(N,3) |CHR$ (the number of


|frames between


|successive movements)


--------------------------------


s$(N,4) |CHR$ (the figure's Y


|coordinate)


--------------------------------


s$(N,5) |CHR$ (the figure's X


|coordinate)


--------------------------------


s$(N,6) |CHR$ (the figure's


|vertical displacement


|each time it moves)


--------------------------------


s$(N,7) |CHR$( the figure's


|horizontal displacement


|each time it moves)


--------------------------------


s$(N,8) |This must be set last


|of all, and must be any


|character whose code is


|greater than 64


--------------------------------





!2.......^.........^.........^.........^.........^.........^....


In the table above, it must be noted that 'N' is used to repre-


sent one of the strings in s$ - the number is arbitrary.


!1.......^.........^.........^.........^........


!B


moving and deactivate. Element s$(N,8) will


automatically reset to CHR$(0). You can test for


this occurrence in a Basic program.





!0.......^.........^.........^..


A TIMELY INTERRUPTION


!1.......^.........^.........^.........^........


OK, it's tea-break time! Arm yourself with a


cuppa and I'll explain how it all works.


The machine code is an interrupt routine. This


means that the program runs itself automatically


50 times a second. Each time it runs it checks


out the array s$ and shuffles sprites around the


screen accordingly. The basic instruction


"RANDOMIZE USR on" simply activates this


interrupt procedure, whereas "RANDOMIZE USR off"


deactivates it. Interrupt procedures are quite


clever; however, it's very easy to muck things


up and just a tiny little bug will spell total


disaster and blast the poor Speccy into


oblivion. This is true simple because the


program runs itself once for every new TV frame,


whether you want it to or not.


Take a peek at the basic program that's lying


around in this article. It manages to do in just


a few statements what would otherwise have been


quite a complicated program; it produces a


figure which bounces around the screen. The


first seven lines just initialise the array, s$,


and line 80 starts things moving. Line 90 is the


one to think about - it looks like an infinite


loop, but in fact it's not; it's just waiting


until the figure hits an edge. If you break out


of the program at any time you'll notice that


the figure will keep moving even while you type


a command, until it hits a wall (when it will


stop). At this point, you should type "RANDOMIZE


USR off" before you do anything else.


Well, that's it for this issue. I'm just going


off to stick my head in a bucket of inspiration


- hopefully in time for me to produce yet more


gems next month. See you then.





!2.......^.........^.........^.........^.........^.........^....


!B


--------------------------------.-------------------------------


10 DIM s$(1,8) Dimensions the array, s$


--------------------------------.-------------------------------


20 LET on=33013 Initialise the variables


30 LET off=33020


--------------------------------.-------------------------------


40 FOR j=1 TO 8 Read the data in line 160


50 READ a


60 LET s$(1,j)=CHR$ a


70 NEXT j


--------------------------------.-------------------------------


80 RANDOMIZE USR on Switches on the sprite facility


--------------------------------.-------------------------------


90 IF s$(1,8)="A" THEN GO TO Waits until a sprite hits the


90 edge of the screen


--------------------------------.-------------------------------


100 LET y=CODE s$(1,4) 'y' is the Y coordinate of the


sprite


--------------------------------.-------------------------------


110 LET x=CODE s$(1,5) 'x' is the X coordinate of the


sprite


--------------------------------.-------------------------------


120 IF y=0 OR y=22 THEN LET s$ Reverses the Y movement of


(1,6)=CHR$ (256-CODE s$(1,6)): B the sprite if necessary


EEP .03,24


--------------------------------.-------------------------------


130 IF x=0 OR x=30 THEN LET s$ Reverses the X movement of


(1,7)=CHR$ (256-CODE s$(1,7)): B the sprite if necessary


EEP .03,12


--------------------------------.-------------------------------


140 LET s$(1,8)="A" Reactivates the sprite


--------------------------------.-------------------------------


150 GO TO 90 A loop to send the action back


to line 90.


--------------------------------.-------------------------------


160 DATA 1,1,2,10,5,255,1,65 Contains the data for s$


--------------------------------.-------------------------------





The Basic program to get things moving on-screen - type it in


and see ...





!B


Machine code Assembler Comments


---------.---------.------------------.-------------------------


ORG 80F5


---------.---------.------------------.-------------------------


3E80 ON LD A,#80


ED47 LD I,A I:=80


ED5E IM 2 Activate interrupt routine


C9 RET


---------.---------.------------------.-------------------------


ED46 OFF IM 0 Deactivate routine


C9 RET


---------.---------.------------------.-------------------------


0181 IADDR DEFW 8101 Direct interrupt control


to address 8101


---------.---------.------------------.-------------------------


F5 SPRITES PUSH AF


C5 PUSH BC


D5 PUSH DE


E5 PUSH HL


DDE5 PUSH IX Stack all registers used


by the routine


DD2A4B5C LD IX,(VARS) Point IX to array s$


DD7E00 LD A,(IX+#00)


FED3 CP #D3


200F JR NZ,EXIT Jump if first variable is


not array s$


DD4604 LD B,(IX+#04) B:=1st dimension of array


(number of sprites)


---------.---------.------------------.-------------------------


C5 SP_LOOP PUSH BC Stack this number


010800 LD BC,#0008


DD09 ADD IX,BC Point IX to start of next


sprite(next array element)


CD7181 CALL NXT_SPRT Treat next sprite


C1 POP BC B:=remaining number of


sprites to treat


10F4 DJNZ SP_LOOP


---------.---------.------------------.-------------------------


DDE1 EXIT POP IX


E1 POP HL


D1 POP DE


C1 POP BC


F1 POP AF Restore all registers


FF RST #38 Carry out normal


interrupt procedures


C9 RET


---------.---------.------------------.-------------------------


CB0C LINE RRC H


CB0C RRC H


CB0C RRC H HL:=coded print position


011F00 LD BC,#001F


09 ADD HL,BC Move print position one


square down and one left


CB04 RLC H


CB04 RLC H


CB04 RLC H HL:=correct print position


C9 RET


---------.---------.------------------.-------------------------


CD4081 WIPE CALL H_WIPE Erase top half of sprite


CD2981 CALL LINE Point HL to bottom half of


sprite


---------.---------.------------------.-------------------------


CD4481 H_WIPE CALL Q_WIPE Erase one square of sprite


23 INC HL Point HL to remaining square


---------.---------.------------------.-------------------------


E5 Q_WIPE PUSH HL


0608 LD B,#08 B:=Number of rows per


square


---------.---------.------------------.-------------------------


3600 WP_LOOP LD (HL),#00 Erase next row


24 INC H Point HL to next row


10FB DJNZ WP_LOOP


E1 POP HL


C9 RET


---------.---------.------------------.-------------------------


AF TEST XOR A A:=00


CD5581 CALL H_TEST Test upper half of sprite


position


CD2981 CALL LINE Point HL to lower half


---------.---------.------------------.-------------------------


CD5981 H_TEST CALL Q_TEST Test one square of sprite


position


23 INC HL Point HL to remaining square


---------.---------.------------------.-------------------------


E5 Q_TEST PUSH HL


0608 LD B,#08


---------.---------.------------------.-------------------------


B6 TS_LOOP OR (HL) If any pixel is set then A


becomes non-zero


24 INC H HL points to next row


10FC DJNZ TS_LOOP


E1 POP HL


C9 RET


---------.---------.------------------.-------------------------


78 FIND_ADDR LD A,B This subroutine computes


E618 AND #18 in HL the print pos of the


F640 OR #40 square (on-screen) which


67 LD H,A has PRINT-AT coords given


78 LD A,B by registers B,C


0F RRCA


0F RRCA


0F RRCA


E6E0 AND #E0


B1 OR C


6F LD L,A


C9 RET


---------.---------.------------------.-------------------------


DD7E07 NXT_SPRT LD A,(IX+#07) A:=activation flag


FE40 CP #40


D8 RET C Return if sprite inactive


DD3501 DEC (IX+#01) Count frames between


movements


C0 RET NZ Return if the sprite does


not require moving


DD7E02 LD A,(IX+#02) A:=frame interval between


movements


DD7701 LD (IX+#01),A Re-initialise frame count


DD4603 LD B,(IX+#03) B:=y coordinate


DD4E04 LD C,(IX+#04) C:=x coordinate


CD6281 CALL FIND_ADDR HL:=print pos of sprite


CD3A81 CALL WIPE Erase sprite


DD7E03 LD A,(IX+#03) A:=y coordinate


DD8605 ADD A,(IX+#05) A:=intended y coordinate


FE17 CP #17


301F JR NC,NS_EXIT Jump if intended y coord


out of range


47 LD B,A B:=intended y coordinate


DD7E04 LD A,(IX+#04) A:=x coordinate


DD8606 ADD A,(IX+#06) A:=intended x coordinate


FE1F CP #1F


3014 JR NC,NS_EXIT Jump if intended x coord


out of range


4F LD C,A C:=intended x coordinate


---------.---------.------------------.-------------------------


C5 PUSH BC


CD6281 CALL FIND_ADDR HL:=intended print pos


CD4E81 CALL TEST Test for collision


C1 POP BC BC:=intended coordinates


A7 AND A


2008 JR NZ,NS_EXIT Jump if sprite has hit


something


DD7003 LD (IX+#03),B Store new y coordinate


DD7104 LD (IX+#04),C Store new x coordinate


180A JR NS_DRAW


---------.---------.------------------.-------------------------


DD360700 NS_EXIT LD (IX+#07),#00 Deactivate sprite


DD4603 LD B,(IX+#03) B:=old y coordinate


DD4E04 LD C,(IX+#04) C:=old x coordinate


---------.---------.------------------.-------------------------


DD6E00 NS_DRAW LD L,(IX+#00) L:=sprite type number


2D DEC L L now in range 0 to 4


2600 LD H,#00 HL now in range 0 to 4


29 ADD HL,HL


29 ADD HL,HL


29 ADD HL,HL


29 ADD HL,HL


29 ADD HL,HL Multiply by 32d


ED5B7B5C LD DE,(UDG) Point DE to graphic A


19 ADD HL,DE Point HL to required


sprite graphics


E5 PUSH HL


CD6281 CALL FIND_ADDR HL:=print pos of sprite


D1 POP DE DE:=address of pixel


information


---------.---------.------------------.-------------------------


CDDB81 DRAW CALL H_DRAW Draw upper half of sprite


CD2981 CALL LINE Point HL to lower half


---------.---------.------------------.-------------------------


CDDF81 H_DRAW CALL Q_DRAW Draw next square of sprite


23 INC HL Point HL to next square


---------.---------.------------------.-------------------------


E5 Q_DRAW PUSH HL


0608 LD B,#08


---------.---------.------------------.-------------------------


1A DR_LOOP LD A,(DE)


77 LD (HL),A Print next row


13 INC DE


24 INC H Point HL to next row


10FA DJNZ DR_LOOP


E1 POP HL


C9 RET


---------.---------.------------------.-------------------------


!1.......^.........^.........^.........^........





!B


--


from Your Spectrum #10 (Dec/Jan.1984/85)


--


!$
Автор
Verter_bot
Загрузки
0
Просмотры
1
Расширение
zip
Размер
7 КБ
Хэш
c18883ce5e6fc771c9bad155e590b0f8
Первый выпуск
Последнее обновление

Оценки

0.00 звезд(ы) 0 оценок
Назад
Вверх