Specialeffekter och spelutveckling
i Java(TM) - Textscrollerexemplet, nu med konfigurerbar
font och bakgrundsbild (TextScroller3)
av Anibal Wainstein
6.0.3 Textscrollerexemplet,
nu med konfigurerbar font och bakgrundsbild (TextScroller3)
Kommer
du ihåg att TextScroller2
som vi skapade förut var ganska begränsad när
det gällde att bestämma appletens dimensioner och
textstorleken? Vi skall nu lägga till extra parametrar
så att appletanvändaren kan specifiera fontegenskaperna.
Även stöd för en bakgrundsbild och en parameter
för att snabba upp texten skall läggas in. Skapa
en tom fil som heter textscroller3.java och kopiera texten
från textscroller2.java. Glöm inte att ändra
"public class textscroller2" till "public class
textscroller3". Vi börjar med att lägga in
följande variabler under deklarationen för den gamla
variabeln "delay":
//Nu måste dimensionsvariabeln "d" vara
//globalt.
public Dimension d;
//Följande variabler används för att hantera
//fonten.
public Font font;
public FontMetrics metrics;
//Variabeln "backgroundimage" kommer att vara
//bakgrundsbilden för textscrollern.
public Image backgroundimage=null;
//För att användaren skall kunna
//snabba upp texten, så skapar
//vi en variabel "textspeed".
public int textspeed;
Förut
använde vi variabeln "d" för att temporärt
lagra appletens storlek. Nu måste vi veta detta även
utanför init() metoden (i paint()), därför
måste den vara global. Nu lägger vi också
två variabler för att lagra fonten och mätinformationen
för fonten. Variabeln "backgroundimage" kommer
att innehålla bakgrundsbilden, om nu användaren
vill specifiera en. Variabeln "textspeed" är
texthastigheten. Ta nu och lägg till följande rad
under inläsningen av parametern "textcolor":
//Nu skall variabeln "textspeed" läsas in så
//att användaren kan specifiera texthastigheten.
textspeed=getIntegerParameter("textspeed",10);
Nu
gäller det att läsa in fontparametrarna. Skriv in
följade rader efter raden ovan:
//Ta reda på om användaren har valt fet eller kursiv stil och
//indikera detta med variabeln "fonttype".
int fonttype=0;
if (getParameter("italic")!=null && getParameter("italic").substring(0,1).equalsIgnoreCase("y"))
fonttype+=Font.ITALIC;
if (getParameter("bold")!=null && getParameter("bold").substring(0,1).equalsIgnoreCase("y"))
fonttype+=Font.BOLD;
//Skapa en font med de parametrar som har
//specifierats.
font=new Font(getParameter("font"),fonttype,getIntegerParameter("fontsize",10));
Två
parametrar kommer att användas när man ska specifiera
fet eller kursiv stil, "bold" resp. "italic".
Om applet användaren specifierar "yes" på
dessa så betyder det att man har valt den stilen. Det
är flera problem som uppkommer här. Användaren
kan helt enkelt glömma bort att specifiera detta, eller
så kan han använda stora bokstäver när
han skriver "yes", eller så kan han bara skriva
"y". Om han glömmer bort att specifiera "italic"
eller "bold" parametrar så kommer getParameter()
att returnera null. Därför måste vi först
undersöka detta. Vi använder sedan substring() metoden
för att undersöka vad första bokstaven är.
Det tredje som vi gör är att konvertera bokstaven
till små bokstäver och jämför den med
"y". Detta görs med equalsIgnoreCase() metoden
i String. Om det är "y" så läggs
integervärdet "Font.ITALIC" respektive "Font.BOLD"
till variabeln "fonttype". Observera att när
"fonttype" är 0, så motsvarar det värdet
"Font.PLAIN". Vad som kan verka förvirrande
är det faktum att vi gör allt detta på en
enda rad. Nu är det så att getParameter returnerar
en String-objekt. Att skriva ".substring()" med
punkten före, innebär att vi anropar det returnerade
objektets substring() metod, som ju finns i String klassen.
Metoden substring() returnerar i sin tur ännu en String-objekt
som vi kan använda för att jämföra med
"y" genom att skriva ".equalsIgnoreCase()".
Variabeln "fonttype" kan sedan användas för
att skapa fonten. I de raderna så läser vi in parametern
"font" som får specifiera fontnamnet och vi
använder getIntegerParameter() för att läsa
in "fontsize".
Nu är det dags att läsa in bakgrundsbilden. Det
är två problem som vi stöter på här.
Först måste vi med if-satsen undersöka om
användaren har specifierat en bakgrundsbild. Har han
gjort det, så måste vi vidare undersöka om
det är en "JPG" eller "GIF" bild
som är de enda två format som stöds av Java.
När det är gjort så använder vi innehållet
i "backimage" strängen för att läsa
in bilden. Skriv in följande rader efter raderna som
skapar fonten:
//Följande rad hämtar en bakgrundsbild om nu
//appletanvändaren har specifierat det. Metoden
//toUpperCase() ser till att bildens namn är
//i stora bokstäver, innan man testar om det
//är en JPEG eller GIF bild.
MediaTracker tracker=new MediaTracker(this);
String backimage=getParameter("backgroundimage");
if (backimage!=null &&
(backimage.toUpperCase().indexOf("JPG")>-1 ||
backimage.toUpperCase().indexOf("GIF")>-1))
{
backgroundimage=getImage(getDocumentBase(),backimage);
tracker.addImage(backgroundimage,0);
try {tracker.waitForAll();}
catch(InterruptedException e) {}
}
Om
nu användaren inte specifierar en bakgrundsbild, så
kommer "backgroundimage" att behålla värdet
null. Senare, när det är dags att rita ut bilden,
kommer vi då att veta om vi skall göra det eller
rensa skärmen med den specifierade bakgrundsfärgen
istället. Nu tar du bort raderna som skapar bufferten
och byter ut dem mot följande rader:
//Observera nu att Dimension togs bort.
d=size();
bufferimage=createImage(d.width,d.height);
bufferg=bufferimage.getGraphics();
//Initiera "metrics" variabeln så att
//den kan användas för att mäta fonten.
bufferg.setFont(font);
metrics=bufferg.getFontMetrics();
//"x" måste initieras så att texten
//börjar scrolla utanför skärmen.
x=d.width;
Observera
att nu togs Dimension-ordet bort, därför att nu
är "d" globalt. Nu initierar vi "metrics"
variabeln så att man kan börja mäta på
fonten. Eftersom vi kommer att rita på just bufferten,
så använder vi den för att skapa FontMetrics-objektet.
Kommer du ihåg att vi initierade "x" så
att texten började på x-positionen 200? Vi hade
ju appletbredden 200 förut, men nu är bredden godtycklig
och bara appletanvändaren vet vad bredden skall vara.
Därför initierar vi "x" till "d.width"
istället, som är appletbredden som appletanvändaren
har definerat.
Det
är ett antal ändringar som måste göras
i paint() metoden innan vi är färdiga:
public synchronized void paint(Graphics g)
{
if (bufferg!=null)
{
//Nu måste vi undersöka om användaren
//specifierade en bakgrundsbild.
//Detta vet vi, för att om han gjorde
//det så är variabeln "backgroundimage"
//inte "null". Om den är det, så
//använder vi den specifierade
//bakgrundsfärgen för att rensa skärmen
//istället.
if (backgroundimage!=null)
{
bufferg.drawImage(backgroundimage,0,0,this);
}
else
{
bufferg.setColor(backgroundcolor);
//fillRect() metoden ändras så att den
//nu rensar den area som användaren
//har specifierat.
bufferg.fillRect(0,0,d.width,d.height);
}
bufferg.setColor(textcolor);
//Meddelandet centreras i skärmen
//med hjälp av värdet (d.height-metrics.getHeight())/2.
bufferg.drawString(message,x,(d.height-metrics.getHeight())/2+metrics.getAscent());
g.drawImage(bufferimage,0,0,this);
//Scrollgränsen måste ändras så att den anpassas
//för godtyckliga applet- eller textdimensioner.
if (x<-metrics.stringWidth(message)) x=d.width;
//Nu används innehållet i "textspeed"
//för att minska "x". Ju högre siffra
//i "textspeed" desto snabbare rör sig
//texten.
x-=textspeed;
}
}
Vi
utnyttjar det faktum att backgroundimage har värdet null,
för att veta om användaren specifierade en giltig
bild eller inte. Har han gjort det, så ritar vi ut den,
annars så rensar vi skärmen precis som förut.
När vi nu skall rita ut meddelandet så använder
vi som förut "x" som horizontell position.
Men nu vill vi att meddelandet skall vara vertikalt centrerat
på skärmen. Det är nu vi får nytta av
"metrics" variabeln. Först så måste
vi lägga på ascent-värdet för fonten
så att fonten börjar ritas ut från där
vi pekar, detta görs med metrics.getAscent(). Nu kan
vi centrera texten genom att ta fram appletens och textens
höjd, "d.height" resp. "metrics.getHeight()".
Drar man bort textens höjd från appletens höjd
och delar med två. Så får man en "centreringssiffra"
som man kan lägga till textens y-position. Räkna
på det, så får du se. Det sista som måste
göras gäller scrollningen. Vi måste initiera
"x" till "d.width" så att texten
börjar om från början när den har scrollat
bort utom synhåll, dvs när "x" är
mindre än textens bredd. Variabeln "textspeed"
används nu för att dekrementera "x". Genom
att öka på "textspeed" kommer alltså
"x" att minska i en snabbare takt och texten ser
ut att röra sig med högre hastighet. Du kan pusta
ut när det gäller run() metoden, vi behöver
inte göra några ändringar där. Däremot
skall vi ändra på HTML parametrarna lite:
<APPLET CODE="textscroller3.class" WIDTH=300 HEIGHT=40> <PARAM name="message" value="Detta är TextScroller3, nu med konfigurerbar font och bakgrundsbild"> <PARAM name="font" value="Courier"> <PARAM name="italic" value="no"> <PARAM name="bold" value="yes"> <PARAM name="fontsize" value="32"> <PARAM name="backgroundimage" value="background.jpg"> <PARAM name="backgroundcolor" value="000000"> <PARAM name="textcolor" value="ffff00"> <PARAM name="textspeed" value="5"> <PARAM name="delay" value="50"> </APPLET>
Här
ovan har vi specifierat att vi vill använda fonten "Courier"
med fet stil och fontstorleken 32. Texthastigheten har satts
till 5 pixels per bildruta och bakgrundsbilden vi kommer att
använda heter "background.jpg". Den är,
och måste, vara exakt lika stor som appletdimensionerna,
300x40 pixels. Klicka
här för att se TextScroller3.
Nästa sida >>
|