Copyright © 2024 by Víctor Parada
This is a little game for the 2025 NOMAM's BASIC 10-liners Contest. This program fits in the PUR-120 category, and it was written using FastBasic 4.6 for the 8-bits ATARI XL/XE computers line. Development started on 2024-03-29, and it took 2+2+1 days. The final version's date is 2024-04-08.
Avoid Blinky while clearing the row of dots, but you can catch him after eating the power pill.
Press the button to start. | |
You are Pac-man on the left side, Blinky is at the right one. Both will run against each other. Press the button to turn around and avoid Blinky. | |
Escape through the sides. Blinky won't follow you through that path. | |
When you eat the power pill, Blinky will be scared for a moment and you can catch him while he is purple. | |
Scoring: At level 1, each dot gives 1 point, power pill gives 4 and the purple ghost gives 20. These points are doubled in level 2, tripled at level 3 and so on. | |
Each time you eat all the dots of the row, the difficulty level will be increased a bit: the time for purple ghost will be shorter and the speed of Blnky will increase. | |
There is only one life. The game is over when Blinky captures you. Press the button to try again. |
A ZPH show featured a WIP game called "Pac-Line 2600" for the Atari 2600 console, the first game programmed by the host James Earl O'Brien. In a previous talk with him, while the game was a secret, he told that this game could be written as a tenliner, and I said that I could try to port it during the show when he had revealed it. During the show, he explained that this game was a port from "Pac-Line", a PICO-8 game by sizescape, which is an enhanced port of "Paku-Paku" by Kenta Cho, a web game released on January 2024.
Original Paku-Paku game.
Current Pac-Line version for PICO-8.
First public 2600 version by James.
I started the development during the show, but the design of the required bitmaps took more time than expected, so I couldn't have a working proto before the end of the show. Anyway, some hours later I could publish in the forum thread a video of my first prototype. Even though both Pac-Line and James' version used the joystick to move Pacman, I decided to use the single-button approach of Paku-Paku; this means that you only have to press the button to change the direction, since Pacman is always moving to either side. The next day, I made major improvements and had a new playable prototype. Before publishing it, I wanted to know the effect about that in the context of the Tenliners Contest. Bunsen from NOMAM confirmed me that this won't invalidate it as an entry for next year's contest, so I published a second video for the current prototype.
Initial prototype.
Second playable prototype.
The following updates were the fine tunning the difficulty increase and to add sound effects. The game started easy enough to learn the mechanics, but the difficulty slowly increased up to the crazy level 25, where it could not be beaten, as the ghost speed doubles Pacman's. On each level the earned score is multiplied by the level number, so it would increase a lot on faster levels. When reaching level 25, if all the ghost were captured, the score should be 11700 points. Any aditional points from there would be considered lucky ones. So, the objective of the game is to capture all the ghosts before reaching the last level, with the purpose of maximizing the score before the end of the game.
But while testing, I found that it was too easy to master the game and to reach to the crazy level, and I wanted to change that by doubling the speed: instead of to move one pixel at a time, move two. The result was a very fast game, a bit harder to master and to reach the top level. In my opinion, it a was better gameplay, and I left it.
After couple of days tweaking and commenting the code, I could have a working release candate with sound FX. I sent it to some friends (including James) to betatest it and receive some feedback.
New bitmaps and new name.
As I recalled that James prefered the joystick approach instead of a single-button one, I changed this for him, and found that I could save one byte of source code by doing this (and four more at the variables initialization because a control variable to avoid continuous side change by not releasing the button was not required). So, either way, the game was still a tenliner, so I decided to include both versions in the distribution disk, but I'm not sure which version will be submitted to the contest.
The final tweaks were palette for the NTSC version and some changes in the bitmaps that look better on the faster version. BTW, there are no timers based on the refresh rate of the TV system, so both PAL and NTSC versions should run at the same speed.
Some months later, I was invited to give a talk at the ExpoAtari Chile 2024. As an aditional event activity, I proposed the "Pac-Line Challenge", a free competition for the attendants, with a single try of the game trying to beat a record from others in a time frame. It was approved, so I prepared two things: a prize and a special single-button controller. At the event, we decided to project the screen to a wall for everyone to see it. Some people really wanted to win and after each try, they went to the end of the line to try again. After an hour, the challenge was closed and we had a winner. The prize, a specially printed mug, was given to him as a trophy at the end of the talk.
A special single-button controller.
People trying to beat the high score.
The projected playfield.
Felipe Sánchez was the winner of the trophy with 6905 points.
Get the PACLINE.ATR file and set it as drive 1 in a real Atari (or emulator). Turn the computer on and a menu should start after the loading completes, then use computer console keys to select between PAL and NTSC, and from single button and joystick mode to control Pacman. A joystick in port 1 is required.
The abbreviated BASIC code is the following:
The full and expanded BASIC listing is:
|
PAC-LINE tenliner (c) 2024 by Víctor Parada |
|
P/M use: P0: Pacman P1: (Fearful) Ghost body P2: Ghost eyes P3: Fearful second layer to avoid transparency Missiles are not used |
a=adr("{binary data}")+1 |
Binary data: 3x8 bytes: Charset (dot, pill and borders) 3x9 bytes: Pacman bitmap (left, closed, right) 2x9 bytes: Ghost bitmap (left 1 and 2) 2x9 bytes: Ghost bitmap (right 1 and 2) 2x9 bytes: Ghost bitmap (fearful 1 and 2) 8 bytes: Color palette |
p=a+33 |
Pacman bitmaps pointer |
g=p+27 |
Ghost bitmaps pinter |
f=g+27 |
Fearful ghost pointer |
e=$2451 |
Constant to save space later |
graphics 8 |
Clears top of RAM (including P/M area) |
graphics 29 |
Set graphics mode 13 (ANTIC 5) without text window (40x12) |
pmgraphics 2 |
Set double line resolution P/M graphics mode |
move f+18,704,8 |
Color palette |
move $E000,$7000,512 move a,$7008,24 |
Copy the charset to RAM and replace some chars |
poke 756,$70 |
Change to new charset |
a=dpeek(560)+7 poke a,7 poke a+6,7 |
Change 2 lines to graphics mode 2 (ANTIC 7) for title and score |
m=dpeek(88)+184 |
Pointer to the first dot in the playfield |
position 4,2 print #6,"{binary data}" |
Print title |
mset m-41,33,3 mset m+39,33,3 |
Draw playfield borders |
mset pmadr(3)+57,6,126 |
Set a block for the second layer of the Fearful Ghost |
do |
MAIN LOOP |
while strig(0) wend |
Wait for trigger to begin |
|
Initialize game variables |
x=0 |
Pacman position |
y=62 |
Ghost position |
o=1 |
Pacman direction (1=right, -1=left) |
q=6 |
Delay for Ghost's counter |
l=0 |
Trigger release control flag (1=pressed, 0=released) |
n=0 |
Dots count |
h=0 |
Hit flag |
k=0 |
Killed ghost flag (select side for eyes to go) |
j=0 |
Timer for fearful Ghost |
s=0 |
Score |
r=0 |
Round counter |
z=0 |
Dot & pill FX delay |
v=0 |
Timer for Pacman |
w=0 |
Timer for Ghost |
|
The following variables are initialized to 0 autiomatically at start-up, then reused at current count: Animation counter for Pacman: t=0 Animation counter for Ghost: u=0 |
repeat |
GAME LOOP |
if n=0 |
Draw the dots and pill over empty playfield |
a=rand(5)*2 |
Random location of the pill |
poke m,1 |
Draw first dot |
move m,m+2,29 |
Copies the dot to the right |
poke m+2+a+18*(x<31),2 |
Pill must be in the other half |
inc r |
Increase round number |
if q and r&3=0 then dec q |
Speed up the Ghost every 4 rounds |
n=16 |
Number of dots |
endif |
|
v=not v |
Timer for Pacman |
w=(w+1)*(w<q) |
Timer for Ghost |
if v=0 |
Move Pacman |
t=(t+1)&3 |
Pacman animation timer |
x=(x+o+62) mod 62 |
Compute next Pacman position (with wrap around) |
move p+9*o*(t/2),pmadr(0)+55,9 |
Update to the corresponding Pacman bitmap |
pmhpos 0,x+x+61 |
Update Pacman position |
endif |
|
c=m+x/2 a=peek(c) if a i=a*a |
Got a dot or pill? |
if a=2 and not k then j=24+q*4 |
Got a pill? Set fearful Ghost timer |
poke c,0 |
Remove dot or pill |
exec _s i |
Score |
dec n |
Decrease dot+pill count |
z=5+i |
Sound FX depends on dot type |
endif |
|
if w=0 or k and v |
Move Ghost |
if k |
Eyes only? |
b=sgn(k-1-y) |
Compute direction |
if b |
At the target side? |
y=y+b exec _g g,e-b*$1B,0,y+y+61,0 |
No, advance one step |
else k=0 |
Yes, re-enable Ghost |
endif endif |
|
if not k |
Not the eyes-only mode? |
u=not u |
Animation step |
if j then dec j |
Decrease fearful ghost counter if enabled |
b=sgn(x-y) |
Compute Ghost direction |
if j |
Check again the counter in order to draw the right ghost mode |
if y<61 and y then y=y-b |
Compute new position of fearful ghost going to the opposite direction |
poke 705, $66+(j&4)*(j<24)*2 |
Set fearful ghost color (blinks when time will be over) |
exec _g f+9*u,0,y+y+61,0, y+y+61 |
Only fearful bitmap, no eyes |
else |
|
y=y+b |
Compute Ghost new position |
poke 705,$24 |
Restore Ghost color |
exec _g g+9*(b+u), e+((b=0)-b)*$1B,y+y+61,y+y+61,0 |
Animate Ghost to the corresponding direction (including eyes) |
endif endif endif |
|
if z then dec z sound 0,40+z*2*i,10,z |
Dot got FX |
poke 77,0 |
Disable attract mode |
if strig(0) |
Check the trigger |
l=1 |
If not pressed, set the "released" flag |
elif l |
If pressed and the released flag is set |
o=-o |
Change Pacman direction |
l=0 endif |
Reset the "released" flag |
h=abs(x-y)<3 and not k |
Collision control. Hitbox allows 3 pixels overlap (ignored when in "eyes-only" mode) |
if j and h |
Check a hit when the Ghost in fearful mode |
j=0 |
Exit fearful mode |
h=0 |
Reset killed flag |
k=1+61*(y<32) |
Enable eyes-only mode |
exec _s 20 |
Increase the score |
endif |
|
until j=0 and h |
Game finishes when Pacman is captured |
for a=0 to 9 sound 0,8+a*8,6,8 poke pmadr(0)+55+a,0 pause 2 next a sound |
Game over sound FX |
loop |
Next try? |
proc _g a b c d dd |
Update Ghost bitmap and position P1: Ghost body P2: Ghost eyes P3: Fearful Ghost background block |
move a,pmadr(1)+55,9 |
Update body bitmap |
dpoke pmadr(2)+57,b |
Update eye bitmap (2 bytes) |
pmhpos 1,c pmhpos 2,d pmhpos 3,dd endproc |
Update corresponding horizontal position |
proc _s a |
Update and print score |
s=s+a*r position 25,7 print #6,rtab(32) s endproc |
The level is a score multiplier |
Return to my 10-liners page.
© 2024 by Víctor Parada - 2024-04-04 (updated: 2024-08-18)