Author Topic: ※ Danmakufu Q&A/Problem thread 3 ※  (Read 146062 times)

HumanReploidJP

  • The Scripter with Something of Common Sense
  • "Start the life of an idol! Let's get STAR~ted!"
    • HumanReploidJP's Youtube Channel
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1800 on: July 30, 2019, 01:05:58 AM »
I have something I didn't know:

You know the one where (2 or 10) bullets are orbiting around the boss or an another bullet, which I saw in most dnh scripts.
Can you explain how  in a way, and give an example code (must be a shot function ObjMove_AddPatternB2).

Let me know.  :)
MiraikeiBudoukan (Futuristic Vineyard) Game Concepts (WIP)
(Non-Touhou, yet bullet-hell-Inspirable (Like JynX). Don't get serious.)

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1801 on: July 30, 2019, 06:41:31 PM »
So, I don't exactly have the spoons to explain how you would do that with ObjMove_AddPatternB2 ALL IN ONE MESSAGE, though I will say that it would likely be much easier to do this by just manually setting the X and Y positions of the bullets. But IDK. We're going to set this up by making a simple pattern where, every 5 seconds, ten bullets are summoned around the boss, will orbit around said boss, and then fire out radially- or at least, how I would do it using ObjMove_AddPatternB2.

Quick warning that this will require not only knowledge of trigonometry, as you would expect, but ALSO calculus. Fortunately, the calculus part isn't THAT difficult to understand, hopefully, so even if you haven't taken a calculus class don't worry too much about it.

The first thing you'd want to do is set some kind of distance variable, for example 100. You're also gonna want to set some starting angle, and maybe make an array of ten (X, Y) points, all around the boss, using some ascent loops and trigonometry. I trust that this is something you're able to do on your own.

Now, one of the first things you'll want to do is make sure to... in a way, rig the bullets such that, no matter what, they are always the same distance from the boss. For the sake of our example, we're gonna have a loop set to run every 300 frames, and each frame it will update the position of all of the bullets. You'll do this with another ascent loop, by getting the angle from each player to the boss. You're gonna want to hold onto this array of angles, it will be helpful later. But then, with this angle, you'll set the position of each of the ten bullets to be equal to (dist * cos(angle) + ObjMove_GetX(objBoss), dist * sin(angle) + ObjMove_GetY(objBoss). Then, you might set it such that this only happens when a certain boolean is true, but you might be able to get around that. I hope you're understanding so far?

Now... for this next part, you're gonna need a bit of calculus. Remember that array of angles from the previous paragraph? Yeah, you need to hold onto them because at each timestep, you're going to want to use ObjMove_AddPatternB2 on each of these bullets, setting the X speed to be equal to dist * sin(angle), and the y speed to be dist * cos(angle). You might be thinking that I've mixed up the sines and cosines here, but in fact, I haven't. We're not using trigonometry to set POSITION, we're using it to set VELOCITY, which means we have to set the X and Y speeds to be equal to the DERIVATIVE of the X and Y positions, which is the X and Y velocities. And, in short...

d/dx(sin(x)) = cos(x), and

d/dx(cos(x)) = sin(x).

This will make it so that the X and Y positions of every bullet will follow a circle. (note: technically, the only reason we need to rig the distance of the bullets is because of the fact that we're doing this on a computer and not in real life, so every differential equation can only be so accurate since they're going in timesteps. It's complicated, but think of it as the bullets being a bit drunk and sorta stepping off the straight line path, so we need to keep them oriented.)

Fortunately, though, this should be aboooout all you'd need to do. I'm gonna post an example of actual code for this in the next post, so give me a moment. In the meantime, feel free to correct or verify anything here if you notice something wrong! ^u^

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1802 on: July 31, 2019, 12:37:21 AM »
Okay, so I found a way to make this work that doesn't use ObjMove_AddPatternB2. Lemme copy and paste it down here.

Code: [Select]
task fire(angle, dir)
{
if(ObjEnemy_GetInfo(objBoss, INFO_LIFE) <= 0){return;}

let dist = 100;
let bulNum = 10;
let time = 240;

let bx = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let by = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let bul = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
let ang = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0];
ascent(i in 0..bulNum)
{
ang[i] = angle + dir * i * 360/bulNum;
bx[i] = dist * cos(ang[i]) + ObjMove_GetX(objBoss);
by[i] = dist * sin(ang[i]) + ObjMove_GetY(objBoss);
bul[i] = CreateShotA1(bx[i], by[i], 2, ang[i], DS_BALL_M_BLUE, 20);
}

loop(time)
{
ascent(i in 0..bulNum)
{
ang[i] = ang[i] + 2 * PHI;
ObjMove_SetPosition(bul[i], dist * cos(ang[i]) + ObjMove_GetX(objBoss), dist * sin(ang[i]) + ObjMove_GetY(objBoss));
ObjMove_SetAngle(bul[i], ang[i]);
}

yield;
}
}

Again, since you said it needed to use ObjMove_AddPatternB2, I can still create a solution that uses it, but I personally think this seems a lot more elegant, and is sort of just how i naturally ended up making the spell. Plus, ObjMove_AddPatternB2 versions of the pattern have the caveat that they need to stay still unless you add the X and Y speed components to the rotating bullets as a vector, which is... I don't even want to get into that. This just seems like a lot less work, but if it's not acceptable for your purposes, let me know.

Sparen

  • Danmakufu Artist
  • Git ready, git set, PUUSH!
    • AFCDTech
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1803 on: July 31, 2019, 02:20:53 PM »
If you really just want objects to move relative to another object, you can just keep track of that other object.

e.g. rotate about the boss.

Given n objects rotating:

Code: [Select]
ascent(i in 0..n) {
    CreateRotatingObj(objBoss, i, n, r);
}

task CreateRotatingObj(parent, ID, numinring, radius) {
    let offset = ID * 360/numinring;
    let obj = CreateShotA1(ObjMove_GetX(parent) + radius*cos(offset), ObjMove_GetY(parent) + radius*sin(offset), 0, 0, 0, 0);
    let objcount = 0;
    while(!Obj_IsDeleted(parent)) {
        ObjMove_SetX(obj, ObjMove_GetX(parent) + radius*cos(offset + objcount);
        ObjMove_SetY(obj, ObjMove_GetY(parent) + radius*sin(offset + objcount);
        objcount += 1;
        yield;
    }
    Obj_Delete(obj);
}
« Last Edit: July 31, 2019, 02:22:33 PM by Sparen »

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1804 on: August 11, 2019, 02:32:20 AM »
Hey, can someone help me?
I've got a bunch of single scripts for a Momiji boss fight, but I'm having trouble stitching them together into a plural script. All eight of the singles work perfectly as intended, but when I run them all as a plural, the game just crashes on me, without even giving so much grace as an error message. Can someone help me find out what's going on?

Here's the code:

Code: [Select]
#TouhouDanmakufu[Plural]
#ScriptVersion[3]
#Title["Momiji Fight"]
#Text["for kiiro"]
@Event
{

}
@Initialize
{
    TPlural;
}
@MainLoop
{
    yield;
}

task TPlural
{
    let dir = GetCurrentScriptDirectory();
    let obj = ObjEnemyBossScene_Create();
    ObjEnemyBossScene_Add(obj, 0, dir ~ "momiji 1.txt");
    ObjEnemyBossScene_Add(obj, 0, dir ~ "momiji spell 1.txt");
    ObjEnemyBossScene_Add(obj, 1, dir ~ "momiji 2.txt");
    ObjEnemyBossScene_Add(obj, 1, dir ~ "momiji spell 2.txt");
    ObjEnemyBossScene_Add(obj, 2, dir ~ "momiji 3.txt");
    ObjEnemyBossScene_Add(obj, 2, dir ~ "momiji spell 3.txt");
    ObjEnemyBossScene_Add(obj, 3, dir ~ "momiji spell 4.txt");
    ObjEnemyBossScene_Add(obj, 4, dir ~ "momiji spell 5.txt");
    ObjEnemyBossScene_LoadInThread(obj);
    ObjEnemyBossScene_Regist(obj);
    while(!Obj_IsDeleted(obj)){
        yield;
    }
    CloseScript(GetOwnScriptID());
}

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1805 on: August 24, 2019, 03:26:18 PM »
How to make a function so that the bullet is gradually increasing/decreasing the alpha ? Had no idea how it works, any help is appreciated.
« Last Edit: August 24, 2019, 03:27:55 PM by BananaCupcakey »
Just keep it neutral :3

JDude :3

  • tururu
  • boy with code
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1806 on: August 24, 2019, 11:49:05 PM »
How to make a function so that the bullet is gradually increasing/decreasing the alpha ? Had no idea how it works, any help is appreciated.

Code: [Select]
function upAlpha(obj, seconds){
ascent(i in 0..256){
ObjRender_SetAlpha(obj, i);
wait(60*seconds);
}
}

function wait(n){loop(n){yield;}}

Pretty simple, but it works with the time as a parameter: if you do upAlpha(obj, 1.5) the alpha will be increased each 1.5 seconds
"dnh is hard" - said no one
"dnh is bullshit" - everyone making a creative pattern

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1807 on: September 21, 2019, 04:54:01 PM »
Hey there! I was just wondering how to make a player shoot bullets. I'm trying to make a player script and I can't for the life of me figure out how to go about doing that. Does anyone have tips to start off doing that at least?

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1808 on: September 21, 2019, 09:05:21 PM »
Hey there! I was just wondering how to make a player shoot bullets. I'm trying to make a player script and I can't for the life of me figure out how to go about doing that. Does anyone have tips to start off doing that at least?

I'm not very expirenced with ph3 in general, but for the player script I've made I've followed thesse steps:
  • Have an image containing the sprite of the shots
  • Create a "player shotdata"
  • Load that Shot data in the player script
  • Make the player actually shoot

The shot data (2) must be something like this:

Code: [Select]
shot_image = "./playershot.png" // image

ShotData {
id = 1
rect = (left,top,right,bottom)
render = ALPHA
alpha = x // 0-255
collision = y // radius of the hitbox
}

ShotData {
id = 2
...

the item (3) it's just store the path of the shotdata in a variable and load it in @initialize
Code: [Select]
let shots = dirCurrent ~ "player_shot.txt";
LoadPlayerShotData(shots);

Now you can use CreatePlayerShotA1 and it shoud work
« Last Edit: September 22, 2019, 10:49:10 AM by theSlug »

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1809 on: September 25, 2019, 05:27:43 PM »
Thank you for the advise! Quick question though do I implement it like this?

task TShoot(){
   CreatePlayerShotA1(GetPlayerX(), GetPlayerY(), 3, 2, 10, 10, 1);
}
« Last Edit: September 25, 2019, 05:35:35 PM by Dire29 »

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1810 on: September 25, 2019, 07:53:08 PM »
Thank you for the advise! Quick question though do I implement it like this?

task TShoot(){
   CreatePlayerShotA1(GetPlayerX(), GetPlayerY(), 3, 2, 10, 10, 1);
}

there are multiple ways to "call" a player shot (and that's really up to the scripter), but in this case, whenever you call TShoot the player should fire a bullet ( e.g if (VK_SHOT==KEY_HOLD){ TShoot() } )
« Last Edit: September 25, 2019, 07:55:18 PM by theSlug »

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1811 on: November 15, 2019, 06:07:34 PM »
Oh gosh it's been a while but I'm genuinely stumped right now
I was wondering if someone could look through the script and see where I'm going wrong because I'm genuinely unsure of what to do right now
It's still not working and I'm not really sure if I'm going about this the wrong way so feel free to look through it

Thank you for the help though! I appreciate every single advise/tip~



« Last Edit: November 16, 2019, 05:30:55 AM by Dire29 »

Sparen

  • Danmakufu Artist
  • Git ready, git set, PUUSH!
    • AFCDTech
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1812 on: November 16, 2019, 02:43:20 AM »
Oh gosh it's been a while but I'm genuinely stumped right now
I was wondering if someone could look through the script and see where I'm going wrong because I'm genuinely unsure of what to do right now
It's still not working and I'm not really sure if I'm going about this the wrong way so feel free to look through it

Thank you for the help though! I appreciate every single advise/tip~

If you think something has gone wrong, tell us what isn't working. Is it a crash? An error? Something's not working the way you want it to?

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1813 on: November 16, 2019, 02:55:58 AM »
The player shots don't really appear :/
The sprite animation seems to be working just fine, it's just the shooting part that's not working

EDIT:

NVM my player shots seem to be working now! I just put in the wrong variable name in the player bullet script ^^;;
« Last Edit: November 16, 2019, 03:57:27 AM by Dire29 »

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1814 on: November 16, 2019, 08:47:57 AM »
The player shots don't really appear :/
The sprite animation seems to be working just fine, it's just the shooting part that's not working

EDIT:

NVM my player shots seem to be working now! I just put in the wrong variable name in the player bullet script ^^;;
Ah, a classic mistake. Yea you got to love that strict variable name for the player bullet script :V I remember it took me several minutes of cursing when I had figured it out.

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1815 on: November 18, 2019, 02:16:00 AM »
Hello again!
So the rest of my player script is working fine now but I was just wondering how you would implement something like Reimu's yin-yang balls.
« Last Edit: November 18, 2019, 06:16:44 PM by Dire29 »

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1816 on: November 19, 2019, 04:02:39 PM »
You mean like a player bomb effect with yin yang balls?

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1817 on: November 19, 2019, 08:40:39 PM »
More like focus and unfocus shots! ^^ (but you know I wouldn't mind learning about that too  :3)

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1818 on: November 20, 2019, 04:22:25 PM »
There are tutorials about that by both Sparen and me for making player scripts + spell bombs. Might want to check them out.

About the Yin yang orbs in focus/unfocus: Basically they are just effect objects around the player that fire the player bullet from that position.


Sparen

  • Danmakufu Artist
  • Git ready, git set, PUUSH!
    • AFCDTech
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1819 on: November 22, 2019, 11:37:12 PM »
There are tutorials about that by both Sparen and me for making player scripts + spell bombs. Might want to check them out.

 :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V :V

...Not yet. It'll be a while before I get to Player Scripts.

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1820 on: November 30, 2019, 01:54:55 PM »
Don't know how to explain this, but I'll try to make it as clear as possible.
1. How to script a trail of straight laser based on random boss movement (rand(n,n)) ? [attach=1]
2. What to script so that the boss can automatically detects and runs into the center of the bullet no matter what position the boss is (directly piercing it) and the bullet will react (like explode etc) [attach=2]
« Last Edit: November 30, 2019, 01:56:54 PM by BananaCupcakey »
Just keep it neutral :3

Sparen

  • Danmakufu Artist
  • Git ready, git set, PUUSH!
    • AFCDTech
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1821 on: November 30, 2019, 03:28:59 PM »
Don't know how to explain this, but I'll try to make it as clear as possible.
1. How to script a trail of straight laser based on random boss movement (rand(n,n)) ? [attach=1]
2. What to script so that the boss can automatically detects and runs into the center of the bullet no matter what position the boss is (directly piercing it) and the bullet will react (like explode etc) [attach=2]

1. Track the boss's position over two frames to determine its angle with atan2. Then fire a laser in the opposite direction
2. Store the object IDs of the bullets and use atan2 in order to determine the angle between the boss and the bullet. You can use object-object collision, or you can see if a given object is in a radius of another in order to determine when to react.

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1822 on: January 05, 2020, 01:59:32 AM »
I'm having problems rendering transparent images. A grey always appears at the edge of the pictures. Just look at this screenshot.

The mandala in the middle is a purely black transparent image put on top of the rest of the background, but where opaque meets transparent, the grey appears.

Sparen

  • Danmakufu Artist
  • Git ready, git set, PUUSH!
    • AFCDTech
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1823 on: January 05, 2020, 02:49:29 PM »
I'm having problems rendering transparent images. A grey always appears at the edge of the pictures. Just look at this screenshot.

The mandala in the middle is a purely black transparent image put on top of the rest of the background, but where opaque meets transparent, the grey appears.

Please provide your code so that we can see your render priorities and blend types. Also provide the raw images so that we can see if there are any notable assumptions that were made when writing the code.

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1824 on: January 05, 2020, 04:49:01 PM »
Please provide your code so that we can see your render priorities and blend types. Also provide the raw images so that we can see if there are any notable assumptions that were made when writing the code.
Code: [Select]
        //The object containing the mandala
let BG = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
ObjPrim_SetTexture(BG,current ~ "BG_Pattern.png");
Obj_SetRenderPriorityI(BG,3);

let BG_Glow = ObjPrim_Create(OBJ_SPRITE_LIST_2D);
ObjPrim_SetTexture(BG_Glow,current ~ "BG_Pattern.png");
Obj_SetRenderPriorityI(BG_Glow,3);
ObjRender_SetBlendType(BG_Glow,BLEND_ADD_RGB);

let BGangle = rand(0,45);
let BGphase = rand(0,360);
let BGalpha = 0;

yield;
Intro;

while(bSpell){
ObjSpriteList2D_ClearVertexCount(BG);

ObjSpriteList2D_SetSourceRect(BG,0,0,800,600);
ObjSpriteList2D_SetDestRect(BG,-320,-240,320,240);
ObjRender_SetAlpha(BG,255*BGalpha);
ObjRender_SetAngleZ(BG,0);
ObjRender_SetColor(BG,255,255,255);
ObjRender_SetPosition(BG,320,240,0);
ObjSpriteList2D_AddVertex(BG);
ObjSpriteList2D_SetSourceRect(BG,800,0,1600,600);
ObjSpriteList2D_SetDestRect(BG,-320,-240,320,240);
ObjRender_SetAlpha(BG,255*sin(BGphase/2)^2*BGalpha);
ObjRender_SetPosition(BG,320,240,0);
ObjSpriteList2D_AddVertex(BG);

//Creating the mandala
ObjSpriteList2D_SetSourceRect(BG,853,601,1278,1026);
ObjSpriteList2D_SetDestRect(BG,-213*0.8,-213*0.8,213*0.8,213*0.8);
ObjRender_SetAlpha(BG,255*BGalpha);
ObjRender_SetAngleZ(BG,BGangle);
ObjRender_SetPosition(BG,320,240,0);
ObjSpriteList2D_AddVertex(BG);

ObjSpriteList2D_CloseVertex(BG);

Drake

  • *
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1825 on: January 05, 2020, 10:40:45 PM »
Ok so this was a lot more complicated looking at than it had to be because what you provided does not match your previous picture, and is very hard to parse because of how you've set it up as a sprite list. I would recommend against using a sprite list here as you barely seem to be reusing any properties and the background pieces are clearly distinct objects.

The core of the matter is that you're alpha blending the black transparent image but are also resizing it. When the resizing happens you're at the mercy of the scaling algorithm, which in this case works against you. Danmakufu is technically at fault here but you should avoid scenarios like this. You have two good options:
- Resize the image ahead of time (ok if the image is always rendered at full size)
- Invert the image to be white instead and use subtract-blend rendering

Here is an example of what you get with the subtract-blend setup (background then mandala then glowy part):

« Last Edit: January 06, 2020, 12:25:05 AM by Drake »

A Colorful Calculating Creative and Cuddly Crafty Callipygous Clever Commander
- original art by Aiけん | ウサホリ -

Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1826 on: February 22, 2020, 02:02:58 AM »
Hello! So I got back into doing Danmakufu again and I'm almost there with implementing something like Reimu's Yin Yang balls. I managed to have them move into a different position when I press the shift key but they teleport instead:
Code: [Select]
if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE)==KEY_HOLD){
ObjRender_SetPosition(extrashot, GetPlayerX-10, GetPlayerY-30, 3);
ObjRender_SetPosition(extrashot2, GetPlayerX+10, GetPlayerY-30, 3);

}
else{
ObjRender_SetPosition(extrashot, GetPlayerX-30, GetPlayerY-30, 3);
ObjRender_SetPosition(extrashot2, GetPlayerX+30, GetPlayerY-30, 3);
}

I know it's because of the SetPosition thing but I'm not sure how to make them NOT teleport. I've tried ObjMove_SetDestAtFrame and other things like that but it doesn't seem to do anything. Is there something else I can try?

Sparen

  • Danmakufu Artist
  • Git ready, git set, PUUSH!
    • AFCDTech
Re: ※ Danmakufu Q&A/Problem thread 3 ※
« Reply #1827 on: February 22, 2020, 02:01:03 PM »
Hello! So I got back into doing Danmakufu again and I'm almost there with implementing something like Reimu's Yin Yang balls. I managed to have them move into a different position when I press the shift key but they teleport instead:
Code: [Select]
if(GetVirtualKeyState(VK_SLOWMOVE)==KEY_PUSH || GetVirtualKeyState(VK_SLOWMOVE)==KEY_HOLD){
ObjRender_SetPosition(extrashot, GetPlayerX-10, GetPlayerY-30, 3);
ObjRender_SetPosition(extrashot2, GetPlayerX+10, GetPlayerY-30, 3);

}
else{
ObjRender_SetPosition(extrashot, GetPlayerX-30, GetPlayerY-30, 3);
ObjRender_SetPosition(extrashot2, GetPlayerX+30, GetPlayerY-30, 3);
}

I know it's because of the SetPosition thing but I'm not sure how to make them NOT teleport. I've tried ObjMove_SetDestAtFrame and other things like that but it doesn't seem to do anything. Is there something else I can try?

I recommend putting their position into variables, and having a 'target'. If they aren't at the target, each frame move the positions closer to the target. The key thing is to do it over multiple frames, while updating the target relative to the player position.