Author Topic: Useful Miscellaneous Code Snippets  (Read 56656 times)

GenericTouhouFailure

  • WHAT DO YOU MEAN IT'S NOT CALLED UNL? *boom*
Re: Useful Miscellaneous Code Snippets
« Reply #60 on: September 10, 2010, 11:34:17 AM »
No drawing functions?




ANIMATE YOUR ZUN Sprite (Works if any sprite is in the same format as ZUN's too, taken from Helepolis's tutorial)
Should be fixed now
Code: [Select]
let ZUN_f = 0;
let ZUN_f2 = 0;
task ZUNimate(sprite){
SetTexture(sprite);
SetRenderState(ALPHA);
SetAlpha(255);
SetGraphicAngle(0,0,0);
SetGraphicScale(0.9,0.9);
DrawGraphic(GetX,GetY);
}
task ZUNimateMain{
if(GetSpeedX()>0){
if(ZUN_f2<10){SetGraphicRect(0,64,64,128);}
if(ZUN_f2>=10 && ZUN_f2<20){SetGraphicRect(64,64,128,128);}
if(ZUN_f2>=20 && ZUN_f2<30){SetGraphicRect(128,64,192,128);}
if(ZUN_f2>=30){SetGraphicRect(192,64,256,128);}
ZUN_f2++;
}
if(GetSpeedX()<0){
if(ZUN_f2<10){SetGraphicRect(0,64,64,128);}
if(ZUN_f2>=10 && ZUN_f2<20){SetGraphicRect(64,64,128,128);}
if(ZUN_f2>=20 && ZUN_f2<30){SetGraphicRect(128,64,192,128);}
if(ZUN_f2>=30){SetGraphicRect(192,64,256,128);}
ZUN_f2++;
SetGraphicAngle(180,0,0);
}
if(int(GetSpeedX())==0){
if(ZUN_f<10){SetGraphicRect(0,0,64,64);}
if(ZUN_f>=10 && ZUN_f<20){SetGraphicRect(64,0,128,64);}
if(ZUN_f>=20 && ZUN_f<30){SetGraphicRect(128,0,192,64);}
if(ZUN_f>=30 && ZUN_f<40){SetGraphicRect(192,0,256,64);}
ZUN_f2 = 0;
}
ZUN_f++;
if(ZUN_f==40){ZUN_f=0;}

}

call ZUNimate(imgBoss) in DRAWLOOP and and ZUNimateMain in mainloop (got to test this)

Custom version of last spell.
This one Ends the spell only after 75 frames instead of ending on bullet contact. (not tested)
Code: [Select]
task lastspell{
yield;
c = false;
ForbidBomb(true);
loop{
if(OnPlayerMissed && !c){
c = true;
loop(75){ yield;}
AddLife(-GetLife);
ExtendPlayer(1);
break;
}

yield;
}
}
« Last Edit: September 10, 2010, 11:13:33 PM by GenericPeerlessWindGod »

Azure Lazuline

  • Looooove!!
  • PM me for free huggles and love!
    • Entanma Project - indie game development
Re: Useful Miscellaneous Code Snippets
« Reply #61 on: September 10, 2010, 06:06:51 PM »
That ZUNimate function has one mistake - you're incrementing a variable in DrawLoop, which means the animation will always increment once per drawn frame. In other words, if you set frameskip to 1, the animation will play at half speed, and if you hold spacebar to fastforward, the animation will continue playing at normal speed even while everything else goes extremely fast. You'll need to do the changes to ZUN_f and ZUN_f2 in a separate function that's called from MainLoop.

GenericTouhouFailure

  • WHAT DO YOU MEAN IT'S NOT CALLED UNL? *boom*
Re: Useful Miscellaneous Code Snippets
« Reply #62 on: September 10, 2010, 11:09:11 PM »
That ZUNimate function has one mistake - you're incrementing a variable in DrawLoop, which means the animation will always increment once per drawn frame. In other words, if you set frameskip to 1, the animation will play at half speed, and if you hold spacebar to fastforward, the animation will continue playing at normal speed even while everything else goes extremely fast. You'll need to do the changes to ZUN_f and ZUN_f2 in a separate function that's called from MainLoop.
oh. Didn't know that.
Thanks.
Changing now....

Iryan

  • Ph?nglui mglw?nafh
  • Cat R?lyeh wgah?nagl fhtagn.
Re: Useful Miscellaneous Code Snippets
« Reply #63 on: September 16, 2010, 12:02:38 AM »
HA! Finally!

Here, have some code that creates an effect object that causes bulges in the background similar to what happens behind the bosses from SA onwards.


BulgeBackground(image, nx, ny, dmax, dfac);

