Author Topic: Danmakufu wonders..  (Read 4980 times)

Matteo

Danmakufu wonders..
« on: April 23, 2012, 04:39:48 PM »
Hi, and first of all i hope i posted this in the right session.
I wanted to ask you if there are online some tutorials for beginners about danmakufu and making scripts.
I know, these tutorials already exist, but i mean tutorials more...simple. It surely is not my fault if i hardly understand c++ language.
Any tips, suggestions...anything will do. I don't lack in immagination, but without some basics notions i can't create anything.
And well, i need tutorials or similar help because it is the fastest way to lear...with university, exams and all i really have no time to loose hours trying to understand by my own, and fail in the progress.

Oh, sorry my bad english...not my first language.

Yadogari

  • Hieda no Akyu of Shrinemaiden
  • Resident Jackass
Re: Danmakufu wonders..
« Reply #1 on: April 23, 2012, 06:48:05 PM »

gtbot

  • Master of ScreenSplit
Re: Danmakufu wonders..
« Reply #2 on: April 23, 2012, 09:48:38 PM »
I highly suggest learning ph3, as for most basic scripts, ph3 and 0.12m are exactly the same with a few constant name changes (CreateShotA1 vs CreateShot01), and much easier handling on pretty much everything. Most basic tutorials for 0.12m also work for ph3.

A good place to get started on learning the simple constants and samples for ph3 would be http://dmf.shrinemaiden.org/wiki/index.php?title=How_to_Write_Scripts and http://dmf.shrinemaiden.org/wiki/index.php?title=Sample_Danmaku_Scripts

A good place on learning general C++ rules for danmakufu would be http://www.shrinemaiden.org/forum/index.php/topic,30.msg171.html#msg171; keep in mind however that the general framework of the rest of this tutorial is of 0.12m, but the mindset of it is generally the same.

If you have any questions there is the Q&A thread for ph3. Lastly you can contact me for small help on things, as I'd happy to be of assistance.

Matteo

Re: Danmakufu wonders..
« Reply #3 on: April 24, 2012, 02:50:15 PM »
Gtbot and R-1, thank you for your help, i will try these tutorials and let's hope that they will be helpfull.
Well, i am mostly a fan of old pc-98 touhou games and would really like to make scripts like the ones of mima or the greatest of all, Yuuka in lotus land story.

R-1, i am looking for tutorials of 0,12m but once and if i understand it i will try also ph3.

gtbot, thank you but i will contact you only if i really need it, that's because i don't want to bother people.


Matteo

Re: Danmakufu wonders..
« Reply #4 on: April 25, 2012, 07:18:41 AM »
Question...

I'm reading "Danmakufu Basics Tutorial! (Blargel)", and i'm starting to understand a little. But i really don't understand how to organize the txt files.
I mean, i need a txt for "level info", one for "boss general info" and "x" txt files, each one for a enemy spell? And in all this mess where should i put the txt for player bullet info?

I fear that i'm starting to considering too much things in the same time. It should be simpler...
So, if i want to do a plural boss, what txt files i need to create in my danmakufu folder and mostly...why that specifics txt files?
This is a question about organization, not scripting per se.

Mmm...scripting seems interesting but so confusing

Drake

  • *
Re: Danmakufu wonders..
« Reply #5 on: April 25, 2012, 08:15:31 AM »
I'm pretty sure you're overthinking it, and you're thinking about too much for the time being. For one spell card, all you need is one script. If you have a bunch of spells and want to stack them in a boss, that's one more script. Every different enemy is one script each, every stage is one script, every player is one script, and so on (well, on a general level). How you organize everything doesn't matter much as long as you're consistent.

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

Matteo

Re: Danmakufu wonders..
« Reply #6 on: April 25, 2012, 09:25:55 PM »
Ok, i'm starting to understand... finally with the tutorials i managed to understand how to make bullets...i finally made my first script.
But... doing CreateShot01 i really don't understand the coordinates. I mean, direction is easy, speed and bullet colour also. What i don't understand is how to put the numbers in getenemy x and y.
If i want to create bullets in a specific position how should i do it? I tryed these randoms patterns:

 CreateShot01(GetEnemyX,GetEnemyY,3,90,RED01,10);
         CreateShot01(32,34,5,45,GREEN05,10);
         CreateShot01(60,90,5,90,WHITE22,10);
         CreateShot01(90,135,1,90,RED01,10);
         CreateShot01(-45,-90,3,67,WHITE22,10);

but the first 2 values ( 32-34; 60-90; 90-135 and -45- -90)... in the screen i really don't know where they are. Top right, middle, bottom-left... easy to say, nice starting position to create a shot. But in numbers i don't know what to write. And danmakufu don't allow for example

