HP Prime for All
English
Русский
Name | Invader |
Description | The classic Space Invaders game. Shoot the aliens before they shoot you. |
Author | Unknown |
Source code formatted by website engine
BEGIN
Init();
GameLoop();
END;
GameLoop()
BEGIN
LOCAL ml := 0;
LOCAL ret, r2, i;
REPEAT
r2 := MainScreen();
IF r2 == 2 THEN
// Init game
energy := 100;
weapon := 0;
ml := 0;
FOR i FROM 1 TO maxbullit DO
bullits(i) := {0, 0, 0, 0, 0};
bombs(i) := {0, 0, 0, 0, 0};
END;
REPEAT
energy := energy+20;
IF energy > 100 THEN energy := 100; END;
ret := RunLevel(levels(ml+1));
ml := (ml+1) MOD SIZE(levels);
UNTIL ret == 1;
END;
UNTIL r2 == 1;
END;
RunLevel(m)
BEGIN
LOCAL ani, sx, sy, ss, ac;
LOCAL dx, dy, mx, my;
LOCAL i, j, ix, k;
LOCAL a, v, mulle, endcount;
LOCAL s := {};
LOCAL toi, toj, spx, spy;
LOCAL playerx := 150;
LOCAL endgame := 0;
LOCAL mus, count, col;
LOCAL entercheck := 0;
LOCAL logcheck := 0;
LOCAL bombcount := RANDINT(10, 50);
LOCAL alienx, alieny, isboss;
LOCAL tik;
LOCAL nextbullit := 0;
LOCAL nextbomb := 0;
LOCAL number_of_aliens;
// setup level
DIMGROB_P(G4, 400*20, 240);
RECT_P(G4, 0);
toi := size(m(1));
toj := size(m);
number_of_aliens := toi*toj;
FOR j FROM 1 TO toj DO
FOR i FROM 1 TO toi DO
ix := (j-1) * toi + (i-1) + 1;
s(ix, 1) := (i-1) * 30;
s(ix, 2) := (j-1) * 30;
s(ix, 3) := 0;
s(ix, 4) := m(j, i);
s(ix, 5) := (i-1) * 30;
s(ix, 6) := (j-1) * 30;
FOR k FROM 0 TO 9 DO
sx := 26*k;
sy := s(ix, 4) * 22;
BLIT_P(G4, s(ix, 1) + k*400, s(ix, 2), G3, sx, sy, sx+26, sy+22);
END
END;
END;
IF number_of_aliens == 1 THEN
isboss := 10;
spx := 3;
ELSE
isboss := 0;
spx := 1;
END;
spy := 1;
ss := 0;
ani := 0;
alienx := 0;
alieny := 0;
mulle := 0;
// Game loop
REPEAT
tik := TICKS() + 50;
RECT_P(G1, 0);
count := 0;
IF mulle == 0 THEN
IF energy < 100 THEN
energy := energy+1;
ELSE
energy := 100;
END;
END;
mulle := (mulle+1) MOD 10;
// Move invaders
CASE
IF ss == 0 THEN
alienx := alienx+spx;
FOR i FROM 1 TO number_of_aliens DO
IF s(i, 3) == 0 THEN
count := count+1;
s(i, 1) := s(i, 1) + spx;
IF s(i, 1) > 294 THEN
ss := 1;
ac := 20;
END;
END;
END;
END;
IF ss == 1 THEN
ac := ac-1;
alieny := alieny+spy;
IF ac == 0 THEN
ss := 2;
END;
FOR i FROM 1 TO number_of_aliens DO
IF s(i, 3) == 0 THEN
count := count+1;
s(i, 2) := s(i, 2) + spy;
IF s(i, 2) > 210 THEN
ss := 4;
endgame := 1;
END;
END;
END;
END;
IF ss == 2 THEN
alienx := alienx-spx;
FOR i FROM 1 TO number_of_aliens DO
IF s(i, 3) == 0 THEN
count := count+1;
s(i, 1) := s(i, 1) - spx;
IF s(i, 1) < 1 THEN
ss := 3;
ac := 20;
END;
END;
END;
END;
IF ss == 3 THEN
ac := ac-1;
alieny := alieny+spy;
IF ac == 0 THEN
ss := 0;
END;
FOR i FROM 1 TO number_of_aliens DO
IF s(i, 3) == 0 THEN
count := count+1;
s(i, 2) := s(i, 2) + spy;
IF s(i, 2) > 210 THEN
ss := 4;
endgame := 1;
END;
END;
END;
END;
END;
ani := (ani+1) MOD 20;
sx := 400 * (ani MOD 10);
// Render invaders
BLIT_P(G1, alienx, alieny, G4, sx, 0, sx+320, 240);
// move bullits and bombs
FOR i FROM 1 TO maxbullit DO
if bullits(i, 5) THEN
bullits(i, 1) := bullits(i, 1) + bullits(i, 3);
bullits(i, 2) := bullits(i, 2) + bullits(i, 4);
RECT_P(G1, bullits(i, 1), bullits(i, 2), bullits(i, 1) + 2, bullits(i, 2) + 4, #FFFF00);
IF bullits(i, 1) < 0 OR
bullits(i, 1) > 320 OR
bullits(i, 2) < 0 OR
bullits(i, 2) > 240 THEN
bullits(i, 5) := 0;
END;
END;
if bombs(i, 5) THEN
bombs(i, 1) := bombs(i, 1) + bombs(i, 3);
bombs(i, 2) := bombs(i, 2) + bombs(i, 4);
IF bombs(i, 5) == 1 THEN
RECT_P(G1, bombs(i, 1), bombs(i, 2), bombs(i, 1) + 2, bombs(i, 2) + 4, #FF00FF);
ELSE
ARC_P(G1, bombs(i, 1), bombs(i, 2), 4, #80FF80);
END;
IF bombs(i, 1) < 0 OR
bombs(i, 1) > 320 OR
bombs(i, 2) < 0 OR
bombs(i, 2) > 240 THEN
bombs(i, 5) := 0;
END;
if bombs(i, 1) > playerx AND
bombs(i, 1) < playerx+19 AND
bombs(i, 2) > 225 THEN
IF bombs(i, 5) == 1 THEN
endgame := 1;
ELSE
energy := energy+25;
IF energy > 100 THEN energy := 100; END;
END;
bombs(i, 5) := 0;
BREAK;
END;
END;
END;
// Check keyboard and mouse
IF ISKEYDOWN(7) THEN // Left
playerx := playerx-1;
IF playerx < 0 THEN playerx := 0; END;
END;
IF ISKEYDOWN(8) THEN // Right
playerx := playerx+1;
IF playerx > 300 THEN playerx := 300; END;
END;
IF ISKEYDOWN(4) THEN // Escape
endgame := 1;
END;
IF ISKEYDOWN(25) THEN // Log
IF logcheck == 0 THEN
IF weapon == 1 THEN
weapon := 0;
ELSE
weapon := 1;
END;
END;
logcheck := 1;
ELSE
logcheck := 0;
END;
IF ISKEYDOWN(30) THEN // Enter
IF entercheck == 0 THEN
CASE
IF weapon == 0 THEN
i := nextbullit+1;
nextbullit := (nextbullit+1) MOD maxbullit;
if bullits(i, 5) == 0 AND energy > 0 THEN
energy := energy-2;
IF energy < 0 THEN energy := 0; END;
bullits(i, 1) := playerx+9;
bullits(i, 2) := 226;
bullits(i, 3) := 0;
bullits(i, 4) := -3.5;
bullits(i, 5) := 1;
END;
END;
IF weapon == 1 THEN
FOR j FROM 1 TO 10 DO
i := nextbullit+1;
nextbullit := (nextbullit+1) MOD maxbullit;
IF bullits(i, 5) == 0 AND energy > 0 THEN
energy := energy-4;
IF energy < 0 THEN energy := 0; END;
bullits(i, 1) := playerx+9;
bullits(i, 2) := 226;
v := RANDOM(3, 8);
a := angfac*RANDOM(-0.05, 0.05);
bullits(i, 3) := v*SIN(a);
bullits(i, 4) := -v*COS(a);
bullits(i, 5) := 1;
END;
END;
END;
END;
entercheck := 1;
END;
ELSE
entercheck := 0;
END;
mus := mouse(); // mouse
IF SIZE(mus(1)) THEN
playerx := B→R(mus(1, 1)) - 9;
IF playerx < 0 THEN playerx := 0; END;
END;
// Colission detect
FOR j FROM 1 TO maxbullit DO
if bullits(j, 5) ≠ 0 THEN
dx := (bullits(j, 1) - alienx) / 30;
IF dx ≥ 0 AND dx < toi THEN
dy := (bullits(j, 2) - alieny) / 30;
IF dy ≥ 0 AND dy < toj THEN
i := IP(dy) * toi+IP(dx) + 1;
mx := (bullits(j, 1) - alienx) MOD 30;
my := (bullits(j, 2) - alieny) MOD 30;
IF s(i, 3) == 0 AND mx < 26 AND my < 22 THEN
bullits(j, 5) := 0;
IF isboss > 0 THEN
isboss := isboss-1;
ELSE
s(i, 3) := 1;
spx := spx+0.1;
RECT_P(G4, s(i, 5), s(i, 6), s(i, 5) + 26, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 400, s(i, 6), s(i, 5) + 426, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 800, s(i, 6), s(i, 5) + 826, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 1200, s(i, 6), s(i, 5) + 1226, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 1600, s(i, 6), s(i, 5) + 1626, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 2000, s(i, 6), s(i, 5) + 2026, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 2400, s(i, 6), s(i, 5) + 2426, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 2800, s(i, 6), s(i, 5) + 2826, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 3200, s(i, 6), s(i, 5) + 3226, s(i, 6) + 22, 0);
RECT_P(G4, s(i, 5) + 3600, s(i, 6), s(i, 5) + 3626, s(i, 6) + 22, 0);
IF number_of_aliens == 1 THEN BossExplode(s(1, 1) + 10, s(1, 2) + 10); END;
END;
IF RANDOM() > 0.75 THEN
ix := nextbomb+1;
nextbomb := (nextbomb+1) MOD maxbullit;
if bombs(ix, 5) == 0 THEN
bombs(ix, 1) := s(i, 1) + 10;
bombs(ix, 2) := s(i, 2) + 10;
bombs(ix, 3) := 0;
bombs(ix, 4) := 2;
bombs(ix, 5) := 2;
END;
END;
END;
END;
END;
END;
END;
IF count == 0 AND endgame == 0 THEN
endgame := 2;
endcount := 50;
END;
IF endcount > 0 THEN endcount := endcount-1; END;
// drop bombs
bombcount := bombcount-1;
IF bombcount == 0 AND isboss == 0 THEN
ix := RANDINT(1, count);
FOR i FROM 1 TO toj*toi DO
IF s(i, 3) == 0 THEN
ix := ix-1;
IF ix == 0 THEN
j := nextbomb+1;
nextbomb := (nextbomb+1) MOD maxbullit;
if bombs(j, 5) == 0 THEN
bombs(j, 1) := s(i, 1) + 10;
bombs(j, 2) := s(i, 2) + 10;
bombs(j, 3) := 0;
bombs(j, 4) := 3.5;
bombs(j, 5) := 1;
END;
END;
END;
END;
bombcount := RANDINT(10, 50);
END;
IF bombcount == 0 AND isboss > 0 THEN
IF s(1, 3) == 0 THEN
FOR i FROM 1 TO 5 DO
j := nextbomb+1;
nextbomb := (nextbomb+1) MOD maxbullit;
if bombs(j, 5) == 0 THEN
bombs(j, 1) := s(1, 1) + 10;
bombs(j, 2) := s(1, 2) + 10;
v := RANDOM(3, 8);
a := angfac*RANDOM(-0.05, 0.05);
bombs(j, 3) := v*SIN(a);
bombs(j, 4) := v*COS(a);
bombs(j, 5) := 1;
END;
END;
END;
bombcount := RANDINT(10, 50);
END;
// Render player
RECT_P(G1, playerx, 232, playerx+19, 240, #FFFF00);
RECT_P(G1, playerx+9, 228, playerx+10, 232, #FFFF00);
IF weapon == 1 THEN
RECT_P(G1, playerx+5, 228, playerx+6, 232, #FFFF00);
RECT_P(G1, playerx+13, 228, playerx+14, 232, #FFFF00);
END;
// Render energy
RECT_P(G1, 215, 0, 320, 5, #0000FF);
CASE
IF energy < 20 THEN col := #FF0000; END;
IF energy < 60 THEN col := #FFFF00; END;
DEFAULT
col := #00FF00;
END;
RECT_P(G1, 217, 2, 217+energy, 3, col);
// Send to screen
BLIT_P(G1);
WHILE tik > TICKS() DO
WAIT(0.005);
END;
UNTIL endgame ≠ 0 AND endcount == 0;
// player killed
IF endgame == 1 THEN
FOR j FROM 1 TO 100 DO
bullits(j, 1) := playerx+10;
bullits(j, 2) := 230;
v := RANDOM(1, 8);
a := RANDOM(angfac);
bullits(j, 3) := v*SIN(a);
bullits(j, 4) := v*COS(a);
bullits(j, 5) := 1;
END;
FOR j FROM 1 TO 1000 DO
tik := TICKS() + 50;
// move bullits and bombs
FOR i FROM 1 TO 100 DO
if bullits(i, 5) THEN
bullits(i, 1) := bullits(i, 1) + bullits(i, 3);
bullits(i, 2) := bullits(i, 2) + bullits(i, 4);
bullits(i, 4) := bullits(i, 4) + 0.2;
IF bullits(i, 1) < 0 OR
bullits(i, 1) > 320 OR
bullits(i, 2) < 0 OR
bullits(i, 2) > 240 THEN
bullits(i, 5) := 0;
END;
END;
END;
// Render stuff
RECT_P(G1, 0);
sx := 400 * (ani MOD 10);
// Render invaders
BLIT_P(G1, alienx, alieny, G4, sx, 0, sx+320, 240);
// Render bullits
count := 0;
FOR i FROM 1 TO 100 DO
IF bullits(i, 5) THEN
RECT_P(G1, bullits(i, 1), bullits(i, 2), bullits(i, 1) + 4, bullits(i, 2) + 4, #FFFF00);
count := count+1;
END;
END;
IF count == 0 THEN BREAK; END;
// Send to screen
BLIT_P(G1);
WHILE tik > TICKS() DO
WAIT(0.005);
END;
END;
END;
RETURN endgame;
END;
Init()
BEGIN
// detect angle mode
IF HAngle = 0 THEN
angfac := 2*π;
ELSE
angfac := 360;
END;
DIMGROB_P(G3, 520, 220);
RECT_P(G3, 0);
DIMGROB_P(G1, 320, 240);
InitAInvaderBob(0, #FF0000);
InitAInvaderBob(1, #F0F000);
InitAInvaderBob(2, #00FF00);
InitAInvaderBob(3, #A000A0);
InitAInvaderBob(4, #0000FF);
InitAInvaderBob(5, #FFFFFF);
InitAInvaderBob(6, #00A0A0);
InitLevels();
END;
InitAInvaderBob(yindex, colour)
BEGIN
LOCAL xoff, yoff, ang, xleg;
LOCAL i, s;
s := 0.2;
yoff := yindex*22;
FOR i FROM 0 TO 10 DO
xoff := i*26;
ang := i;
xleg := 4+4*SIN(ang*angfac/10);
RECT_P(G3, xoff+xleg, yoff+70*s, xoff+7+xleg, yoff+22, 0, colour);
RECT_P(G3, xoff+11+xleg, yoff+14, xoff+18+xleg, yoff+22, 0, colour);
RECT_P(G3, xoff+4, yoff+3, xoff+22, yoff+16, 0, colour);
RECT_P(G3, xoff+7, yoff, xoff+19, yoff+3, colour);
RECT_P(G3, xoff+7, yoff+6, xoff+12, yoff+13, 0, #FFFFFF);
RECT_P(G3, xoff+14, yoff+6, xoff+19, yoff+13, 0, #FFFFFF);
RECT_P(G3, xoff+7, yoff+8, xoff+9, yoff+11, 0);
RECT_P(G3, xoff+14, yoff+8, xoff+16, yoff+11, 0);
END;
END;
BossExplode(xx, yy)
BEGIN
LOCAL j, i, tik;
LOCAL count, v, a;
FOR j FROM 1 TO 100 DO
bullits(j, 1) := xx;
bullits(j, 2) := yy;
v := RANDOM(1, 8);
a := RANDOM(angfac);
bullits(j, 3) := v*SIN(a);
bullits(j, 4) := v*COS(a);
bullits(j, 5) := 1;
END;
FOR j FROM 1 TO 1000 DO
tik := TICKS() + 50;
// move bullits and bombs
FOR i FROM 1 TO 100 DO
if bullits(i, 5) THEN
bullits(i, 1) := bullits(i, 1) + bullits(i, 3);
bullits(i, 2) := bullits(i, 2) + bullits(i, 4);
bullits(i, 4) := bullits(i, 4) + 0.2;
IF bullits(i, 1) < 0 OR
bullits(i, 1) > 320 OR
bullits(i, 2) < 0 OR
bullits(i, 2) > 240 THEN
bullits(i, 5) := 0;
END;
END;
END;
// Render stuff
RECT_P(G1, 0);
// sx := 400 * (ani MOD 10);
// Render invaders
// BLIT_P(G1, alienx, alieny, G4, sx, 0, sx+320, 240);
// Render bullits
count := 0;
FOR i FROM 1 TO 100 DO
IF bullits(i, 5) THEN
RECT_P(G1, bullits(i, 1), bullits(i, 2), bullits(i, 1) + 4, bullits(i, 2) + 4, #FFFF00);
count := count+1;
END;
END;
IF count == 0 THEN BREAK; END;
// Send to screen
BLIT_P(G1);
WHILE tik > TICKS() DO
WAIT(0.005);
END;
END;
END;
InitLevels()
BEGIN
levels := {{{0, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 1, 1, 0, 0}, {0, 0, 1, 3, 1, 0, 0}, {0, 0, 0, 0, 0, 0, 0}},
{{1, 1, 1, 1, 1}, {2, 2, 2, 2, 2}, {2, 2, 2, 2, 2}},
{{1}},
{{2, 2, 2, 2, 2, 2}, {1, 1, 1, 1, 1, 1}, {3, 3, 3, 3, 3, 3}, {2, 2, 2, 2, 2, 2}},
{{0, 0, 5, 0, 0, 0, 0, 0, 0}, {0, 0, 5, 0, 0, 0, 0, 0, 0}, {5, 5, 5, 5, 5, 5, 5, 5, 5},
{0, 0, 5, 0, 0, 0, 0, 0, 0}, {0, 0, 5, 0, 0, 0, 0, 0, 0}}};
END;
MainScreen()
BEGIN
LOCAL xoff, yoff, ang, xleg;
LOCAL tik, endgame := 0;
LOCAL mus, delay;
delay := 10;
xoff := 110;
yoff := 60;
ang := 0;
DIMGROB_P(G1, 320, 240);
REPEAT
tik := TICKS() + 50;
IF delay > 0 THEN delay := delay-1; END;
xleg := 20+20*SIN(ang*angfac/30);
ang := (ang+1) MOD 30;
RECT_P(G1, 0);
RECT_P(G1, xoff+xleg, yoff+70, xoff+35+xleg, yoff+110, 0, #FF0000);
RECT_P(G1, xoff+55+xleg, yoff+70, xoff+90+xleg, yoff+110, 0, #FF0000);
RECT_P(G1, xoff+20, yoff+15, xoff+110, yoff+80, 0, #FF0000);
RECT_P(G1, xoff+35, yoff, xoff+95, yoff+15, #FF0000);
RECT_P(G1, xoff+35, yoff+30, xoff+60, yoff+65, 0, #FFFFFF);
RECT_P(G1, xoff+70, yoff+30, xoff+95, yoff+65, 0, #FFFFFF);
RECT_P(G1, xoff+35, yoff+40, xoff+50, yoff+55, 0);
RECT_P(G1, xoff+70, yoff+40, xoff+85, yoff+55, 0);
TEXTOUT_P("Cute Invaders", G1, 130, 200, 0, #FFFF00);
TEXTOUT_P("2013 by Henryk K", G1, 120, 220, 0, #FFFF00);
TEXTOUT_P("Touch screen to start", G1, 100, 40, 0, #FFFF00);
BLIT_P(G1);
IF ISKEYDOWN(4) THEN // Escape
endgame := 1;
END;
mus := mouse(); // mouse
IF SIZE(mus(1)) AND delay == 0 THEN
endgame := 2;
END;
WHILE tik > TICKS() DO
WAIT(0.005);
END;
UNTIL endgame;
RETURN endgame;
END;