' Deze code is geschreven door Maurits van der Schee. ' Ik heb geprobeerd de code zo leesbar mogelijk te houden. ' Dit programma simuleert een biljartspel ' ' DECLARE SUB TekenKeu (Bal AS INTEGER, Snelheid AS INTEGER) DECLARE SUB TekenMikPunt (xKeu AS INTEGER, yKeu AS INTEGER, Positie AS INTEGER, Kleur AS INTEGER) DECLARE SUB TekenKeuEnMikPunt (Bal AS INTEGER, Richting AS INTEGER, Snelheid AS INTEGER) DECLARE SUB StootBal (Bal AS INTEGER) DECLARE SUB TekenTafel () DECLARE SUB RolBallenTotStilstand () DECLARE SUB VraagStartWaarden () DECLARE FUNCTION BallenStil () DECLARE FUNCTION BerekenBeeldenPerSeconde () 'SUBROUTINES EN FUNCTIES 'Geef alle variabelen startwaarden DECLARE SUB StartWaarden () 'Video subroutines DECLARE SUB StartVideo () DECLARE SUB TekenBallen () 'Wiskundige functies in graden ipv radialen DECLARE FUNCTION MyCOS (Graden AS DOUBLE) DECLARE FUNCTION MySIN (Graden AS DOUBLE) DECLARE FUNCTION MyTAN (Graden AS DOUBLE) DECLARE FUNCTION MyATAN (Breuk AS DOUBLE) DECLARE FUNCTION MyACOS (Breuk AS DOUBLE) DECLARE FUNCTION MyASIN (Breuk AS DOUBLE) 'Normale verplaatsing DECLARE SUB VerplaatsBallen () 'Verwerk de botsingen met de rand DECLARE SUB VerwerkRandBotsingen () 'Verwerk de botsingen met de ballen DECLARE SUB VerwerkBotsingen () 'Kijk of twee ballen elkaar raken DECLARE FUNCTION BotsTest (Bal1 AS INTEGER, Bal2 AS INTEGER) 'Als twee ballen elkaar raken zorgt deze subroutine 'voor de verwerking van de botsing. DECLARE SUB BotsBallen (Bal1 AS INTEGER, Bal2 AS INTEGER) 'CONSTANTEN CONST RECHTS = 1 CONST LINKS = 2 CONST BOVEN = 3 CONST ONDER = 4 CONST BEELDENPERSECONDE = 50 CONST TRUE = -1 CONST FALSE = 0 CONST PI = 3.141592654# CONST AANTALBALLEN = 3 'stuks CONST STRAALBAL = 10 'pixels CONST SCHERMMODUS = 12 '(640 x 480 16 kleuren) CONST SCHERMBREEDTE = 640 'pixels CONST SCHERMHOOGTE = 480 'pixels CONST ACHTERGRONDKLEUR = 0 CONST TAFELKLEUR = 6 CONST LAKENKLEUR = 2 CONST MIKPUNTKLEUR = 0 CONST LENGTEMIKPUNT = 10 CONST TAFELHOOGTE = (3 / 4) * SCHERMHOOGTE CONST TAFELBREEDTE = 1 * SCHERMBREEDTE CONST TAFELBANDBREEDTE = 20 'pixels 'Berekende constanten (niet aanpassen) CONST LAKENBREEDTE = TAFELBREEDTE - 2 * TAFELBANDBREEDTE CONST LAKENHOOGTE = TAFELHOOGTE - 2 * TAFELBANDBREEDTE CONST LAKENLINKS = (SCHERMBREEDTE - LAKENBREEDTE) / 2 CONST LAKENRECHTS = LAKENLINKS + LAKENBREEDTE CONST LAKENBOVEN = (SCHERMHOOGTE - LAKENHOOGTE) / 2 CONST LAKENONDER = LAKENBOVEN + LAKENHOOGTE 'REEKS VARIABELEN 'Richting in graden: 0 = rechts; 90 = omlaag; 180 = links; 270 = omhoog DIM SHARED Richting(1 TO AANTALBALLEN) AS DOUBLE 'Snelheid in pixels/simulatiestap DIM SHARED Snelheid(1 TO AANTALBALLEN) AS DOUBLE 'XPositie van het middelpunt van de bal DIM SHARED xPositie(1 TO AANTALBALLEN) AS DOUBLE 'YPositie van het middelpunt van de bal DIM SHARED yPositie(1 TO AANTALBALLEN) AS DOUBLE 'Kleur van de bal DIM SHARED Kleur(1 TO AANTALBALLEN) AS INTEGER 'XPositie van de bal op het scherm (double buffer) DIM SHARED XPositieScherm(1 TO AANTALBALLEN) AS INTEGER 'YPositie van de bal op het scherm (double buffer) DIM SHARED YPositieScherm(1 TO AANTALBALLEN) AS INTEGER 'VARIABELEN DIM SHARED StappenPerBeeld AS INTEGER DIM SHARED Wrijving AS DOUBLE 'PROGRAMMA CALL StartVideo CALL VraagStartWaarden CALL TekenTafel CALL TekenBallen DO CALL StootBal(1) CALL RolBallenTotStilstand LOOP FUNCTION BallenStil 'Deze functie kijkt of alle ballen stil liggen 'en retourneert of dit zo is. DIM TotaleSnelheid 'Zet de totale snelheid op nul aan het begin TotaleSnelheid = 0 'Tel voor elke bal de snelheid van de bal op bij de totale snelheid FOR I = 1 TO AANTALBALLEN TotaleSnelheid = TotaleSnelheid + Snelheid(I) NEXT I 'Als de ballen stil liggen retourneer waar anders onwaar IF TotaleSnelheid = 0 THEN BallenStil = TRUE ELSE BallenStil = FALSE END FUNCTION FUNCTION BerekenBeeldenPerSeconde DIM StartTijd AS INTEGER DIM Beelden AS INTEGER StartTijd = VAL(RIGHT$(TIME$, 2)) DO WHILE StartTijd = VAL(RIGHT$(TIME$, 2)) LOOP StartTijd = VAL(RIGHT$(TIME$, 2)) DO WHILE StartTijd = VAL(RIGHT$(TIME$, 2)) Beelden = Beelden + 1 'Bereken de nieuwe positie in een aantal stappen FOR I = 1 TO StappenPerBeeld 'In elke stap worden de ballen een beetje verplaatst CALL VerplaatsBallen 'In elke stap worden de botsingen van de ballen met de rand verwerkt CALL VerwerkRandBotsingen 'In elke stap worden de botsingen van de ballen met elkaar verwerkt CALL VerwerkBotsingen NEXT I LOOP BerekenBeeldenPerSeconde = Beelden END FUNCTION SUB BotsBallen (Bal1 AS INTEGER, Bal2 AS INTEGER) 'Hier moet worden geschreven wat er gebeurt bij een botsing 'van Bal1 met Bal2. Van deze ballen is bekend dat ze botsen '(overlappen) en de snelheid en richting moet worden aangepast. ' 'De volgende globale variabelen moeten worden gebruikt/aangepast: '- XPositie(Bal1) '- YPositie(Bal1) '- Snelheid(Bal1) '- Richting(Bal1) '- XPositie(Bal2) '- YPositie(Bal2) '- Snelheid(Bal2) '- Richting(Bal2) ' 'Bal2 ligt stil ' DIM dx AS DOUBLE DIM dy AS DOUBLE DIM RichtingBal1 AS DOUBLE DIM RichtingBal2 AS DOUBLE DIM SnelheidBal1 AS DOUBLE DIM SnelheidBal2 AS DOUBLE DIM NieuweRichtingBal1 AS DOUBLE DIM NieuweRichtingBal2 AS DOUBLE DIM NieuweSnelheidBal1 AS DOUBLE DIM NieuweSnelheidBal2 AS DOUBLE debug = FALSE 'debug = TRUE RichtingBal1 = Richting(Bal1) SnelheidBal1 = Snelheid(Bal1) RichtingBal2 = Richting(Bal2) SnelheidBal2 = Snelheid(Bal2) IF debug THEN LOCATE 1, 1 PRINT "=> start" PRINT "RichtingBal1: "; RichtingBal1 PRINT "SnelheidBal1: "; SnelheidBal1 PRINT "RichtingBal2: "; RichtingBal2 PRINT "SnelheidBal2: "; SnelheidBal2 END IF 'Trek de vector van Richting(Bal2) af van RichtingBal2 (x-x=0) RichtingBal2 = 0 SnelheidBal2 = 0 'Trek de vector van Richting(Bal2) af van RichtingBal1 dx = MyCOS(RichtingBal1) * SnelheidBal1 - MyCOS(Richting(Bal2)) * Snelheid(Bal2) dy = MySIN(RichtingBal1) * SnelheidBal1 - MySIN(Richting(Bal2)) * Snelheid(Bal2) IF dx >= 0 AND dy >= 0 THEN RichtingBal1 = 0 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy < 0 THEN RichtingBal1 = 180 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy >= 0 THEN RichtingBal1 = 180 - MyATAN(ABS(dy) / ABS(dx)) IF dx >= 0 AND dy < 0 THEN RichtingBal1 = 360 - MyATAN(ABS(dy) / ABS(dx)) IF dx = 0 AND dy >= 0 THEN RichtingBal1 = 0 IF dx = 0 AND dy < 0 THEN RichtingBal1 = 360 IF RichtingBal1 < 0 THEN RichtingBal1 = RichtingBal1 + 360 IF RichtingBal1 >= 360 THEN RichtingBal1 = RichtingBal1 - 360 SnelheidBal1 = SQR(ABS(dx) ^ 2 + ABS(dy) ^ 2) IF debug THEN PRINT "=> bal2 stil" PRINT "RichtingBal1: "; RichtingBal1 PRINT "SnelheidBal1: "; SnelheidBal1 PRINT "RichtingBal2: "; RichtingBal2 PRINT "SnelheidBal2: "; SnelheidBal2 END IF dx = xPositie(Bal2) - xPositie(Bal1) dy = yPositie(Bal2) - yPositie(Bal1) IF dx > 0 AND dy >= 0 THEN NieuweRichtingBal2 = 0 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy < 0 THEN NieuweRichtingBal2 = 180 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy >= 0 THEN NieuweRichtingBal2 = 180 - MyATAN(ABS(dy) / ABS(dx)) IF dx > 0 AND dy < 0 THEN NieuweRichtingBal2 = 360 - MyATAN(ABS(dy) / ABS(dx)) IF dx = 0 AND dy >= 0 THEN NieuweRichtingBal2 = 0 IF dx = 0 AND dy < 0 THEN NieuweRichtingBal2 = 360 IF NieuweRichtingBal2 < 0 THEN NieuweRichtingBal2 = NieuweRichtingBal2 + 360 IF NieuweRichtingBal2 >= 360 THEN NieuweRichtingBal2 = NieuweRichtingBal2 - 360 NieuweRichtingBal1 = RichtingBal1 - NieuweRichtingBal2 IF NieuweRichtingBal1 < 0 THEN NieuweRichtingBal1 = NieuweRichtingBal1 + 360 IF NieuweRichtingBal1 >= 360 THEN NieuweRichtingBal1 = NieuweRichtingBal1 - 360 IF NieuweRichtingBal1 >= 180 THEN NieuweRichtingBal1 = NieuweRichtingBal2 - 90 ELSE NieuweRichtingBal1 = NieuweRichtingBal2 + 90 END IF IF NieuweRichtingBal1 < 0 THEN NieuweRichtingBal1 = NieuweRichtingBal1 + 360 IF NieuweRichtingBal1 >= 360 THEN NieuweRichtingBal1 = NieuweRichtingBal1 - 360 NieuweSnelheidBal1 = ABS(MySIN(ABS(RichtingBal1 - NieuweRichtingBal2)) * SnelheidBal1) NieuweSnelheidBal2 = ABS(MyCOS(ABS(RichtingBal1 - NieuweRichtingBal2)) * SnelheidBal1) IF debug THEN PRINT "=> na botsing stille bal" PRINT "NieuweRichtingBal1: "; NieuweRichtingBal1 PRINT "NieuweSnelheidBal1: "; NieuweSnelheidBal1 PRINT "NieuweRichtingBal2: "; NieuweRichtingBal2 PRINT "NieuweSnelheidBal2: "; NieuweSnelheidBal2 END IF 'Tel de vector van Richting(Bal2) op bij NieuweRichtingBal1 en NieuweRichtingBal2 dx = MyCOS(NieuweRichtingBal1) * NieuweSnelheidBal1 + MyCOS(Richting(Bal2)) * Snelheid(Bal2) dy = MySIN(NieuweRichtingBal1) * NieuweSnelheidBal1 + MySIN(Richting(Bal2)) * Snelheid(Bal2) IF dx > 0 AND dy >= 0 THEN NieuweRichtingBal1 = 0 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy < 0 THEN NieuweRichtingBal1 = 180 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy >= 0 THEN NieuweRichtingBal1 = 180 - MyATAN(ABS(dy) / ABS(dx)) IF dx > 0 AND dy < 0 THEN NieuweRichtingBal1 = 360 - MyATAN(ABS(dy) / ABS(dx)) IF dx = 0 AND dy >= 0 THEN NieuweRichtingBal1 = 0 IF dx = 0 AND dy < 0 THEN NieuweRichtingBal1 = 360 IF NieuweRichtingBal1 < 0 THEN NieuweRichtingBal1 = NieuweRichtingBal1 + 360 IF NieuweRichtingBal1 >= 360 THEN NieuweRichtingBal1 = NieuweRichtingBal1 - 360 NieuweSnelheidBal1 = SQR(ABS(dx) ^ 2 + ABS(dy) ^ 2) dx = MyCOS(NieuweRichtingBal2) * NieuweSnelheidBal2 + MyCOS(Richting(Bal2)) * Snelheid(Bal2) dy = MySIN(NieuweRichtingBal2) * NieuweSnelheidBal2 + MySIN(Richting(Bal2)) * Snelheid(Bal2) IF dx > 0 AND dy >= 0 THEN NieuweRichtingBal2 = 0 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy < 0 THEN NieuweRichtingBal2 = 180 + MyATAN(ABS(dy) / ABS(dx)) IF dx < 0 AND dy >= 0 THEN NieuweRichtingBal2 = 180 - MyATAN(ABS(dy) / ABS(dx)) IF dx > 0 AND dy < 0 THEN NieuweRichtingBal2 = 360 - MyATAN(ABS(dy) / ABS(dx)) IF dx = 0 AND dy >= 0 THEN NieuweRichtingBal2 = 0 IF dx = 0 AND dy < 0 THEN NieuweRichtingBal2 = 360 IF NieuweRichtingBal2 < 0 THEN NieuweRichtingBal2 = NieuweRichtingBal2 + 360 IF NieuweRichtingBal2 >= 360 THEN NieuweRichtingBal2 = NieuweRichtingBal2 - 360 NieuweSnelheidBal2 = SQR(ABS(dx) ^ 2 + ABS(dy) ^ 2) IF debug THEN PRINT "=> na correctie stille bal2" PRINT "NieuweRichtingBal1: "; NieuweRichtingBal1 PRINT "NieuweSnelheidBal1: "; NieuweSnelheidBal1 PRINT "NieuweRichtingBal2: "; NieuweRichtingBal2 PRINT "NieuweSnelheidBal2: "; NieuweSnelheidBal2 PRINT "====================================" SLEEP END IF Richting(Bal1) = NieuweRichtingBal1 Richting(Bal2) = NieuweRichtingBal2 Snelheid(Bal1) = NieuweSnelheidBal1 Snelheid(Bal2) = NieuweSnelheidBal2 END SUB FUNCTION BotsTest (Bal1 AS INTEGER, Bal2 AS INTEGER) 'Deze functie kijkt of twee gegeven ballen elkaar raken 'en retourneert de gevonden waarde. DIM XAfstand AS DOUBLE DIM YAfstand AS DOUBLE DIM Afstand AS DOUBLE 'Bereken de afstand op de x-as. XAfstand = ABS(xPositie(Bal1) - xPositie(Bal2)) 'Bereken de afstand op de y-as. YAfstand = ABS(yPositie(Bal1) - yPositie(Bal2)) 'Met behulp van Pythagoras vinden we de afstand diagonaal. Afstand = SQR(XAfstand ^ 2 + YAfstand ^ 2) 'Treed er een botsing op? IF Afstand < 2 * STRAALBAL THEN 'Ja, deze functie retourneert waar. BotsTest = TRUE ELSE 'Nee, deze functie retourneert onwaar. BotsTest = FALSE END IF END FUNCTION FUNCTION MyACOS (Breuk AS DOUBLE) DIM ACOS IF Breuk = 0 THEN ACOS = 90 ELSE ACOS = MyATAN((SQR(1 - Breuk ^ 2)) / Breuk) IF Breuk < 0 THEN ACOS = ACOS + 180 END IF MyACOS = ACOS END FUNCTION FUNCTION MyASIN (Breuk AS DOUBLE) IF ABS(Breuk) = 1 THEN MyASIN = Breuk * 90 ELSE MyASIN = MyATAN(Breuk / SQR(1 - Breuk ^ 2)) END IF END FUNCTION FUNCTION MyATAN (Breuk AS DOUBLE) MyATAN = ATN(Breuk) * 180 / PI END FUNCTION FUNCTION MyCOS (Graden AS DOUBLE) MyCOS = COS(Graden * (PI / 180)) END FUNCTION FUNCTION MySIN (Graden AS DOUBLE) MySIN = SIN(Graden * (PI / 180)) END FUNCTION FUNCTION MyTAN (Graden AS DOUBLE) MyTAN = TAN(Graden * (PI / 180)) END FUNCTION SUB RolBallenTotStilstand 'Deze funtie laat de ballen rollen totdat ze stil liggen 'Zolang de ballen niet stil liggen WHILE NOT BallenStil 'Als de gebruiker ESC drukt is het programma afgelopen IF INKEY$ = CHR$(27) THEN SYSTEM 'Teken de ballen CALL TekenBallen 'Bereken de nieuwe positie in een aantal stappen FOR I = 1 TO StappenPerBeeld 'In elke stap worden de ballen een beetje verplaatst CALL VerplaatsBallen 'In elke stap worden de botsingen van de ballen met de rand verwerkt CALL VerwerkRandBotsingen 'In elke stap worden de botsingen van de ballen met elkaar verwerkt CALL VerwerkBotsingen NEXT I WEND END SUB SUB StartVideo 'De schermmodus wordt ingesteld op 640x480x16 (modus 12). SCREEN SCHERMMODUS 'Wacht tot de video gestart is SLEEP 1 'De achtergrond wordt mooi gevuld met de achtergrondkleur. PAINT (1, 1), ACHTERGRONDKLEUR 'Laat iets zien zodat de gebruiker weet dat het programma gestart is. LOCATE 15, 34 PRINT "Basic Biljart" END SUB SUB StootBal (Bal AS INTEGER) DIM Toets AS STRING DIM StootSnelheid AS INTEGER DIM StootRichting AS INTEGER 'Initiele stootrichting en snelheid 'Zouden beter kunnen, bijv richting naar dichtsbijzijnde bal StootRichting = 0 StootSnelheid = 10 'Zolang de gebruiker niet op Enter drukt blijf om invoer vragen WHILE NOT Toets = CHR$(13) 'Bescherm de extreme waarden IF StootRichting >= 360 THEN StootRichting = StootRichting - 360 IF StootRichting < 0 THEN StootRichting = StootRichting + 360 IF StootSnelheid < 1 THEN StootSnelheid = 1 IF StootSnelheid > 49 THEN StootSnelheid = 49 'Teken de keu CALL TekenKeuEnMikPunt(Bal, StootRichting, StootSnelheid) 'Wacht op een toets van de gebruiker DO Toets = INKEY$ LOOP WHILE Toets = "" 'Als de gebruiker een extended key (bv pijltjestoets) heeft gedrukt IF LEFT$(Toets, 1) = CHR$(0) THEN 'Sla de extended key op Toets = RIGHT$(Toets, 1) 'Als de extended key pijl-omhoog is IF Toets = CHR$(72) THEN 'Verlaag de stootsnelheid StootSnelheid = StootSnelheid - 1 END IF 'Als de extended key pijl-omlaag is IF Toets = CHR$(80) THEN 'Verhoog de stootsnelheid StootSnelheid = StootSnelheid + 1 END IF 'Als de extended key pijl-links is IF Toets = CHR$(75) THEN 'Verlaag de stootrichting (met 1 graad) StootRichting = StootRichting - 1 END IF 'Als de extended key pijl-rechts is IF Toets = CHR$(77) THEN 'Verhoog de stootrichting (met 1 graad) StootRichting = StootRichting + 1 END IF 'Als de toets niet extended is ELSE 'Als de toets ESC is IF Toets = CHR$(27) THEN 'Stop het programma SYSTEM END IF END IF WEND 'De snelheid is relatief tov het aantal StappenPerBeeld Snelheid(Bal) = (StootSnelheid / 10) / StappenPerBeeld 'Sla de richting op bij deze bal Richting(Bal) = StootRichting END SUB SUB TekenBallen DIM NieuweXPositie AS INTEGER DIM NieuweYPositie AS INTEGER 'Loop alle ballen af en verwijder ze en teken ze opnieuw als dit nodig is. FOR I = 1 TO AANTALBALLEN 'Rond de nieuwe posities af op gehele getallen NieuweXPositie = xPositie(I) NieuweYPositie = yPositie(I) 'Als de bal niet al op de juiste positie staat. IF NOT (XPositieScherm(I) = NieuweXPositie AND YPositieScherm(I) = NieuweYPositie) THEN 'Verwijder de bal van het scherm. CIRCLE (XPositieScherm(I), YPositieScherm(I)), STRAALBAL, LAKENKLEUR PAINT (XPositieScherm(I), YPositieScherm(I)), LAKENKLEUR 'Sla de nieuwe positie op. XPositieScherm(I) = xPositie(I) YPositieScherm(I) = yPositie(I) 'Teken de bal op het scherm. CIRCLE (XPositieScherm(I), YPositieScherm(I)), STRAALBAL - 1, Kleur(I) PAINT (XPositieScherm(I), YPositieScherm(I)), Kleur(I) END IF NEXT I END SUB SUB TekenKeu (Bal AS INTEGER, Snelheid AS INTEGER) STATIC BalGetekend AS INTEGER STATIC VorigeSnelheid AS INTEGER 'Teken de bal IF NOT BalGetekend THEN CIRCLE (230, 30), 25, Kleur(Bal) PAINT (230, 30), Kleur(Bal) LINE (140, 43)-(200, 43), 2, , &H1 LINE (140, 44)-(200, 44), 2, , &H101 LINE (142, 45)-(200, 45), 2 BalGetekend = TRUE END IF 'Teken de keu IF NOT Snelheid = VorigeSnelheid THEN IF NOT VorigeSnelheid = 0 THEN LINE (1, 19)-(150 - VorigeSnelheid, 41), ACHTERGRONDKLEUR, BF LINE (150 - VorigeSnelheid, 20)-(190 - VorigeSnelheid, 40), ACHTERGRONDKLEUR, BF LINE (190 - VorigeSnelheid, 20)-(200 - VorigeSnelheid, 20), ACHTERGRONDKLEUR LINE (190 - VorigeSnelheid, 40)-(200 - VorigeSnelheid, 40), ACHTERGRONDKLEUR CIRCLE (178 - VorigeSnelheid, 30), 25, ACHTERGRONDKLEUR, (360 - 23) * (PI / 180), 23 * (PI / 180) END IF LINE (1, 19)-(150 - Snelheid, 41), 6, BF LINE (150 - Snelheid, 20)-(190 - Snelheid, 40), 15, BF LINE (190 - Snelheid, 20)-(200 - Snelheid, 20), 15 LINE (190 - Snelheid, 40)-(200 - Snelheid, 40), 15 CIRCLE (178 - Snelheid, 30), 25, 15, (360 - 23) * (PI / 180), 23 * (PI / 180) VorigeSnelheid = Snelheid END IF END SUB SUB TekenKeuEnMikPunt (Bal AS INTEGER, Richting AS INTEGER, Snelheid AS INTEGER) DIM RichtingLinksBoven AS DOUBLE DIM RichtingLinksOnder AS DOUBLE DIM RichtingRechtsBoven AS DOUBLE DIM RichtingRechtsOnder AS DOUBLE STATIC xKeu AS INTEGER STATIC yKeu AS INTEGER STATIC KeuPositie AS INTEGER CALL TekenKeu(Bal, Snelheid) CALL TekenMikPunt(xKeu, yKeu, KeuPositie, TAFELKLEUR) RichtingLinksBoven = 180 + MyATAN((yPositie(Bal) - LAKENBOVEN) / (xPositie(Bal) - LAKENLINKS)) RichtingLinksOnder = 90 + MyATAN((xPositie(Bal) - LAKENLINKS) / (LAKENONDER - yPositie(Bal))) RichtingRechtsBoven = 270 + MyATAN((LAKENRECHTS - xPositie(Bal)) / (yPositie(Bal) - LAKENBOVEN)) RichtingRechtsOnder = 0 + MyATAN((LAKENONDER - yPositie(Bal)) / (LAKENRECHTS - xPositie(Bal))) IF (CDBL(Richting) > RichtingRechtsBoven AND CDBL(Richting) <= 360) OR (CDBL(Richting) >= 0 AND CDBL(Richting) <= RichtingRechtsOnder) THEN xKeu = LAKENRECHTS + 1 yKeu = yPositie(Bal) + MyTAN(CDBL(Richting)) * (LAKENRECHTS - xPositie(Bal)) KeuPositie = RECHTS END IF IF CDBL(Richting) > RichtingLinksBoven AND CDBL(Richting) <= RichtingRechtsBoven THEN xKeu = xPositie(Bal) + MyTAN(270 + CDBL(Richting)) * (yPositie(Bal) - LAKENBOVEN) yKeu = LAKENBOVEN - 1 KeuPositie = BOVEN END IF IF Richting > RichtingLinksOnder AND Richting <= RichtingLinksBoven THEN xKeu = LAKENLINKS - 1 yKeu = yPositie(Bal) - MyTAN(CDBL(Richting) - 180) * (xPositie(Bal) - LAKENLINKS) KeuPositie = LINKS END IF IF Richting > RichtingRechtsOnder AND Richting <= RichtingLinksOnder THEN xKeu = xPositie(Bal) - MyTAN(90 + CDBL(Richting)) * (LAKENONDER - yPositie(Bal)) yKeu = LAKENONDER + 1 KeuPositie = ONDER END IF CALL TekenMikPunt(xKeu, yKeu, KeuPositie, MIKPUNTKLEUR) 'LOCATE 1, 1 'PRINT RichtingLinksBoven 'PRINT RichtingLinksOnder 'PRINT RichtingRechtsBoven 'PRINT RichtingRechtsOnder END SUB SUB TekenMikPunt (xKeu AS INTEGER, yKeu AS INTEGER, Positie AS INTEGER, Kleur AS INTEGER) IF Positie = RECHTS THEN LINE (xKeu, yKeu)-(xKeu + LENGTEMIKPUNT, yKeu - LENGTEMIKPUNT / 2), Kleur LINE (xKeu, yKeu)-(xKeu + LENGTEMIKPUNT, yKeu + LENGTEMIKPUNT / 2), Kleur LINE (xKeu + LENGTEMIKPUNT, yKeu - LENGTEMIKPUNT / 2)-(xKeu + LENGTEMIKPUNT, yKeu + LENGTEMIKPUNT / 2), Kleur PAINT (xKeu + LENGTEMIKPUNT - 1, yKeu), Kleur END IF IF Positie = BOVEN THEN LINE (xKeu, yKeu)-(xKeu - LENGTEMIKPUNT / 2, yKeu - LENGTEMIKPUNT), Kleur LINE (xKeu, yKeu)-(xKeu + LENGTEMIKPUNT / 2, yKeu - LENGTEMIKPUNT), Kleur LINE (xKeu - LENGTEMIKPUNT / 2, yKeu - LENGTEMIKPUNT)-(xKeu + LENGTEMIKPUNT / 2, yKeu - LENGTEMIKPUNT), Kleur PAINT (xKeu, yKeu - LENGTEMIKPUNT + 1), Kleur END IF IF Positie = LINKS THEN LINE (xKeu, yKeu)-(xKeu - LENGTEMIKPUNT, yKeu - LENGTEMIKPUNT / 2), Kleur LINE (xKeu, yKeu)-(xKeu - LENGTEMIKPUNT, yKeu + LENGTEMIKPUNT / 2), Kleur LINE (xKeu - LENGTEMIKPUNT, yKeu - LENGTEMIKPUNT / 2)-(xKeu - LENGTEMIKPUNT, yKeu + LENGTEMIKPUNT / 2), Kleur PAINT (xKeu - LENGTEMIKPUNT + 1, yKeu), Kleur END IF IF Positie = ONDER THEN LINE (xKeu, yKeu)-(xKeu - LENGTEMIKPUNT / 2, yKeu + LENGTEMIKPUNT), Kleur LINE (xKeu, yKeu)-(xKeu + LENGTEMIKPUNT / 2, yKeu + LENGTEMIKPUNT), Kleur LINE (xKeu - LENGTEMIKPUNT / 2, yKeu + LENGTEMIKPUNT)-(xKeu + LENGTEMIKPUNT / 2, yKeu + LENGTEMIKPUNT), Kleur PAINT (xKeu, yKeu + LENGTEMIKPUNT - 1), Kleur END IF END SUB SUB TekenTafel 'De achtergrond wordt mooi gevuld met de achtergrondkleur. LINE (0, 0)-(SCHERMBREEDTE, SCHERMHOOGTE), ACHTERGRONDKLEUR, BF 'Nu wordt de pooltafel getekend LINE (LAKENLINKS - TAFELBANDBREEDTE, LAKENBOVEN - TAFELBANDBREEDTE)-(LAKENRECHTS + TAFELBANDBREEDTE, LAKENBOVEN - TAFELBANDBREEDTE), TAFELKLEUR LINE (LAKENLINKS - TAFELBANDBREEDTE, LAKENBOVEN - TAFELBANDBREEDTE)-(LAKENLINKS - TAFELBANDBREEDTE, LAKENONDER + TAFELBANDBREEDTE), TAFELKLEUR LINE (LAKENLINKS - TAFELBANDBREEDTE, LAKENONDER + TAFELBANDBREEDTE)-(LAKENRECHTS + TAFELBANDBREEDTE, LAKENONDER + TAFELBANDBREEDTE), TAFELKLEUR LINE (LAKENRECHTS + TAFELBANDBREEDTE, LAKENBOVEN - TAFELBANDBREEDTE)-(LAKENRECHTS + TAFELBANDBREEDTE, LAKENONDER + TAFELBANDBREEDTE), TAFELKLEUR PAINT (LAKENLINKS - TAFELBANDBREEDTE + 1, LAKENBOVEN - TAFELBANDBREEDTE + 1), TAFELKLEUR 'Het laken krijgt de lakenkleur LINE (LAKENLINKS, LAKENBOVEN)-(LAKENRECHTS, LAKENBOVEN), LAKENKLEUR LINE (LAKENLINKS, LAKENBOVEN)-(LAKENLINKS, LAKENONDER), LAKENKLEUR LINE (LAKENLINKS, LAKENONDER)-(LAKENRECHTS, LAKENONDER), LAKENKLEUR LINE (LAKENRECHTS, LAKENBOVEN)-(LAKENRECHTS, LAKENONDER), LAKENKLEUR PAINT (LAKENLINKS + 1, LAKENBOVEN + 1), LAKENKLEUR END SUB SUB VerplaatsBallen DIM XSnelheid AS DOUBLE DIM YSnelheid AS DOUBLE 'Loop alle ballen af en verplaats ze. FOR I = 1 TO AANTALBALLEN 'SOSCASTOA => Cos(x) = Aanliggende/Schuine 'Cos(Richting) = XSnelheid/Snelheid 'XSnelheid = Cos(Richting)*Snelheid XSnelheid = MyCOS(Richting(I)) * Snelheid(I) xPositie(I) = xPositie(I) + XSnelheid 'SOSCASTOA => Sin(x) = Overstaande/Schuine 'Sin(Richting) = YSnelheid/Snelheid 'YSnelheid = Sin(Richting)*Snelheid YSnelheid = MySIN(Richting(I)) * Snelheid(I) yPositie(I) = yPositie(I) + YSnelheid 'Pas Wrijving toe Snelheid(I) = Snelheid(I) - (Wrijving / StappenPerBeeld) IF Snelheid(I) < 0 THEN Snelheid(I) = 0 NEXT I END SUB SUB VerwerkBotsingen DIM Bal1 AS INTEGER DIM Bal2 AS INTEGER FOR Bal1 = 1 TO AANTALBALLEN FOR Bal2 = 1 TO AANTALBALLEN 'Een bal botst altijd met zichzelf, maar 'daarin zijn we niet geinteresseerd. IF NOT Bal1 = Bal2 THEN IF BotsTest(Bal1, Bal2) = TRUE THEN BotsBallen Bal1, Bal2 'Einde van deze routine om opnieuw botsen 'van dit paar ballen te voorkomen. EXIT SUB END IF END IF NEXT Bal2 NEXT Bal1 END SUB SUB VerwerkRandBotsingen 'Hier worden botsingen van de ballen met de randen gecontroleerd en 'verwerkt. FOR I = 1 TO AANTALBALLEN 'Bevindt de bal zich op een illegale positie? (Links) IF (xPositie(I) - STRAALBAL) < LAKENLINKS THEN 'Ja, dan is deze gebotst en moeten we de X richting omdraaien. Richting(I) = (Richting(I) - 180) * -1 'Als richting nu negatief is moeten we dat corrigeren. IF Richting(I) < 0 THEN Richting(I) = Richting(I) + 360 END IF END IF 'Bevindt de bal zich op een illegale positie? (Rechts) IF (xPositie(I) + STRAALBAL) >= LAKENRECHTS THEN 'Ja, dan is deze gebotst en moeten we de X richting omdraaien. Richting(I) = (Richting(I) - 180) * -1 'Als richting nu negatief is moeten we dat corrigeren. IF Richting(I) < 0 THEN Richting(I) = Richting(I) + 360 END IF END IF 'Bevindt de bal zich op een illegale positie? (Boven) IF (yPositie(I) - STRAALBAL) < LAKENBOVEN THEN 'Ja, dan is deze gebotst en moeten we de Y richting omdraaien. Richting(I) = Richting(I) * -1 'Als richting nu negatief is moeten we dat corrigeren. IF Richting(I) < 0 THEN Richting(I) = Richting(I) + 360 END IF END IF 'Bevindt de bal zich op een illegale positie? (Onder) IF (yPositie(I) + STRAALBAL) >= LAKENONDER THEN 'Ja, dan is deze gebotst en moeten we de Y richting omdraaien. Richting(I) = Richting(I) * -1 'Als richting nu negatief is moeten we dat corrigeren. IF Richting(I) < 0 THEN Richting(I) = Richting(I) + 360 END IF END IF NEXT I END SUB SUB VraagStartWaarden 'Deze subroutine geeft alle variabelen een startwaarde. 'We beginnen met de reeks variabelen: FOR I = 1 TO AANTALBALLEN Richting(I) = 0 Snelheid(I) = 0 'Tijdelijke oplossing voor de startposities/kleur van de ballen: xPositie(I) = LAKENLINKS + (I) * (LAKENBREEDTE / (AANTALBALLEN + 1)) yPositie(I) = LAKENBOVEN + LAKENHOOGTE / 2 XPositieScherm(I) = xPositie(I) - 1 YPositieScherm(I) = yPositie(I) - 1 Snelheid(I) = 0 Kleur(I) = 16 - I NEXT I 'De Random Number Generator wordt gevoerd met een seed van de timer. RANDOMIZE TIMER 'Initialiseer het aantal stappen van de simulatie. StappenPerBeeld = 10 'Bereken het huidig aantal beelden per seconden en corrigeer het 'aantal stappen per beeld aannemend dat deze een lineair verband hebben StappenPerBeeld = (StappenPerBeeld * BerekenBeeldenPerSeconde) / BEELDENPERSECONDE 'Geef Wrijving een waarde Wrijving = .01 / StappenPerBeeld END SUB