You are currently viewing Ośla łączka w Hollywood, cz. 3 – bazgrolnik podejście trzecie i ostatnie

Ośla łączka w Hollywood, cz. 3 – bazgrolnik podejście trzecie i ostatnie

Witam w trzecim odcinku szkółki. Do tej pory miała ona dwa odcinki. W pierwszej był to prosty program pokazujący obsługę zdarzeń myszy. Robił coś pożytecznego – był prostym szkicownikiem. Jeden kolor tła (czarny) i jeden pisak o jednej grubości (biały). Część druga to rewolucja – 10 kolorów, gumka, różne grubości pisaków i gumek. Wydawało mi się, że na tym koniec, ale… po roku wróciłem do Hollywood i zabawa zaczęła się od nowa.

Wszystko się zmienia

Po tych wszystkich materiałach – podręczniku, szkółce, artykułach – zorientowałem się, że edukowanie w Hollywood nie ma takiego sensu, jak mi się wydawało. Odbiorców jest mało, a oczekiwania często idą w stronę akademickiej poprawności zamiast praktycznej nauki. Dlatego zmieniłem podejście: zamiast tłumaczyć i uproszczać kod pod początkujących, skupiłem się na własnych projektach. Rozwinąłem program ze szkółki do poziomu w którym zrealizowałem sam to, do czego (bezskutecznie) zachęcałem:
– wstawiłem program do naszego sklepiku amigaonline
– wstawiłem program na itch.io
– wstawiłem pliki na GitHuba

Zacząłem od zera i doszedłem do miejsca, gdzie wystawiam się „tam gdzie wszyscy”. To jest dla mnie wyjście z piwnicy i daje mi to zwyczajną satysfakcję. Po ukończeniu wersji 2.4 na Hollywood 9.1 uznałem, że skoro idzie mi to sensownie, to warto przejść na Hollywood 11. Teraz robię już tylko dla siebie, w ramach hobby, a jeśli coś okaże się wartościowe – stanie się produktem. Bazgrolnik kosztuje 15 zł, a na itch.io 5 euro. Różnica między „nie sprzedało się za 2 euro” a „nie sprzedało się za 10 euro” jest czysto akademicka. W całej tej szkółce chodziło nie tylko o kod, ale też o pokazanie procesu: od pierwszej linijki do gotowej aplikacji, którą można wystawić jako komercyjny produkt. Nie robię tego dla zarobku, tylko po to, żeby doprowadzić sprawę do końca i pokazać, że da się przejść całą drogę. Gdyby chodziło mi o pieniądze, nie byłoby tego wszystkiego co poniżej.

Kolejne artykuły domkną cały proces. Na Patronite wrzucę osobny materiał o tym, jak na Windows skonfigurować GitHuba i wrzucać własne repozytoria – to już nie jest część amigowa, więc nie pasuje do tej szkółki. Treści na Patronite są darmowe, więc każdy będzie mógł z tego skorzystać. W czasopiśmie z kolei opiszę, jak wystawić projekt na itch.io. Te materiały – podręcznik z 2021 roku, trzy odcinki szkółki, artykuł o GitHubie na Patronite i tekst o itch.io w czasopiśmie – razem stworzą pełną ścieżkę: od pierwszych kroków w Hollywood do opublikowania gotowego produktu. To nie jest tylko „cykl szkółki”, tylko cały proces, który chciałem pokazać od początku do końca.

W wieku 52 lat wejście na rynek jako zawodowy programista jest praktycznie nierealne – statystyki rekrutacyjne i sytuacja po wejściu AI mówią same za siebie. Ale rozwój jako hobbysta to zupełnie inna historia i tu ograniczeń nie mam.

Co się działo w kodzie od ostatniej wersji

Bardzo wiele. Wszystko jest w PDF-ie dołączonym do programu. Największe zmiany to zapis do pliku i utworzenie dodatkowych okien informacyjnych (klawiszologia i informacje o programie). Dodałem też dodatkowe „satysfakcjonujące” grube przybory – mazak i gąbkę. Na belce dodałem informację o aktualnie wybranym pisaku – kolor i grubość. Mam konkretne pomysły jak rozwijać ten program, ale on ma ideowe ograniczenia. Obecnie jest wersja 2.7, która ma wersję amigową 68k przetestowaną pod emulatorami AmigaOS 3.x i na X5000 pod AmigaOS 4.1. Podejrzewam, że chodzi na wszystkim.