Call in @Initialize to create an SA-like bulge at the position of the player in a given image drawn over the playing field.
Processor heavy depending on the parameters.

image = path of the image, duh.
nx, ny = number of rows and columns in the effect object. The higher the numbers, the smoother the background, but also more slowdown. Due to danmakufu's bad array handling, should not exceed 10/15.
dmax = maximum buldge of any given vertex. Should not exceed (width_of_playing_field / nx) or (height_of_playing_field / ny).
dfac = value between 0 and 1. Determines the crassness of the buldge edge. A good value is ~0.98.

Code: [Select]
    task BulgeBackground(image, nx, ny, dmax, dfac){

        let dx=(GetClipMaxX-GetClipMinX)/nx;
        let dy=(GetClipMaxY-GetClipMinY)/ny;

        let du=480/nx;                                 //width of the image goes here
        let dv=640/ny;                                //height of the image goes here

        let vertnum=floor(ny/2)*4*nx + floor(0.5+ny/2)*(2*nx+2) +1 -ny;

        yield;yield;

        let obj = Obj_Create(OBJ_EFFECT);


            ObjEffect_SetRenderState(obj,ALPHA);
            ObjEffect_SetTexture(obj, image);

             ObjEffect_SetPrimitiveType(obj, PRIMITIVE_TRIANGLESTRIP);
             ObjEffect_CreateVertex(obj, vertnum);

        Obj_SetPosition(obj, GetClipMinX, GetClipMinY);

        let xar=[];
        let yar=[];

        let by=0;

        while(by<=(ny)){
            if(by%2==0){
                ascent(i in 0..(2*nx+2)){
                    xar=xar~[floor(i/2)];
                    yar=yar~[by + i%2 ];
                }
            }else{
                ascent(i in 0..(4*nx)){
                    xar=xar~[nx - (i%2 + floor(i/4) ) ];
                    yar=yar~[by + floor(i/2)%2 ];
                }
            }

            by++;
            if(by<(ny)){ xar=erase(xar, length(xar)-1); yar=erase(yar, length(yar)-1); }
        }

        let td=0;
        let ta=0;

        let ophi=rand(0, 360);

        while(Obj_BeDeleted(obj)==false){

            ophi+=7;

                ObjEffect_SetLayer(obj,1);

            ascent(i in 0..vertnum){

                td= ((GetClipMinX + xar[i]*dx - GetPlayerX)^2 + (GetClipMinY + yar[i]*dy - GetPlayerY)^2)^0.5;                    // Change to GetX and GetY to
                ta= atan2(GetClipMinY + yar[i]*dy - GetPlayerY, GetClipMinX + xar[i]*dx - GetPlayerX);                          // center the bulge on the boss and not the player

                ObjEffect_SetVertexXY(obj, i, xar[i]*dx + cos(ta)*dmax*(dfac^td)*(4+sin(ophi+ta*6))/5 , yar[i]*dy + sin(ta)*dmax*(dfac^td)*(4+sin(ophi+ta*6))/5);

                ObjEffect_SetVertexUV(obj, i, xar[i]*du, yar[i]*dv);

                ObjEffect_SetVertexColor(obj, i, 255, 255-255*(dfac^td), 255-255*(dfac^td), 255-255*(dfac^td));

            }
            yield;
        }
    }

I remember Azure telling me that creating a render target, drawing the actual background on the render target and then using the render target as the image for the effect object is possible. If so, then this would enable you to generate the bulge in the actual background, and not just in one image.


For those who are interested, I have attached an image on how the vertices are aligned in the object. 20% of the vertices are redundant, but they are still necessary because of the shape of the object, otherwise interferences occur when the grid is distorted.
« Last Edit: September 16, 2010, 08:35:47 AM by Iryan »
Old Danmakufu stuff can be found here!

"As the size of an explosion increases, the numbers of social situations it is incapable of solving approaches zero."

Iryan

  • Ph?nglui mglw?nafh
  • Cat R?lyeh wgah?nagl fhtagn.
Re: Useful Miscellaneous Code Snippets
« Reply #64 on: October 04, 2010, 06:11:35 PM »
Inspired by a certain post in the request thread, I made a more generalized version of the one requested:

Function: GetLineBorderPoint(px, py, tx, ty)

What it does: returns [a, b], which are the coordinates of the point of intersection between the playing field's border and a ray from one point in the direction of another point.

Parameters:

px, py: source point
tx, ty: target point

