• Welcome to Touhou Wiki!
  • Registering is temporarily disabled. Check in our Discord server to request an account and for assistance of any kind.

Touhou Danmakufu/Samples/03

From Touhou Wiki
Jump to navigation Jump to search

File List

Danmakufu_sample03
|
+-- Danmakufu_sample03.txt
|
+-- Danmakufu_sample03.h.txt
|
+-- img
    |
    +-- Danmakufu_sample03.png
    |
    +-- Danmakufu_familiar.png


Danmakufu_sample03.txt

#TouhouDanmakufu
#Title[Ambition Sign "Buretsu Crisis"]
#Text[IN Stage 3: Clone of the Keine's spell card]
#Image[.\img\Danmakufu_sample03.png]
#Player[FREE]
#ScriptVersion[2]

script_enemy_main {
    let Name    = "Ambition Sign "\""Buretsu Crisis"\";
    let ImgBoss = "script\img\ExRumia.png";

    // initial position
    let XIni    = GetCenterX;
    let YIni    = GetClipMinY + 128;

    @Initialize {
        SetLife(2000);
        SetTimer(33);
        SetScore(20000000);
        SetDamageRate(5, 5);

        LoadGraphic(ImgBoss);
        LoadGraphic(ImgFam);
        SetTexture(ImgBoss);
        setGraphicStop;

        CutIn(YOUMU, Name, "", 0, 0, 0, 0);

        TMain;
    }

    @MainLoop {
        SetCollisionA(GetX, GetY, 32);
        SetCollisionB(GetX, GetY, 16);
        yield;
    }

    @DrawLoop {
        DrawGraphic(GetX, GetY);
    }

    @Finalize {
        DeleteGraphic(ImgBoss);
        DeleteGraphic(ImgFam);
    }

    // main task
    task TMain {
        yield;

        ready;
        TRate;

        arrangeFam;

        TLevitate;
        TFire;
    }

    // change the damage rates
    task TRate {
        wait(120);
        SetDamageRate(60, 60);
    }

    // go to the initial position and ready to attack
    sub ready {
        let wIni = 120 - WArrFam;

        SetMovePosition02(XIni, YIni, wIni);
        setGraphicMove;

        SetInvincibility(wIni);
        wait(wIni);

        setGraphicPose;
    }

    // arrange the familiars
    sub arrangeFam {
        // the center of the familiar triangle
        // The x-coordinate is measured from the center line.
        let xFamCenter = (GetCenterX - GetClipMinX) / 2;
        let yFamCenter = YIni;

        // direction angle of the familiars from the center
        let angleFam   = [0, 120, -120];

        // summon the left familiars
        ascent(i in 0..3) {
            CreateEnemyFromScript("Familiar", GetCenterX - xFamCenter, yFamCenter,
                                  0, angleFam[i], 1);
        }

        // summon the right familiars
        ascent(i in 0..3) {
            CreateEnemyFromScript("Familiar", GetCenterX + xFamCenter, yFamCenter,
                                  0, angleFam[i] + 180, -1);
        }

        wait(WArrFam);
    }

    // levitate little bit
    task TLevitate {
        let angle = 0;

        loop {
            SetY(YIni + 4 * sin(angle));
            yield;

            angle += 3;
        }
    }

    // fire the aiming shots
    task TFire {
        loop {
            wait(170);
            CreateShot01(GetX, GetY, 0.8, GetAngleToPlayer, AQUA02, 60);
        }
    }

    // set the graphic region
    sub setGraphicStop  { SetGraphicRect(  0,   0,  64,  64); }    // stopping
    sub setGraphicPose  { SetGraphicRect( 64,   0, 128,  64); }    // special pose
    sub setGraphicLeft  { SetGraphicRect(128,   0, 192,  64); }    // move left
    sub setGraphicRight { SetGraphicRect(192,   0, 256,  64); }    // move right

    // set the graphic region according to the moving direction
    sub setGraphicMove {
        if(GetSpeedX < 0) {
            setGraphicLeft;
        } else {
            setGraphicRight;
        }
    }

    #include_function ".\Danmakufu_sample03.h.txt"
}

script_enemy Familiar {
    // center of the familiars
    let XCenter = GetX;
    let YCenter = GetY;

    // distance and direction angle from the center
    // The actual direction is dirBase + dir.
    let r       = 0;
    let dir     = 0;
    let DirBase = GetAngle;

    // moving direction (+-1)
    let DirMove = GetArgument;

    @Initialize {
        SetLife(2000);
        SetScore(10000);
        SetDamageRateEx(50, 50, 25, 25);

        SetTexture(ImgFam);
        setGraphicFast;

        TMain;
    }

    @MainLoop {
        // change the appearance according to the moving mode
        if(GetKeyState(VK_SLOWMOVE) == KEY_HOLD) {
            setGraphicSlow;
        } else {
            SetCollisionA(GetX, GetY, 32);
            setGraphicFast;
        }

        yield;
    }

    @DrawLoop {
        DrawGraphic(GetX, GetY);
    }

    // main task
    task TMain {
        yield;

        ready;

        TRotate;
        TFire;
    }

    // go to the initial position and ready to attack
    sub ready {
        let vr =  32 / WArrFam;    // radial velocity
        let w  = 210 / WArrFam;    // anglular velocity

        loop(WArrFam) {
            r += vr;
            move(w);
            yield;
        }
    }

    // rotate around the (XCenter, YCenter)
    task TRotate {
        wait(45);

        loop {
            move(0.77);
            yield;
        }
    }

    // fire to the center of the familiar triangle
    task TFire {
        loop {
            CreateShot01(GetX, GetY, 1, DirBase + dir + 180, AQUA12, 0);
            wait(10);
        }
    }

    // move to the next position
    //     w: angular velocity
    function move(w) {
        dir += w * DirMove;

        SetX(XCenter + r * cos(DirBase + dir));
        SetY(YCenter + r * sin(DirBase + dir));
        SetGraphicAngle(0, 0, dir);    // tilt the graphic
    }

    // set the graphic region
    sub setGraphicFast { SetGraphicRect( 0,  0, 48, 48); }    // on fast move
    sub setGraphicSlow { SetGraphicRect( 0, 48, 48, 96); }    // on slow move

    #include_function ".\Danmakufu_sample03.h.txt"
}


Danmakufu_sample03.h.txt

let CSD     = GetCurrentScriptDirectory;
let ImgFam  = CSD ~ "img\Danmakufu_familiar.png";

// frames to arrange the familiars
let WArrFam = 30;

// wait for w frames
function wait(w) {
    loop(w) { yield; }
}


Danmakufu_sample03.png

Danmakufu sample03.png


Danmakufu_familiar.png

Danmakufu familiar.png