Ikonka też jest amigowa, dwustanowa, ale najważniejsze jest to, jak powstała litera B. To nie jest „nabazgrane B”, tylko litera odtworzona z pamięci mięśniowej sprzed czterdziestu paru lat. Musiałem się cofnąć do pierwszej klasy podstawówki. Jestem rocznik 73′ i miałem wtedy siedem lat oraz ogromne szczęście do nauczycielki, która stwierdziła, że długopis uczy brzydkiego charakteru pisma, bo się ślizga. Wszyscy pisali długopisami, bo to był już standard – a ona uparła się, że nasza klasa będzie pisać piórem. I to nawet nie wiecznym. Kazała konserwatorowi wyciągnąć z szafy stare, czerwone, drewniane kałamarze, które leżały tam pewnie od lat. Ponawiercał ławki i poprzykręcał te kałamarze. Jak ktoś przyniósł pióro wieczne na lekcję, to miał obniżaną ocenę i następnym razem musiał przynieść zwykłe. To było wyzwanie, dzisiaj dzieci byłyby pewnie „ztraumatyzowane” a dla mnie to najpiękniejsze wspomnienia. Jak stalówkę za mocno przyciskało się, to się rozdwajała. Jak za dużo wzięło atramentu – powstawał kleks. Kleksy pani usuwała kredą. I dopiero kiedy próbowałem narysować ikonę, zrozumiałem, że pamiętam nie kształt litery, tylko ruch ręki. Pierwsza próba była zła. Druga też. Dopiero trzecia wyszła tak, jak wtedy, kiedy siedziałem w tej ławce i uczyłem się stawiać pierwsze litery. To jest dokładnie to samo B.

Kod od wersji 2.6 ma kompilację do wersji Miniwood, a od 2.7 program wersję anglojęzyczną (także PDF). Na razie tylko na Windows i tylko na itch,io.

Przyszłe zmiany jakie planuję wprowadzić to remapowanie klawiszy przy okazji wprowadzenia ołówka (cieniutki szary pisak do szkicowania zanim zacznie się rysować) oraz dwa nowe kolory kredek. Amigowa wersja będzie mieć zamiast PDF-a AmigaGuide. Wersja 3 ma mieć dodane jednokrotne cofnięcie. Ponieważ miało nie być „undo” rozwiążę to jako „automatyczną gumkę”. To będzie taka „gumka-pamiętaczka”, pozwalająca wymazać ostatnie bazgroły. Zapamiętywane będzie ostatnie rysowanie między wciśnięciem a puszczeniem przycisku myszki. To może być jeden do kilkudziesięciu ruchów myszą, zależy jaką kto ma ekspresję w bazgraniu. Ale to w wersji 3, bo to na tyle duża funkcjonalność, że zasługuje na pełną wersję. Są też inne pomysły, ale to już zależy jak bardzo będzie mi się chciało, czy nie rzucę się na nowy projekt. Co bym nie dodał, to z założenia zawsze będzie taki Flappy Bird wśród programów do rysowania.

Prezentacja kodu

Kod jest bardzo obszernie okomentowany. Tak że można powiedzieć część artykułu to komentarze. Objętość wzrosła głównie przez dodanie okien takich jak klawiszologia. Kod udostępniłem na GitHubie na licencji MIT w historycznych wersjach 1,2 i obecnej 2.7.


; ── METRYCZKA ───────────────────────────────────────────────────────────────
; Powinno się dawać, ale bez tego program działa. 
; To nie jest okno "o programie", tego nie widać nigdzie poza kodem. 
@APPTITLE "Bazgrolnik"
@APPAUTHOR "Truman Burbank"
@APPCOPYRIGHT "amiga.org.pl"
@APPVERSION "$VER: Bazgrolnik 2.71"
@APPDESCRIPTION "Program do odręcznego rysowania"

@VERSION 11,0

; Tu są zadeklarowane moduły do Miniwooda, czyli jakie biblioteki mają być dołączane 
; jeśli wypuszcza się wersję Miniwood. Nie ma to wpływu na zwykłą wersję. 
; W komentarzach podane jest na co to ma wpływ. 
@IF #HW_MINI
    @USING "icon"       ; @APPICON
    @USING "graphics"   ; #WHITE, #BLACK, RGB() itp.
    @USING "text"       ; SetFont, SetFontStyle, SetFontColor, TextOut, UseFont
    @USING "display"    ; CreateDisplay, OpenDisplay, CloseDisplay, SelectDisplay,
				; ActivateDisplay, SaveSnapshot, Cls, Flip, SetTitle,
				; BeginDoubleBuffer, EndDoubleBuffer
    @USING "imageio"    ; obsługa formatów obrazów (PNG w SaveSnapshot)
    @USING "dos"        ; Exists(), MakeDirectory()
    @USING "draw"       ; Box, Line
    @USING "event"      ; InstallEventHandler, WaitEvent, IsKeyDown, MouseX, MouseY,
			; IsLeftMouse, IsRightMouse
    @USING "system"     ;  bez niego skompilowany program się nie uruchamia
    @USING "string"		 ;  bez niego skompilowany program się nie uruchamia
    @USING "object"        ; ?
    @USING "pointer"       ;?
    @USING "error"         ; ?
@ENDIF

; ── IKONA PROGRAMU ───────────────────────────────────────────────────────────────────
@APPICON
; s na końcu (np. Ic16x16s) to wersja "wybranej" ikony (selected state) – używana na AmigaOS 
; i kompatybilnych, gdzie ikony mają dwa stany: normalny i zaznaczony (gdy kliknie się w ikonę).
; Na Windows, macOS i Linux wersja s jest ignorowana – ikony są tam zawsze statyczne.
{Ic16x16="ikonki/16_ikonka.png", Ic16x16s="ikonki/16w_ikonka.png",
Ic24x24="ikonki/24_ikonka.png", Ic24x24s="ikonki/24w_ikonka.png",
Ic32x32="ikonki/32_ikonka.png", Ic32x32s="ikonki/32w_ikonka.png",
Ic48x48="ikonki/48_ikonka.png", Ic48x48s="ikonki/48w_ikonka.png",
Ic64x64="ikonki/64_ikonka.png", Ic64x64s="ikonki/64w_ikonka.png",
Ic96x96="ikonki/96_ikonka.png", Ic96x96s="ikonki/96w_ikonka.png",
Ic128x128="ikonki/128_ikonka.png", Ic128x128s="ikonki/128w_ikonka.png",
Ic256x256="ikonki/256_ikonka.png", Ic256x256s="ikonki/256w_ikonka.png",
Ic512x512="ikonki/512_ikonka.png", Ic512x512s="ikonki/512w_ikonka.png"}

; ── EKRAN ───────────────────────────────────────────────────────────────────
; Zdefiniowane okno programu. 
@DISPLAY {Title = "Program do bazgrania 2.7", Width = 800, Height = 600}

; Podwójne buforowanie: rysuje się w buforze tylnym, a Flip() wyświetla gotową klatkę.
; Bez tego rysowanie byłoby widoczne na żywo (migotanie).
BeginDoubleBuffer()

; ── KOLORY ───────────────────────────────────────────────────────────────────
; Hollywood nie pozwala używać RGB() w Const (Const przyjmuje tylko literały),
; więc kolory wielokrotnego użytku trzymamy jako Local.
Local kRamki    = RGB(100, 100, 200)   ; obramowanie okien dialogowych
Local kOkienek = RGB(20, 20, 40)      ; tło okien dialogowych
Local kStopki   = RGB(150, 150, 200)   ; tekst stopki okien dialogowych

; ── KATALOG ZAPISU ───────────────────────────────────────────────────────────
; Uproszczone ze względu na braki w AmigaOS. 
; Katalog Bazgranie jest tworzony przy pierwszym uruchomieniu programu. 
; Zawsze w tym samym katalogu co plik wykonywalny, przez co niezależbny od systemu. 
Local katalogZapisu = "Bazgranie/"
If Exists(katalogZapisu) = False Then MakeDirectory(katalogZapisu)

; ── STAN PROGRAMU ────────────────────────────────────────────────────────────
; poprzednieX/Y = -1 oznacza brak punktu startowego linii (mysz nie jest
; wciśnięta). Wartość -1 jest niemożliwa jako współrzędna ekranu, więc
; działa jako bezpieczna wartość "brak danych".
Local poprzednieX     = -1, poprzednieY = -1
Local aktualnaGrubosc = 5
Local aktualnaGumka   = 15
Local aktualnyKolor   = #WHITE
Local pomocWidoczna   = False
Local infoWidoczna    = False

