News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

Word Wrap Function

Started by Tifu, February 05, 2009, 06:03:31 PM

Previous topic - Next topic

Tifu

My new game has a lot of documents for the player to read, and I couldn't find wordwrap code anywhere so I quickly whipped some up myself ;D

PlayBASIC Code: [Select]
FUNCTION WordWrap(limit,x,y,tempstring$)
; limit is the number of characters allowed per line
; x is the x location for the text command
; y is the y location for the text command
; tempstring$ is the text to be word wrapped
; repeats until whole phrase is printed to screem
REPEAT
; repeats until a line is complete
NEWLINE=0
REPEAT
wordend=0: char=0
word$=""
; repeat until a word is complete
REPEAT
; build up word letter by letter
word$=word$+LEFT$(tempstring$,1): tempstring$=RIGHT$(tempstring$,LEN(tempstring$)-1)
; if you reach a space, then it is the end of a word
if RIGHT$(word$,1)=" " then WordEnd=1
char=char+1
; precaution in case there are no spaces in phrase, in such a condition it
; won't print properly, but shouldn't crash game :)!
if char>=limit then WordEnd=1
UNTIL WordEnd=1
; work out if the length of the current line is over the limit
totalLEN=LEN(line$)+LEN(word$)
; if current line is over the limit, we take a new line
if totalLEN>limit then NEWLINE=1
; if not we add the current word to the current line, and go add a new word
if totalLEN<=limit
line$=line$+word$
endif
; again, precaution to prevent game crashing
if char>=limit then NEWline=1
UNTIL NEWLine=1
; print to screen!
text x,y,line$
; the last word to be calculated gets put on the next line
line$=word$
; move text down 20
y=y+20
; and see if we are done!
lengthstring=LEN(tempstring$)
UNTIL lengthstring<=0
; done?
EndFunction



And now someone will tell me playbasic has a command to do this normally and I just wasted 30 mins ;D

reno

No, I don't think PB has a command for this ;)
More games ? Go to my website :)
http://www.thereeteam.com/

kevin

#2
Tifu,

  Thanks for posting your code.  I'm not sure if your familiar with them or not, but you could probably simplify the way it breaks downs the words with the MID$() and MID() functions.   Using the Left$() and Right$() combination is a real memory thrasher  

  A bit like this

PlayBASIC Code: [Select]
   S$="This is the message that i want to wrap this is some more text stuff"
WordWrapTest(10,0,0,s$)

Sync
waitkey



FUNCTION WordWrapTest(limit,x,y,tempstring$)

StringLen=Len(TempString$)
height=GetFontHeight(GetCurrentFont())
Pos=1
repeat
Found=False
EndPos=ClipRange(Pos+limit,1,StringLen)

// Scan from the end of this row backwards,looking for a space chr.
// if we find it, then this becomes the row length
for lp=EndPOs to Pos step -1
If mid(TempString$,lp)=32
Row$=mid$(TempString$,Pos,lp-pos)
pos=lp+1
Found=true
exitfor
endif
next

// if no space was present, then this line is probably too long for the row
if Found=false
// if this occurs, the text in this row is longer than than viewport character width
// so it just dumps it and moves on :)
Row$=mid$(TempString$,Pos,Limit)
pos=pos+limit
endif

text x,y,Row$
Y=y+height
until pos>=Len(TempString$)

EndFunction


     

  Another option might be to use SPlitToArray(),  which could do all the word separation work for you.

darkx

#3
I ran the code from Kevin and there seems to be a bug that last word is always moved below.

PlayBASIC Code: [Select]
wordwraptest(640,0,0,"Test Hello")
sync
waitkey
end

Function WordWraptest(limit,x,y,tempstring$)

StringLen=Len(TempString$)
height=GetFontHeight(GetCurrentFont())
Pos=1
Repeat
Found=False
EndPos=ClipRange(Pos+limit,1,StringLen)

// Scan from the end of this row backwards,looking for a space chr.
// if we find it, then this becomes the row length
For lp=EndPOs To Pos Step -1
If Mid(TempString$,lp)=32
Row$=Mid$(TempString$,Pos,lp-pos)
pos=lp+1
Found=True
ExitFor
EndIf
Next

// if no space was present, then this line is probably too long for the row
If Found=False
// if this occurs, the text in this row is longer than than viewport character width
// so it just dumps it and moves on :)
Row$=Mid$(TempString$,Pos,Limit)
pos=pos+limit
EndIf

Text x,y,Row$
Y=y+height
Until pos>=Len(TempString$)

EndFunction





"Test" and "Hello" are suppost to be on the same line.

kevin

#4
PlayBASIC Code: [Select]
   S$="Hello World"

WordWrapTest(100,0,0,s$)

Sync
waitkey



FUNCTION WordWrapTest(limit,x,y,tempstring$)

StringLen=Len(TempString$)
height=GetFontHeight(GetCurrentFont())
Pos=1
repeat
EndPos=Pos+limit

if EndPos<StringLen
// Scan from the end of this row backwards,looking for a space chr.
// if we find it, then this becomes the row length
Found=False
for lp=EndPos to Pos step -1
If mid(TempString$,lp)=32
Row$=mid$(TempString$,Pos,lp-pos)
pos=lp+1
Found=true
exitfor
endif
next

// if no space was present, then this line is probably too long for the row
if Found=false
// if this occurs, the text in this row is longer than than viewport character width
// so it just dumps it and moves on :)
Row$=mid$(TempString$,Pos,Limit)
pos=pos+limit
endif

else
Row$=mid$(TempString$,Pos,StringLen+1-pos)
Pos=StringLen+1
endif

text x,y,Row$
Y=y+height
until pos>=StringLen

EndFunction





Tifu

That one seems to work great. Much thanks :)

kevin

#6
 Just a point,  but I wasn't actually posting an alternative version, it's more an example of how you could use MID().

If you have lots of text dialogs, then you might want to look into something along the lines of a simple markup parser.   So you can embed tags within the content.