function CreateSprite2D(x,y,img,style,pri,source,dest){
	let obj = ObjPrim_Create(OBJ_SPRITE_2D);
	ObjPrim_SetTexture(obj,img);
	Obj_SetRenderPriorityI(obj,pri);
	ObjRender_SetBlendType(obj,style);
	ObjSprite2D_SetSourceRect(obj,source[0],source[1],source[2],source[3]);
	ObjSprite2D_SetDestRect(obj,dest[0],dest[1],dest[2],dest[3]);
	ObjRender_SetPosition(obj,x,y,0);
	return obj;
}

task DrawDebugText(x,y,text){
	let obj = ObjText_Create();
	ObjText_SetFontSize(obj,12);
	ObjText_SetFontBold(obj,true);
	ObjText_SetText(obj,text);
	ObjText_SetFontColorTop(obj,255, 255, 255);
	ObjText_SetFontColorBottom(obj,255, 255, 255);
	ObjText_SetFontBorderType(obj,BORDER_FULL);
	Obj_SetRenderPriority(obj,1);
	ObjRender_SetX(obj,x);
	ObjRender_SetY(obj,y);
	yield;
	yield;
	Obj_Delete(obj);
}

task RenderPlayer(img){
	ObjPrim_SetTexture(obj_player,img);
	Obj_SetRenderPriorityI(obj_player,48);
	ObjSprite2D_SetSourceRect(obj_player,0,0,32,48);
	ObjSprite2D_SetDestRect(obj_player,-16,-24,16,24);
	let frame = [0,0];
	let idle = 0;
	let left = 0;
	let right = 0;
	let ic = 0;
	let alpha = 255;
	
	let obj_hitbox = [CreateSprite2D(GetPlayerX,GetPlayerY,img_pl_sloweffect,BLEND_ALPHA,59,[0,0,63,63],[-31.5,-31.5,31.5,31.5]),CreateSprite2D(GetPlayerX,GetPlayerY,img_pl_sloweffect,BLEND_ALPHA,59,[0,0,63,63],[-31.5,-31.5,31.5,31.5])];
	let z = 0;
	let hc = 0;
	
	loop{
		let move = false;
		if(B_LEFT && !B_RIGHT && right==0 && !Respawning){move=true; idle=0; right=0; left++; if(left>33){left=13;}}
		if(B_RIGHT && !B_LEFT && left==0 && !Respawning){move=true; idle=0; left=0; right++; if(right>33){right=13;}}
		if(!move && left>0){if(left>13){left=13;} left--;} if(left<0){left=0;}
		if(!move && right>0){if(right>13){right=13;} right--;} if(right<0){right=0;}
		if(!move && left==0 && right==0){idle++; if(idle>=40){idle=0;}}
		
		if(idle>=0){frame=[0,0];}
		if(idle>=5){frame=[1,0];}
		if(idle>=10){frame=[2,0];}
		if(idle>=15){frame=[3,0];}
		if(idle>=20){frame=[4,0];}
		if(idle>=25){frame=[5,0];}
		if(idle>=30){frame=[6,0];}
		if(idle>=35){frame=[7,0];}
		
		if(left>0){frame=[0,1];}
		if(left>3){frame=[1,1];}
		if(left>6){frame=[2,1];}
		if(left>9){frame=[3,1];}
		if(left>12){frame=[4,1];}
		if(left>17){frame=[5,1];}
		if(left>22){frame=[6,1];}
		if(left>27){frame=[7,1];}
		
		if(right>0){frame=[0,2];}
		if(right>3){frame=[1,2];}
		if(right>6){frame=[2,2];}
		if(right>9){frame=[3,2];}
		if(right>12){frame=[4,2];}
		if(right>17){frame=[5,2];}
		if(right>22){frame=[6,2];}
		if(right>27){frame=[7,2];}
		
		let p_x_d = round(GetPlayerX)-GetPlayerX; let p_y_d = round(GetPlayerY)-GetPlayerY;
		ObjSprite2D_SetDestRect(obj_player,-16+p_x_d,-24+p_y_d,16+p_x_d,24+p_y_d);
		ObjSprite2D_SetSourceRect(obj_player,32*frame[0],48*frame[1],32*(frame[0]+1),48*(frame[1]+1));
		if(GetPlayerInvincibilityFrame==0){
			ic=0;
			ObjRender_SetColor(obj_player,255,255,255);
		}else{
			if(ic<3){
				ObjRender_SetColor(obj_player,128,128,255);
			}else{
				ObjRender_SetColor(obj_player,255,255,255);
			}
			ic++; if(ic>=6){ic=0;}
		}
		if(GetPlayerState==STATE_HIT){
			alpha-=255/GetPlayerRebirthFrame;
		}else{
			alpha=255;
		}
		ObjRender_SetAlpha(obj_player,alpha*(GetCommonData("Player_Alpha",255)/255));
		
		//Hitbox
		if(B_SLOW && GetPlayerState!=STATE_DOWN && GetPlayerState!=STATE_HIT && !Respawning){
			hc+=1/10; hc=min(hc,1);
		}else{
			let frame = 15;
			if(GetPlayerState==STATE_HIT){frame=8;}
			hc-=1/frame; hc=max(hc,0);
		}
		ObjRender_SetPosition(obj_hitbox[0],GetPlayerX,GetPlayerY,0);
		ObjRender_SetPosition(obj_hitbox[1],GetPlayerX,GetPlayerY,0);
		ObjRender_SetScaleXYZ(obj_hitbox[0],2-1*sin(hc*90),2-1*sin(hc*90),1);
		ObjRender_SetScaleXYZ(obj_hitbox[1],sin(hc*90),sin(hc*90),1);
		ObjRender_SetAlpha(obj_hitbox[1],(255*hc)*(GetCommonData("Player_Alpha",255)/255));
		ObjRender_SetAlpha(obj_hitbox[0],(128*hc)*(GetCommonData("Player_Alpha",255)/255));
		ObjRender_SetAngleZ(obj_hitbox[0],-z);
		ObjRender_SetAngleZ(obj_hitbox[1],z);
		z+=15-13*sin(hc*90); if(z>360){z-=360;};
		yield;
	}
}