; ── FUNKCJE ──────────────────────────────────────────────────────────────────
; Aktualizuje pasek tytułowy głównego okna tak, żeby użytkownik zawsze
; widział aktywny kolor i grubość bez otwierania okna pomocy.
; Przy aktywnej gumce (PPM wciśnięty) dokłada też jej rozmiar.
Function OdswiezTytul()
	Local kolorNazwa = "nieznany"
	If aktualnyKolor = #WHITE            Then kolorNazwa = "bialy"
	If aktualnyKolor = #RED              Then kolorNazwa = "czerwony"
	If aktualnyKolor = #BLUE             Then kolorNazwa = "niebieski"
	If aktualnyKolor = #YELLOW           Then kolorNazwa = "zolty"
	If aktualnyKolor = #GREEN            Then kolorNazwa = "zielony"
	If aktualnyKolor = RGB(255, 128, 0)  Then kolorNazwa = "pomaranczowy"
	If aktualnyKolor = #PURPLE           Then kolorNazwa = "fioletowy"
	If aktualnyKolor = RGB(139, 69, 19)  Then kolorNazwa = "brazowy"
	If aktualnyKolor = #GRAY             Then kolorNazwa = "szary"
	If aktualnyKolor = #BLACK            Then kolorNazwa = "czarny"
	Local opis = "Program do bazgrania 2.7 :: " .. kolorNazwa .. " " .. aktualnaGrubosc .. " px"
	If IsRightMouse() Then opis = opis .. " (gumka " .. aktualnaGumka .. " px)"
	SetTitle(opis)
EndFunction

; Resetuje punkt startowy linii do wartości "brak danych".
; Musi być wywołana przy każdym zwolnieniu przycisku myszy – bez tego
; przy ponownym ruchu myszy Hollywood próbowałby ciągnąć linię od miejsca
; ostatniego kliknięcia do aktualnej pozycji kursora, nawet jeśli mysz
; była w międzyczasie przeniesiona. 
; -1 jest wartością spoza ekranu, więc działa jako bezpieczny znacznik „brak punktu".
Function ZresetujKursor()
	poprzednieX, poprzednieY = -1, -1
	OdswiezTytul()
EndFunction

