Czy istnieje możliwość odczytania znaku w konsoli<ort> ,</ort> podając X i Y ?
Program wczytuje do konsoli na bieżąco znaki z pliku tekstowego<ort> ,</ort> ale dochodzą inne<ort> ,</ort> w zależności od ingerencji <ort>urzytkownika</ort>. Najbardziej mi zależy<ort> ,</ort> aby sprawdzał<ort> ,</ort> czy jest "< >(różna)" od ' ' czyli spacji. powiem<ort> ,</ort>że jest to prosta gierka i XY będzie pobierany z położenia ludzika<ort> ,</ort> a dalsza część algorytmu będzie opisywała całego ludzika z O,|,/,. Procedura będzie sprawdzała<ort> ,</ort> czy w planszy (zbiorze znaków specjalnych czcionki Terminal)przed ludzikiem jest ścianka. Dałbym sobie z tym radę<ort> ,</ort> tylko to odczytywanie znaku w punkcie XY. Procedura wczytująca opiera się na kojarzeniu plik<ort> ,</ort> i poleceniu readln(plik ,String);
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31

- Rejestracja:ponad 19 lat
- Ostatnio:3 miesiące
- Zrób tablicę w pamięci zawierającą to co wyświetlasz na ekran, sprawdzaj w tablice.
- http://msdn.microsoft.com/en-us/library/windows/desktop/ms684965%28v=vs.85%29.aspx

- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
Chyba źle się do tego zabierasz; Jeśli dobrze zrozumiałem, to współrzędne ścian nigdzie nie są przechowywane, a Ty potrzebujesz sprawdzać co się znajduje w danym miejscu na ekranie konsoli; Nie powinieneś tego robić - dane o planszy musisz gdziesz przechowywać, najlepiej w macierzy dwuwymiarowej i do niej się odnosić, przy wykrywaniu kolizji; A ekran to ekran - ma jedynie wyświetlać obraz;
Opisany wyżej sposób zastosowałem w swojej (niedokończonej) grze SnakeASCII, dość dobrze się to obsługuje i działa wystarczająco szybko, by nie trzeba było narzekać.
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
Niby są przechowywane w pliku tekstowym jako "rysunek' , ALE położenie jako tylko znaki i program musiałby odczytywać je na bieżąco. Warto chyba jednak załadować ten rysuneczek do pamięci. gracz przesuwa planszę w prawo czy w lewo w menu , a algorytm usuwa odpowiednią ilość spacji lub je dodaje na początku każdej linii. Naciśnięcie klawisza J powoduje wyświetlenie za każdym cyklem pętli while(rysowanie planszy ,readkey) w pierwszej linijce danych takich jak życie , punkty , oraz pó. XY ludzika ,numer muzyki. To dodaje automatycznie jedną linijkę do współrzędnych .
Pytanie 2 : Jak programowo włączyć tryb pełnoekranowy [Alt] + [enter].
Pytanie 3 : Jak zmienić (i czy się da ?) rozmiar czcionki w bieżącym okienku
Pytanie 4 : Czy da się stworzyć timer w konsoli? Chciałbym , aby działał jako przerwanie (poruszanie przeciwnikiem ,etc...);
Stosuję bibliotekę CRT z Pascala.


- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
Niby są przechowywane w pliku tekstowym jako "rysunek' , ALE położenie jako tylko znaki i program musiałby odczytywać je na bieżąco.
Chodzi właśnie o to, aby dane o ścianach i obiektach trzymać co najmniej w jednej macierzy; Dzięki temu ekran będzie służył jedynie do wyświetlania i nie będziesz musiał tracić czasu; A wszelkie operacje będą wykonywane w pamięci, więc będą szybkie;
Jeżeli Twoja plansza może być większa niż okno konsoli, to dodatkowo polecam skorzystać z dwóch zmiennych liczbowych, które określać będą lewy i górny offset; Z tych offsetów będzie korzystać procedura rysująca obiekty na ekranie, aby dokładnie wiedzieć który fragment mapy narysować w konsoli;
gracz przesuwa planszę w prawo czy w lewo w menu , a algorytm usuwa odpowiednią ilość spacji lub je dodaje na początku każdej linii.
Lepiej by było podać kod, niż go opisywać; Poważnie - opis niewiele daje, bo nie jest tak precyzyjny, jak kod;
Naciśnięcie klawisza J powoduje wyświetlenie za każdym cyklem pętli while(rysowanie planszy ,readkey) w pierwszej linijce danych takich jak życie , punkty , oraz pó. XY ludzika ,numer muzyki.
Tylko pamiętaj o tym, aby odrysowywać jedynie te fragmenty ekranu, które tego wymagają; Rysowanie po konsoli jest potwornie wolne, więc nie przerysowuj całego ekranu, bo będzie to trwało zbyt długo; W swojej grze przerysowuję dosłownie kilka znaków na całym ekranie w każdej klatce, więc całość działa bardzo płynnie - sam też tak powinieneś zrobić;
Pytanie 2 : Jak programowo włączyć tryb pełnoekranowy [Alt] + [enter].
Można zasymulować wciśnięcie tych klawiszy; Zobacz tutaj;
Pytanie 3 : Jak zmienić (i czy się da ?) rozmiar czcionki w bieżącym okienku
Fontu, nie czcionki; Zobacz tutaj - ja tego jeszcze nie testowałem, więc w razie czego dopytuj @vpiotr;
Pytanie 4 : Czy da się stworzyć timer w konsoli? Chciałbym , aby działał jako przerwanie (poruszanie przeciwnikiem ,etc...);
Stosuję bibliotekę CRT z Pascala.
Da się w bardzo prosty sposób, i to nawet kilka, działających "jednocześnie" :]
Za dużo było by tłumaczenia jak na post, więc pobierz sobie archiwum SnakeASCII_full_source.zip i zobacz jak to jest zaimplementowane; Klasa pojedynczego timera znajduje się w module Timer.pp
, a używana jest w klasie TGame
z modułu Game.pp
; Zobacz jak główna pętla w metodzie TGame.Play
używa tych dwóch liczników;
Ogólnie chodzi o to, że główna pętla zamraża program w każdej iteracji na 40ms
; W każdej iteracji zostają także wywołane metody Step
w dwóch timerach; Każdemu timerowi nadawana jest ilość klatek do odliczenia - im więcej klatek (więcej razy 40ms
), tym dłużej trzeba czekać na odliczenie pełnego interwału; Aby sprawdzić, czy dany licznik doliczył już zadaną ilość klatek, należy skorzystać z metody ItsTime
i jeśli zwróci True - można wykonać jakąś akcję;
Takich timerów możesz obsługiwać w jednej pętli i 20, a program nadal będzie jedno-wątkowy; To jest sposób podpatrzony z konstrukcji starych gier na Pegasusa - jest bardzo prosty do zrealizowania i dla prostej gry wystarczy;
- SnakeASCII_full_source.zip (461 KB) - ściągnięć: 181
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
Podaję kod odpowiedzialny za centrowanie :
-Korzysta on z procedury LOAD(deklarowana ręcznie) -odczytuje ona zawartość dokumentu aż do pustej lini (repeat i UNTIL):
PROCEDURA WCZYTUJACA- LOAD:
procedure Load;
var
Plik : TextFile; // nowa zmienna
S : String;
begin
writeln('');
// otworz plik
AssignFile(Plik, plansza);
Reset(Plik);
repeat // petla
Readln(Plik, S); // odczytaj plik
writeln(horizontal+S); // dodaj linie ;-komentarz
until S = ''; // jeżeli napotkasz na pusta linie zakończ działanie pętli
CloseFile(Plik); // zamknij plik
end;
Procedura USTAWIAJĄCA ŚRODEK(ręcznie):
procedure modyf;
begin
while z<>'x' do
begin
crt.ClrScr;
SetConsoleTitle('TEXTMAN -Ustawienia');
{
//-------------TRYB PRŁNOEKRANOWY ALT + ENTER-----
PostMessage(GetStdHandle(STD_OUTPUT_HANDLE), KF_ALTDOWN, 0, 0);
PostMessage(GetStdHandle(STD_OUTPUT_HANDLE), 256, 0,integer(#13));
PostMessage(GetStdHandle(STD_OUTPUT_HANDLE), 257, 0, integer(#13));
PostMessage(GetStdHandle(STD_OUTPUT_HANDLE), KF_UP, 0, 0);
PostMessage(GetStdHandle(STD_OUTPUT_HANDLE), 18, 0, 0); }
//------------------------------------------------
writeln('MODYFIKACJA GRY');
writeln('1.Centrowanie POZIOME');
writeln('Nacisnij prawy lub lewy klawisz.Ustaw środek');
crt.TextColor(11);
writeln('<- -> ,Q-podglad, X-koniec');
writeln('Ustawienia jakości obrazu : Z -niska jakość V -wysoka jakość');
crt.TextColor(12);
writeln(horizontal+'Ĺ');
Z:=crt.ReadKey;
crt.TextColor(7);
if z='q' then begin load; readkey; end;
if length(horizontal)<79 then if z='M' then horizontal:=horizontal+' '; //prawo dodaj spacje
if z='K' then Delete(horizontal, length(horizontal)-1, 1); //lewo -usuń ostatni znak
if z='z' then crt.LowVideo;
if z='v' then crt.HighVideo;
end;
Z:=' '; //resetuj ,aby ostatni znak to nie x
end;
ostatnim znakiem nie może być po zakończeniu X , bo wtedy dojdzie do zakończenia gry.Dzięki temu cofamy się tylko z bieżących ustawień.
Zmienna horizontal (string) przechowuje łańcuch -spacje ,które dodawane są na początku lini menu , planszy , etc...
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
Ok ! Mam już jeden problem z głowy : tryb pełnoekranowy , jak widać miałem dobry tok myślenia -symulacja wciśnięcia klawiszy (kawałek błędnego kodu oznaczony jako komentarz) Wystarczyło :
keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), 0, 0);
keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, 0), 0, 0);
keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), KEYEVENTF_KEYUP, 0);
**DZIĘKI ! ** Aplikacja waży już sobie ok 400 KB :-) . Opanowałem kolorowanie pojedynczych znaków za pomocą CRTka , oddtwarzanie dźwięków WAW (rozszerzenie zmienione na MUS dla niepoznaki ) ,stworzę jeszcze z dwa zegary , nauczę przeciwnika iść w kierunku mnie (sprawdzanie pozycji mnie , wroga i ewentualna korekcja przez +1 / -1 XY)
Ma ktoś jeszcze pomysł , jak rozwiązać problem strzelania pociskami ? Nie chodzi tutaj czym , czy zmiana koloru , prosta animacja tylko o to jak tworzyć nowe zaraz po wystrzeleniu , żeby usser nie miał nad nim już kontroli. Lot jego to chyba na timerze trzeba zrobić , bo nie ma jak.

- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
@programista97 - możesz pokazać zrzut tej gry? Bo póki co nie rozumiem w ogóle co chcesz osiągnąć; Czemu linie z pliku czytasz "na żywo", zamiast załadować sobie cały plik do pamięci?

3000
post - jak miło :>
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
Tak wygląda całość : sorry za jakość. W kodzie jak zwykle muszę zrobić porządek. Na szczęście , po ostatnich waszych namowach nauczyłem się pisać w miarę czytelnie kod , więc poprawki będą dotyczyły tylko usunięcia poleceń "serwisowych"( sprawdzających coś , które nie działały , etc) oznaczonych jako komenty oraz zrobienie odpowiednich wcięć.
Na żywo miało wczytywać z dwóch powodów : plansze miały być potężne (Ile Microsoft Windows wierszy i kolumn dał), więc aby nie zapychać pamięci , dwa to modyfikacja w czasie gry : naciśnięcie klawisza , zrobienie jakiejś czynności miało modyfikować planszę ( tworzenie drzwi , przejść , nowych pomieszczeń czy nawet rysowanie planszy podczas gry. Obawiałem się ,że gdy ktoś będzie to odpalał na małej ilości pamięci , to może strasznie mulić
- gg.jpg (71 KB) - ściągnięć: 185

- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
No i co teraz potrzebujesz zrobić z tym wczytywaniem linii z pliku?
[...] więc poprawki będą dotyczyły tylko usunięcia poleceń "serwisowych"( sprawdzających coś , które nie działały , etc) oznaczonych jako komenty [...]
Nie rób tego komentarzami, bo za dużo z tym roboty... Polecam zrobić sobie prosty mechanizm logowania "serwisowych" informacji do pliku tekstowego; W tych miejscach, w których chcesz podglądnąć jakieś dane, wstaw instrukcje wpisujące wymagane dane do pliku; Na końcu zdefiniuj sobie symbol, np.:
{$DEFINE DEBUG_GAME}
i dyrektywami $IFDEF obejmij te linijki, np.:
{$IFDEF DEBUG_GAME}
LogData('[Coords] X: ', intX, ', Y: ', intY);
{$ENDIF}
Gdzie instrukcja LogData
dopisuje nową linijkę do pliku logu, a zmienne intX
i intY
to współrzędne jakiegoś obiektu;
Takich symboli możesz utworzyć więcej, aby móc logować informacje tylko danego typu; Dzięki temu będziesz mógł włączyć/wyłączyć dane logowanie za pomocą zaremowania lub odblokowania definicji;
W źródłach RTL i LCL jest sporo zaremowanych intrukcji DebugLn
; Wiadome - można ręcznie odblokowywać/blokować pojedyncze wywołania, jednak aby to zrobić ze wszystkimi - trzeba znaleźć wszystkie wywołania i coś z nimi zrobić.
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
Nie mam takich chyba poleceń , co musiałbym włączać i wyłączać - zostały stare śmieci przykład : z próby wywołania fullscreena ,nie udało się to dodałem to jako komentarz , aby dwa razy nie pisać ,jak znajdę błąd. Ale metoda jest genialna ! Dzięki , kiedyś ją wykorzystam ! No ! Kod wygląda coraz lepiej. Teraz już widać zagnieżdżone procedury ,instrukcje warunkowe. jeszcze z 30 minut i będzie czytelny , jak Michał Anioł namalował (nie chodzi o tego troyana :-) )

- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
Teraz już widać zagnieżdżone procedury ,instrukcje warunkowe.
Unikaj zagnieżdżania procedur/funkcji, a tym bardziej zagnieżdżania wielopoziomowego; Zaletą jest oczywiście czytelność i wydzielenie "uniwersalnego" fragmentu kodu do zastosowań lokalnych, ale kompilator potrafi wygenerować przez to niezłą siekę, czasem mocno nieoptymalną; Choć wiadome - są przypadki, w których jest to sensowne i uzasadnione;
Najlepiej by było, gdybyś całość pisał obiektowo - podzielił kod na czytelne klasy, bez używania globalnych elementów, czy luźno deklarowanych procedur, rozległych typów itd.; Łatwiej Ci będzie zarządzać kodem, no i czytelność wzrośnie;
Możesz zobaczyć na kod mojej gry - tam mam wszystko rozdzielone na moduły, a konkretne elementy gry, jak np. obsługa rozgrywki, malowania ekranu, timerów itd. opakowane są w czytelne klasy; Łatwo się ich używa i łatwo się też je modyfikuje czy rozwija.
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
Oto kodzik. Upiększałem go ręcznie , po program do modelowania kodu uszkodził mi poprzedni , nie mniej jest o wiele czytelniejszy niż poprzednio :
program game;
{$APPTYPE CONSOLE}
uses
SysUtils,windows,crt,MMSystem;
var
z:char; //przechowuje znak nac. klawisza
horizontal,life, points, pasek, znak, plansza :string;
x, x2, y, y2, metoda :byte; //metoda -metoda rysowania ludzika 0 lub 1;
showbar, mute :boolean;
muzyka :integer;
//////////////////////////////////////////////////////////////// K O D /////////////////////////////////////////////////////////////////
procedure FULLSCREEN;
begin
keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), 0, 0);
keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, 0), 0, 0);
keybd_event(VK_RETURN, MapVirtualKey(VK_RETURN, 0), KEYEVENTF_KEYUP, 0);
keybd_event(VK_MENU, MapVirtualKey(VK_MENU, 0), KEYEVENTF_KEYUP, 0);
end;
procedure fizyka ;//główne procedury gry
begin
// UPS ! TUTAJ MIAŁY ZNALEŹĆ SIĘ POLECENIA ODNOŚNIE FIZYKI.
end;
procedure Load;
var
Plik : TextFile; // nowa zmienna
S : String;
begin
writeln('');
AssignFile(Plik, plansza);
Reset(Plik);
repeat // petla
Readln(Plik, S); // odczytaj plik
writeln(horizontal+S); // dodaj linie ;-komentarz
until S = ''; // jeżeli napotkasz na pusta linie zakończ działanie pętli
CloseFile(Plik); // zamknij plik
end;
procedure bar;
begin
TextColor(9); //jniebieski
writeln('Life : '+life);
GotoXY(length('Life : '+life)+10,1);
TextColor(10);
writeln('Points : '+points);
GotoXY((length('Points : '+points)+length('Life : '+life)+20),1);
TextColor(13);
writeln('X_Y_KEY_MUSIC : '+inttostr(X)+'_'+inttostr(Y)+'_'+z+'_'+inttostr(muzyka));
TextColor(7);//normalny
end;
procedure postac;
begin
if metoda=0 then begin //podstawowa
crt.TextColor(12);
if showbar then begin
gotoXY(x+2,y+2);write('O');
gotoXY(x+1,y+3);write('/ł\');
gotoXY(x+2,y+4);write('/');
gotoXY(x+3,y+4);write('\');
end else begin
gotoXY(x+2,y+1);write('O');
gotoXY(x+1,y+2);write('/ł\');
gotoXY(x+2,y+3);write('/');
gotoXY(x+3,y+3);write('\');
end;
end;
if metoda=1 then begin
gotoXY(x+2,y+3);
writeln('Ü');
end;
crt.TextColor(7);
end;
procedure postac2;
begin
if metoda=0 then begin //podstawowa
crt.TextColor(1);
if showbar then begin
gotoXY(x2+2,y2+2);write('O');
gotoXY(x2+1,y2+3);write('/ł\');
gotoXY(x2+2,y2+4);write('/');
gotoXY(x2+3,y2+4);write('\');
end else begin
gotoXY(x2+2,y2+1);write('O');
gotoXY(x2+1,y2+2);write('/ł\');
gotoXY(x2+2,y2+3);write('/');
gotoXY(x2+3,y2+3);write('\');
end;
end;
if metoda=1 then begin
gotoXY(x+2,y+3);
writeln('Ü');
end;
TextColor(7);
end;
procedure audio;
begin
while z<>'x' do begin
Z:=crt.ReadKey;
TextColor(15);
clrscr;
writeln(horizontal+'Glosnosc dla WAV zmien : +/- , M-off/on mute');
if NOT mute then writeln(horizontal+'ł'+pasek) else writeln('ł');
gotoxy(52,2);
writeln('ł');
gotoxy(0,0);
if z='=' then if length(pasek)<51 then pasek:=pasek+'Ű';
if z='-' then if length(pasek)>0 then Delete(pasek, length(pasek)-1, 1);//usun ostatni znak
if z='m' then if mute then mute:=false else mute:=true;
if NOT mute then waveOutSetVolume(WAVE_MAPPER, Integer((length(pasek)*5 shl 24) or (length(pasek)*5 shl 8))) else
waveOutSetVolume(WAVE_MAPPER, Integer((0 shl 24) or (0 shl 8)));
end;
textColor(7);
z:=' ';
end;
procedure setmusic; //procedura ustawiająca aktualną melodię
begin
if NOT mute then begin
if muzyka=0 then PlaySound('music4.mus', 0, SND_ASYNC or SND_LOOP);
if muzyka=1 then PlaySound('music3.mus', 0, SND_ASYNC or SND_LOOP);
if muzyka=2 then PlaySound('music2.mus', 0, SND_ASYNC or SND_LOOP);
if muzyka=3 then PlaySound('music1.mus', 0, SND_ASYNC or SND_LOOP);
end;
end;
//--------------KOD GRY------------------------------------
procedure gra;
begin
setmusic;
while z<>'x' do begin
clrscr;
if showbar then bar;
load;
postac;
postac2;
z:=readkey;
////////////////ograniczenia obszarow konsoli , po któerych można się poruszać////////////////
if x<75 then if z='M' then x:=x+1;
if x>0 then if z='K' then x:=x-1;
if y<21 then if z='P' then y:=y+1;
if y>0 then if z='H' then y:=y-1; //ograniczenie o rozmiarów konsoli dla ludzika 1
if x2<75 then if z='d' then x2:=x2+1;
if x2>0 then if z='a' then x2:=x2-1;
if y2<21 then if z='s' then y2:=y2+1;
if y2>0 then if z='w' then y2:=y2-1; //ograniczenie o rozmiarów konsoli dla ludzika 2
if z='j' then if showbar then showbar:=false else showbar :=true; //pokaż ukryj pasek
if z='Q' then if muzyka>0 then muzyka:=muzyka-1; //pagedown - zmień na poprzednią melodię
if z='I' then if muzyka<3 then muzyka:=muzyka+1; //pageup -zmień na następną melodię
if ((z='Q') or (z='I')) then setmusic; //jeśli naciśnięto pagedown lub pageup ,to zacznij oddtwarzanie melodii /przerwij odtwarzanie bierzącej
if z='t' then if plansza='plansza2.txt' then plansza:='plansza.txt' else plansza:='plansza2.txt'; //zmaina planszy
if z='b' then FullScreen; //włacz pełny ekran
end;
z:=' '; //reset ostatniego, naciśniętego klawisza - znaku
end;
//------------------------KONIEC KODU GRY--------------------------------
procedure modyf;
begin
while z<>'x' do begin
ClrScr;
SetConsoleTitle('TEXTMAN -Ustawienia');
writeln('MODYFIKACJA GRY');
writeln('1.Centrowanie POZIOME');
writeln('Nacisnij prawy lub lewy klawisz.Ustaw środek');
TextColor(11);
writeln('<- -> ,Q-podglad, X-koniec');
writeln('Ustawienia jakości obrazu : Z -niska jakość V -wysoka jakość');
TextColor(12);
writeln(horizontal+'Ĺ');
Z:=crt.ReadKey;
TextColor(7);
if z='q' then begin
load;
readkey;
end;
if length(horizontal)<79 then if z='M' then horizontal:=horizontal+' '; //prawo dodaj spacje
if z='K' then Delete(horizontal, length(horizontal)-1, 1); //lewo -usuń ostatni znak
if z='z' then crt.LowVideo;
if z='v' then crt.HighVideo;
end;
Z:=' '; //resetuj ,aby ostatni znak to nie x
end;
procedure configmenu;
begin
while z<>'x' do begin
clrscr;
SetConsoleTitle('TEXTMAN -Main menu');
writeln(horizontal+'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»');
writeln(horizontal+'ş------------->CONFIGURATION<-------------ş');
writeln(horizontal+'ĚÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍą');
writeln(horizontal+'ş CONFIG MENU ş');
writeln(horizontal+'ČÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍĽ');
TextColor(9);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş 1ş- Ustawienia audio');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(10);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş 2ş- Ustawienia grafiki');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(14);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş Xş- Wyjscie');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(7);
Z:=crt.ReadKey;
if z='1' then audio ;
if z='2' then modyf ;
end;
z:= ' ';
end;
////////////////////////B O O T GRY//////////////////////////////////////
begin
SetConsoleTitle('TEXTMAN');
windows.beep(300,100);
windows.beep(400,100);
windows.beep(300,100);
windows.beep(400,100);
windows.beep(500,50);
windows.beep(300,50);
writeln('Witamy w GRZE. Copyright by ');
GotoXY(29 ,1);
TextColor(12);
writeln('Adam Xxxxxx');
GotoXY(0 ,2);
TextColor(7);
writeln('Press ');
GotoXY(7 ,2);
TextColor(11);
writeln('enter ');
GotoXY(14 ,2);
TextColor(7);
writeln('to continue...'); //kolorowanie tekstu
readln;
//////////////////////////////////// ustawienia poczatkowe ///////////////
pasek:='ŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰŰ'; //głośność 50 %
plansza:='plansza.txt'; //pierwsza plansza
life:='*****'; //życie
x:=29+length(horizontal);
y:=10;
x2:=11+length(horizontal);
y2:=20; //położenie ludzikow
metoda:=0; //metoda obrazowania ludzikow
horizontal:=' '; //centrowanie
points:='0'; //ustawienia początkowe
showbar:=false; //nie pokazuj na poczatku paska
////////////////////////////////////////////
waveOutSetVolume(WAVE_MAPPER, Integer((100 shl 24) or (100 shl 8))); //ustaw glośńóść na ok 50 %
PlaySound('music5.mus', 0, SND_ASYNC or SND_LOOP); //odtworz muzykę dla menu
while ((z<>'s') or (z<>'a') or (z<>'x')) do begin
if NOT mute then if z=' ' then PlaySound('music5.mus', 0, SND_ASYNC or SND_LOOP);
ClrScr;
SetConsoleTitle('TEXTMAN -Main menu');
writeln(horizontal+'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»');
writeln(horizontal+'ş------------->TEXTMAN<-------------ş');
writeln(horizontal+'ĚÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍą');
writeln(horizontal+'ş MAIN MENU ş');
writeln(horizontal+'ČÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍĽ');
TextColor(10);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş Sş- Start Gry');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(14);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş Aş- Ustawienia Gry');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(9);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş Xş- Wyjscie');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(7);
Z:=crt.ReadKey;
if z='s' then GRA ;
if z='a' then configmenu ;
if z='x' then exit ;
end;
end.
niestety -zrobiłem już paczkę z grą , ale jet duuużo większa niż 20MB , -głównie muzyka najwięcej zajmuje
O ! Program nie zajmuje już 400 KB tylko 57 KB :O
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
A co do ASCI wężyka to ekstra gra ! Szacun !

- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
To jeszcze nie jest gra - póki co można sztywną rozgrywkę zagrać; Wszystko jest obsługiwane - sterowanie wężem, łapanie złotka, wydłużanie, obsługa przechodzenia przez moduły, w których było złapane złotko, tryb turbo (tymczasowy i trwały), liczenie czasu w sekundach; Jednak docelowo ma wyglądać jak normalna gra - menu, lista graczy, różne tryby rozgrywki, zapisywanie wyników i inne bajery;
Jednak aby móc skompilować kod u siebie, trzeba dodać do projektu paczkę do obsługi plików TreeStructInfo - paczkę ze stabilnym API pobrać można stąd; Jeszcze wiele w tej grze będzie kiedyś dodane, ale potrzebuję czasu; A jak wiadomo, wolnego czasu zawsze zbyt mało.
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
czasu to każdy (a może nie ?) ma za mało. Menu to pikuś w porównaniu z samą grą.
-Co więc sądzisz o kodzie ? procedurę odtwarzania muzyki możesz wyłączyć i grę skompilować , albo ja ją skompiluję , bo nie zajmuje już więcej niż 59 KB więc jako załącznik spokojnie przejdzie.


- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
-Co więc sądzisz o kodzie ?
Hmm... Kod jest typowo proceduralny, momentami nieoptymalny;
Sugerowałem Ci wcześniej, abyś wszystko opakował w klasy - gra stricte obiektowa będzie łatwiejsza w zarządzaniu i rozwijaniu; Poza tym kod nie jest sformatowany, do tego zawiera zarówno polskie, jak i angielskie identyfikatory, a to błąd; Wybierz jeden język (najlepiej angielski) i wszystko w nim nazywaj; Do tego wstawiasz komentarze, które opisują czym jest kod, zamiast oznaczać co gdzie jest; Na przykład tu:
repeat // petla
Readln(Plik, S); // odczytaj plik
writeln(horizontal+S); // dodaj linie ;-komentarz
until S = ''; // jeżeli napotkasz na pusta linie zakończ działanie pętli
CloseFile(Plik); // zamknij plik
Opisujesz w komentarzach coś, co jest oczywiste;
Jeśli chodzi o inne kawałki kodu, to niedocięgnięć wcale nie jest tak mało; Ale może po kolei;
uses
SysUtils,windows,crt,MMSystem;
var
z:char; //przechowuje znak nac. klawisza
horizontal,life, points, pasek, znak, plansza :string;
x, x2, y, y2, metoda :byte; //metoda -metoda rysowania ludzika 0 lub 1;
showbar, mute :boolean;
muzyka :integer;
Góra zmiennych globalnych... Nie może tak być - opakuj wszystko w klasy i używaj ich pól, a w metodach tylko zmiennych lokalnych (ewentualnie pól klasy i stałych); Stałe mogą być globalne, ale pod warunkiem, że będą używane w całej aplikacji, lub przynajmniej w kilku jej modułach; Poza tym identyfikatory znów w róznych językach;
procedure FULLSCREEN;
Powinieneś ją nazwać SetConsoleFullScreen
; Przyjęło się, że samymi wielkimi literami nazywa się tylko i wyłącznie stałe; Poza tym polecam Ci używać pustych nawiasów w przypadku procedur, funkcji lub metod, które nie posiadają parametrów; Dzięki temu od razu widać, która instrukcja to procedura/funkcja/metoda, a które to zmienne; I jeszcze jedna rzecz - nazwy procedur, funkcji i metod powinny w pierwszym członie zawierać czasownik, np. Set*
, Get*
, Add*
, Remove*
, Init*
itd.; To pozwoli po samej nazwie zrozumieć co "podprogram" wykonuje;
procedure Load;
{...}
repeat // petla
Readln(Plik, S); // odczytaj plik
writeln(horizontal+S); // dodaj linie ;-komentarz
until S = ''; // jeżeli napotkasz na pusta linie zakończ działanie pętli
CloseFile(Plik); // zamknij plik
end;
Tego typu operacje powinieneś umieścić w bloku Try Finally, aby zabezpieczyć się przed ewentualnymi wyciekami pamięci, w przypadku zaistnienia wyjątku wewnątrz pętli;
procedure bar;
begin
TextColor(9); //jniebieski
writeln('Life : '+life);
GotoXY(length('Life : '+life)+10,1);
TextColor(10);
{...}
Używasz cyferek do ustawienia kolorów, które nie wiadomo jaki kolor określają; Korzystaj ze zdefiniowanych stałych, np. Blue
, White
, Yellow
itd.; Wszystkie te stałe zadeklarowane są w module Crt
;
procedure postac;
begin
if metoda=0 then begin //podstawowa
crt.TextColor(12);
if showbar then begin
gotoXY(x+2,y+2);write('O');
gotoXY(x+1,y+3);write('/ł\');
gotoXY(x+2,y+4);write('/');
gotoXY(x+3,y+4);write('\');
end else begin
gotoXY(x+2,y+1);write('O');
gotoXY(x+1,y+2);write('/ł\');
gotoXY(x+2,y+3);write('/');
gotoXY(x+3,y+3);write('\');
end;
end;
if metoda=1 then begin
gotoXY(x+2,y+3);
writeln('Ü');
end;
crt.TextColor(7);
end;
Źle formatujesz kod, łamiesz zasadę DRY
, nie korzystasz z instrukcji wyboru Case, poza tym nazwa procedury kompletnie nic nie mówi jej przeznaczeniu; Możesz tę procedurę napisać w ten sposób:
procedure DrawHero();
var
intOffset: Byte;
begin
case metoda of // nazwij tę zmienną sensowniej
0: begin
TextColor(12); // tu użyj stałej
intOffset := Byte(Boolean(ShowBar)) + 1;
GoToXY(X + 2, Y + intOffset + 1); Write('O');
GoToXY(X + 1, Y + intOffset + 2); Write('/ł\');
GoToXY(X + 2, Y + intOffset + 3); Write('/');
GoToXY(X + 3, Y + intOffset + 3); Write('\');
end;
1: begin
GoToXY(X + 2, Y + 3);
WriteLn('Ü');
end;
end;
TextColor(7); // użyj stałej
end;
W przypadku procedury postac2
zrób to samo, albo połącz te dwie procedury w jedną, bo różni je jedynie kolor, ustawiany na początku;
procedure audio;
{...}
if z='=' then if length(pasek)<51 then pasek:=pasek+'Ű';
if z='-' then if length(pasek)>0 then Delete(pasek, length(pasek)-1, 1);//usun ostatni znak
if z='m' then if mute then mute:=false else mute:=true;
Użyj instrukcji wyboru, bo za każdym razem i tak wszystkie warunki są sprawdzane - trzy razy sprawdzasz wartość zmiennej z
i nigdzie nie masz Else, więc cała drabinka jest sprawdzana;
procedure setmusic; //procedura ustawiająca aktualną melodię
begin
if NOT mute then begin
if muzyka=0 then PlaySound('music4.mus', 0, SND_ASYNC or SND_LOOP);
if muzyka=1 then PlaySound('music3.mus', 0, SND_ASYNC or SND_LOOP);
if muzyka=2 then PlaySound('music2.mus', 0, SND_ASYNC or SND_LOOP);
if muzyka=3 then PlaySound('music1.mus', 0, SND_ASYNC or SND_LOOP);
end;
end;
To da się mocno skrócić:
procedure SetMusic();
begin
if not Mute then
PlaySound(Format('music%d.mus', [4 - Muzyka]), 0, SND_ASYNC or SND_LOOP);
end;
Magia...
procedure gra;
{...}
if x<75 then if z='M' then x:=x+1;
if x>0 then if z='K' then x:=x-1;
if y<21 then if z='P' then y:=y+1;
if y>0 then if z='H' then y:=y-1; //ograniczenie o rozmiarów konsoli dla ludzika 1
if x2<75 then if z='d' then x2:=x2+1;
if x2>0 then if z='a' then x2:=x2-1;
if y2<21 then if z='s' then y2:=y2+1;
if y2>0 then if z='w' then y2:=y2-1; //ograniczenie o rozmiarów konsoli dla ludzika 2
if z='j' then if showbar then showbar:=false else showbar :=true; //pokaż ukryj pasek
if z='Q' then if muzyka>0 then muzyka:=muzyka-1; //pagedown - zmień na poprzednią melodię
if z='I' then if muzyka<3 then muzyka:=muzyka+1; //pageup -zmień na następną melodię
if ((z='Q') or (z='I')) then setmusic; //jeśli naciśnięto pagedown lub pageup ,to zacznij oddtwarzanie melodii /przerwij odtwarzanie bierzącej
if z='t' then if plansza='plansza2.txt' then plansza:='plansza.txt' else plansza:='plansza2.txt'; //zmaina planszy
if z='b' then FullScreen; //włacz pełny ekran
{...}
Znowu - użyj instrukcji Case... Poza tym do inkrementacji używaj Inc, a do dekrementacji Dec; No i taką konstrukcję:
if showbar then showbar:=false else showbar :=true;
można zamienić na prostą negację:
ShowBar := not ShowBar;
Krócej, prościej i szybciej;
procedure modyf;
{...}
if z='q' then begin
load;
readkey;
end;
if length(horizontal)<79 then if z='M' then horizontal:=horizontal+' '; //prawo dodaj spacje
if z='K' then Delete(horizontal, length(horizontal)-1, 1); //lewo -usuń ostatni znak
if z='z' then crt.LowVideo;
if z='v' then crt.HighVideo;
{...}
Znowu Case czeka na użycie;
procedure configmenu;
{...}
writeln(horizontal+'ÉÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍ»');
writeln(horizontal+'ş------------->CONFIGURATION<-------------ş');
writeln(horizontal+'ĚÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍą');
writeln(horizontal+'ş CONFIG MENU ş');
writeln(horizontal+'ČÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍÍĽ');
TextColor(9);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş 1ş- Ustawienia audio');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(10);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş 2ş- Ustawienia grafiki');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(14);
writeln(horizontal+' '+'ÉÍÍ»');
writeln(horizontal+' '+'ş Xş- Wyjscie');
writeln(horizontal+' '+'ČÍÍĽ');
TextColor(7);
{...}
Wpakuj te literały do macierzy i wyświetlaj w pętlach;
windows.beep(300,100);
windows.beep(400,100);
windows.beep(300,100);
windows.beep(400,100);
windows.beep(500,50);
windows.beep(300,50);
Te wartości także - zadeklaruj macierz dwuwymiarową i wywołuj procedurę Beep w pętli;
while ((z<>'s') or (z<>'a') or (z<>'x')) do begin
Korzystaj ze zbiorów:
while not (z in ['s', 'a', 'x']) do
Poza tym używasz literałów, więc nie będzie możliwości zmiany klawiszy sterowania;
if NOT mute then if z=' ' then PlaySound('music5.mus', 0, SND_ASYNC or SND_LOOP);
Łącz warunki, zamiast tworzenia osobnych instrukcji warunkowych:
if (not Mute) and (z = '') then
PlaySound('music5.mus', 0, SND_ASYNC or SND_LOOP);
if z='s' then GRA ;
if z='a' then configmenu ;
if z='x' then exit ;
Znowu **Case**a brakuje;
No i ciągle używasz dwóch instrukcji - GoToXY w połączeniu z Write; Stwórz sobie procedurę, która będzie od razu przenosić kursor w odpowiednie miejsce i wyświetlać tekst:
procedure DrawText(AX, AY: Byte; const AText: String);
begin
GoToXY(AX, AY);
Write(AText);
end;
Ewentualnie przyjmuj jeszcze w parametrze kolory tekstu i tła; Choć lepiej by było zaklearować drugą taką procedurę, i ją przeładować:
procedure DrawText(AX, AY: Byte; const AText: String); overload;
procedure DrawText(AX, AY: Byte; const AText: String; ATextColor, ABackColor: Byte); overload
To na początek tyle - wszystkiego nie sposób opisać w jednym poście :]
- Rejestracja:ponad 10 lat
- Ostatnio:prawie 10 lat
- Postów:31
No sporo niedociągnięć , ale tutaj po to właśnie jestem , aby ktoś dobrze mi podpowiedział. Myślę że jak wszystko poprawię , to wielkość programu będzie tak mała , że można by się pokusić ,żeby ją wgrać do jakiegoś procka :-) . Przede mną sporo jeszcze nauki.

- Rejestracja:ponad 13 lat
- Ostatnio:około 4 godziny
- Lokalizacja:Tuchów
- Postów:12167
Myślę że jak wszystko poprawię , to wielkość programu będzie tak mała , że można by się pokusić ,żeby ją wgrać do jakiegoś procka
Do jakiego procka? Masz na myśli jakiś mikrokontroler? Co prawda jest mikroPASCAL, więc można pisać w Pascalu i takie programy; Ale nie robiłem tego nigdy - jakiś czas temu poczytałem trochę z ciekawości.