To run online, click here: RUN ONLINE
Code:
' PROGRAM Dogfight David
' (c) Starsoft 2022 Pascalated BASIC
' (c) Starsoft 2023 Pascalated Boriel ZX BASIC
' Pascalated Sinclair BASIC (c) 1987 by ZarSoft
' Pascalated BASIC Converter (c) 2021 by Zarsoft
' Pascalated Boriel (c) 2023 by ZarSoft
' ZX BASIC Compiler (c) 2008 by Boriel
#include <input.bas> ' number = VAL INPUT(12)
#include <screen.bas> ' SCREEN$ function
#include <attr.bas> ' ATTR function
'--- Pascalated Boriel ---
#define PROGRAM REM
#define BEGIN REM
'#define CONST CONST
#define VAR DIM
#define INTEGER LONG
#define REAL FLOAT
#define CHAR STRING
'#define STRING STRING
#define BOOLEAN UBYTE
#define TYPE AS
'#define WHILE WHILE
#define REPEAT DO
#define UNTIL LOOP UNTIL
#define PROCEDURE SUB
CONST TRUE TYPE BOOLEAN = 1
CONST FALSE TYPE BOOLEAN = 0
PROGRAM Dogfight David
' CONSTant declarations
CONST DX TYPE INTEGER = 1 ' index for automaton for moveForward
CONST DY TYPE INTEGER = 2 ' index for automaton for moveForward
' VAR - Global variables
REM boolean GAMEOVER
VAR player1COL TYPE INTEGER
VAR player1LIN TYPE INTEGER
VAR player1COL0 TYPE INTEGER
VAR player1LIN0 TYPE INTEGER
VAR player2COL TYPE INTEGER
VAR player2LIN TYPE INTEGER
VAR player2COL0 TYPE INTEGER
VAR player2LIN0 TYPE INTEGER
VAR DirectionP1 TYPE INTEGER
VAR DirectionP2 TYPE INTEGER
VAR missile1COL TYPE INTEGER
VAR missile1LIN TYPE INTEGER
VAR missile1COL0 TYPE INTEGER
VAR missile1LIN0 TYPE INTEGER
VAR missile2COL TYPE INTEGER
VAR missile2LIN TYPE INTEGER
VAR missile2COL0 TYPE INTEGER
VAR missile2LIN0 TYPE INTEGER
VAR DirectionM1 TYPE INTEGER
VAR missile1Fuel TYPE INTEGER
VAR DirectionM2 TYPE INTEGER
VAR missile2Fuel TYPE INTEGER
VAR Sprite$(8) TYPE STRING ' automaton for plane image
VAR KeyMap(13,2,2) TYPE INTEGER ' automaton to use several keys
VAR DXY(8,2) TYPE INTEGER ' automaton for moveForward
VAR key TYPE INTEGER
VAR range TYPE INTEGER
VAR player1Points TYPE INTEGER
VAR player2Points TYPE INTEGER
VAR Clock,Clock0 TYPE INTEGER
VAR Period TYPE INTEGER = 8
PROCEDURE WaitClock
VAR elapsed TYPE INTEGER
REPEAT
ScanKey
LET Clock = PEEK 23672
LET elapsed = Clock-Clock0
IF elapsed<0 THEN LET elapsed = elapsed+256
UNTIL elapsed >= Period
LET Clock0 = Clock0 + Period: IF Clock0 > 255 THEN LET Clock0 = Clock0 - 256
REM PRINT AT 0,0;INK 2;elapsed;" ";
END PROCEDURE
PROCEDURE Process1
LET player1LIN0 = player1LIN
LET player1COL0 = player1COL
LET DirectionP1 = DirectionP1 + KeyMap(key,1,1)
IF DirectionP1 > 8 THEN LET DirectionP1 = 1
IF DirectionP1 < 1 THEN LET DirectionP1 = 8
LET player1LIN = player1LIN + DXY(DirectionP1,DY)
IF player1LIN > 21 THEN LET player1LIN = 1
IF player1LIN < 1 THEN LET player1LIN = 21
LET player1COL = player1COL + DXY(DirectionP1,DX)
IF player1COL > 31 THEN LET player1COL = 1
IF player1COL < 1 THEN LET player1COL = 31
PRINT AT player1LIN0 , player1COL0 ; " ";
PRINT AT player1LIN , player1COL ; ink 6; Sprite$(DirectionP1);
END PROCEDURE
PROCEDURE Process2
LET player2LIN0 = player2LIN
LET player2COL0 = player2COL
LET DirectionP2 = DirectionP2 + KeyMap(key,2,1)
IF DirectionP2 > 8 THEN LET DirectionP2 = 1
IF DirectionP2 < 1 THEN LET DirectionP2 = 8
LET player2LIN = player2LIN + DXY(DirectionP2,DY)
IF player2LIN > 21 THEN LET player2LIN = 0
IF player2LIN < 0 THEN LET player2LIN = 21
LET player2COL = player2COL + DXY(DirectionP2,DX)
IF player2COL > 31 THEN LET player2COL = 0
IF player2COL < 0 THEN LET player2COL = 31
PRINT AT player2LIN0 , player2COL0 ; " ";
PRINT AT player2LIN , player2COL ; ink 5; Sprite$(DirectionP2);
END PROCEDURE
PROCEDURE Player1Shot
BORDER 2
LET player2Points = player2Points + 1
PRINT AT 23, 20; PAPER 1; ink 4; "Points: "; player2Points;
LET player1LIN0 = player1LIN
LET player1COL0 = player1COL
PRINT AT player1LIN , player1COL ; "\F"
LET missile2Fuel = 0
PRINT AT missile2LIN , missile2COL ; ink 5; "\F"
LET player1LIN = player2LIN + 11
IF player1LIN > 21 THEN LET player1LIN = player1LIN - 21
LET player1COL = 0
LET DirectionP1 = 1
FOR i = 1 TO 20 : BEEP .005,5*RND : NEXT i
PRINT AT player1LIN0 , player1COL0 ; " "
PRINT AT player1LIN , player1COL ; ink 6; Sprite$(DirectionP1)
PRINT AT missile2LIN , missile2COL ; " "
END PROCEDURE
PROCEDURE Player2Shot
BORDER 2
LET player1Points = player1Points + 1
PRINT AT 23, 0; PAPER 1; ink 4; "Points: "; player1Points;
LET player2LIN0 = player2LIN
LET player2COL0 = player2COL
PRINT AT player2LIN , player2COL ; "\F"
LET missile1Fuel = 0
PRINT AT missile1LIN , missile1COL ; ink 6; "\F"
LET player2LIN = player1LIN + 11
IF player2LIN > 21 THEN LET player2LIN = player2LIN - 21
LET player2COL = 31
LET DirectionP2 = 5
FOR i = 1 TO 20 : BEEP .005,5*RND : NEXT i
PRINT AT player2LIN0 , player2COL0 ; " "
PRINT AT player2LIN , player2COL ; ink 5; Sprite$(DirectionP2)
PRINT AT missile1LIN , missile1COL ; " "
END PROCEDURE
PROCEDURE ProcessMissile1
LET missile1LIN0 = missile1LIN
LET missile1COL0 = missile1COL
LET missile1LIN = missile1LIN + DXY(DirectionM1,DY)
IF missile1LIN > 21 THEN LET missile1LIN = 1
IF missile1LIN < 1 THEN LET missile1LIN = 21
LET missile1COL = missile1COL + DXY(DirectionM1,DX)
IF missile1COL > 31 THEN LET missile1COL = 1
IF missile1COL < 1 THEN LET missile1COL = 31
LET missile1Fuel = missile1Fuel - 1
PRINT AT missile1LIN0 , missile1COL0 ; " "
IF ABS(missile1LIN - player2LIN) <= range AND ABS(missile1COL - player2COL) <= range THEN Player2Shot
IF missile1Fuel > 0 THEN PRINT AT missile1LIN , missile1COL ; ink 6; "\A"
END PROCEDURE
PROCEDURE ProcessMissile2
LET missile2LIN0 = missile2LIN
LET missile2COL0 = missile2COL
LET missile2LIN = missile2LIN + DXY(DirectionM2,DY)
IF missile2LIN > 21 THEN LET missile2LIN = 1
IF missile2LIN < 1 THEN LET missile2LIN = 21
LET missile2COL = missile2COL + DXY(DirectionM2,DX)
IF missile2COL > 31 THEN LET missile2COL = 1
IF missile2COL < 1 THEN LET missile2COL = 31
LET missile2Fuel = missile2Fuel - 1
PRINT AT missile2LIN0 , missile2COL0 ; " "
IF ABS(missile2LIN - player1LIN) <= range AND ABS(missile2COL - player1COL) <= range THEN Player1Shot
IF missile2Fuel > 0 THEN PRINT AT missile2LIN , missile2COL ; ink 5; "\A"
END PROCEDURE
PROCEDURE Fire1
LET missile1Fuel = 15
LET DirectionM1 = DirectionP1
LET missile1COL = player1COL + DXY(DirectionP1,DX)
IF missile1COL > 31 THEN LET missile1COL = 1
IF missile1COL < 1 THEN LET missile1COL = 31
LET missile1LIN = player1LIN + DXY(DirectionP1,DY)
IF missile1LIN > 21 THEN LET missile1LIN = 1
IF missile1LIN < 1 THEN LET missile1LIN = 21
PRINT AT missile1LIN , missile1COL ; ink 6; "\A"
END PROCEDURE
PROCEDURE Fire2
LET missile2Fuel = 15
LET DirectionM2 = DirectionP2
LET missile2COL = player2COL + DXY(DirectionP2,DX)
IF missile2COL > 31 THEN LET missile2COL = 1
IF missile2COL < 1 THEN LET missile2COL = 31
LET missile2LIN = player2LIN + DXY(DirectionP2,DY)
IF missile2LIN > 21 THEN LET missile2LIN = 1
IF missile2LIN < 1 THEN LET missile2LIN = 21
PRINT AT missile2LIN , missile2COL ; ink 5; "\A"
END PROCEDURE
PROCEDURE WaitForPlayer
VAR B$ TYPE STRING
PRINT AT 13,3; ink 6; " Difficulty: 1, 2 or 3"
REPEAT
PAUSE 0
LET B$ = INKEY$
UNTIL B$ >= "1" AND B$ <= "3"
LET range = 3 - VAL B$
LET dif = VAL B$
IF dif = 1 THEN Period = 24
IF dif = 2 THEN Period = 16
IF dif = 3 THEN Period = 8
RANDOMIZE
LET Clock0 = PEEK 23672
CLS
END PROCEDURE
PROCEDURE InitGame
LET player1LIN = 5 : LET player1COL = 0 : LET DirectionP1 = 1
LET player2LIN = 16 : LET player2COL = 31 : LET DirectionP2 = 5
PRINT AT player1LIN, player1COL; ink 6; Sprite$(DirectionP1)
PRINT AT player2LIN, player2COL; ink 5; Sprite$(DirectionP2)
LET missile1Fuel = 0
LET missile2Fuel = 0
LET player1Points = 0
LET player2Points = 0
END PROCEDURE
PROCEDURE initScreen
BORDER 1 : PAPER 1 : ink 7 : CLS
PRINT AT 0,9; ink 4; "Dogfight David";
PRINT AT 21,0; ink 4; " (c) 2022, 2023 STARSOFT";
PRINT AT 22,0; ink 4; " Pascalated BASIC";
PRINT AT 23,0; ink 4; " Compiled by Boriel ZX BASIC";
PRINT AT 10,3; "Player1: ASD Player2: JKL"
PRINT AT 13,9; ink 6; "Please wait..."
END PROCEDURE
PROCEDURE DefineChars
VAR n TYPE INTEGER
'RESTORE Sprites
READ car$
REPEAT
FOR i=0 TO 7
READ n
POKE USR car$+i,n
NEXT i
READ car$
UNTIL car$ = ""
END PROCEDURE
PROCEDURE Sprites
DATA "A"
DATA BIN 00000000
DATA BIN 00000000
DATA BIN 00001000
DATA BIN 00011100
DATA BIN 00111110
DATA BIN 00011100
DATA BIN 00001000
DATA BIN 00000000
DATA "B"
DATA BIN 00000010
DATA BIN 01000011
DATA BIN 01100110
DATA BIN 01111100
DATA BIN 00111000
DATA BIN 00011100
DATA BIN 00101110
DATA BIN 00000111
DATA "C"
DATA BIN 00111100
DATA BIN 00011000
DATA BIN 00011000
DATA BIN 00011000
DATA BIN 11111111
DATA BIN 01111110
DATA BIN 00011000
DATA BIN 00000000
DATA "D"
DATA BIN 01000000
DATA BIN 11000010
DATA BIN 01100110
DATA BIN 00111110
DATA BIN 00011100
DATA BIN 00111000
DATA BIN 01110100
DATA BIN 11100000
DATA "E"
DATA BIN 00010000
DATA BIN 00110000
DATA BIN 00110001
DATA BIN 01111111
DATA BIN 01111111
DATA BIN 00110001
DATA BIN 00110000
DATA BIN 00010000
DATA "F"
DATA BIN 00100010
DATA BIN 01010101
DATA BIN 10001000
DATA BIN 00000000
DATA BIN 01000100
DATA BIN 10101010
DATA BIN 00010001
DATA BIN 00000000
DATA "G"
DATA BIN 00001000
DATA BIN 00001100
DATA BIN 10001100
DATA BIN 11111110
DATA BIN 11111110
DATA BIN 10001100
DATA BIN 00001100
DATA BIN 00001000
DATA "H"
DATA BIN 00000000
DATA BIN 00001110
DATA BIN 01011100
DATA BIN 00111000
DATA BIN 01111000
DATA BIN 11101100
DATA BIN 11000111
DATA BIN 10000010
DATA "I"
DATA BIN 00000000
DATA BIN 00011000
DATA BIN 01111110
DATA BIN 11111111
DATA BIN 00011000
DATA BIN 00011000
DATA BIN 00011000
DATA BIN 00111100
DATA "J"
DATA BIN 11100000
DATA BIN 01110100
DATA BIN 00111000
DATA BIN 00011100
DATA BIN 00111110
DATA BIN 01100110
DATA BIN 11000010
DATA BIN 01000000
DATA ""
END PROCEDURE
PROCEDURE InitProg
DefineChars
REM automaton for plane image
'DIM Sprite$(8)
LET Sprite$(1) = "\G"
LET Sprite$(2) = "\J"
LET Sprite$(3) = "\I"
LET Sprite$(4) = "\H"
LET Sprite$(5) = "\E"
LET Sprite$(6) = "\B"
LET Sprite$(7) = "\C"
LET Sprite$(8) = "\D"
REM automaton for moveForward
'DIM DXY(8,2)
LET DXY(1,DX) = 1 : LET DXY(1,DY) = 0
LET DXY(2,DX) = 1 : LET DXY(2,DY) = -1
LET DXY(3,DX) = 0 : LET DXY(3,DY) = -1
LET DXY(4,DX) = -1 : LET DXY(4,DY) = -1
LET DXY(5,DX) = -1 : LET DXY(5,DY) = 0
LET DXY(6,DX) = -1 : LET DXY(6,DY) = 1
LET DXY(7,DX) = 0 : LET DXY(7,DY) = 1
LET DXY(8,DX) = 1 : LET DXY(8,DY) = 1
REM automaton for keys
'DIM KeyMap(32,2,2)
LET KeyMap(2,1,1) = 1
LET KeyMap(3,1,2) = TRUE
LET KeyMap(5,1,1) = -1
LET KeyMap(4,1,1) = -1 : LET KeyMap(4,1,2) = TRUE
LET KeyMap(7,1,1) = 1 : LET KeyMap(7,1,2) = TRUE
LET KeyMap(9,2,1) = 1
LET KeyMap(5,2,2) = TRUE
LET KeyMap(3,2,1) = -1
LET KeyMap(13,2,1) = -1 : LET KeyMap(4,2,2) = TRUE
LET KeyMap(7,2,1) = 1 : LET KeyMap(7,2,2) = TRUE
END PROCEDURE
PROCEDURE Game
InitProg
initScreen
InitGame
WaitForPlayer
PRINT AT 23,0; ink 4; "Points: "; player1Points;
PRINT AT 23,20; ink 4; "Points: "; player2Points;
REPEAT
WaitClock
BORDER 1
LET key = 192 - IN 65022
Process1
IF missile1Fuel = 0 THEN IF KeyMap(key,1,2) = 1 THEN BEEP .1,5: Fire1
IF missile1Fuel THEN ProcessMissile1
IF missile2Fuel THEN ProcessMissile2
LET key = 192 - IN 49150
Process2
IF missile2Fuel = 0 THEN IF KeyMap(key,2,2) = 1 THEN BEEP .1,5: Fire2
IF missile1Fuel THEN ProcessMissile1
IF missile2Fuel THEN ProcessMissile2
UNTIL FALSE
END PROCEDURE
BEGIN
REM PRINT "Demo for Pascalated BASIC"
PAUSE 50
Game
END