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 20:08
       
      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 20:08
       
      xxl znowu koduje, mamo nastaw budyń!
      • 3:
         
        CommentAuthorTheFender
      • CommentTime10 Aug 2019 21:08 zmieniony
       
      xxl robi w basicu, to na pewno jakaś prowokacja.




      :D
      • 4:
         
        CommentAuthorhospes
      • CommentTime10 Aug 2019 21:08
       
      xxl: teraz prosimy pierwsze wprawki w STOSie;)
      • 5: CommentAuthorurborg
      • CommentTime10 Aug 2019 22:08
       
      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 23:08
       
      powiedzialbym tak... nawet 10x przyspieszenie to malo. tu potrzeba innego podejscia chyba
      • 7:
         
        CommentAuthorpirx
      • CommentTime10 Aug 2019 23:08
       
      ale to ma być czysty bejzik?
      • 8: CommentAuthorxxl
      • CommentTime10 Aug 2019 23:08
       
      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 01:08 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 01:08
       
      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 02:08
       
      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 03:08
       
      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 10:08
       
      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 10:08
       
      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 12:08 zmieniony
       
      dzieki. tak dla przypomnienia gdzie taki efekt smiga:
      Gyruss, Star Wars, Star Raiders II, Star Raiders, Blaster
      • 16: CommentAuthortbxx
      • CommentTime11 Aug 2019 13:08
       
      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 15:08
       
      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 16:08
       
      mozesz to skompilowac lub podac sciezke w przykladach madpascala gdzie to znalezc?
      • 19: CommentAuthortebe
      • CommentTime11 Aug 2019 18:08
       
      PAS, OBX
      • 20: CommentAuthorxxl
      • CommentTime11 Aug 2019 21:08
       
      przelecialem basicowy program TurboBasicCompilerem:
      • 21: CommentAuthorxxl
      • CommentTime11 Aug 2019 22:08 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 00:08 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 03:08
       
      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 16:08 zmieniony
       
      ta demonstracja byla w basicu?

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

      • 27: CommentAuthorxxl
      • CommentTime16 Aug 2019 09:08
       
      obroty:

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


      pc:


      Apple2:


      ST:


      Amiga:
      • 30: CommentAuthorbob_er
      • CommentTime16 Aug 2019 11:08
       
      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 15:08
       
      piekne

      • 32: CommentAuthorQTZ
      • CommentTime16 Aug 2019 17:08 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 20:08
       
      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 17:08 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