Code: [Select]
function GetLineBorderPoint(px, py, tx, ty){

let ta = atan2(ty-py, tx-px);

if( ta>= atan2(GetClipMinY - py, GetClipMinX - px) && ta<=  atan2(GetClipMinY - py, GetClipMaxX - px)){
return [px - (GetClipMinY-py)*tan(ta+90), GetClipMinY];
}
if( ta>= atan2(GetClipMinY - py, GetClipMaxX - px) && ta<=  atan2(GetClipMaxY - py, GetClipMaxX - px)){
return [GetClipMaxX, py + (GetClipMaxX-px)*tan(ta)];
}
if( ta>= atan2(GetClipMaxY - py, GetClipMaxX - px) && ta<=  atan2(GetClipMaxY - py, GetClipMinX - px)){
return [px - (GetClipMaxY-py)*tan(ta-90), GetClipMaxY];
}
if( ta> atan2(GetClipMaxY - py, GetClipMinX - px) || ta<  atan2(GetClipMinY - py, GetClipMinX - px)){
return [GetClipMinX, py + (GetClipMinX-px)*tan(ta+180)];
}
}
Old Danmakufu stuff can be found here!

"As the size of an explosion increases, the numbers of social situations it is incapable of solving approaches zero."

Chronojet ⚙ Dragon

  • The Oddity
  • 今コソ輝ケ、我ガ未来、ソノ可能性!!
Re: Useful Miscellaneous Code Snippets
« Reply #65 on: October 05, 2010, 05:31:04 AM »
Function: GetLineBorderPoint(px, py, tx, ty)

