Fandom

Touhou Wiki

Touhou Danmakufu: Object Bullets

7,297pages on
this wiki
Add New Page
Talk0 Share

Ad blocker interference detected!


Wikia is a free-to-use site that makes money from advertising. We have a modified experience for viewers using ad blockers

Wikia is not accessible if you’ve made further modifications. Remove the custom ad blocker rule(s) and the page will load as expected.


Overview

Object bullets are ones created by Obj_Create. Object bullets can be used as the standard bullets created by CreateShot01. In fact, object bullets are used in that manner except that the bullets have bomb-resistance. But, in many cases, object bullets are minutely controlled frame by frame like Reisen's danmaku. In order to control the object bullets, microthreads are very very useful.

Object Bullets

Example

// Homing shot
//     x      : x-coordinate
//     y      : y-coordinate
//     v      : velocity
//     angle  : initial direction angle
//     graphic: garphic of bullet
//     delay  : delay frame
task THomingShot(x, y, v, angle, graphic, delay) {
    // bullet object
    let obj = Obj_Create(OBJ_SHOT);

    // initial settings
    Obj_SetPosition   (obj, x, y);
    Obj_SetSpeed      (obj, v);
    ObjShot_SetGraphic(obj, graphic);
    ObjShot_SetDelay  (obj, delay);

    // control the direction
    let maxTraverse = 0.5;    // max. angle of traverse
    while(! Obj_BeDeleted(obj)) {
        Obj_SetAngle(obj, angle);
        yield;

        // direction angle to player's character
        let dir = atan2(GetPlayerY - Obj_GetY(obj),
                        GetPlayerX - Obj_GetX(obj));

        // difference between 'dir' and 'angle'
        let diff = dir - angle;
        while(diff >= 180) { diff -= 360; }    // adjust the range
        while(diff < -180) { diff += 360; }

        let diffAbs = (|diff|);
        if(diffAbs < maxTraverse) {
            // if the difference is small,
            // the bullet turns to the player's character
            angle = dir;
        } else {
            // otherwise, the bullet turns 'maxTraverse' degrees
            angle += maxTraverse * diff / diffAbs;
        }
    }
}

This microthread can be used like CreateShot01.


Object Lasers

Example

// Reflection laser
//     x      : x-coordinate
//     y      : y-coordinate
//     v      : velocity
//     angle  : initial direction angle
//     maxLen : max. length
//     width  : width
//     graphic: garphic of bullet
task TReflectionLaser(x, y, v, angle, maxLen, width, graphic) {
    // adjust the angle
    while(angle >= 180) { angle -= 360; }
    while(angle < -180) { angle += 360; }

    // bullet object
    let obj = Obj_Create(OBJ_LASER);

    // initial settings
    Obj_SetPosition   (obj, x, y);
    Obj_SetAngle      (obj, angle);
    ObjLaser_SetWidth (obj, width);
    ObjShot_SetGraphic(obj, graphic);
    ObjLaser_SetSource(obj, false);

    TReflectionLaser_Lengthen(obj, maxLen, v);
    TReflectionLaser_Move    (obj, x, y, v, angle);

    while(! Obj_BeDeleted(obj)) {
        x = Obj_GetX(obj);
        y = Obj_GetY(obj);

        // reflection detection
        if(angle < 0 && y < GetClipMinY) {
            // ceil
            TReflectionLaser(x, y, v, -angle, maxLen, width, graphic);
            break;
        } else if(((-90 < angle && angle < 90) && x > GetClipMaxX) ||
                   ((angle < -90 || 90 < angle) && x < GetClipMinX))
        {
            // wall
            TReflectionLaser(x, y, v, 180 - angle, maxLen, width, graphic);
            break;
        }
        yield;
    }
}

// lengthen the object laser
task TReflectionLaser_Lengthen(obj, maxLen, v) {
    let len = 0;
    let max = floor(maxLen / v);
    let i   = 0;

    while(! Obj_BeDeleted(obj)) {
        // When the length is negative,
        // the laser extends backward.
        ObjLaser_SetLength(obj, -len);
        yield;

        if(i < max) {
            len += v;
            i++;
        } else if(i == max) {
            ObjLaser_SetLength(obj, -maxLen);
            break;
        }
    }
}

// move the object laser
// Since Obj_SetSpeed is ignored in case of object laser,
// the motion needs to be controlled by Obj_SetPosition.
task TReflectionLaser_Move(obj, x, y, v, angle) {
    let vx = v * cos(angle);
    let vy = v * sin(angle);

    while(! Obj_BeDeleted(obj)) {
        Obj_SetPosition(obj, x, y);
        yield;

        x += vx;
        y += vy;
    }
}

This microthread can be used like CreateLaser01.


Also on Fandom

Random Wiki