; ── OKNO POMOCY (display 2) ──────────────────────────────────────────────────
; Okno jest tworzone i wypełniane treścią raz przy starcie programu,
; ale pozostaje niewidoczne – pokazuje się dopiero po naciśnięciu H.
; Borderless usuwa belkę tytułową i przyciski systemowe.
; Hidden=True pozwala przygotować okno wcześniej, dzięki czemu pokazuje się natychmiast.
; DragRegion obejmujący cały obszar okna pozwala je przeciągać klikając
; w dowolnym miejscu, co rekompensuje brak belki tytułowej.
CreateDisplay(2, {Width = 680, Height = 500, Color = kOkienek,
	Borderless = True,
	Hidden = True,
	DragRegion = {{Type = #BOX, X = 0, Y = 0, Width = 680, Height = 500}}})

; True = SelectDisplay bez przejęcia fokusa klawiatury – display 1 pozostaje
; aktywny, więc klawisze działają od razu po starcie bez klikania w okno
; FILLNONE = rysujemy tylko obrys, bez wypełnienia.
SelectDisplay(2, True)

SetFillStyle(#FILLNONE)
Box(10, 10, 658, 478, kRamki)

; Nagłówek czcionką wbudowaną #SANS – dla jednej linii tekstu nie warto
; ładować pełnego pliku TrueType, #SANS jest dostępny natychmiast.
SetFont(#SANS, 20)
SetFontStyle(#BOLD)
SetFontColor(#WHITE)
TextOut(#CENTER, 20, "SKRÓTY KLAWISZOWE")
SetFontStyle(#NORMAL)
Line(20, 60, 658, 60, kRamki, {Thickness = 1})

; DejaVu Sans przez silnik wbudowany (#FONTENGINE_INBUILT) –
; czcionka jest linkowana do pliku programu przy kompilacji,
; więc działa na każdej platformie bez instalowania czcionki w systemie.
@FONT 1, "DejaVu Sans", 20, {Engine=#FONTENGINE_INBUILT}
UseFont(1)
SetFontColor(#WHITE)

; Lewa kolumna: blok tekstu, \n to zwykłe łamanie linii.
TextOut(30, 75,
	"[color=11468287][b]FOLDER ZAPISU PNG[/b][/color]\n" ..
	"m – zapisz rysunek jako PNG\n" ..
	"[color=16776960]" .. katalogZapisu .. "[/color]")

TextOut(30, 185,
	"[color=11468287][b]KOLORY[/b][/color]\n" ..
	"1 – biały\n" ..
	"2 – czerwony\n" ..
	"3 – niebieski\n" ..
	"4 – żółty\n" ..
	"5 – zielony\n" ..
	"6 – pomarańczowy\n" ..
	"7 – fioletowy\n" ..
	"8 – brązowy\n" ..
	"9 – szary\n" ..
	"0 – czarny")

; Prawa kolumna – drugi blok tekstu, przesunięty w prawo.
TextOut(360, 75,
	"[color=11468287][b]GRUBOŚĆ LINII[/b][/color]\n" ..
	"a –  5 px (cienka)\n" ..
	"s – 10 px (średnia)\n" ..
	"d – 15 px (gruba)\n" ..
	"f – 40 px (mazak)\n" ..
	"\n" ..
	"[color=11468287][b]ROZMIAR GUMKI[/b][/color]\n" ..
	"z – 15 px (mała)\n" ..
	"x – 40 px (duża)\n" ..
	"c – 80 px (gąbka)\n" ..
	"\n" ..
	"[color=11468287][b]INNE[/b][/color]\n" ..
	"SPACJA – wyczyść ekran\n" ..
	"LPM    – rysowanie\n" ..
	"PPM    – gumka\n" ..
	"[color=16776960]h    – pomoc\n" ..
	"i    – metryczka[/color]")

SetFontColor(kStopki)
TextOut(#CENTER, #BOTTOM - 5, "Nacisnij H, aby zamknąć")

SelectDisplay(1)

; ── OKNO INFORMACJI (display 3) ──────────────────────────────────────────────
; Analogicznie do okna pomocy – tworzone przy starcie, pokazywane klawiszem I.
CreateDisplay(3, {Width = 500, Height = 340, Color = kOkienek,
	Borderless = True,
	Hidden = True,
	DragRegion = {{Type = #BOX, X = 0, Y = 0, Width = 500, Height = 340}}})

SelectDisplay(3, True)

SetFillStyle(#FILLNONE)
Box(10, 10, 478, 328, kRamki)

SetFont(#SANS, 20)
SetFontStyle(#BOLD)
SetFontColor(#WHITE)
TextOut(#CENTER, 20, "INFORMACJE")
SetFontStyle(#NORMAL)
Line(20, 60, 478, 60, kRamki, {Thickness = 1})

; Każda linia osobno z #CENTER jako X i ręcznym Y –
; zgodnie z zasadą "lewo-środek" Y wskazuje środek linii.
UseFont(1)
SetFontColor(#WHITE)
TextOut(#CENTER, 140, "Adam Bogumił Mierzwa")
TextOut(#CENTER, 175, "[color=11468287][b]Bazgrolnik 2.7[/b][/color]")
TextOut(#CENTER, 210, "zrobiony w Hollywood 11")

SetFontColor(kStopki)
TextOut(#CENTER, #BOTTOM - 5, "Nacisnij I, aby zamknąć")

SelectDisplay(1)

; ── OBSŁUGA ZDARZEŃ ──────────────────────────────────────────────────────────
InstallEventHandler({
	OnMouseDown = Function()
		; Okna pomocy i info odbierają fokus klawiatury gdy użytkownik w nie kliknie.
		; ActivateDisplay(1) przywraca go natychmiast do głównego okna rysowania,
		; dzięki czemu klawisze skrótów działają bez dodatkowego klikania.
		ActivateDisplay(1)
		; Punkt startowy ustawiamy tylko przy pierwszym wciśnięciu –
		; jeśli już mamy punkt (poprzednieX >= 0), nie nadpisujemy go tutaj,
		; bo OnMouseMove przejmuje aktualizację podczas ruchu
		If poprzednieX = -1 And poprzednieY = -1 Then poprzednieX, poprzednieY = MouseX(), MouseY()
	EndFunction,

	OnMouseUp      = Function() ZresetujKursor() EndFunction,
	OnRightMouseUp = Function() ZresetujKursor() EndFunction,

	OnMouseMove = Function()
		Local obecneX, obecneY = MouseX(), MouseY()
		; Rysujemy odcinek od poprzedniej do obecnej pozycji kursora.
		; Warunek poprzednieX >= 0 zabezpiecza przed rysowaniem gdy mysz
		; porusza się bez wciśniętego przycisku (sam ruch nie rysuje)
		If IsLeftMouse() And poprzednieX >= 0 And poprzednieY >= 0
			Line(poprzednieX, poprzednieY, obecneX, obecneY, aktualnyKolor, {Thickness = aktualnaGrubosc})
		EndIf
		; Gumka działa tak samo jak pisak, ale zawsze rysuje czarnym kolorem
		; i grubszą linią, żeby skutecznie zakrywać narysowane ślady
		If IsRightMouse() And poprzednieX >= 0 And poprzednieY >= 0
			Line(poprzednieX, poprzednieY, obecneX, obecneY, #BLACK, {Thickness = aktualnaGumka})
			OdswiezTytul()
		EndIf
		; Przesuwamy punkt startowy do aktualnej pozycji – następny ruch
		; będzie kontynuacją linii od tego miejsca, a nie skoku od początku
		If IsLeftMouse() Or IsRightMouse() Then poprzednieX, poprzednieY = obecneX, obecneY
		Flip()
	EndFunction,

	OnKeyDown = Function()
		; Klawisz H pokazuje lub ukrywa okno pomocy.
		; Return po obsłudze zapobiega dalszemu przetwarzaniu tego zdarzenia.
		; OpenDisplay(2) otwiera okno i wybiera je jako bieżący output device,
		; po czym SelectDisplay(1, True) natychmiast wraca do display 1
		; bez kradnięcia fokusa klawiatury (drugi argument True = noactivate).
		If IsKeyDown("h")
			pomocWidoczna = Not pomocWidoczna
			If pomocWidoczna
				OpenDisplay(2)
				SelectDisplay(1, True)
			Else
				CloseDisplay(2)
			EndIf
			Return
		EndIf

		; Klawisz I pokazuje lub ukrywa okno informacji o programie
		If IsKeyDown("i")
			infoWidoczna = Not infoWidoczna
			If infoWidoczna
				OpenDisplay(3)
				SelectDisplay(1, True)
			Else
				CloseDisplay(3)
			EndIf
			Return
		EndIf

		; Zapis PNG z automatyczną numeracją – szuka pierwszego wolnego numeru,
		; żeby nie nadpisywać poprzednich rysunków
		If IsKeyDown("m")
			Local nr = 1
			Local nazwa = katalogZapisu .. "bazgranie_" .. nr .. ".png"
			While Exists(nazwa)
				nr = nr + 1
				nazwa = katalogZapisu .. "bazgranie_" .. nr .. ".png"
			Wend
			SaveSnapshot(nazwa, #SNAPDISPLAY, #IMGFMT_PNG)
			SetTitle("Zapisano: " .. nazwa)
		EndIf

		; Czyszczenie ekranu – resetuje też punkt startowy, bo po Cls()
		; stary punkt wskazywałby na wyczyszczone miejsce
		If IsKeyDown("SPACE")
			Cls(#BLACK)
			poprzednieX, poprzednieY = -1, -1
		EndIf

		; Kolory pisaka – klawisze 1-0
		If IsKeyDown("1") Then aktualnyKolor = #WHITE            ; biały
		If IsKeyDown("2") Then aktualnyKolor = #RED              ; czerwony
		If IsKeyDown("3") Then aktualnyKolor = #BLUE             ; niebieski
		If IsKeyDown("4") Then aktualnyKolor = #YELLOW           ; żółty
		If IsKeyDown("5") Then aktualnyKolor = #GREEN            ; zielony
		If IsKeyDown("6") Then aktualnyKolor = RGB(255,128,0)    ; pomarańczowy
		If IsKeyDown("7") Then aktualnyKolor = #PURPLE           ; fioletowy
		If IsKeyDown("8") Then aktualnyKolor = RGB(139,69,19)    ; brązowy
		If IsKeyDown("9") Then aktualnyKolor = #GRAY             ; szary
		If IsKeyDown("0") Then aktualnyKolor = #BLACK            ; czarny

		; Grubość pisaka – klawisze a, s, d, f
		If IsKeyDown("a") Then aktualnaGrubosc = 5
		If IsKeyDown("s") Then aktualnaGrubosc = 10
		If IsKeyDown("d") Then aktualnaGrubosc = 15
		If IsKeyDown("f") Then aktualnaGrubosc = 40

		; Rozmiar gumki – z (mała), x (duża), c (gąbka)
		If IsKeyDown("z") Then aktualnaGumka = 15
		If IsKeyDown("x") Then aktualnaGumka = 40
		If IsKeyDown("c") Then aktualnaGumka = 80

		OdswiezTytul()
	EndFunction
})

; ── GŁÓWNA PĘTLA ─────────────────────────────────────────────────────────────
; WaitEvent usypia program aż do następnego zdarzenia (mysz lub klawiatura),
; dzięki czemu nie zajmuje procesora w oczekiwaniu – ważne na słabszym sprzęcie
; jak AmigaOS4 czy MorphOS. Flip() po każdym zdarzeniu zapewnia że np.
; czyszczenie ekranu spacją jest widoczne od razu, bez czekania na ruch myszy
Repeat
	WaitEvent
	Flip()
Forever

EndDoubleBuffer()

Kwestie „dlaczego tak”

Pierwsza wątpliwość może być, dlaczego przy pisakach użyłem IF-ów. Przy tej ilości to nie jest problem, czy teraz 10 czy w przyszłości 12 kredek – kod jest czytelny. Można zrobić to inaczej, ale ja zrobiłem tak jak chciałem. Nie z niewiedzy – chociaż dalej się uczę. Można użyć konstrukcji z Case albo tablicy – na przykład. Testowałem obie wersje, nie były szybsze ani w żaden sposób lepsze. Case jest bardziej czytelny, ale przy tej liczbie warunków różnica nie robi wrażenia.

Dziwadełko z tworzeniem okna przy starcie, które jest chowane. To miało być dla słabych konfiguracji amigowych, można zrezygnować z tego mechanizmu. Okna to w ogóle „zeżarły” dużo linii kodu.

Zapis pliku był inaczej rozwiązany w niepublicznej wersji, np. pod Windows zapisywały się pliki w katalogu w MyDocuments, a pod różne systemy odpowiednio do ścieżek położenia dopasowane były slash/backslash. Niestety amigowe systemy wykładały się na tym mechanizmie – zapis działał, ale był komunikat przy uruchomieniu programu. Po prostu są tak prymitywne, że nie ma czegoś takiego jak odpowiednik Home czy User. Co prawda Amiga ma coś takiego jak PROGDIR:, ale to jest dobre do ładowania zasobów programu, a nie do zapisywania danych użytkownika. Nie chcę tego rozwijać, ale obecne rozwiązanie jest wygodne i proste,.

Można przerobić IsKeyDown na OnKeyDown na przykład, bo w tym programie wystarczy zarejestrować wciśnięcie klawisza, IsKeyDSown jest przeznaczone raczej do rejestrowania stale wciśniętego klawisza. np. strzałek czy klawiszy WSAD w grze. I znów – wiem, jestem świadomy tego.

Znaki zapytania w komentarzach w sekcji Miniwood biorą się stąd, że to nowość. Nie jest wszystko udokumentowane, dlatego metodą prób i błędów doszedłem co muszę dodać, żeby program się skompilował. Zysk z wersji Miniwood to niecały megabajt.

Ważne: program do poprawnej kompilacji i uruchomienia będzie wołał o pliki ikonek. Tam gdzie plik skryptu powinien być katalog Ikonki a w nim ikonki o podanych rozmiarach. Najlepiej zakomentować bądź usunąć cały blok IKONA PROGRAMU.

Zakończenie

Ze mną i Hollywood spotkać się będzie można w numerze 13 magazynu Amiga NG, gdzie opiszę tworzenie płatka Kocha z kolorowymi wariantami A później? Zachęcam do wejścia na Discorda, mamy oddzielny pokój Programowanie. On jest normalnie niewidoczny, żeby nie bajdurzyć w nim o walorach osobistych Maryny, ale jak ktoś interesuje się pisaniem w Hollywood to wystarczy zagadać na ogólnym i dopiszę.

Ten post ma jeden komentarz

Dodaj komentarz