- Return to Touhou Danmakufu: Additional Information
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.
- Return to Touhou Danmakufu: Additional Information