~Hakurei Shrine~ > Rika and Nitori's Garage Experiments

※ Danmakufu Q&A/Problem thread 3 ※

<< < (2/366) > >>

Sparen:

--- Quote from: Lollipop on February 05, 2016, 10:57:35 PM ---2 questions.

1. How to do a magic circle (the circles that spin around the boss)
2. How to spawn familiars

--- End quote ---

1. Depends on what you want. The built-in system uses a primitive object with a large number of vertices. You can also use a 2D sprite (or multiple 2D sprites) instead of a primitive.
2. Depends on what you mean by 'familiar'. If they have life bars, implement them as Obj_Enemy. If they do not have life bars, you can use 2D sprites and control their movement and positioning using trigonometry.

iVAwalys:
Since someone asked me to explain how I made the following code work, and since the old thread has reached its limit, I couldn't edit it, so I'm posting it here:

Basically, this line of code was supposed to spawn a circle of bullets out of a bigger bullet if it reaches the sides of the screen:

let rx = ObjMove_GetX(shot);
let ry = ObjMove_GetY(shot);
let angleR = rand(0, 360);
while(rx > 0 && rx < GetStgFrameWidth){yield;}
if(rx <= 0){
loop(12){
CreateShotA2(rx, ry, 4, angleR, -0.1, 1, rand(30,32), 10);
CreateShotA2(rx, ry, 4, angleR, -0.1, 1, rand(30,32), 10);
ObjShot_SetDeleteFrame(shot, 0);
angleR += 360/12;}
}
if(rx >= GetStgFrameWidth){
loop(12){
CreateShotA2(rx, ry, 4, angleR, -0.1, 1, rand(30,32), 10);
CreateShotA2(rx, ry, 4, angleR, -0.1, 1, rand(30,32), 10);
ObjShot_SetDeleteFrame(shot, 0);
angleR += 360/12;}
}
}
--- End code ---
However, the bullets exploded instantly after being spawned. So, why didn't it work? It was a mistake to put while(rx > 0 && rx < GetStgFrameWidth){yield;} so far in the task. I just needed to put it one line after the task is declared, and it started to work!
And, after a few tweaks and fixes to prevent 0,0 spawning, I finally got my explosions.

while(ObjMove_GetX(shot) > 20 && ObjMove_GetX(shot) < GetStgFrameWidth-20){yield;}
// Replace Width with Height and GetX with GetY if you want it to explode if it touches the upper and lower screen instead of the sides.
let rx = ObjMove_GetX(shot);
let ry = ObjMove_GetY(shot);
let angleR = rand(0,360);
if(rx <= 20&&!Obj_IsDeleted(shot)){
// Replace rx with ry if you want it to explode if it touches the upper and the lower screen instead of the sides.
loop(14){
CreateShotA2(rx, ry, 4, angleR, -0.1, 1, rand(30,32), 5);
ObjShot_SetDeleteFrame(shot, 5);
angleR += 360/14;}
}
if(rx >= GetStgFrameWidth-20&&!Obj_IsDeleted(shot)){
// Replace Width with Height if you want it to explode if it touches the upper and the lower screen instead of the sides.
loop(14){
CreateShotA2(rx, ry, 4, angleR, -0.1, 1, rand(30,32), 5);
ObjShot_SetDeleteFrame(shot, 5);
angleR += 360/14;}
}
}
--- End code ---
And just wanted to point out, the "3" in the thread title is in Arabic, while the "II" in the old was in Greek. Just a meaningless observation.
also, yes, i did edit my post that many times because why not do everything wrong

Lollipop:
How do you make bullets fire not in a ring, but in a square?

Uruwi:

--- Quote from: Lollipop on February 06, 2016, 07:00:49 PM ---How do you make bullets fire not in a ring, but in a square?

--- End quote ---

Here.

Create four line segments for a square.

Drake:
Um, that Wolfram link doesn't exactly give anything useful over here (misinterpreted query?), and even if it gave some equations it isn't necessarily obvious how you would implement it to do what you want, and that's still assuming they could follow the math required.

Where you start is that you want to get a line segment that describes one side. For a square this could be a line between points (1,0) and (0,1), but I'm continuing with general regular polygons. We're going to draw an n-sided polygon inside of the unit circle (radius is 1). Since going all the way around the circle is 360 degrees, splitting that into n sides means each corner is at a multiple of 360/n degrees. Since these corner points are supposed to lie on the unit circle, the first corner's coordinates are (cos(360/n), sin(360/n)), so the first side will be a line segment from (1,0) to (cos(360/n), sin(360/n)) (see here, which is one side of a triangle, n=3). Note that if n=4 for a square, (cos(360/n), sin(360/n)) = (cos(90), sin(90)) = (0,1).

Now you can convert this line to polar coordinates (which I didn't work through myself), and this ends up with r = cos(180/n) / cos(angle - (180/n)). However, this is only what we want for the single side, with angles from 0 to 360/n (see here). If you keep increasing the angle past that, the value for the radius r you get just keeps increasing, which is useless (see here). But the first side's angles work, so you can make sure you get the same radii for the other sides as the first side by throwing in a modulo (so the radius for angle=360/n+1 is the same as for angle=1, etc).
The equation is then r = cos(180/n) / cos((angle % (360/n)) - (180/n)). You can see this working here. Change the n=4 at the end to other values for different polygons.

Soooo, what this gives you is a base unit. You can think of the radius r values as the required speed for a bullet moving at a given angle, so that the overall shape moves at a speed of 1. If you want to rotate the shape, just change the angle in the equation to (angle - offset) instead.