CreateShot01(middle,middle,5,90,WHITE22,10);

...a pity. So confusing

ExPorygon

  • Veteran Danmakufu Scripter
  • Currently working on a full Touhou fangame!
    • Ephemeral Entertainment
Re: Danmakufu wonders..
« Reply #7 on: April 25, 2012, 09:37:11 PM »
The first 2 parameters in CreateShot01 are the x and y coordinates from which the bullet will be fired, as you probably already know. GetEnemyX and GetEnemyY are functions that represent the boss's current coordinates. Using these as your x and y coordinates will mean that the bullet will be fired from whatever the boss's current coordinates are.

If you don't want to fire bullets relative to the boss, then this attached image should help you. It will show what the coordinate plane of the danmakufu window looks like.

Matteo

Re: Danmakufu wonders..
« Reply #8 on: April 25, 2012, 10:00:21 PM »
Thank you Ozzy, your informations are gold to me! Well, now i'm too tired but tomorrow i will try to create some bullets. With the little i know now, i should be able to master the creation of "CreateShot01" anywhere in the screen with colour,direction and speed that i like. A small step, but little by little i'm surely learning.

Thank you to you all for your help and kindness.
Until next problem arise...

Matteo

Re: Danmakufu wonders..
« Reply #9 on: April 26, 2012, 01:31:51 PM »
Ok, i Have made a spell card using only createshot01 and createlaser01. I worked a bit on timing and bgm and such... if i have to give it a level i would say -Hard- (but i usually struggle to beat touhou games on normal so...

I posted the link, if you want to try it and tell me what you think of it i would be really glad. But remember, this is my first script, my first spell card...it surely is far from good!

http://www.mediafire.com/download.php?fy6az72m66d6j44

Btw, now what i must absolutely find is how to create different shooting tasks... for example a task that shoot some bullets in apattern for the first 20 seconds, than a task that delete it and create new different bullets in a new pattern
« Last Edit: April 26, 2012, 05:19:00 PM by Matteo »

ExPorygon

  • Veteran Danmakufu Scripter
  • Currently working on a full Touhou fangame!
    • Ephemeral Entertainment
Re: Danmakufu wonders..
« Reply #10 on: April 26, 2012, 05:47:56 PM »
Ok, i Have made a spell card using only createshot01 and createlaser01. I worked a bit on timing and bgm and such... if i have to give it a level i would say -Hard- (but i usually struggle to beat touhou games on normal so...

I posted the link, if you want to try it and tell me what you think of it i would be really glad. But remember, this is my first script, my first spell card...it surely is far from good!

Alright, not bad for a first pattern. Honestly, I've seen worse and yours sort of reminds me of my first pattern (even though mine was half copied code). This definitely shows that you have mastered CreateShot01 and CreateLaser01 well. My biggest complaint would be that it starts up before the cut in even goes away, so I recommend putting something like wait(120); in the beginning of mainTask to delay its start.

Also, you should probably know that the only thing yield does is make the task pause for 1 frame. In other words, yield; and wait(1); mean the same thing. So unless your loops don't have any waits in them, the yields in your loops and tasks are just excessive and don't change much of anything. However, definitely make sure that any infinite loop has at least 1 yield or wait in it otherwise Danmakufu will freeze.

Comments on the pattern: The bullets are a bit fast, but the main problem has to be that Cirno is so close to the bottom of the screen, I barely have time to react to her lasers. Also, why does she seem to be shooting green dots and regular red bullets at 45 and 135 angles, respectively? It doesn't seem to serve much purpose. Also why is Infinite Being playing for Mima and why is Cirno there? I'm confused.

Btw, now what i must absolutely find is how to create different shooting tasks... for example a task that shoot some bullets in apattern for the first 20 seconds, than a task that delete it and create new different bullets in a new pattern

You can try making your fire loop repeat only so many times. Then have it call a new task after it's done. Something like this:
Code: [Select]
task fire1 {
loop(20) {
*fire bullets and stuff*
wait(60);
}
fire2;
}
task fire2 {
loop(20) {
*fire other bullets and other stuff*
wait(60);
}
fire1;
}
This will have the first fire task repeat 20 times. After 20 loops (which will take 20 seconds since it's being made to wait 60 frames each repeat) the second fire task will begin, doing something else.
« Last Edit: April 26, 2012, 05:52:52 PM by Ozzy »

Matteo

Re: Danmakufu wonders..
« Reply #11 on: April 26, 2012, 05:55:58 PM »
Thank you Ozzy, i really appreciate your help.
I will try to follow your advices to update this script... i think i will post it soon if it is good.
The point is, i prefer to master these thing before trying to do harder things.

About Cirno, well i used that image only as a funny background, the real target is mima.
Infinite being? Well... i took the first mp3 i had to see if i could load it in a danmakufu script. Also, i don't have an mp3 to load for "complete darkness". A pity.

Ok, i'm going to try the task fire1 and 2 thing now.

Thanks again Ozzy!

mmm i tryied but it gives me error..

@Finalize{
          
                DeleteGraphic(imgBoss);
                DeleteGraphic(cut);
                DeleteGraphic(bg);

   }
   

   
   task mainTask{
      yield;
      fire;
                movement;
                fire2;
   }

        task movement{
                loop{
                        SetMovePosition01(GetCenterX-100,120,3);
                        wait(120);
                        SetMovePosition01(GetCenterX+100,120,3);
                        wait(120);
                 }
       

   
   task fire{
      loop(10){
                        wait(120);
                        CreateShot01(GetEnemyX,GetEnemyY,6,GetAngleToPlayer,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,5,GetAngleToPlayer-10,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,5,GetAngleToPlayer+10,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4.5,GetAngleToPlayer+20,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4.5,GetAngleToPlayer-20,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4,GetAngleToPlayer,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4,GetAngleToPlayer,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,3,GetAngleToPlayer-60,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,3,GetAngleToPlayer+60,AQUA01,10);
                        wait(60);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer-30, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer+30, 200, 16, GREEN01, 20);
                        wait(30);
                       
      }
             fire2;
        }
        task fire2{
                loop(10) {
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-30, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+30, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer+15, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer-15, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer, 200, 16, YELLOW01, 20);
                        wait(120);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer+10, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+20, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+30, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer+40, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+50, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+60, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer-10, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-20, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-30, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer-40, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-50, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-60, 200, 16, RED01, 20);
                        yield;
                       
            }
                 fire;   
}



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


}
« Last Edit: April 26, 2012, 06:21:34 PM by Matteo »

