Hem E-böcker Specialeffekter och spelutveckling i Java Textscrollerexemplet 

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 >>