- Current Location:
- PureZC
- » PureZC Forums
- » Scripts
- » Laser.zh
Laser.zh
Overview
Creator:
Moosh
Added: 16 Feb 2016
Tags:
Library
Downloads: 150
|
Download Script (1.87 KB) |
Information
This is a header of mine that I made for bosses that use laser weapons.
Description Setup Reviews Comments
This is a header of mine that I made for bosses that use laser weapons. While the functions themselves are pretty self explanatory, it comes with no documentation as I made it for personal use. Since it's seen some use in scripts already, I'm putting it on the database for compatibility purposes. Documentation may be added in the future.
Laser functions are meant to be run every frame in a for loop. They work just like draw functions.
Alucard648
Posted 11 December 2023 - 04:24 AM
I would like to have opinion on documentation made for this library inside script file.
//laser.zh by Moosh //A library that allows rendering laser beams and processing collision with Link for damage. Best used for enemy or boss attacks. //Import and compile the library. It requires ghost.zh and all it`s dependencies. //All laser beam functions have similar input arguments. //Layer - layer used to render laser beam. //X and Y. Coordinates for origin for infinite laser beams. //X1, Y1, X2, Y2 - coordinates of two points for rendering laser beam segments in between. //Width - width of laser beam, in pixels. //Rotation - angle for infinite laser beams. //Damage - if set to >0, processes collision with Link and applies damage, if collision detected. // Only 2x2 pixels wide hitbox in the center of Link`s hitbos is used to detect collisions with lasers. //Color - color used to render laser. //Draws an infinite laser beam originating at given X and Y coordinates, pointing at given angle, with given width and single color and on the given layer. void DrawLaser(int layer, int x, int y, int width, int rotation, int color){ Screen->Circle(layer, x+width, y, width, color, 1, x, y, rotation, true, 128); Screen->Rectangle(layer, x+width, y-width, x+width+512, y+width, color, 1, x, y, rotation, true, 128); } //Draws a laser beam between two given points, each has X and Y coordinates. Layer to draw, width and color are also inputed. void DrawLaserSegment(int layer, int x1, int y1, int x2, int y2, int width, int color){ Screen->Circle(layer, x1+width, y1, width, color, 1, x1, y1, Angle(x1, y1, x2, y2), true, 128); Screen->Circle(layer, x2+width, y2, width, color, 1, x2, y2, Angle(x2, y2, x1, y1), true, 128); Screen->Rectangle(layer, x1+width, y1-width, x1+Distance(x1, y1, x2, y2)-width, y1+width, color, 1, x1, y1, Angle(x1, y1, x2, y2), true, 128); } //Checks collision between Link and laser beam, originating at given X and Y coordinates and having given width and rotation angle, and applies Damage to Link on collision. void LaserDetect(int x, int y, int width, int rotation, int damage){ width = Max(1, width-3); if(RotRectCollision(x+VectorX(128, rotation), y+VectorY(128, rotation), width, 128, rotation, CenterLinkX(), CenterLinkY(), 6, 6, 0)){ DamageLink(damage); } } //Checks collision between Link and laser beam between two pairs of given X and Y coordinates and having given width and rotation angle, and applies Damage to Link on collision. void LaserDetectSegment(int x1, int y1, int x2, int y2, int width, int damage){ width = Max(1, width-3); if(LaserDetect2Segment(x1, y1, x2, y2, width)){ DamageLink(damage); } } //Checks collision between Link and laser beam, originating at given X and Y coordinates and having given width and rotation angle. Reurns true,if collision exists and false otherwise. bool LaserDetect2(int x, int y, int width, int rotation){ if(RotRectCollision(x+VectorX(128, rotation), y+VectorY(128, rotation), width, 128, rotation, CenterLinkX(), CenterLinkY(), 6, 6, 0)){ return true; } return false; } //Checks collision between Link and laser beam between two pairs of given X and Y coordinates and having given width and rotation angle. Reurns true,if collision exists and false otherwise. bool LaserDetect2Segment(int x1, int y1, int x2, int y2, int width){ int rotation = Angle(x1, y1, x2, y2); int Dist = Distance(x1, y1, x2, y2)/2; if(RotRectCollision(x1+VectorX(Dist, rotation), y1+VectorY(Dist, rotation), width, Dist, rotation, CenterLinkX(), CenterLinkY(), 6, 6, 0)){ return true; } return false; } //Combines angular infinite laser rendering and processing collision with Link, applying damage, if collision occurs and damage is >0. void Laser(int layer, int x, int y, int width, int rotation, int damage, int color){ DrawLaser(layer, x, y, width, rotation, color); if(damage>0)LaserDetect(x, y, width, rotation, damage); } //Combines laser beam segment rendering and processing collision with Link, applying damage, if collision occurs and damage is >0. void LaserSegment(int layer, int x1, int y1, int x2, int y2, int width, int damage, int color){ DrawLaserSegment(layer, x1, y1, x2, y2, width, color); if(damage>0)LaserDetectSegment(x1, y1, x2, y2, width, damage); } //Render a 3-color angular infinite laser beam, using a set of 3 consecutive colors, starting with the given one. //If damage is >0, also process collision detection with Link and applying damage on collision. void Laser3Color(int layer, int x, int y, int width, int rotation, int damage, int color){ DrawLaser(layer, x, y, width, rotation, color+2); DrawLaser(layer, x, y, width/4*3, rotation, color+1); DrawLaser(layer, x, y, width/2, rotation, color); if(damage>0)LaserDetect(x, y, width, rotation, damage); } //Render a 3-color angular infinite laser beam, using 3 given colors. //If damage is >0, also process collision detection with Link and applying damage on collision. void Laser3Color(int layer, int x, int y, int width, int rotation, int damage, int color1, int color2, int color3){ DrawLaser(layer, x, y, width, rotation, color1); DrawLaser(layer, x, y, width/4*3, rotation, color2); DrawLaser(layer, x, y, width/2, rotation, color3); if(damage>0)LaserDetect(x, y, width, rotation, damage); } //Render a 3-color laser beam segment, using 3 given colors. //If damage is >0, also process collision detection with Link and applying damage on collision. void Laser3ColorSegment(int layer, int x1, int y1, int x2, int y2, int width, int damage, int color1, int color2, int color3){ DrawLaserSegment(layer, x1, y1, x2, y2, width, color1); DrawLaserSegment(layer, x1, y1, x2, y2, width/4*3, color2); DrawLaserSegment(layer, x1, y1, x2, y2, width/2, color3); if(damage>0)LaserDetectSegment(x1, y1, x2, y2, width, damage); } //Immediately deals unblockable Damage to Link. All other defenses (rings, mercy invincibility, Nayru`s Love spell etc.) are still respected. void DamageLink(int Damage){ eweapon e = FireEWeapon(EW_SCRIPT10, Link->X+InFrontX(Link->Dir, 12), Link->Y+InFrontY(Link->Dir, 12), 0, 0, Damage, -1, -1, EWF_UNBLOCKABLE); e->Dir = Link->Dir; e->DrawYOffset = -1000; SetEWeaponLifespan(e, EWL_TIMER, 1); SetEWeaponDeathEffect(e, EWD_VANISH, 0); } //Deals damage to Link, if he collides with given rectangle. Top left corner coordinates, width and height must be provided. void MakeHitbox(int X, int Y, int W, int H, int Damage){ eweapon e = FireEWeapon(EW_SCRIPT10, X, Y, 0, 0, Damage, -1, -1, EWF_UNBLOCKABLE); e->DrawYOffset = -1000; e->HitWidth = W; e->HitHeight = H; SetEWeaponLifespan(e, EWL_TIMER, 1); SetEWeaponDeathEffect(e, EWD_VANISH, 0); } //Returns true, if two given rotated rectangles collide, false otherwise. bool RotRectCollision(float x1c, float y1c, float height1, float width1, float rot1, float x2c, float y2c, float height2, float width2, float rot2){ float rad1=Sqrt(height1*height1+width1*width1); float rad2=Sqrt(height2*height2+width2*width2); float angle1=RadtoDeg(ArcSin(height1/rad1)); float angle2=RadtoDeg(ArcSin(height2/rad2)); float x1[4]; float y1[4]; float x2[4]; float y2[4]; float axisX[4]; float axisY[4]; float proj; float minProj1; float maxProj1; float minProj2; float maxProj2; x1[0]=x1c+rad1*Cos(rot1-angle1); y1[0]=y1c+rad1*Sin(rot1-angle1); x1[1]=x1c+rad1*Cos(rot1+angle1); y1[1]=y1c+rad1*Sin(rot1+angle1); x1[2]=x1c+rad1*Cos(rot1+180-angle1); y1[2]=y1c+rad1*Sin(rot1+180-angle1); x1[3]=x1c+rad1*Cos(rot1+180+angle1); y1[3]=y1c+rad1*Sin(rot1+180+angle1); x2[0]=x2c+rad2*Cos(rot2-angle2); y2[0]=y2c+rad2*Sin(rot2-angle2); x2[1]=x2c+rad2*Cos(rot2+angle2); y2[1]=y2c+rad2*Sin(rot2+angle2); x2[2]=x2c+rad2*Cos(rot2+180-angle2); y2[2]=y2c+rad2*Sin(rot2+180-angle2); x2[3]=x2c+rad2*Cos(rot2+180+angle2); y2[3]=y2c+rad2*Sin(rot2+180+angle2); axisX[0]=x1[0]-x1[1]; axisY[0]=y1[0]-y1[1]; axisX[1]=x1[2]-x1[1]; axisY[1]=y1[2]-y1[1]; axisX[2]=x2[0]-x2[1]; axisY[2]=y2[0]-y2[1]; axisX[3]=x2[2]-x2[1]; axisY[3]=y2[2]-y2[1]; for(int i=0; i<4; i++){ proj=x1[0]*axisX[i]+y1[0]*axisY[i]; minProj1=proj; maxProj1=proj; for(int j=1; j<4; j++){ proj=x1[j]*axisX[i]+y1[j]*axisY[i]; if(proj<minProj1) minProj1=proj; if(proj>maxProj1) maxProj1=proj; } proj=x2[0]*axisX[i]+y2[0]*axisY[i]; minProj2=proj; maxProj2=proj; for(int j=1; j<4; j++){ proj=x2[j]*axisX[i]+y2[j]*axisY[i]; if(proj<minProj2) minProj2=proj; if(proj>maxProj2) maxProj2=proj; } if(maxProj2<minProj1 || maxProj1<minProj2) return false; } return true; } //Debug RectCollision. Returns true, if two given rectangles collide, false otherwise. if DEBUG is true, collision boxes are rendered. bool RotRectCollision(float x1c, float y1c, float height1, float width1, float rot1, float x2c, float y2c, float height2, float width2, float rot2, bool debug){ float rad1=Sqrt(height1*height1+width1*width1); float rad2=Sqrt(height2*height2+width2*width2); float angle1=RadtoDeg(ArcSin(height1/rad1)); float angle2=RadtoDeg(ArcSin(height2/rad2)); float x1[4]; float y1[4]; float x2[4]; float y2[4]; float axisX[4]; float axisY[4]; float proj; float minProj1; float maxProj1; float minProj2; float maxProj2; x1[0]=x1c+rad1*Cos(rot1-angle1); y1[0]=y1c+rad1*Sin(rot1-angle1); x1[1]=x1c+rad1*Cos(rot1+angle1); y1[1]=y1c+rad1*Sin(rot1+angle1); x1[2]=x1c+rad1*Cos(rot1+180-angle1); y1[2]=y1c+rad1*Sin(rot1+180-angle1); x1[3]=x1c+rad1*Cos(rot1+180+angle1); y1[3]=y1c+rad1*Sin(rot1+180+angle1); x2[0]=x2c+rad2*Cos(rot2-angle2); y2[0]=y2c+rad2*Sin(rot2-angle2); x2[1]=x2c+rad2*Cos(rot2+angle2); y2[1]=y2c+rad2*Sin(rot2+angle2); x2[2]=x2c+rad2*Cos(rot2+180-angle2); y2[2]=y2c+rad2*Sin(rot2+180-angle2); x2[3]=x2c+rad2*Cos(rot2+180+angle2); y2[3]=y2c+rad2*Sin(rot2+180+angle2); axisX[0]=x1[0]-x1[1]; axisY[0]=y1[0]-y1[1]; axisX[1]=x1[2]-x1[1]; axisY[1]=y1[2]-y1[1]; axisX[2]=x2[0]-x2[1]; axisY[2]=y2[0]-y2[1]; axisX[3]=x2[2]-x2[1]; axisY[3]=y2[2]-y2[1]; if(debug){ Screen->Rectangle(6, x1c-width1, y1c-height1, x1c+width1, y1c+height1, 1, -1, x1c, y1c, rot1, true, 128); Screen->Rectangle(6, x2c-width2, y2c-height2, x2c+width2, y2c+height2, 2, -1, x2c, y2c, rot2, true, 128); } for(int i=0; i<4; i++){ proj=x1[0]*axisX[i]+y1[0]*axisY[i]; minProj1=proj; maxProj1=proj; for(int j=1; j<4; j++){ proj=x1[j]*axisX[i]+y1[j]*axisY[i]; if(proj<minProj1) minProj1=proj; if(proj>maxProj1) maxProj1=proj; } proj=x2[0]*axisX[i]+y2[0]*axisY[i]; minProj2=proj; maxProj2=proj; for(int j=1; j<4; j++){ proj=x2[j]*axisX[i]+y2[j]*axisY[i]; if(proj<minProj2) minProj2=proj; if(proj>maxProj2) maxProj2=proj; } if(maxProj2<minProj1 || maxProj1<minProj2) return false; } return true; }