Skocz do zawartości

Rekomendowane odpowiedzi

witam
chce zrobic pojawiajaca sie wiadomosc z wysrodkowanym textem
tzn.nie ważne jaki text bedzie dlugi chce by wiadomosc ktora sie wyswietli
na kazdej linijce miala max 40 znakow(jak bedzie wiecej to ma przeskoczyc na nastepna linijke, i byla wysrodkowana na kazdej lini

zmienna z tekstem to global.wiadomosc

ekran ma szerokosc 1280/800
wyswietlanie textu na srodku ekranu to:
draw_text(640,400,global.wiadomosc)

co mam dalej zrobic ?

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

draw_set_halign(fa_center) przed draw_text

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
10 minut temu, Uzjel napisał:

draw_set_halign(fa_center) przed draw_text

no dobra,a jak zrobić,by przeskakiwał tekst linijke niżej jak jest ponad 40 znaków?

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Spróbuj użyć draw_text_ext, nie jestem pewien, czy nowa linia będzie wyśrodkowana, musisz sprawdzić. Jeżeli nie, to pozostaje podzielenie linii np. do tablicy i rysować wg. własnego algorytmu.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Poczytaj o:

string_width(string)

https://docs.yoyogames.com/source/dadiospice/002_reference/strings/string_width.html

string_height(string)

https://docs.yoyogames.com/source/dadiospice/002_reference/strings/string_width_ext.html

string_width_ext(string, sep, w)

https://docs.yoyogames.com/source/dadiospice/002_reference/strings/string_width_ext.html

string_height_ext(string, sep, w)

https://docs.yoyogames.com/source/dadiospice/002_reference/strings/string_height_ext.html

 

To może Ci się na przyszłość przydać. Dzięki temu możesz sam wyliczyć dokładną pozycję tekstu. Co do Twojego problemu z linijką niżej. Od tego jest "#", czyli nowa linia.  Np.: "Tekst#Tekst2" zostanie wyświetlony jeden pod drugim:

Cytuj

Tekst
Tekst2

Musisz stawiać "#" w stringu co 40 znaków. Nie wiem jak dokładnie to u Ciebie działa, ale możesz to robić, albo ręcznie jeśli jest taka opcja w Twoim przypadku, albo musisz pod to napisać funkcję. To rozwiązanie jest o tyle fajne, że druga i każda kolejna linijka jest wyśrodkowywana według draw_set_halign.

Jeśli # odpada to poczytaj o tych funkcjach które podałem wyżej. Wyśrodkowanie tekstu który ma draw_set_halign(fa_left) - czyli domyślną wartość - robisz po prostu tak:

draw_string(x - string_width(str)/2, y, str);

Przy czym str to Twój string oczywiście ;)

Obliczenie nowej linii to po prostu:

draw_string(x - string_width(str)/2, y, str); //linia 1
draw_string(x - string_width(str2)/2, y + string_height(str), str2); //linia 2

Przy czym str to string linii pierwszej, a str2 to string linii drugiej.

Czyli dodajesz do Y wysokość stringa pierwszego.

Możesz też użyć według poprzedniej metody:

draw_set_halign(fa_center);
draw_string(x, y, str); //linia 1
draw_string(x, y + string_height(str), str2); //linia 2

Obie opcje dadzą ten sam efekt co:

draw_set_halign(fa_center);
draw_string(x, y, str + "#" + str2)

W zasadzie opcja z płotkiem tak, czy siak wydaję się chyba najprostsza. "fa_center" załatwi sprawę za Ciebie, a # możesz dodać na etapie algorytmu budowania takiego stringa. Czyli co 40 znaków dodawaj # i tyle.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

draw_text_ext i draw_set_halign załatwią sprawę, używam od lat.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
12 godzin temu, gnysek napisał:

draw_text_ext i draw_set_halign załatwią sprawę, używam od lat.

Tyle, ze parametr "W" w draw_text_ext liczy po pikselach, a nie znakach. Najczęściej to załatwia sprawę, ale może Ice Cube chce typowo 40 znaków wtedy draw_text z płotkiem i draw_set_halign powinien dać radę lepiej. Pytanie czy na prawdę mu to potrzebne, bo wiadomo, że draw_text_ext jest szybsze i prostsze. A te funkcje przytoczyłem, bo bardzo fajnie mieć ich świadomość. Ja używam ich czasami jeśli nie muszę co prawda wyśrodkowywać tekstu, ale potrzebuję wyliczyć jakaś mniej typową pozycję wyświetlania.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

draw_text_ext - jest fajne,ale liczy w pixelach ,a jak to policzyc w "stringach",chciałbym wiedzieć tak na przyszłość jak sie robi działania na tych "stringach" :D

 

znalazłem taką funkcje string_length(str) 

 

if string_length(global.wiadomosc)>40  znajdz miejsce miedzy slowami(spacje) w okolicach 40 i dodaj w tym miejscu #

 

show_message(tekst)

 

ktoś potrafiłby to ogarnąć?

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Ale 40 liter "i" a 40 liter "w" to jest 5x tyle szerokości, dlatego w pikselach lepiej moim zdaniem.

 

Jednak, zeby nie powiedzieć, że się nie da, to:

 

https://www.gmlscripts.com/script/string_wordwrap

 

string_wordwrap(string,40,"\n\r", false); // dla gms 1 można '#'

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Panowie, mój problem jest nieco inny, ale też dotyczy tekstu , nie chciałem więc zakładać nowego tematu. Chodzi mi o zawijanie tekstu.

 

Funkcja draw_text_ext pozwala na zawinięcie tekstu, jeśli przekroczy on odpowiednią ilość pixeli. Problem polega na tym, że dotyczy to tylko słów odseparowanych spacją. Jeśli string zawarty w tejże funkcji będzie składał się z jednego, długaśnego słowa, którego długość przekracza długość jednej całej linijki, to wrapowanie zostanie zignorowane :( . Czy wie ktoś jak sprawić, aby funkcja draw_text_ext wrapowała też pojedyńcze słowa, które są dłuższe niż długość jednej linijki?

 

Będę wdzięczny za pomoc,

nowy_user!

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Ma łamać nawet w pół słowa?

 

var stack = '', result = '', text = 'Lorem ipsum dolor sit amet', len = 40; // 40px;

for(i=1; i<=string_length(text); i++) {

  var c = string_char_at(text, i);

  if (string_width(stack + c) > len {

    result += stack + '#';

    stack = '';

  } else {

    stack += c;

  }

}

 

result += stack;

return stack;

 

Jakoś tak, ale to się na pewno wywali, jak len będzie mniejsze niż najszersza litera.

  • Lubię (+1) 1

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Dzięki Gnysek, ale nie do końca mi o to chodziło...

 

W Twoim przykładzie odnosimy się do ilości liter w danej zmiennej string, a mi chodzi po prostu o prawie taką samą funkcję jak draw_text_ext, gdzie możemy sobie wpisać długość linii ( wyrażoną w pikselach ) i po przekroczeniu tej wartości tekst jest przeniesiony do następnej linijki. To wszystko fajnie działa z funkcją draw_text_ext, do momentu, gdy jeden wyraz jest dłuższy (  w pikselach) od tej wartości podanej w draw_text_ext, wtedy dochodzi do takiej sytuacji, którą przedstawiam poniżej w obrazku:

 

image.png.354305a28492d43970861bbce51849f8.png

 

Chciałbym móc narysować tekst dokładnie tak jak to robię funkcją draw_tex_ext z tą jedną różnicą, że gdy dane słowo jest dłuższe ( w pikselach, a nie w ilości liter) niż wartość, którą podaje , to aby dzieliło ten wyraz i jego drugą część, która nie zmieściła się w jednej linijce, przeniosło do kolejnej linijki.

 

Mam nadzieję, że teraz opisałem mój problem bardziej klarownie, będę wdzięczny za pomoc :)

 

pozdrawiam,

nowy_user

 

 

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Cześć, możesz podzielić słowa które są dłuższe niż dana szerokość i rysować tekst za pomocą draw_text_ext. Skrypt do łamania słów:

/// scr_wrap_words(string,w)
var text = argument0, len = argument1;

var strlen = string_length(text);
var i = 1, c = '', word = '', result = '';

while (i < strlen + 1) {
    c = string_char_at(text, i++);
    
    if (string_width(word + c) > len) {
        word += '#';
    }
    
    word += c;
    
    if (c == ' ') {
        result += word;
        word = '';
    }
}

return result + word;

 

W połączeniu z draw_draw_text:

var text = scr_wrap_words("Lorem ipsum dolor sit amet, andverylongwordthatmustbesplitted.", 100);

draw_set_color(c_black);
draw_rectangle(10, 10, 110, 210, false);

draw_set_color(c_white);
draw_text_ext(10, 10, text, 15, 100);

 

Rezultat powinien być wystarczający:

gI2NzjV.png

  • Lubię (+1) 1

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
52 minuty temu, Konrad-GM napisał:

draw_text_ext(10, 10, text, 15, 100);

 

 

 

@Konrad-GM , dziękuję za ten kod, rzeczywiście działa,  no prawie bez zarzutu.  W sytuacji gdy przed tym dłuższym słowem dodamy więcej niż jedną spację tekst dalej będzie wychodzić poza kwadrat :( Po wpisaniu takiego kodu:

 

var text = scr_wrap_words("Lorem ipsum dolor sit amet,        andverylongwordthatmustbesplitted.", 100);

draw_set_color(c_black);
draw_rectangle(10, 10, 110, 210, false);

draw_set_color(c_white);
draw_text_ext(10, 10, text, 15, 100);

Mamy następującą sytuację: 

 

image.png.b824fe91900f356dc65536dc5afd9d58.png

 

Co ciekawe, jeśli zamieniłbym spację na jakikolwiek inny znak np. _  to działałoby bez zarzutu... tylko te przeklęte spacje psują cały efekt :(Gdybyś miał jakiś pomysł jak to naprawić to będę wdzięczny, choć już i tak dużo zrobiłeś wysyłając poprzedni kod.

 

Dzięki i pozdrawiam!

nowy_user

 

 

 

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

A mój skrypt nie działał dobrze ? Nie ten z gml scripts, ten drugi (włącz sortowanie w temacie po dacie, a nie po ocenie).

W skrypcie Kondrada-GM problemem jest fragment:

if (c == ' ') {
        result += word;
        word = '';
    }

który jak widzi spację, uznaje, że słowo się zmieściło i dodaje na result, przestając zliczać - tymczasem result powinno się resetować wraz z dodaniem znaku # (a najlepiej jeśli znak C to spacja albo pierwszy znak w linii go nie dodawać).

 

Czyli jakoś tak:

 

var stack = '', result = '', text = 'Lorem ipsum dolor sit amet', len = 40; // 40px;
for(i=1; i<=string_length(text); i++) 
  var c = string_char_at(text, i);
  if (string_width(stack + c) > len {
    result += stack + '#';
    stack = (c == ' ') ? '' : c; // W GMS1: if (c == ' ') stack = '' else stack = 'c';
  } else {
    stack += c;
  }
}

result += stack;
return stack;

 

  • Lubię (+1) 1

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach
  1. Gnysek, użyłem kodu według Twoich zaleceń, stworzyłem skrypt scr_wrap_words o następującej zawartości (dla GMS 1.4999):
/// scr_wrap_words(string,w)

var text = argument0, len = argument1;
var stack = '', result = '';

for(i=1; i<=string_length(text); i++) 
{
  var c = string_char_at(text, i);
  if (string_width(stack + c)) > len 
  {
    result += stack + '#';
    if (c == ' ') stack = '' else stack = 'c';
  } 
  else 
  {
    stack += c;
  }
}

result += stack;
return stack;

 

 a następnie wywołałem go z mojego obiektu za pomocą skryptu:

var text = scr_wrap_words('aaaaaaaaaaaaaaaaaaaaaaaaaaa',100);

draw_set_color(c_black);
draw_rectangle(10, 10, 110, 210, false);

draw_set_color(c_white);
draw_text_ext(10, 10, text, 15, 100);

Czyli jak widać , nawet nie kombinowałem ze spacją, a efekt jest taki:

image.png

 

... czyli ucięło kilkanaście pierwszych 'a' , tych które normalnie mieściłyby się w prostokącie, zostawiło tylko te, które miały wychodzić poza prostokąt, a dodatkowo, przed całym tekstem dodało literkę 'c', której w ogóle nie wprowadzałem. W takiej sytuacji nie dodawałem nawet podwójnej spacji, żeby się jeszcze bardziej nie wykrzaczyło. Hm.. co tu mogło pójść nie tak?

 

EDIT 

chyba wiem co, w Twoim skrypcie na końcu powinno być return result; zamiast return stack;  tak mi się wydaję, że po małej korekcie teraz już chyba działa ok :-) Wielkie dzięki za pomoc!

 

EDIT 2 , a jednak jeszcze nie działa tak jak należy, dla kodu : 

 

var text = scr_wrap_words('Tymon  Piotr   Usprawiedliwienie',100);


draw_set_color(c_black);
draw_rectangle(10, 10, 110, 210, false);

draw_set_color(c_white);
draw_text_ext(10, 10, text, 15, 100);

 

wyświetla się takie coś:

 

image.png.35d5ac3c15ce5744875560bcbc9936cc.png

 

czyli tekst właściwie się zawija, nawet przy trzech spacjach przed danym słowem, ale są dwa problemy:

1)  Zawija słowo Piotr, które spokojnie mogłoby się zmieścić cały w drugiej linijce. Kod powinien 'łamać' tylke te bardzo długie słowa, których długość (wyrażona w pikselach) wynosi więcej niż argument1. Czyli słowo Piotr powinno być tu przeniesione w całości do drugiej linijki, natomiast słowo Usprawiedliwienie jest właściwie podzielone

2) Skrypt dodaje  niepotrzebnie literkę c na początku kolejnych linijek, bez żadnego powodu. Własciwie to nie dodaje tylko podmienia, i zamiast Piotr mamy Piocr. 

 

 

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Ok, przerobiłem swój kod żeby łamał słowa jak i linie, traktując ciąg spacji również jak słowo:

