atarionline.pl BASIC - Starfield - Forum Atarum

Jeśli chcesz wziąć udział w dyskusjach na forum - zaloguj się. Jeżeli nie masz loginu - poproś o członkostwo.

  • :
  • :

Vanilla 1.1.4 jest produktem Lussumo. Więcej informacji: Dokumentacja, Forum.

    • 1: CommentAuthorxxl
    • CommentTime10 Aug 2019
     
    napisałem coś takiego w BASICu. Działa ... no... prawie stoi. Można przekopiować tekst do Altirry i samemu spróbować.

    pytanie: może ma ktoś lepszy algorytm albo poprawi ten tak, żeby działał chociaż wolno ale nie żenująco wolno.



    10 STAR=50:SPEED=5:ROZX=159:ROZY=95:DEPTH=ROZX
    20 DIM X(STAR),Y(STAR),Z(STAR),XEKR(STAR),YEKR(STAR),ISON(STAR)

    30 FOR A=1 TO STAR:GOSUB 500:Z(A)=INT(DEPTH*RND(0)):NEXT A

    40 FOR A=1 TO STAR
    50 Z(A)=Z(A)-SPEED
    60 IF Z(A)<=1 THEN GOSUB 500: Z(A)=DEPTH
    70 X=(X(A)*DEPTH)/Z(A)+(ROZX/2): IF X<0 OR X>ROZX THEN GOSUB 500: Z(A)=DEPTH: GOTO 100
    80 Y=(Y(A)*DEPTH)/Z(A)+(ROZY/2): IF Y<0 OR Y>ROZY THEN GOSUB 500: Z(A)=DEPTH: GOTO 100
    90 XEKR(A)=X:YEKR(A)=Y:ISON(A)=1
    100 NEXT A

    110 GRAPHICS 7+16: COLOR 1

    120 FOR A=1 TO STAR
    130 IF ISON(A)=1 THEN PLOT XEKR(A),YEKR(A)
    140 NEXT A

    150 GOTO 40

    500 REM new star
    510 X(A)=INT(ROZX*RND(0)-(ROZX/2)): REM od -(szerokosc/2) do +(szerokosc/2)
    520 Y(A)=INT(ROZY*RND(0)-(ROZY/2))
    530 ISON(A)=0
    540 RETURN
    • 2: CommentAuthorgorgh
    • CommentTime10 Aug 2019
     
    xxl znowu koduje, mamo nastaw budyń!
    • 3:
       
      CommentAuthorTheFender
    • CommentTime10 Aug 2019 zmieniony
     
    xxl robi w basicu, to na pewno jakaś prowokacja.




    :D
    • 4:
       
      CommentAuthorhospes
    • CommentTime10 Aug 2019
     
    xxl: teraz prosimy pierwsze wprawki w STOSie;)
    • 5: CommentAuthorurborg
    • CommentTime10 Aug 2019
     
    Czały czas skaczesz do procedury z linii 500. Przesuń ją jak najblizej początku listingu, bo przy każdym skoku interpreter szuka linii do której skaczesz zaczynając od początku listingu. No i upchnij całą procedurę w jednym wierszu kodu. A jesli pamieć nie jest problemem to wogóle nie wyskakuj z pętli tylko wstaw tą procedurę wewnątrz pętli.
    • 6: CommentAuthorxxl
    • CommentTime10 Aug 2019
     
    powiedzialbym tak... nawet 10x przyspieszenie to malo. tu potrzeba innego podejscia chyba
    • 7: CommentAuthorpirx
    • CommentTime10 Aug 2019
     
    ale to ma być czysty bejzik?
    • 8: CommentAuthorxxl
    • CommentTime10 Aug 2019
     
    przerobienie tego na asma da kopa ale nie o to chodzi.

    chcialbym poznac sprtne sposoby na przyspieszenie tego algorytmu w basicu lub inny algorytm.
    • 9:
       
      CommentAuthorlarek
    • CommentTime11 Aug 2019 zmieniony
     
    Wersja (chyba) zgodna z pierwowzorem:
    10 GOTO 100

    20 FOR A=1 TO STAR:Z(A)=Z(A)-SPEED
    30 IF Z(A)<=1 THEN X(A)=INT(ROZX*RND(0)-ROZX2):Y(A)=INT(ROZY*RND(0)-ROZY2):Z(A)=DEPTH
    40 X=(X(A)*DEPTH)/Z(A)+ROZX2
    50 IF X<0 OR X>ROZX THEN X(A)=INT(ROZX*RND(0)-ROZX2):Y(A)=INT(ROZY*RND(0)-ROZY2):Z(A)=DEPTH: GOTO 90
    60 Y=(Y(A)*DEPTH)/Z(A)+ROZY2
    70 IF Y<0 OR Y>ROZY THEN X(A)=INT(ROZX*RND(0)-ROZX2):Y(A)=INT(ROZY*RND(0)-ROZY2):Z(A)=DEPTH: GOTO 90
    80 XEKR(A)=X:YEKR(A)=Y:COLOR 0:PLOT XOLD(A),YOLD(A):COLOR 1:PLOT XEKR(A),YEKR(A):XOLD(A)=X:YOLD(A)=Y
    90 NEXT A:GOTO 20

    100 STAR=50:SPEED=5:ROZX=159:ROZY=95:DEPTH=ROZX:ROZX2=ROZX/2:ROZY2=ROZY/2
    120 DIM X(STAR),Y(STAR),Z(STAR),XEKR(STAR),YEKR(STAR),ISON(STAR),XOLD(STAR),YOLD(STAR)
    130 FOR A=1 TO STAR:X(A)=INT(ROZX*RND(0)-ROZX2):Y(A)=INT(ROZY*RND(0)-ROZY2):Z(A)=INT(DEPTH*RND(0)):NEXT A
    140 GRAPHICS 7+16: GOTO 20




    Wersja nie wiem czy w 100% zgodna:
    10 GOTO 100

    20 F.A=1TO STAR:Z(A)=Z(A)-SPEED:IF Z(A)<=1THEN X(A)=INT(ROZX*RND(0)-ROZX2):Y(A)=INT(ROZY*RND(0)-ROZY2):Z(A)=DEPTH
    30 X=(X(A)*DEPTH)/Z(A)+ROZX2:IF X<0 OR X>ROZX THEN X(A)=INT(ROZX*RND(0)-ROZX2):Z(A)=DEPTH:NEXT A:GOTO 20
    40 Y=(Y(A)*DEPTH)/Z(A)+ROZY2:IF Y<0 OR Y>ROZY THEN Y(A)=INT(ROZY*RND(0)-ROZY2):Z(A)=DEPTH:NEXT A:GOTO 20
    50 XEKR(A)=X:YEKR(A)=Y:C.0:PLOT XOLD(A),YOLD(A):C.1:PLOT XEKR(A),YEKR(A):XOLD(A)=X:YOLD(A)=Y:NEXT A:GOTO 20

    100 STAR=50:SPEED=5:ROZX=159:ROZY=95:DEPTH=ROZX:ROZX2=ROZX/2:ROZY2=ROZY/2
    120 DIM X(STAR),Y(STAR),Z(STAR),XEKR(STAR),YEKR(STAR),ISON(STAR),XOLD(STAR),YOLD(STAR)
    130 FOR A=1 TO STAR:X(A)=INT(ROZX*RND(0)-ROZX2):Y(A)=INT(ROZY*RND(0)-ROZY2):Z(A)=INT(DEPTH*RND(0)):NEXT A
    140 GRAPHICS 7+16: GOTO 20


    • 10: CommentAuthorjakubd
    • CommentTime11 Aug 2019
     
    Odpaliłem to z czystej ciekawości w trybie warp Altirry da się oglądać :)
    Możliwości optymalizacji samego kodu jest mnóstwo:
    1. Pozbyć się dzieleń - policzyć je raz, a dobrze
    2. SUBy wywalić, zrobić inline
    3. Zastąpić niewydajne zmiennoprzecinkowe RND kawałkiem assemblera, czy choćby odczytem peek z pamięci POKEY.
    4. Z pewnością warto malować na drugim ekranie i przełączać gotowe pamięci ekranu - nie będzie widać rysowania i migania.

    Jednak to wszystko za mało, żeby w ten sposób uzyskać płynność zbliżoną choćby do tego co daje tryb warp przy 50 gwiazdach.

    Zamiast oczywistej matematyki trzeba użyć sztuczek, które emulują oczekiwany efekt.

    Propozycja 1, która skraca obliczenia o jakieś 20-25%: zrobić obliczenia dla 1/4 ekranu i rozłożyć to na pozostałe ćwiartki symetrycznie i zrobić tak, żeby było potrzebne tylko dodawanie.

    Z pewnością trzeba pomyśleć nad inną heurystyką, która jakoś skróci obliczenia - w Atari Basic warto maksymalnie redukować dzielenia, ograniczać mnożenia.

    To tak na początek.
    • 11: CommentAuthorjakubd
    • CommentTime11 Aug 2019
     
    Widzę, że larek po prostu to zrobił, zamiast gadać :) Ale i tak prędkość jest tego nadal żenująca (potwierdzam, wersja 2 daje inny, choć zbliżony, rezultat) i dlatego podejście trzeba po prostu zmienić diametralnie.
    • 12: CommentAuthorpirx
    • CommentTime11 Aug 2019
     
    w czystym beju da się zanimować najwyżej pixel czy dwa na ramkę, czego by nie wymyślać.
    można to zaczarować tak, jak w 10linerze carrera autorstwa dmsc, czyli mieć prekalkulowane wiersze z kropkami w odpowiednich miejscach i tylko budować dl.
    • 13: CommentAuthorxxl
    • CommentTime11 Aug 2019
     
    modyfikacja kodu Larka: dodalem sprawdzenie czy na pewno rysowac punkty w kolorze 0:

    10 GOTO 100

    20 FOR A=1 TO STAR
    30 Z(A)=Z(A)-SPEED:IF Z(A)<=1 THEN 95
    40 X=(X(A)*DEP)/Z(A)+RX2:IF X<0 OR X>RX THEN 95
    60 Y=(Y(A)*DEP)/Z(A)+RY2:IF Y<0 OR Y>RY THEN 95
    80 IF IO(A)=1 THEN COLOR 0:PLOT XE(A),YE(A)
    81 XE(A)=X:YE(A)=Y:IO(A)=1:COLOR 1:PLOT X,Y
    90 NEXT A:GOTO 20

    95 IF IO(A)=1 THEN IO(A)=0:C.0:PL.XE(A),YE(A)
    96 X(A)=RX*RND(0)-RX2:Y(A)=RY*RND(0)-RY2:Z(A)=DEP:NEXT A:GOTO 20

    100 STAR=50:SPEED=5:RX=159:RY=95:DEP=RX:RX2=RX/2:RY2=RY/2
    120 DIM X(STAR),Y(STAR),Z(STAR),XE(STAR),YE(STAR),IO(STAR)
    130 F.A=1 TO STAR:X(A)=RX*RND(0)-RX2:Y(A)=RY*RND(0)-RY2:Z(A)=DEP*RND(0):IO(A)=0:N.A
    140 GRAPHICS 7+16: GOTO 20
    • 14:
       
      CommentAuthorKaz
    • CommentTime11 Aug 2019
     
    Podpowiem, że można używać znacznika [ code ] oraz domknięcia [ / code] (bez spacji oczywiście) i wtedy będzie się pojawiać wyróżnienie programu oraz jego możliwość zapisania w formacie ATASCII.

    10 GOTO 100

    20 FOR A=1 TO STAR
    30 Z(A)=Z(A)-SPEED:IF Z(A)<=1 THEN 95
    40 X=(X(A)*DEP)/Z(A)+RX2:IF X<0 OR X>RX THEN 95
    60 Y=(Y(A)*DEP)/Z(A)+RY2:IF Y<0 OR Y>RY THEN 95
    80 IF IO(A)=1 THEN COLOR 0:PLOT XE(A),YE(A)
    81 XE(A)=X:YE(A)=Y:IO(A)=1:COLOR 1:PLOT X,Y
    90 NEXT A:GOTO 20

    95 IF IO(A)=1 THEN IO(A)=0:C.0:PL.XE(A),YE(A)
    96 X(A)=RX*RND(0)-RX2:Y(A)=RY*RND(0)-RY2:Z(A)=DEP:NEXT A:GOTO 20

    100 STAR=50:SPEED=5:RX=159:RY=95:DEP=RX:RX2=RX/2:RY2=RY/2
    120 DIM X(STAR),Y(STAR),Z(STAR),XE(STAR),YE(STAR),IO(STAR)
    130 F.A=1 TO STAR:X(A)=RX*RND(0)-RX2:Y(A)=RY*RND(0)-RY2:Z(A)=DEP*RND(0):IO(A)=0:N.A
    140 GRAPHICS 7+16: GOTO 20
    • 15: CommentAuthorxxl
    • CommentTime11 Aug 2019 zmieniony
     
    dzieki. tak dla przypomnienia gdzie taki efekt smiga:
    Gyruss, Star Wars, Star Raiders II, Star Raiders, Blaster
    • 16: CommentAuthortbxx
    • CommentTime11 Aug 2019
     
    Hmm, ale tych gier nie robili w BASIC'u ;)
    PS. ja sobie myślałem że XXL by sobie poradził z konwersją:

    a tu kilka kropek stanowi problem ;P
    • 17: CommentAuthortebe
    • CommentTime11 Aug 2019
     
    w przykładach do MadPascala też śmiga bo jest realizowany na całkowitych a nie rzeczywistych zmiennych

    uses crt, fastgraph;

    const star_max = 64;
    star_speed = 2;

    w = 160;
    h = 96;

    cx = w div 2;
    cy = h div 2;

    ds = 3;

    var star_x, star_y, px, py: array [0..star_max-1] of byte;
    star_s: array [0..star_max-1] of shortint;

    x, y, i: byte;


    procedure init;
    begin
    randomize;

    x:=w shr 1;
    y:=h shr 1;

    for i:=0 to star_max-1 do begin
    star_x[i]:=random(0);
    star_y[i]:=random(0);
    star_s[i]:=random(0);
    end;

    end;


    procedure anim;

    function test: Boolean;
    begin

    Result := ((px[i]<cx-ds) or (px[i]>cx+ds)) and ((py[i]<cy-ds) or (py[i]>cy+ds));

    end;

    begin

    for i:=0 to star_max-1 do begin

    if test then begin

    SetColor(0);
    PutPixel(px[i], py[i]);

    end;

    dec(star_s[i], star_speed);
    if (star_s[i] < 0) then star_s[i]:=random(64);

    px[i] := x+(star_x[i] div star_s[i]);
    py[i] := y+(star_y[i] div star_s[i]);


    if test then begin

    SetColor(1);
    PutPixel(px[i], py[i]);

    end;

    end;

    end;



    begin

    InitGraph(7+16);

    init;

    repeat
    pause;
    anim;
    until keypressed;

    end.
    • 18: CommentAuthorxxl
    • CommentTime11 Aug 2019
     
    mozesz to skompilowac lub podac sciezke w przykladach madpascala gdzie to znalezc?
    • 19: CommentAuthortebe
    • CommentTime11 Aug 2019
     
    PAS, OBX
    • 20: CommentAuthorxxl
    • CommentTime11 Aug 2019
     
    przelecialem basicowy program TurboBasicCompilerem:
    • 21: CommentAuthorxxl
    • CommentTime11 Aug 2019 zmieniony
     
    takie tam uproszeczenia i dodanie zmiane koloru wiazdy gdy jest blisko

    10 GOTO 100

    20 FOR A=1 TO STAR
    30 ZA=Z(A)-SPEED:IF ZA<=1 THEN 95
    40 X=XD(X(A)+RX2)/ZA+RX2:IF X<0 OR X>RX THEN 95
    60 Y=YD(Y(A)+RY2)/ZA+RY2:IF Y<0 OR Y>RY THEN 95
    80 IF IO(A)=1 THEN COLOR 0:PLOT XE(A),YE(A)
    81 Z(A)=ZA:XE(A)=X:YE(A)=Y:IO(A)=1:COLOR 2: IF ZA>DEP2 THEN COLOR 1
    82 PLOT X,Y
    90 NEXT A:GOTO 20

    95 IF IO(A)=1 THEN IO(A)=0:C.0:PL.XE(A),YE(A)
    96 X(A)=RX*RND(0)-RX2:Y(A)=RY*RND(0)-RY2:Z(A)=DEP:GOTO 90

    100 STAR=10:SPEED=5:RX=159:RY=95:DEP=RX:RX2=RX/2:RY2=RY/2:DEP2=DEP/2
    120 DIM X(STAR),Y(STAR),Z(STAR),XE(STAR),YE(STAR),IO(STAR),XD(RX),YD(RY)
    130 F.A=1 TO STAR:X(A)=RX*RND(0)-RX2:Y(A)=RY*RND(0)-RY2:Z(A)=DEP*RND(0):IO(A)=0:N.A
    131 FOR A=1 TO RX: XD(A)=(A-RX2)*DEP: NEXT A
    132 FOR A=1 TO RY: YD(A)=(A-RY2)*DEP: NEXT A
    140 GRAPHICS 7+16: GOTO 20
    • 22: CommentAuthorpirx
    • CommentTime12 Aug 2019 zmieniony
     
    jak już walczysz w turbobeju to może tak:
    STAR=10:SPEED=5:RX=159:RY=95:DEP=RX:RX2=RX/2:RY2=RY/2:DEP2=DEP/2
    DIM X(STAR),Y(STAR),Z(STAR),XE(STAR),YE(STAR),IO(STAR),XD(RX),YD(RY)
    F.A=1 TO STAR:X(A)=RAND(RX)-RX2:Y(A)=RAND(RY)-RY2:Z(A)=RAND(DEP):IO(A)=0:N.A
    FOR A=1 TO RX: XD(A)=(A-RX2)*DEP: NEXT A
    FOR A=1 TO RY: YD(A)=(A-RY2)*DEP: NEXT A
    GRAPHICS 7+16

    do
    FOR A=1 TO STAR
    ZA=Z(A)-SPEED
    X=XD(X(A)+RX2)/ZA+RX2
    Y=YD(Y(A)+RY2)/ZA+RY2
    IF ZA<=1 OR X<0 OR X>RX or Y<0 OR Y>RY
    IF IO(A)=1 THEN IO(A)=0:C.0:PL.XE(A),YE(A)
    X(A)=RAND(RX)-RX2:Y(A)=RAND(RY)-RY2:Z(A)=DEP
    else
    IF IO(A)=1 THEN COLOR 0:PLOT XE(A),YE(A)
    Z(A)=ZA:XE(A)=X:YE(A)=Y:IO(A)=1:COLOR 2
    IF ZA>DEP2 THEN COLOR 1
    PLOT X,Y
    endif
    NEXT A
    loop


    tylko przerobiłem na TB + 1 wywołanie losowania nowego pkt zamiast 3
    łatwa komplikacja do TB za pomocą tbxl-parser (https://github.com/dmsc/tbxl-parser)
    • 23: CommentAuthorstc
    • CommentTime12 Aug 2019
     
    10 GOTO 100
    20 FOR ST=O TO FST STEP STAR:FOR A=I TO STAR:COLOR O:PLOT XE(A),YE(A):COLOR CS(ST+A)
    30 XE(A)=XS(ST+A):YE(A)=YS(ST+A):PLOT XE(A),YE(A):NEXT A:NEXT ST:GOTO 20
    100 TRAP 10:? "NUMBER OF STARS (MAX 50)?":INPUT STAR:IF STAR<0 OR STAR>50 THEN STAR=50
    110 I=1:O=0:SPEED=5:RX=159:RY=95:DEP=RX:RX2=RX/2:RY2=RY/2:DEP2=DEP/2:IZS=RX/SPEED:FST=STAR*(IZS-I)
    120 DIM X(STAR),Y(STAR),Z(STAR),XE(STAR),YE(STAR),XD(RX),YD(RY),XS(IZS*STAR),YS(IZS*STAR),CS(IZS*STAR)
    130 FOR A=I TO STAR:X(A)=RX*RND(O)-RX2:Y(A)=RY*RND(O)-RY2:Z(A)=DEP*RND(O):XE(A)=O:YE(A)=O:NEXT A
    140 FOR A=I TO RX:XD(A)=(A-RX2)*DEP:NEXT A:FOR A=I TO RY:YD(A)=(A-RY2)*DEP:NEXT A
    150 FOR ST=O TO FST STEP STAR:DS=ST/STAR*SPEED:FOR A=I TO STAR
    160 ZA=Z(A)-DS:X=XD(X(A)+RX2)/ZA+RX2:Y=YD(Y(A)+RY2)/ZA+RY2
    170 IF X<O OR X>RX OR Y<O OR Y>RY THEN X(A)=RX*RND(O)-RX2:Y(A)=RY*RND(O)-RY2:Z(A)=DEP:GOTO 160
    180 C=2:IF ZA>DEP2 THEN C=I
    190 CS(ST+A)=C:XS(ST+A)=X:YS(ST+A)=Y:NEXT A:? "STEP ";ST/STAR;" OF ";INT(IZS):NEXT ST
    200 GRAPHICS 7+16:GOTO 20


    precalc rulez?
    • 24: CommentAuthorxxl
    • CommentTime13 Aug 2019 zmieniony
     
    ta demonstracja byla w basicu?

    ->link<-
    • 25:
       
      CommentAuthorKaz
    • CommentTime13 Aug 2019
     
    Wątpliwe. Tu masz ten plik:
    • 26: CommentAuthorxxl
    • CommentTime14 Aug 2019
     
    po przepisaniu na asma przy czym caly czas OS PLOT

    • 27: CommentAuthorxxl
    • CommentTime16 Aug 2019
     
    obroty:

    • 28:
       
      CommentAuthorKaz
    • CommentTime16 Aug 2019
     
    TDC robił też takie w Action! i też wtedy jest to szybkie.
    • 29: CommentAuthorxxl
    • CommentTime16 Aug 2019
     
    c64:


    pc:


    Apple2:


    ST:


    Amiga:
    • 30: CommentAuthorbob_er
    • CommentTime16 Aug 2019
     
    ZObacz 'alternative demo' compo: ->link<- . W tym roku tematem były gwiazdy, większość prac (od miejsca 2go do końca) to były starfieldy.
    • 31: CommentAuthorxxl
    • CommentTime16 Aug 2019
     
    piekne

    • 32: CommentAuthorQTZ
    • CommentTime16 Aug 2019 zmieniony
     
    Aż się prosi żeby kamera się obróciła i pokazała, że jest to w 3D :)

    Też spróbowałem zoptymalizować wersję z Basic-a, ale w zasadzie zrobiłem to samo co już zostało zrobione.

    Dodatkowo zapisuję *.5 zamiast /2, ale czy w praktyce to przyspiesza to właściwie nie jestem pewien - trzeba by zrobić test... (tu i tak niewiele to zmieni).

    Sprawdziłem wykonując w pętli - jest szybciej :)

    Do testu użyłem PEEK(540)
    • 33: CommentAuthorxxl
    • CommentTime16 Aug 2019
     
    obroty. obracamy punkt o 360. na uwage zasluguje brak mnozenia a dzielenie to przesuniecie bitowe (bardzo szybkie na 6502)

    10 GR.7:C.1:OX=30:OY=0
    30 F.A=0 TO 63
    40 OX=OX+OY
    50 OY=OY-OX
    60 PLOT 80+OX,48+OY
    70 N.A

    10 GR.7:C.1:OX=30:OY=0
    30 F.A=0 TO 100
    40 OX=OX+OY/16
    50 OY=OY-OX/16
    60 PLOT 80+OX,48+OY
    70 N.A

    10 GR.7:C.1:OX=30:OY=0
    30 F.A=0 TO 403
    40 OX=OX+OY/64
    50 OY=OY-OX/64
    60 PLOT 80+OX,48+OY
    70 N.A
    • 34: CommentAuthorQTZ
    • CommentTime22 Aug 2019 zmieniony
     
    Miałem na myśli obrót kamery np. w stronę oglądającego :)

    Czy coś jak tu:

    (Gra jest w tym tygodniu darmowa)

    Dzielenie /2 powinno być szybkie, jednak w Basic-u dzielenie jest powolne.

    Edit: Poprawka FASTCHIP: ->link<- ->link<- i ->link<- ->link<-

    Zamieniłem dzielenia na mnożenia i działa nieco szybciej - szczególnie widać w ostatnim przykładzie:
    40 OX=OX+OY*.015625
    50 OY=OY-OX*.015625