Wikia

Touhou Wiki

Touhou Danmakufu: Object Bullets

7,297pages on
this wiki
Talk0

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.


Around Wikia's network

Random Wiki