Hem E-böcker Specialeffekter och spelutveckling i Java Rymdpiraterna kommer!

Specialeffekter och spelutveckling i Java(TM) - Rymdpiraterna kommer!

av Anibal Wainstein

5.1.3 Rymdpiraterna kommer!

Nu kommer du att märka att allt krångel med polisskeppets rörelser kommer att löna sig. Rymdpiraterna kommer att röra sig likadant och då kommer de där rutinerna väl till pass. Animationen för piratskeppen lagras i Image-arrayen "pirateship" och ser ut som följande:

pirateship[0] pirateship[1] pirateship[2] pirateship[3] pirateship[4]

Som du ser så är dom riktade åt andra hållet. Självklart, vad trodde du? Ditt skepp är inte SÅ skräckinjagande så att dom flyr för glatta livet. Vi börjar med att lägga upp deklarationerna:

//I variabeln "pirateship" är animationen
//för piratskeppen lagrade.
Image pirateship[];

//Det behövs fyra int-arrayer för
//rymdpiraternas  rörelser.
//"piratev" indikerar den vertikala hastigheten.
//"piratepy" indikerar den vertikala positionen.
//"piratepx" indikerar den horizontella positionen.
//"piratey" indikerar den vertikala positionen
//som piraten skall komma upp till efter en stund,
//dvs destinationen.
int piratev[],piratepy[],piratepx[],piratedy[];

//"maxpirates" indikerar hur många pirater som
// visas i skärmen samtidigt.
int maxpirates=3;


Eftersom vi har flera pirater i rymden så måste vi ha arrayer för att lagra rörelseegenskaperna för var och en. Arrayen "piratev" motsvarar hastigheten "v" hos polisskeppet. Den vertikala positionen "piratepy" motsvarar "py" och "piratey" motsvarar muspekarens position "y0". Nu måste vi också ha en variabel för att lagra den horizontella positionen hos piratskeppen, så vi lägger till arrayen "piratepx". De här skeppen kommer att röra sig genom skärmen mot polisskeppet. Genom att ändra på maxpirates skall man kunna bestämma hur många pirater som kan visas på skärmen samtidigt. I init() metoden måste vi först lägga in funktionen för att ladda in animationen. Lägg in följande rader mellan inladdningen av "ground" och "try" raden:

//Piratskeppen laddas in. De läggs i position 6
//och framåt på spåraren.
pirateship=new Image[5];
for (int i=0; i<5; i++)
{
    pirateship[i]=getImage(getDocumentBase(),"pirateship"+i+".gif");
    tracker.addImage(pirateship[i],i+6);
}

Observera att vi har skrivit in "+6" så att piratskeppen hamnar efter "ground" bilden i spåraren. Initieringen av piratskeppen läggs in efter inladdningen av bilderna och ser ut som följande:

//Max fyra pirater skall finnas på skärmen
//samtidigt.
piratev=new int[maxpirates];
piratepy=new int[maxpirates];
piratepx=new int[maxpirates];
piratedy=new int[maxpirates];

//Piratskeppen initieras.
for (int i=0; i<maxpirates; i++)
    initPirateShip(i);

Metoden initPirateShip() används för att initialisera piratskeppens position och destination. Kommer du ihåg att när vi skrev rutinerna för polisskeppets rörelser, så använde vi oss av variabeln "y0" som vertikal destination för skeppet? Vi kommer att använda samma trick här, men nu bestäms den vertikala destinationen av ett slumpvärde mellan 0 och 300 (300 är höjden på appleten). Även startpunkten för piratskeppet får ett slumpvärde. För att räkna ut slumpvärdet använder vi random() metoden som vi beskrev i kapitel4. Metoden initPirateShip() ser ut så här:

public void initPirateShip(int n)
{
    piratev[n]=0;

    //De vertikala start- och destinationspunkterna
    //får vara slumpmässiga.
    piratepy[n]=(int) (Math.random()*300.0);
    piratedy[n]=(int) (Math.random()*300.0);

    //Också skeppets horizontella position är
    //slumpmässig, fast vi lägger till ett värde
    //så att skeppet startar alltid 
    //utanför appletskärmen.
    piratepx[n]=(int) (Math.random()*300.0+400.0);
}

Det börjar redan bli svårläst i run() metoden och innan vi lägger in ännu mer rader får vi rensa. Vi gör en egen metod av raderna som hanterar polisskeppets rörelser. Detta kan vi göra utan risk eftersom polisskeppets variabler är globala:

public void movePoliceShip()
{
    //movePoliceShip() metoden hanterar
    //polisskeppets rörelser.
    if (y0-py>0)
    {
        v++;
        if (y0-py<10) v=3;
        if (y0-py<5) v=1;
    }
    if (y0-py<0)
    {
        v--;
        if (y0-py>-10) v=-3;
        if (y0-py>-5) v=-1;
    }
    if (y0-py==0) v=0;
    if (v<-4) v=-4;
    if (v>4) v=4;
    py+=v;
}

För att hantera piratskeppens rörelser så skapar vi nu en liknande metod:

public void movePirateShips()
{
    //movePirateShips() metoden hanterar
    //piratskeppens rörelser.
    for (int i=0; i<maxpirates; i++)
    {
        //Först tar man hand om de vertikala
        //rörelserna. Dessa rutiner är
        //identiska med polisskeppets men
        //man använder arrayer istället.
        if (piratedy[i]-piratepy[i]>0)
        {
            piratev[i]++;
            if (piratedy[i]-piratepy[i]<10) piratev[i]=3;
            if (piratedy[i]-piratepy[i]<5) piratev[i]=1;
        }
        if (piratedy[i]-piratepy[i]<0)
        {
            piratev[i]--;
            if (piratedy[i]-piratepy[i]>-10) piratev[i]=-3;
            if (piratedy[i]-piratepy[i]>-5) piratev[i]=-1;
        }
        if (piratedy[i]-piratepy[i]==0) piratev[i]=0;
        if (piratev[i]<-4) piratev[i]=-4;
        if (piratev[i]>4) piratev[i]=4;
        piratepy[i]+=piratev[i];

        //Nu räknar man ut det horizontella rörelserna.
        //Om piratskeppet har åkt förbi polisskeppet så
        //"skapa" ett nytt skepp.
        if (piratepx[i]<-100) initPirateShip(i);

        //Piratskeppen rör sig med hastigheten 4.
        piratepx[i]-=4;

        //Om slumpvärdet är mindre än 0.05 så räkna ut en
        //ny vertikal destination.
        if (Math.random()<0.05) piratedy[i]=(int) (Math.random()*300.0);
    }
}

Som du ser så är raderna som hanterar piratskeppens vertikala rörelser nästan identiska med polisskeppets. Skillnaden är att vi nu har en for-slinga som ser till att alla piratskeppens variabler uppdateras. I metoden har vi också lagt in rader för att skeppen ska röra sig åt vänster med hastigheten 4. När skeppen kommer utanför skärmen, dvs passerar polisskeppet, så anropas initPirateShip() så att piratskeppet får nya värden och placeras på andra sidan skärmen. Detta ger spelaren intrycket att ett nytt skepp är på ingång. Den sista raden används för att räkna ut en ny vertikal destination för skeppet. I praktiken kommer det att se ut som om en "osynlig muspekare" klickar så att skeppet rör sig sidledes. Detta händer bara när slumpvärdet som räknas ut i if-satsen råkar vara mindre än 0.05 (som vi sa tidigare ger random() flyttalsvärden mellan 0 och 1). Det betyder att det finns en 5% chans att piratskeppen svänger i varje bildruta. Till sist tittar vi också på run() metoden:

public void run()
{
    while (true)
    {
        //Alla rader som hanterar polisskeppets
        //metoder har flyttats ut till metoden
        //movePoliceShip().
        movePoliceShip();

        //Metoden movePirateShips() hanterar
        //piratskeppens rörelser.
        movePirateShips();

        groundposition-=2;
        if (groundposition<-600) groundposition=0;
        bufferg.drawImage(ground,groundposition,0,this);
        if (groundposition<-200)
            bufferg.drawImage(ground,(groundposition+600),0,this);

        //For-slingan ritar ut alla piratskepp.
        //Nu använder vi piratepx för att placera
        //piratskeppen horizontellt.
        for (int i=0; i<maxpirates; i++)
            bufferg.drawImage(pirateship[2+piratev[i]/2]
                 ,piratepx[i],-25+piratepy[i],this);

        bufferg.drawImage(policeship[2+v/2],0,-55+py,this);
        update(getGraphics());
        try {Thread.sleep(sleeptime);}
        catch(InterruptedException e) {}
    }
}


Observera att vi nu anropar movePoliceShip() och movePirateShips() i början av run() metoden. Den nya for-slingan används för att rita ut piratskeppen. Samma trick som i fallet med polisskeppet används för att rita ut rätt bild på piratskeppet. Den justeras också med 25 pixlar uppåt så att medelpunkten på piratskeppet centreras kring "piratepy" positionen. Klicka här för att se resultatet.

 

 

Nästa sida >>