task BulletHitEff(x,y,v,dir,accel,dirvel,maxv,tex,blend,frame,iscale,mscale,ialpha,malpha,icolor,mcolor,ang,angvel){
	let obj = CreateSprite2D(x,y,tex,blend,47,[frame[0][1],frame[0][2],frame[0][3],frame[0][4]],[-(frame[0][3]-frame[0][1])/2,-(frame[0][4]-frame[0][2])/2,(frame[0][3]-frame[0][1])/2,(frame[0][4]-frame[0][2])/2]);
	let maxtime = 0;
	//[[frame,rect1,rect2,rect3,rect4]]
	ascent(f in 0..length(frame)){
		maxtime+=frame[f][0];
	}
	ascent(f in 0..length(frame)){
		loop(frame[f][0]){
			iscale[0]=iscale[0]+(mscale[0]/maxtime);
			iscale[1]=iscale[1]+(mscale[1]/maxtime);
			icolor[0]=icolor[0]+(mcolor[0]/maxtime);
			icolor[1]=icolor[1]+(mcolor[1]/maxtime);
			icolor[2]=icolor[2]+(mcolor[2]/maxtime);
			ialpha+=malpha/maxtime;
			ang+=angvel;
			if(accel!=0){
				v+=accel;
				if(accel>0){v=min(v,maxv);}else{v=max(v,maxv);}
			}
			dir+=dirvel;
			ObjRender_SetPosition(obj,ObjRender_GetX(obj)+v*cos(dir),ObjRender_GetY(obj)+v*sin(dir),0);
			ObjRender_SetAngleZ(obj,ang);
			ObjRender_SetScaleXYZ(obj,iscale[0],iscale[1],0);
			ObjRender_SetColor(obj,icolor[0],icolor[1],icolor[2]);
			ObjRender_SetAlpha(obj,ialpha);
			ObjSprite2D_SetSourceRect(obj,frame[f][1],frame[f][2],frame[f][3],frame[f][4]);
			ObjSprite2D_SetDestRect(obj,-(frame[f][3]-frame[f][1])/2,-(frame[f][4]-frame[f][2])/2,(frame[f][3]-frame[f][1])/2,(frame[f][4]-frame[f][2])/2);
			yield;
		}
	}
	Obj_Delete(obj);
}