/// scr_wrap_string(string,w)
var text = argument0, len = argument1;

var strlen = string_length(text);
var i = 1, c = '', w = '', word = '', line = '', result = '';

while (i <= strlen) {
    c = string_char_at(text, i++);
    w = string_char_at(word, 1);

    // lamanie tekstu
    if (c == '#') {
        result += line + word + '#';
        line = '';
        word = '';
        w = '';
        continue;
    }

    // przelamujemy linie
    if (line != '' && string_width(line + word) > len) {
        result += line + '#';
        line = '';
    }

    // przelamujemy slowo
    if (string_width(word + c) > len) {
        line += word + '#';
        word = '';
        w = '';
    }

    // budujemy slowo
    // ciag spacji traktujemy jako slowo
    if ((c == ' ' && (w == '' || w == ' ')) || (c != ' ' && w != ' ')) {
        word += c;
    }
    else {
        line += word;
        word = c;
        
        // linii nie zaczynamy spacja
        if (string_char_at(line, 1) == ' ') {
            line = '';
        }
    }
}

result += line;
result += word;
return result;

 

Jako, że teraz skrypt ten łamie tekst również w linii, nie potrzebujemy używać draw_text_ext a wystarczy draw_text:

var text = scr_wrap_string("Lorem ipsum dolor sit amet,                     andverylongwordthatmustbesplitted", 100);

