Copyright © 2020 by Víctor Parada
This is a little game for the 2020 NOMAM's BASIC 10-liners Contest. This program fits in the "stock" PUR-80 category, and it was written using Atari BASIC for the 8-bits ATARI XL/XE. Development started on 2020-03-12, and it took 3 days. The final version's date is 2020-03-14.
UPDATE: It obtained the 57th place of 87 entries in the category.
Coronavirus is spreading widely and too fast. Lead your population to a safe area within the time.
Virus is spreading and your population at the bottom of the screen is in danger. | |
Use your joystick to lead one group at a time to the safe area at the top of the screen, once you leave the bottom area, you cannot go back. | |
Once a group is safe, some more time is added, and you can lead another group. | |
You can arrive to any position in the safe area, but following groups should fill the empty spots. | |
You can move diagonally to pass through blocking viruses. | |
If the group you are leading becomes infected, you die. | |
When the time is over, infection becames unstoppable and the game ends. | |
You win only when all groups are safe! |
While developing Wazers, one of the game dynamics I thought was to move lots of wazers from the bottom of the playfield to the top, but as I decided to do what I finally did in that game, I kept the idea for a simple game for the PUR-80 category. Later, with COVID-19 (Coronavirus) pandemia on course worldwide, I thought about using this dynamics in a game where you need to rescue and cuarantine people without being infected.
When I had time, I prototyped it using Atari BASIC. I selected graphics mode 2 (ANTIC 7) without text window because the screen size provides a 20x12 colorful text playfield. The idea was to put 20 elements in the bottom of the screen, and allow the player to select one of them and run with it to the top of the screen, going through moving enemies. There would be one virus per row, moving from side to side, but changing its direction unexpetedly. In order to force the action, a timer was included, and the initial spot would be blocked, making impossible to return to it as a safe place. An asterisk would represent the virus, and an uppercase O the player, because I was almost sure than I won't be able to fit code for new bitmaps.
In a couple of hours I got most of the dynamics working. As it felt too easy to go from one side to the other, I decided to add more viruses per line, but, in order to do not make the viruses move at half speed, I decided to sometimes do not remove the viruses when moving them, as it seems that the plague is spreading. Of course, when the virus goes over the left ones, it could remove it or left it again. Also, it becames hard to see where a virus actually is when it is moving over the left ones.
1st prootype
Adding difficulty
The problem was that I was using 9 of the 10 available lines of code, and two features weren't included yet: a functional timer and a way to select which of the remaining objects should be selected. I thought I could add the timer, but I had to discard the selection of the remaining objects. This feature was planned as a way to do not be blocked by the virus at the bottom, but after some simulations, never happened that I could not move the next object, because diagonal movement was allowed since the beginning. But I could not add the timer because I could not fit it in the lines where it should be.
Doing some code optimization to get more space, I removed the initial random direction of each virus, and make them all start moving to the right. Also, some cosmetics where changed to save more bytes, and I could fit the timer management in the code. But I found that the timer decreased too fast during my tests, and I had no space in the screen to store a larger number, so I decided to add more time when the player reached the top side. This made me to do more code optimization to include all the required code.
Cosmetics were changed
A working timer
While testing, I discovered that I forgot to continuously disable the attract mode, and a "POKE 77,0" had to be inserted somewhere in the loop. It was another challenge, because I also found a border condition when the game finishes that should be also solved. After some logics changes, I could fix all the pendings, but it took another day... Unfortunatelly, there is no sound in this game.
Final version
Get the CORONAVI.ATR file and set it as drive 1 in a real Atari (or emulator). Turn on the computer and the game should start after loading. A joystick in port 1 is required.
The abbreviated BASIC code is the following:
The full and expanded BASIC listing is:
|
Symbology: virus=202 player = 47 blocked = 130 pending = 175 saved = 111 dead = 208 |
0 |
LINE 0: Initialization |
graphics 18 |
Enables text mode with 20x12 resolution and 5 colors (4 for text and 1 for background) |
dim v(8),d(8) |
Virus arrays: V(0-8): horizontal position of virus D(0-8): moving direction of the virus |
? #6;"TIME=999{binary data}" |
Prints game title |
z=adr("{binary data}") |
Joystick's bit table (x*4+y) |
s=40580 |
Memory address where playfield data starts, same as s=peek(88)+256*peek(89)+20 |
1 |
LINE 1: Sets up the playfield |
poke 77,0 |
Disables attract mode |
c=s+20 position 0,11 for i=0 to 8 |
Routine to build the start state of the game |
x=int(rnd(0)*18)+1 v(i)=x |
Choose a column where to put the virus |
d(i)=1 |
Each virus will start moving to the right |
poke c+x,202 |
Puts the virus |
2 |
LINE 2: |
c=c+20 |
Next playfild line's memory address |
print #6;"{binary data}"; next i |
Prints the first 9*2=18 groups |
print #6;"{binary data}"; |
Prints cels 19 and 20, the last one in another (active) color |
o=40799 |
Sets current position of active group |
x=19 y=10 |
Sets current coordinates of active group |
n=20 |
Sets number of total groups to save |
k=0 |
Not killed... yet! |
r=1 |
Groups are alive |
f=0 |
Frecuency for the player to move |
t=999 |
Sets timer |
3 |
LINE 3: GAME LOOP |
i=(i+1)*(i<8) |
Selects next virus line (9 lines: from 0 to 8) |
c=s+20+i*20 |
Computes memory address for the virus line |
w=v(i) |
Gets current virus horizontal position |
h=(w=0)+(w=19)+(rnd(0)<0.1) |
Decides if the direction of the virus should change |
if h then d(i)=-d(i) |
Changes virus direction if it was decided |
4 |
LINE 4: |
p=c+w |
Gets memory address for current virus |
q=p+d(i) |
Gets next memory address for current virus |
k=peek(q)=47 |
Is the player in the new position? |
poke p,202*(rnd(0)<0.12) |
Removes the virus from its old position, except if a random trail is left behind |
poke q,202 |
Puts the virus in its new position |
v(i)=w+d(i) |
Updates current horizonta position of the virus |
f=f+1 |
Increase player frecuency counter |
5 |
LINE 5: Updates player's position |
t=t-(t>0) |
Decrease global timer |
j=peek(z+stick(0)) |
Reads the joystick |
on f<3 or j=5 or k goto 9 |
Skip player movement if is not time to move, joystick was not moved or the player was killed |
f=0 |
Resets the player delay |
a=int(j/4) b=j-a*4-1 a=a-1 |
Computes movement deltas |
6 |
LINE 6: |
p=o |
Makes old position the current one |
w=x+a>=0 and x+a<20 u=y+b>=0 and y+b<10 |
Check for inbound new position |
a=a*(not(y=10 and b+1)) |
Horizontal move is prohibited inside bottom line if y=11 and b+1 then a=0 |
c=b*u*20 |
Computes new vertical movement of the player in the playfield |
o=p+a*w |
Updates horizontally current position in the playfield |
7 |
LINE 7: |
h=peek(o+c)<>111 |
Unable to move over a saved group |
o=o+c*h |
Updates vertically current position in the playfield |
k=peek(o)=202 |
Is there a virus? |
x=x+a*w |
Updates current horizontal coordinate of the player |
poke p,130*(y=10) |
Removes the player from the old location, and fill space fro the bottom line |
y=y+b*u*h |
Updates vertical coordinate of the player |
8 |
LINE 8: When a group reaches the top, select the next one |
poke o,47+64*(y=0) |
Moves the player to the new position, making it saved if it reached the top line |
if y=0 then n=n-1 x=n-1 y=10 |
Saved a group, continue with next group |
r=n>0 |
Not last group? |
o=40779+n poke o,47*r |
Changes color for the next active group |
t=t+47-n |
Extra time |
9 |
LINE 9: End of loops (in a loop) |
position 5,0 print #6;t;"{binary data}"; |
Prints timer |
on k=0 and t>0 and n goto 3 |
Game ends when killed, time is over or all groups were rescued |
poke o,208*r |
Kills the group (unless the player wins) |
on strig(0) goto 9 |
Wait for the trigger to start a new game |
run |
Restarts the game |
Return to my 10-liners page.
© 2020 by Víctor Parada - 2020-03-14 (updated: 2020-08-15)