task GrazeEff(ba){
	ascent(b in 0..min(length(ba),6)){
		if(!Obj_IsDeleted(ba[b])){Particle(ba[b]);}
	}
	
	task Particle(bullet){
		let size = rand(4,6);
		let obj = CreateSprite2D((GetPlayerX+ObjRender_GetX(bullet))/2,(GetPlayerY+ObjRender_GetY(bullet))/2,img_pl_particle,BLEND_ADD_ARGB,49,[0,0,16,16],[-size,-size,size,size]);
		let s = 1; let v = rand(2,6); let ang = rand(0,360);
		loop(15){
			s-=1/15;
			ObjRender_SetPosition(obj,ObjRender_GetX(obj)+v*cos(ang),ObjRender_GetY(obj)+v*sin(ang),0);
			ObjRender_SetScaleXYZ(obj,s,s,s);
			yield;
		}
		Obj_Delete(obj);
	}
}

task MissEff{
	while(GetPlayerState==STATE_HIT){
		loop(5){Particle;}
		yield;
	}
	if(GetPlayerState!=STATE_NORMAL){
		InvBurst(GetPlayerX,GetPlayerY);
		InvBurst(GetPlayerX+64,GetPlayerY);
		InvBurst(GetPlayerX-64,GetPlayerY);
		InvBurst(GetPlayerX,GetPlayerY+64);
		InvBurst(GetPlayerX,GetPlayerY-64);
		Shockwave;
	}
	
	task Particle{
		let obj = CreateSprite2D(GetPlayerX,GetPlayerY,img_pl_particle,BLEND_ADD_ARGB,49,[0,0,16,16],[-8,-8,8,8]);
		let v = rand(5,15); let c = 0; let s = rand(0.25,0.75); let ang = rand(0,360); let f = rand_int(15,20);
		ObjRender_SetScaleXYZ(obj,s,s,s); ObjRender_SetColor(obj,255,128,255); ObjRender_SetAngleZ(obj,rand(0,360));
		loop(f){
			c+=90/f;
			ObjRender_SetPosition(obj,ObjRender_GetX(obj)+v*cos(ang),ObjRender_GetY(obj)+v*sin(ang),0);
			ObjRender_SetScaleXYZ(obj,s*cos(c),s*cos(c),s*cos(c));
			ObjRender_SetAlpha(obj,255*cos(c));
			yield;
		}
		Obj_Delete(obj);
	}
	
	task Shockwave{
		let obj = CreateSprite2D(GetPlayerX,GetPlayerY,img_pl_deadcircle,BLEND_ADD_ARGB,49,[0,0,64,64],[-16,-16,16,16]);
		let s = 1; let a = 255;
		loop(30){
			s+=8/30; a-=255/30;
			ObjRender_SetScaleXYZ(obj,s,s,s);
			ObjRender_SetAlpha(obj,a);
			yield;
		}
		Obj_Delete(obj);
	}

	task InvBurst(x,y){
		let obj1 = CreateSprite2D(x,y,img_pl_circle,BLEND_INV_DESTRGB,50,[0,0,256,256],[-128,-128,128,128]);
		let obj2 = CreateSprite2D(x,y,img_pl_circle,BLEND_INV_DESTRGB,50,[0,0,256,256],[-128,-128,128,128]);
		ObjRender_SetScaleXYZ(obj1,0,0,0);
		ObjRender_SetScaleXYZ(obj2,0,0,0);
		let c1 = 0; let c2 = 0;
		loop(30){
			c1+=90/60;
			let radi1 = (800-800*cos(c1))/128;
			ObjRender_SetScaleXYZ(obj1,radi1,radi1,radi1);
			BreakBulletCircle(x,y,radi1*128);
			yield;
		}
		loop(30){
			c1+=90/60;
			c2+=90/60;
			let radi1 = (800-800*cos(c1))/128;
			let radi2 = (800-800*cos(c2))/128;
			ObjRender_SetScaleXYZ(obj1,radi1,radi1,radi1);
			ObjRender_SetScaleXYZ(obj2,radi2,radi2,radi2);
			BreakBulletCircle(x,y,radi1*128);
			yield;
		}
		loop(30){
			c2+=90/60;
			let radi2 = (800-800*cos(c2))/128;
			ObjRender_SetScaleXYZ(obj2,radi2,radi2,radi2);
			yield;
		}
		Obj_Delete(obj1); Obj_Delete(obj2);
	}
}