ExPorygon

  • Veteran Danmakufu Scripter
  • Currently working on a full Touhou fangame!
    • Ephemeral Entertainment
Re: Danmakufu wonders..
« Reply #12 on: April 26, 2012, 06:22:24 PM »
Thank you Ozzy, i really appreciate your help.
I will try to follow your advices to update this script... i think i will post it soon if it is good.
The point is, i prefer to master these thing before trying to do harder things.
That's good, it's best to learn the basics and work off of that. Don't try to do too much too quickly

About Cirno, well i used that image only as a funny background, the real target is mima.
Infinite being? Well... i took the first mp3 i had to see if i could load it in a danmakufu script. Also, i don't have an mp3 to load for "complete darkness". A pity.
I realized that Mima was the target, I was just kidding really since it seemed a bit odd for them to be together.

Good luck making scripts! I hope to see more soon!

Matteo

Re: Danmakufu wonders..
« Reply #13 on: April 26, 2012, 07:01:46 PM »
Code: [Select]
#TouhouDanmakufu
#Title[base per modifiche2]
#Text[just a tutorial to present it]
#Player[FREE]
#ScriptVersion[2]

script_enemy_main{

        let CSD = GetCurrentScriptDirectory;

        let imgBoss = CSD ~ "img\Sprite.png";
        let cut = CSD ~ "img\Cut.png";
        let bg = CSD ~ "img\lake.png";
        let bgm = CSD ~ "bmg\Legendary Illusion ~ Infinite Being.mp3";

@Initialize{
SetLife(1000);
                SetTimer(60);
                SetScore(2000);
SetMovePosition01(GetCenterX,GetCenterY,5);

                LoadGraphic(imgBoss);
                LoadGraphic(cut);
                LoadGraphic(bg);
                LoadMusic(bgm);
                PlayMusic(bgm);

                CutIn(YOUMU,"Scripting like a Cirno - Easy -",cut,0,0,300,450);
 
mainTask;
}

@MainLoop{
                SetCollisionA(GetX,GetY,32);
                SetCollisionB(GetX,GetY,16);
                yield;


}

@DrawLoop{

                SetTexture(imgBoss);
                SetRenderState(ALPHA);
                SetAlpha(255);
                SetGraphicRect(0,0,110,110);
                SetGraphicScale(1,1);
                SetGraphicAngle(0,0,0);
                DrawGraphic(GetX,GetY);
}

@BackGround{

                SetTexture(bg);
                SetRenderState(ALPHA);
                SetAlpha(255);
                SetGraphicRect(0,0,512,512);
                SetGraphicScale(1,1);
                SetGraphicAngle(0,0,0);
                DrawGraphic(GetCenterX,GetCenterY);

}

@Finalize{
       
                DeleteGraphic(imgBoss);
                DeleteGraphic(cut);
                DeleteGraphic(bg);

}



task mainTask{
yield;
fire;
                movement;
                fire2;
}

        task movement{
                loop{
                        SetMovePosition01(GetCenterX-100,120,3);
                        wait(120);
                        SetMovePosition01(GetCenterX+100,120,3);
                        wait(120);
                 }
        task fire {
                loop(10)}
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-30, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+30, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer+15, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer-15, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer, 200, 16, YELLOW01, 20);
                        wait(120);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer+10, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+20, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+30, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer+40, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+50, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer+60, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer-10, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-20, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-30, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 6,GetAngleToPlayer-40, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-50, 200, 16, RED01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 4,GetAngleToPlayer-60, 200, 16, RED01, 20);                     
                       
         }
}