draw_set_color(c_black);
draw_rectangle(10, 10, 110, 210, false);

draw_set_color(c_white);
draw_text(10, 10, text);

 

OYiWEyh.png

  • Super (+1) 1

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Wygląda na to że teraz działa! Jutro jeszcze potestuje, ale myślę, że teraz będzie ok. Wielkie dzięki Panowie za pomoc, budujecie Polską scenę GMa !

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

pisałem kod z głowy i nie testowałem, stąd niedoróbki - chyba i tak mi nieźle poszło, jak na nieodpalenie game makera :D

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Zgadza się Gnysek, bardzo dobrze Ci poszło,  ja np. nie potrafię sobie wyobrazić kodzenia bardziej skomplikowanych skryptów tylko głowie, zwłaszcza od czasu, gdy korzystam z gmlive to większość robię metodą prób i błędów. 

 

Dzięki jeszcze raz za pomoc. Teoretycznie zastanawiam się, czy można jeszcze jakoś sprawić, aby tekst który wychodzi poza kwadrat od dołu ( czyli gdy napiszemy wystarczająco dużo tekstu) nie był w ogóle wyświetlany…. ale nie chciałbym nadwyrężać Waszej życzliwości i gościnności.

 

Jeszcze raz dziękuję i pozdrawiam :-)

nowy_user

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

można, ale pytanie, czy faktycznie tego chcesz :) może lepiej narysować na surface i wyświetlać tylko jego część ? wtedy łatwiej by było go scrollować :)

  • Lubię (+1) 1

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Też o tym myślałem, problem w tym, że zamierzam mieć kilkadziesiąt takich boxów w jednym roomie, nawet ok 50 - 60 ... a  z tego, co mi wiadomo, to surface są bardzo pamięciożerne... ale pokombinuje i może coś fajnego mi wyjdzie :-)

 

 

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Ale możesz przecież rysować na jednym surface, nie musisz mieć 50. Rysuj, czyść, rysuj, czyść. To powinno być w miarę stabilne.

 

 

ale glScissor to by naprawdę ratował sporo, nawet gry rpg na starych konsolach wykorzystywały to do obcinania tekstów.

Udostępnij tego posta


Odnośnik do posta
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się tutaj.

Zaloguj się tutaj

  • Przeglądający   0 użytkowników

    Brak zarejestrowanych użytkowników, przeglądających tę stronę.

×