Perfect for MASTER SPAAAAAAAAAAAAA(ry lasers that spawn bullets from the sides of the screen. :V

Chronojet ⚙ Dragon

  • The Oddity
  • 今コソ輝ケ、我ガ未来、ソノ可能性!!
Re: Useful Miscellaneous Code Snippets
« Reply #66 on: November 03, 2010, 10:48:52 PM »
Secant, Cosecant, and Cotangent functions. :\

Code: [Select]
function sec(n) { return 1/cos(n); }
function csc(n) { return 1/sin(n); }
function cot(n) { return 1/tan(n); }

GenericTouhouFailure

  • WHAT DO YOU MEAN IT'S NOT CALLED UNL? *boom*
Re: Useful Miscellaneous Code Snippets
« Reply #67 on: November 26, 2010, 01:24:47 PM »
GetPointInDirection(300,300,10,60);
would return the point 10 pixels away from 300 300 at a 60 degree angle (for spawning bullets or items in circles away from centerpoint of boss.
Code: [Select]
function GetPointInDirection(x,y,r,a){
let rx = x+r*cos(a);
let ry = y+r*sin(a);
return [rx,ry];
}
function GetPointInDirectionFromBoss(r,a){
return GetPointInDirection(GetX,GetY,r,a);
}
function GetPointInDirectionFromPlayer(r,a){
return GetPointInDirection(GetPlayerX,GetPlayerY,r,a);
}
quite useless for someone who has already memorized cos/sin whatever but i'll just post this here.

Drake

  • *
Re: Useful Miscellaneous Code Snippets
« Reply #68 on: November 26, 2010, 02:30:19 PM »
oh god so many letters that would be so confusing
and then you'd have brackets everywhere holy god

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

ChiyuriKitashirakawa

  • timesurfingSailor
  • Time is my sea, space my board.
Re: Useful Miscellaneous Code Snippets
« Reply #69 on: November 29, 2010, 08:53:39 PM »
Homing angles for the lazy!
GetRelativeAngleToPlayer gets the angle between the point of coords (objX,objY) to the player. Think of it like a GetAngleToPlayer that works on any point of the field instead of (GetX,GetY).
GetRelativeAngleToTarget does the same, but instead of using the player as a target, it uses the point (tarX,tarY).
Code: [Select]
function GetRelativeAngleToPlayer(objX,objY){
return GetRelativeAngleToTarget(objX,objY,GetPlayerX,GetPlayerY)
}
function GetRelativeAngleToTarget(objX,objY,tarX,tarY){
if (objX > tarX){ return 180 - atan2((|objY-tarY|),(| objX-tarX |));}
return atan2((|objY-tarY|),(| objX-tarX |));
}

Drake

  • *
Re: Useful Miscellaneous Code Snippets
« Reply #70 on: November 30, 2010, 12:06:31 AM »
Simple revision for less typing and naming standards and cleanliness etc.

Code: [Select]
function Obj_GetAngleToPlayer(obj){
    return Obj_GetAngleToPoint(obj,GetPlayerX,GetPlayerY)
}

function Obj_GetAngleToPoint(obj,tarX,tarY){
    if (Obj_GetX(obj) > tarX){
        return 180 - atan2((|Obj_GetY(obj)-tarY|),(| Obj_GetX(obj)-tarX |));
    }
    return atan2((|Obj_GetY(obj)-tarY|),(| Obj_GetX(obj)-tarX |));
}

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

Arcorann

  • hey catgirl
  • Surprisingly unkempt
Re: Useful Miscellaneous Code Snippets
« Reply #71 on: December 02, 2010, 10:02:44 AM »
I was looking at the GetPointToLine function and wondering "Why do we need this trig?"...

So, here's my version:
Code: [Select]
   function GetPointToLine(ox, oy, p1x, p1y, p2x, p2y){

      let dist= ( (oy-p1y)*(p2x-p1x)-(ox-p1x)*(p2y-p1y) )/(( (p2x-p1x)^2 + (p2y-p1y)^2 )^0.5) ;

      return dist;
   }

This should give the same result, including sign, as the original by Iryan.

Azure Lazuline

  • Looooove!!
  • PM me for free huggles and love!
    • Entanma Project - indie game development
Re: Useful Miscellaneous Code Snippets
« Reply #72 on: December 09, 2010, 03:07:10 AM »
WrapText
Splits one string into multiple, only breaking at spaces. "Text" is the text input (obviously), "spaces" is the maximum number of characters on one line. Returns an array of strings, one entry per line. The ^ character can force a line-break.

Code: [Select]
function WrapText(text, spaces){
text=text~" ";
let strings=[];
let numstrings=0;
let k=0;
let lastletter=1;
while(length(text)>0&&lastletter>0){
lastletter=0;
k=0;
while(k<spaces&&k<length(text)){
if(text[k]==' '){lastletter=k;}
if(text[k]=='^'){
text[k]=' '; //add a newline
k=spaces;
}
k++;
}
strings=strings~[text[0..lower(lastletter,length(text))]];
text=text[lower(lastletter+1,length(text))..length(text)];
numstrings++;
}

return strings;
}

Drake

  • *
Re: Useful Miscellaneous Code Snippets
« Reply #73 on: January 24, 2011, 02:52:55 AM »
Naut I hate you :(

GetAscii

Should be self-explanatory. Input character and either "NUMBER" or "LOWER" for speed purposes, receive ascii value.

Code: [Select]
function GetAscii(char,type){
alternative(type)
case("NUMBER"){
alternative(char)
case('0'){return 48;} case('1'){return 49;} case('2'){return 50;} case('3'){return 51;}
case('4'){return 52;} case('5'){return 53;} case('6'){return 54;} case('7'){return 55;}
case('8'){return 56;} case('9'){return 57;}
}
case("LOWER"){
alternative(char)
case('a'){return 97;} case('b'){return 98;} case('c'){return 99;} case('d'){return 100;}
case('e'){return 101;} case('f'){return 102;} case('g'){return 103;} case('h'){return 104;}
case('i'){return 105;} case('j'){return 106;} case('k'){return 107;} case('l'){return 108;}
case('m'){return 109;} case('n'){return 110;} case('o'){return 111;} case('p'){return 112;}
case('q'){return 113;} case('r'){return 114;} case('s'){return 115;} case('t'){return 116;}
case('u'){return 117;} case('v'){return 118;} case('w'){return 119;} case('x'){return 120;}
case('y'){return 121;} case('z'){return 122;}
}
}

If someone wants to expand it, cool. I personally don't.

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

Blargel

  • RAWR!
  • I'M AN ANGRY LOLI!
Re: Useful Miscellaneous Code Snippets
« Reply #74 on: January 25, 2011, 01:30:50 AM »
Uh, Drake?

Code: [Select]
GetAscii(character){
    return character+0;
}

Seriously. If you want to go from ascii to character, that's another story. You'll need to do that alternative nonsense unless there's a better way I'm not thinking of right now.

Btw, to people who don't know, the parameter would be 'a' if you wanted the ascii for a and not "a". Single quotes not double.
<WorkingKeine> when i get home i just go to the ps3 and beat people up in blazblue with a loli
<Azure> Keine: Danmakufu helper by day, violent loli by night.

Drake

  • *
Re: Useful Miscellaneous Code Snippets
« Reply #75 on: January 25, 2011, 01:39:56 AM »
but but but dnh crashed the last time i did that

why does it work now

:C

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

Blargel

  • RAWR!
  • I'M AN ANGRY LOLI!
Re: Useful Miscellaneous Code Snippets
« Reply #76 on: March 26, 2011, 09:10:17 AM »
Stealing code from other people and then converting it to Danmakufu. Wooo

Collision_Box_Box

Determines if two rectangles are intersecting with each other. Returns true if they are and false if they are not.

cx1, cy1 is the center coordinates of rectangle 1.
w1, h1 is the width and height of rectangle 1.
r1 is the rotation of rectangle 1.

The other 5 parameters are the same except for rectangle 2.

Code: [Select]
function Collision_Box_Box(cx1, cy1, w1, h1, r1, cx2, cy2, w2, h2, r2){
    let rectA = CalculateCorners(cx1, cy1, w1, h1, r1);
    let rectB = CalculateCorners(cx2, cy2, w2, h2, r2);

    let axisList = [
        rectA[1] - rectA[0],
        rectA[1] - rectA[2],
        rectB[0] - rectB[3],
        rectB[0] - rectB[1]
    ];
   
    ascent(i in 0..4){
        if(!IsAxisCollision(axisList[i])){
            return false;
        }
    }
   
    return true;
   
   
    function CalculateCorners(cx, cy, width, height, rotation){
        if(rotation == 0){
            return [
                [cx-width/2, cy-height/2],
                [cx+width/2, cy-height/2],
                [cx+width/2, cy+height/2],
                [cx-width/2, cy+height/2]
            ];
        }
        else {
            let angles = [
                atan2(height/-2, width/-2)+rotation,
                atan2(height/2, width/-2)+rotation,
                atan2(height/2, width/2)+rotation,
                atan2(height/-2, width/2)+rotation
            ];
            let distance = (height^2 + width^2)^0.5/2;
            return [
                [cx+cos(angles[0])*distance, cy+sin(angles[0])*distance],
                [cx+cos(angles[1])*distance, cy+sin(angles[1])*distance],
                [cx+cos(angles[2])*distance, cy+sin(angles[2])*distance],
                [cx+cos(angles[3])*distance, cy+sin(angles[3])*distance]
            ];
        }
    }
   
   
    function IsAxisCollision(axis){
        let rectAScalars = [
            GenerateScalar(rectA[0], axis),
            GenerateScalar(rectA[1], axis),
            GenerateScalar(rectA[2], axis),
            GenerateScalar(rectA[3], axis)
        ];
        let rectBScalars = [
            GenerateScalar(rectB[0], axis),
            GenerateScalar(rectB[1], axis),
            GenerateScalar(rectB[2], axis),
            GenerateScalar(rectB[3], axis)
        ];
       
        let rectAMin = ArrayMin(rectAScalars);
        let rectAMax = ArrayMax(rectAScalars);
        let rectBMin = ArrayMin(rectBScalars);
        let rectBMax = ArrayMax(rectBScalars);

        if(rectBMax <= rectAMax && rectBMax >= rectAMin)
        {
            return true;
        }
        else if (rectAMax <= rectBMax && rectAMax >= rectBMin)
        {
            return true;
        }

        return false;
    }
   
   
    function GenerateScalar(corner, axis){
        let num = (corner[0] * axis[0]) + (corner[1] * axis[1]);
        let denom = (axis[0] * axis[0]) + (axis[1] * axis[1]);
        let divisionResult = num / denom;
       
        let cornerProjected = [divisionResult * axis[0], divisionResult * axis[1]];
       
        let scalar = (axis[0] * cornerProjected[0]) + (axis[1] * cornerProjected[1]);
        return scalar;
    }
}

function ArrayMin(array){
    let min = array[0];
    ascent(i in 1..length(array)){
        if(array[i] < min){ min = array[i]; }
    }
    return min;
}

function ArrayMax(array){
    let max = array[0];
    ascent(i in 1..length(array)){
        if(array[i] > max){ max = array[i]; }
    }
    return max;
}

I nested CalculateCorners, IsAxisCollision, and GenerateScalar because nothing should really be using those besides the collision function itself. ArrayMin and ArrayMax are also used by the collision function but those are probably useful elsewhere too so I left them unnested.
« Last Edit: March 26, 2011, 09:13:27 AM by Blargel »
<WorkingKeine> when i get home i just go to the ps3 and beat people up in blazblue with a loli
<Azure> Keine: Danmakufu helper by day, violent loli by night.

CK Crash

  • boozer
Re: Useful Miscellaneous Code Snippets
« Reply #77 on: May 21, 2011, 03:39:52 AM »
Bumping because Naut said so.

Wavy background effect

Code: [Select]
task WavyBG(imgBG,HScroll,VScroll)
{
let obj = Obj_Create(OBJ_EFFECT);
let s = 0;

Obj_SetPosition(obj,0,0);
ObjEffect_SetTexture(obj,imgBG);
ObjEffect_SetPrimitiveType(obj,PRIMITIVE_TRIANGLESTRIP);
ObjEffect_SetLayer(obj,0);
ObjEffect_CreateVertex(obj,32);

while(!Obj_BeDeleted(obj))
{
ascent(i in 0..16)
{
ObjEffect_SetVertexUV(obj,i*2,HScroll,i*32+s*VScroll);
ObjEffect_SetVertexUV(obj,i*2+1,512+HScroll,i*32+s*VScroll);
ObjEffect_SetVertexXY(obj,i*2,GetClipMinX+sin(s+i*16)*64-64,sin(s+i*5)*64 + i*40-64);
ObjEffect_SetVertexXY(obj,i*2+1,GetClipMaxX+sin(s+i*16)*64+64,sin(s+i*5)*64 + i*40-64);
}
s++;
yield;
}
}

Load the image first, then call this function in @Initialize.

Darkness1

  • Nothing to see here.
  • Enigmatic, isn't it?
Re: Useful Miscellaneous Code Snippets
« Reply #78 on: May 29, 2011, 04:30:07 PM »
Function for objects: TurnToPoint.

Four Parameters, which are id, speed, PointX and PointY.

Makes an object bullet/laser turn till it points at a certain point at the playing field. Doesn't loop by itself. Speed is the speed it turns at. Inputting a negative value for speed gives you awkward results. Id is (obviously) the id of the object.


EDIT: Improved version by Blargel.
Code: [Select]
function TurnToPoint(id, speed, PointX, PointY){
    let current_angle = Obj_GetAngle(id);
    let target_angle = atan2(PointY-Obj_GetY(id), PointX-Obj_GetX(id));
    let adist = AngularDistance(current_angle, target_angle);

    if(absolute(adist) < speed){
        Obj_SetAngle(id, target_angle);
    }
    else {
        if(adist > 0){
            Obj_SetAngle(id, Obj_GetAngle(id)+speed);
        }
        else if(adist < 0){
            Obj_SetAngle(id, Obj_GetAngle(id)-speed);
        }
    }
}


« Last Edit: June 01, 2011, 05:45:24 AM by Darkness1 »

Something XutaWoo-y

  • Adorable Weaponsmith
Re: Useful Miscellaneous Code Snippets
« Reply #79 on: May 30, 2011, 02:22:43 AM »
atan2 gets -180 to 180. Bullets are usually given 0 to 360.

Also, depending on the situation the bullets could be +360. Meaning that they would have to spin even more. Although these problems probably shouldn't be fixed by that function. Maybe another function that goes with it.

Arcorann

  • hey catgirl
  • Surprisingly unkempt
Re: Useful Miscellaneous Code Snippets
« Reply #80 on: May 30, 2011, 06:50:42 AM »
Blargel did a few angle functions on the first page. Using them:

Code: [Select]
function TurnToPoint(id, speed, PointX, PointY){ //Use a positive value for speed!
    adist = AngularDistance(Obj_GetAngle(id),atan2(PointY-Obj_GetY(id),PointX-Obj_GetX(id)))
    if(adist<0){
        Obj_SetAngle(id, Obj_GetAngle(id)-speed);}
    if(adist>0){
        Obj_SetAngle(id, Obj_GetAngle(id)+speed);}
    }

Darkness1

  • Nothing to see here.
  • Enigmatic, isn't it?
Re: Useful Miscellaneous Code Snippets
« Reply #81 on: May 30, 2011, 01:44:26 PM »
Blargel did a few angle functions on the first page. Using them:

Code: [Select]
function TurnToPoint(id, speed, PointX, PointY){ //Use a positive value for speed!
    adist = AngularDistance(Obj_GetAngle(id),atan2(PointY-Obj_GetY(id),PointX-Obj_GetX(id)))
    if(adist<0){
        Obj_SetAngle(id, Obj_GetAngle(id)-speed);}
    if(adist>0){
        Obj_SetAngle(id, Obj_GetAngle(id)+speed);}
    }

It works as wanted, but when i try it my lasers start to vibrate :( (Yeah, i got no clue why).

Arcorann

  • hey catgirl
  • Surprisingly unkempt
Re: Useful Miscellaneous Code Snippets
« Reply #82 on: May 31, 2011, 12:11:42 AM »
Yes, I think I see the problem. When the angular distance is less than the speed it still turns with the full value. Try this:
Code: [Select]
function TurnToPoint(id, speed, PointX, PointY){ //Use a positive value for speed!
    adist = AngularDistance(Obj_GetAngle(id),atan2(PointY-Obj_GetY(id),PointX-Obj_GetX(id)))
    if(absolute(adist)<=speed){
        Obj_SetAngle(id, Obj_GetAngle(id)-adist);}
    if(adist<-speed){
        Obj_SetAngle(id, Obj_GetAngle(id)-speed);}
    if(adist>speed){
        Obj_SetAngle(id, Obj_GetAngle(id)+speed);}
    }

Darkness1

  • Nothing to see here.
  • Enigmatic, isn't it?
Re: Useful Miscellaneous Code Snippets
« Reply #83 on: May 31, 2011, 11:46:42 AM »
Still nothing. But i experimented with the two ways you did it and the best i could get was this:
Code: [Select]
function TurnToPoint(id, speed, PointX, PointY){
let adist = AngularDistance(Obj_GetAngle(id),atan2(PointY-Obj_GetY(id),PointX-Obj_GetX(id)));

    if(absolute(adist)<=speed && adist<0){
        Obj_SetAngle(id, Obj_GetAngle(id)-adist);}

    if(absolute(adist)<=speed && adist>0){
        Obj_SetAngle(id, Obj_GetAngle(id)+adist);}

    if(adist<0 && adist<speed){
        Obj_SetAngle(id, Obj_GetAngle(id)-speed);}

    if(adist>0 && adist>speed){
        Obj_SetAngle(id, Obj_GetAngle(id)+speed);}

    }

No more vibration, but it looks weird when the turning goes negative (counter-clock).

Blargel

  • RAWR!
  • I'M AN ANGRY LOLI!
Re: Useful Miscellaneous Code Snippets
« Reply #84 on: May 31, 2011, 08:34:16 PM »
Code: [Select]
function TurnToPoint(id, speed, PointX, PointY){
    let current_angle = Obj_GetAngle(id);
    let target_angle = atan2(PointY-Obj_GetY(id), PointX-Obj_GetY(id));
    let adist = AngularDistance(current_angle, target_angle);

    if(absolute(adist) < speed){
        Obj_SetAngle(id, target_angle);
    }
    else {
        if(adist > 0){
            Obj_SetAngle(id, Obj_GetAngle(id)+speed);
        }
        else if(adist < 0){
            Obj_SetAngle(id, Obj_GetAngle(id)-speed);
        }
    }
}

Pretty sure this is correct. If it still looks weird, you might have something else interfering with the rotation.
<WorkingKeine> when i get home i just go to the ps3 and beat people up in blazblue with a loli
<Azure> Keine: Danmakufu helper by day, violent loli by night.

Darkness1

  • Nothing to see here.
  • Enigmatic, isn't it?
Re: Useful Miscellaneous Code Snippets
« Reply #85 on: June 01, 2011, 05:38:41 AM »
Code: [Select]
function TurnToPoint(id, speed, PointX, PointY){
    let current_angle = Obj_GetAngle(id);
    let target_angle = atan2(PointY-Obj_GetY(id), PointX-Obj_GetY(id));
    let adist = AngularDistance(current_angle, target_angle);

    if(absolute(adist) < speed){
        Obj_SetAngle(id, target_angle);
    }
    else {
        if(adist > 0){
            Obj_SetAngle(id, Obj_GetAngle(id)+speed);
        }
        else if(adist < 0){
            Obj_SetAngle(id, Obj_GetAngle(id)-speed);
        }
    }
}

Pretty sure this is correct. If it still looks weird, you might have something else interfering with the rotation.

First when i tested this, i thought i didn't work as well, but it was just a little typing mistake. It now works, thanks!
« Last Edit: June 01, 2011, 05:46:12 AM by Darkness1 »

Darkness1

  • Nothing to see here.
  • Enigmatic, isn't it?
Re: Useful Miscellaneous Code Snippets
« Reply #86 on: June 15, 2011, 11:47:51 AM »
Sorry for the double post, but:

A new version of the last function, TurnToAngle(id, speed, angle).

Three Parameters, which are id, speed and angle.

Makes an object bullet/laser turn till it's angle is equal to the number input as the parameter angle. Doesn't loop by itself. Speed is the speed it turns at. Inputting a negative value for speed gives you awkward results. Id is the id of the object.

Code: [Select]

function TurnToAngle(id, speed, angle){
    let current_angle = Obj_GetAngle(id);
    let target_angle = angle;
    let adist = AngularDistance(current_angle, target_angle);

    if(absolute(adist) < speed){
        Obj_SetAngle(id, target_angle);
    }
    else {
        if(adist > 0){
            Obj_SetAngle(id, Obj_GetAngle(id)+speed);
        }
        else if(adist < 0){
            Obj_SetAngle(id, Obj_GetAngle(id)-speed);
        }
    }
}

Blargel

  • RAWR!
  • I'M AN ANGRY LOLI!
Re: Useful Miscellaneous Code Snippets
« Reply #87 on: July 09, 2011, 01:38:58 AM »
GetPointInRectangle(ox, oy, pcx, pcy, recl, recw, align);

This function checks wether or not a given point lies within a given rectangle. Returns true if it is and false if it isn't.

Parameters:

ox, oy: Coordinates of the seperate point.
pcx, pcy: Coordinates of the center of the rectangle.
recl, recw: Length and width of the rectangle.
align: the alignment of the rectangle, i.e. the angle the longer side points at.

Code: [Select]
function GetPointInRectangle(ox, oy, pcx, pcy, recl, recw, align){

let dist1;
let dist2;
let isit=false;

dist1=(| GetPointToLine(ox, oy, pcx, pcy, pcx+cos(align), pcy+sin(align)) |);
dist2=(| GetPointToLine(ox, oy, pcx, pcy, pcx+cos(align+90), pcy+sin(align+90)) |);

if( (dist1<0.5*recw)&&(dist2<0.5*recl) ){ isit=true; }

return(isit);
}

Making a (possibly) more optimized version of this for someone on IRC. Same parameters. I may have swapped the length and width parameters because Iryan has weird ass naming sense :V

Code: [Select]
function GetPointInRectangle(ox, oy, pcx, pcy, recl, recw, align){
    //Applying transformations to point instead of rectangle
    let distance = ((ox-pcx)^2+(oy-pcy)^2)^0.5;
    let angle = atan2(oy-pcy, ox-pcy)-align;
    let new_ox = cos(angle)*distance;
    let new_oy = sin(angle)*distance;

    //Checking if transformed point is within rectangle that is now axis-aligned and centered on origin
    return (absolute(new_ox) <= recl/2 && absolute(new_oy) <= recw/2);
}
« Last Edit: July 09, 2011, 01:48:01 AM by Blargel »
<WorkingKeine> when i get home i just go to the ps3 and beat people up in blazblue with a loli
<Azure> Keine: Danmakufu helper by day, violent loli by night.

Chronojet ⚙ Dragon

  • The Oddity
  • 今コソ輝ケ、我ガ未来、ソノ可能性!!
Re: Useful Miscellaneous Code Snippets
« Reply #88 on: August 16, 2011, 04:32:27 AM »
I'm going to update Blargel's ShootShape function. Like Blargel, I don't know if this belongs here or not.



Code: [Select]
function ShootShape(spawnX, spawnY, v, angle, num, bside, graphic, delay) {
ascent(i in 0..num) {
let sx = spawnX+cos(angle+i*360/num); let sy = spawnY+sin(angle+i*360/num); let sxN = spawnX+cos(angle+(i+1)*360/num); let syN = spawnY+sin(angle+(i+1)*360/num);
CreateShot01(spawnX, spawnY, v*(((sx-spawnX)^2+(sy-spawnY)^2)^0.5), atan2(sy-spawnY,sx-spawnX), graphic, delay);
ascent(j in 0..bside) {
let toAngle = atan2(syN-sy,sxN-sx); let toDist = (((sxN-sx)^2+(syN-sy)^2)^0.5); let sx2 = sx+toDist/bside*j*cos(toAngle); let sy2 = sy+toDist/bside*j*sin(toAngle);
CreateShot01(spawnX, spawnY, v*(((sx2-spawnX)^2+(sy2-spawnY)^2)^0.5), atan2(sy2-spawnY,sx2-spawnX), graphic, delay);
}
}
}

ShootShape
Shoots an outward shape function.

Parameter list:
spawnX, spawnY: spawning coordinates of the shape
v: velocity of corner bullets
angle: angle one of the corner bullets is aimed at
num: number of corners in the shape
bside: number of bullets in a side of the shape
graphic: bullet graphic used by the shape's bullets
delay: frames of delay given to each bullet

Example:
ShootShape(GetX, GetY, 3, GetAngleToPlayer, 3, 15, RED01, 10);
   This looks like the boss shoots a 3-sided shape (a triangle) with 15 bullets on each side, at the player.

Rosen

  • Cry moar desu!
  • Hyu~ dorodorodoro!
Re: Useful Miscellaneous Code Snippets
« Reply #89 on: September 03, 2011, 07:29:07 AM »
LSegmentIntersectPoint returns the point of intersection, if the 2 given segments intersect. If they don't intersect, it returns an array [-1,-1].
Can be used in any script version.

Segment 1: (x1,y1), (x2,y2).
Segment 2: (x3,y3), (x4,y4).

Code: [Select]
function LSegmentIntersectPoint(let x1, let y1, let x2, let y2, let x3, let y3, let x4, let y4) {

let d = (x2 - x1)*(y3 - y4) - (x3 - x4)*(y2 - y1);

if (d == 0) { return [-1,-1]; }

let d1 = (x3 - x1)*(y3 - y4) - (x3 - x4)*(y3 - y1);
let d2 = (x2 - x1)*(y3 - y1) - (x3 - x1)*(y2 - y1);

let t1 = d1 / d;
let t2 = d2 / d;
let point = [0,0];
if (t1 >= 0 && t1 <= 1 && t2 >= 0 && t2 <= 1) {
point[0] = t1*x2 + (1-t1)*x1;
point[1] = t1*y2 + (1-t1)*y1;
return point;

} else {
return [-1,-1];
}

}