task fire2{
loop(10){
                        CreateShot01(GetEnemyX,GetEnemyY,6,GetAngleToPlayer,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,5,GetAngleToPlayer-10,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,5,GetAngleToPlayer+10,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4.5,GetAngleToPlayer+20,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4.5,GetAngleToPlayer-20,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4,GetAngleToPlayer,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,4,GetAngleToPlayer,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,3,GetAngleToPlayer-60,AQUA01,10);
                        CreateShot01(GetEnemyX,GetEnemyY,3,GetAngleToPlayer+60,AQUA01,10);
                        wait(60);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer-30, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer, 200, 16, GREEN01, 20);
                        CreateLaser01(GetEnemyX,GetEnemyY, 2,GetAngleToPlayer+30, 200, 16, GREEN01, 20);
                        wait(30);
                       
}
}



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



}

Ok, this is a sample script i made in which i wanted to do 10 times task fire than 10 times task fire2 and after that, again fire than fire2 and so on... well it's 30 minutes i try but danmakufu gives me error.
What do i do wrong???

Matteo

Re: Danmakufu wonders..
« Reply #14 on: April 26, 2012, 09:09:40 PM »
Ok, considering that i still don't understand how to do this "task fire and taskfire2" thing, i tryied to master the @MainLoop function. I'm far from good, but i managed to do a spellcard that i think is nice, considering that my ability are only createbullet01 and createlaser01, for now.

Spellcard: Rainbow-colored darkness

http://www.mediafire.com/download.php?67foclqi9daodks

I hope you like it, and tell me if something is bad...that will help me improve!
« Last Edit: April 26, 2012, 09:11:45 PM by Matteo »

ExPorygon

  • Veteran Danmakufu Scripter
  • Currently working on a full Touhou fangame!
    • Ephemeral Entertainment
Re: Danmakufu wonders..
« Reply #15 on: April 27, 2012, 02:54:19 AM »
Ok, this is a sample script i made in which i wanted to do 10 times task fire than 10 times task fire2 and after that, again fire than fire2 and so on... well it's 30 minutes i try but danmakufu gives me error.
What do i do wrong???

Ok, first off, try to avoid posting large blocks of code in posts. Use pastebin.com next time before Helepolis does it for you.

As for what the problem is, the first thing wrong is that the "}" after the loop in fire1 should be a "{". In addition, you don't have an ending bracket ( } ) for the movement task. However, as it is, you script will run both fire tasks simultaneously since you called them at the same time, in mainTask. After 10 repetitions, the script will then do nothing. If you look more closely at the example I gave, you can see that I started by only calling fire1 in mainTask, and within fire1, I had fire2 be called after the 10 repetitions of the loop. fire2 would then do the same thing for fire1.

Do you understand? I may have introduced something a bit more advanced than you were ready for. If you want a simpler method to doing this just try and the entire sequence in one loop and one task, instead of multiple tasks.

Matteo

Re: Danmakufu wonders..
« Reply #16 on: April 27, 2012, 04:42:11 AM »
Ok Ozzy, i won't post again large code than.
Also, i think now i'm understanding what you say, but one thing is understanding how to do a script...another is making it work.
So, i will try this and if i have to use tasks i guess that @mainloop style should be avoided.

Thanks!

Helepolis

  • Charisma!
  • *
  • O-ojousama!?
Re: Danmakufu wonders..
« Reply #17 on: April 27, 2012, 05:39:24 AM »
Matteo, good to see that you picked up Danmakufu. Although if you want to continue asking questions about "how to fix this error", please continue in http://www.shrinemaiden.org/forum/index.php/topic,12397.0.html

And a/s it was said by Ozzy, post large code at this website pastebin.com and then post the url here.

Locking this thread as it served its purpose already.

--Hele