Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #TouhouDanmakufu
- #Title[Profielwerkstuk 1]
- #Text[(easy)]
- #Player[FREE]
- #ScriptVersion[2]
- script_enemy_main{
- let CSD = GetCurrentScriptDirectory;
- let imgBoss = CSD ~ "img/Death Ball.png";
- let bg = CSD ~ "img/Stars.png";
- let slide = 0;
- @Initialize{
- SetLife(1000);
- SetTimer(60);
- SetScore(100000);
- SetMovePosition01(GetCenterX,GetCenterY,5);
- LoadGraphic(imgBoss);
- LoadGraphic(bg);
- CutIn(YOUMU,"Wind Bullets - easy -",imgBoss,0,0,100,100);
- LoadMusic(CSD ~ "bgm\Bad Situation.mp3");
- PlayMusic(CSD ~ "bgm\Bad Situation.mp3");
- mainTask;
- }
- @MainLoop{
- SetCollisionA(GetX,GetY,50);
- SetCollisionB(GetX,GetY,40);
- yield;
- }
- @DrawLoop{
- SetTexture(imgBoss);
- SetRenderState(ALPHA);
- SetAlpha(255);
- SetGraphicRect(0,0,100,100);
- SetGraphicScale(1,1);
- SetGraphicAngle(0,0,0);
- DrawGraphic(GetX,GetY);
- }
- @BackGround{
- SetTexture(bg);
- SetRenderState(ALPHA);
- SetAlpha(255);
- SetGraphicRect(0,0-slide,512,512-slide);
- SetGraphicScale(1,1);
- SetGraphicAngle(0,0,0);
- DrawGraphic(GetCenterX,GetCenterY);
- slide +=2;
- }
- @Finalize{
- DeleteGraphic(imgBoss);
- DeleteGraphic(bg);
- }
- task mainTask{
- yield;
- hypocycloid2(GetEnemyX,GetEnemyY,100,0.7,0.8); //Hypocycloid with radius 100, the final
- //two numbers are shape modifiers
- movement;
- }
- task movement{ //moves the boss around
- loop{
- SetMovePosition01(GetCenterX-100,120,5);
- wait(120);
- SetMovePosition01(GetCenterX+100,120,5);
- wait(120);
- yield;
- }
- }
- task hypocycloid2(a,b,r,k,l){
- loop{
- //First make sure k has only one decimal space and is between 0 and 1
- k = absolute(trunc(10*k)/10 - trunc(k));
- //Calculate the limit for the amount of points to spawn. The arc length of the
- //shape is dependant on the value f the smallest nominator of the fraction of k
- //ToFractionNom and ToFractionDeNom return the nominator and the denominator of
- //that fraction, respectively, while the division by their GCD or Greatest
- //Common Divisor makes sure it's in its most simplified form. Then multiply by
- //a full circle since this value is the amount of turns it has to make.
- //For example, k = 3/7 would simply return 3 while k = 0.4 would return 2 since
- //k = 0.4 = 4/10 = 2/5.
- let limit = 360 * (ToFractionNom(k) / GCD(ToFractionNom(k), ToFractionDeNom(k)));
- let t = 0;
- //Makes sure 100 bullets are distributed along the shape. This, along with the
- //former ensures that no matter what values you take the generation speed won't
- //differ significantly.
- loop(100){
- t += limit/100;
- //The formulas themselves. These aren't like the normal Hypocycloid ones,
- //which I'm aware of, but when testing with an immobile shape this did
- //exactly what I expected it to do.
- let x = a + r * ( (1 - k) * cos(t) + l * k * cos((1 - k) / k * t));
- let y = b + r * ( (1 - k) * sin(t) - l * k * sin((1 - k) / k * t));
- RotatingBullet(x, y, 3, GetAngleToPlayer, RED01);
- //This is embedded within the Hypocycloid task and the loop to enable
- //me to pass several values to it, most notably the center coordinates of
- //the spirograph.
- task RotatingBullet(x, y, v, angle, graphic) {
- let obj=Obj_Create(OBJ_SHOT);
- Obj_SetPosition(obj, x, y);
- Obj_SetAngle(obj, angle);
- Obj_SetSpeed(obj, v);
- ObjShot_SetGraphic(obj, graphic);
- ObjShot_SetDelay (obj, 0);
- ObjShot_SetBombResist (obj, true);
- //atan3 does the same as atan, with the difference that it
- //requires x and y like atan2 but handles degenerate cases like
- //x = 0 and y = 0 properly. This angle is required to make sure
- //that not all bullets will start at an angle of 0, which would
- //make it a dense rotating line instead of a shape.
- let angle = atan3(x-a,y-b);
- let t2 = 0;
- //This is just the distance from the center of the spirograph
- //(a,b) to the bullet (x,y) which will become the radius of its
- //rotation around (a,b)
- let r = ((x-a)^2 + (y-b)^2)^0.5;
- while(Obj_BeDeleted(obj)==false) {
- t2 += 1;
- //Makes the shape move downwards. No idea why this value
- //has to be this low, but b += 1 was enough to make the
- //shape zip past in a single frame.
- //Perhaps this is part of the problem?
- b += 0.01;
- //Describes the circular motion of the bullet. Pretty
- //straightforward.
- x = a + r * cos(t2 + angle);
- y = b + r * sin(t2 + angle);
- Obj_SetPosition(obj, x, y);
- yield;
- }
- }
- }
- wait(300);
- }
- }
- //Speaks for itself, I think. What it does exactly has been described above already.
- function atan3(x,y){
- if ( x == 0 && y == 0 ){
- break;
- }
- if ( x == 0 ){
- if ( y > 0 ){
- return 90;
- }else{
- return 270;
- }
- }
- if ( y == 0 ){
- if ( x > 0 ){
- return 0;
- }else{
- return 180;
- }
- }
- let a = atan(y/x);
- if ( x < 0 ){a = -a;}
- return a;
- }
- //Using Eulers formula. Tried doing some simple GCD's by hand and it worked perfectly.
- function GCD(a,b){
- let c;
- loop{
- if ( b == 0 ){return a;}
- c = b;
- b = a % b;
- a = c;
- }
- }
- //Returns the nominator of the value a. Keeps shifting the decimal point until the value equals
- //itself truncated, which means it doesn't have any decimal part anymore.
- function ToFractionNom(a){
- loop{
- a *= 10;
- if( a == trunc(a) ){return a;}
- }
- }
- //Same as the above, just returns the denominator instead of the nominator.
- function ToFractionDeNom(a){
- let b = 1;
- loop{
- a *= 10;
- b *= 10;
- if( a == trunc(a) ){return b;}
- }
- }
- //wait function
- function wait (w){
- loop(w){yield;}
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment