Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// @function scr_collisionMesh(object index,room width,room height,texture size)
- /// @param objectIndex
- /// @param room width
- /// @param room height
- /// @param texture size
- //Created by Spasman
- //This script will take every instance of a defined object index and merge them all into larger, less resource intensive instances
- //Good for games that use a bunch of instances for collision and nothing else!
- //NOTE: This script creates rather large sprites, so remember to use sprite_delete() if the generated collision meshes are eventually destroyed or if the room ends/changes or you will have a big memory leak!
- //object index = Defines what object to merge into a collision mesh
- //room width = Tells the script what the room width is. Just put room_width if you don't know what to do here.
- //room height = Tells the script what the room height is. Just put room_height if you don't know what to do here.
- //texture size = Defines what you want as the maximum mesh/texture size. A size of 512 or 1024 are both good options. The bigger the size, the less instances you will have but at the cost of GPU.
- //Create variables
- collision_surface = -1
- cutX = 0
- cutY = 0
- spr = -1
- sprW = 0
- sprH = 0
- sprIndex = 0
- //defines a variable the script needs in every existing instance of the defined object index
- with(argument0) {
- collisionMesh = false
- collisionID = -1
- }
- //A big scary nested while loop that will cut the surface into the pieces and turn them into sprites/collision masks
- //cutX and cutY define the current position of where we're cutting up the surface. Think of it as the point of the knife when slicing cake!
- //Enter the first while loop to determine height.
- while(1) {
- //Break out of the FIRST while loop when the cutting position Y goes beyond the room height.
- if cutY >= argument2 {
- break;
- }
- cutX = 0
- //Before we determine height, enter a SECOND while loop to determine the width
- while(1) {
- //Set the default sprite size to the defined texture size
- sprW = argument3
- sprH = argument3
- //If the cutting position + defined texture size go beyond the defined room sizes, adjust to only reach the end of room.
- if cutX+sprW > argument1 {
- sprW = point_distance(cutX,0,argument1,0)
- }
- if cutY+sprH > argument2 {
- sprH = point_distance(0,cutY,0,argument2)
- }
- //create a surface with the same size as the current cutting area
- collision_surface = surface_create(sprW,sprH)
- //sets the surface target to what we just created
- //then clear the surface alpha of any texture errors that would mess with the collision mask
- surface_set_target(collision_surface);
- draw_clear_alpha(c_white,0)
- //draw the sprite assigned to the defined object index. Use the cutting position to draw the sprites within the surface area.
- //Uses the variable we set before to make sure it isn't an object generated by this script
- with(argument0) {
- if collisionMesh = false {
- if (x-other.cutX)+sprite_get_width(sprite_index) > 0 and (x-other.cutX) < other.sprW and (y-other.cutY)+sprite_get_height(sprite_index) > 0 and y-other.cutY < other.sprH {
- draw_sprite(sprite_index,image_index,x-other.cutX,y-other.cutY)
- collisionID = other.sprIndex
- }
- }
- }
- //Resets the surface back to the application surface
- surface_reset_target();
- //Create the sprite and collision mask from the surface from the cutting position, with the set width and height from sprW/sprH
- spr = sprite_create_from_surface(collision_surface,0,0,sprW,sprH,false,false,0,0)
- sprite_collision_mask(spr, false, 0, 0, 0, sprW, sprH, 0, 0);
- //Create an instance of the defined object index at the cutting position and assign the newly created sprite from it
- //Sets the collisionMesh variable to true so the script ignores it
- //Use something like sprite_create in the object's destroy/room end events to delete the newly made sprites to prevent memory leaks, in case collisionMesh isn't enough
- mb = instance_create_depth(cutX,cutY,0,argument0)
- mb.sprite_index = spr
- mb.collisionMesh = true
- mb.sprite_create = true
- mb.collisionID = sprIndex
- //Move the X coordinates of the cutting position to the next texture page. Stop yourself short w/ point_distance() if you try to go beyond the room width
- if cutX+argument3 > argument1 {
- cutX += point_distance(cutX,0,argument1,0)
- }
- else {
- cutX += argument3
- }
- //Destroy the surface to free up memory
- surface_free(collision_surface);
- sprIndex += 1
- //Break out of the SECOND while loop when the cutting position X goes beyond the room width.
- if cutX >= argument1 {
- break;
- }
- }
- //Move the Y coordinates of the cutting position to the next texture page. Stop yourself short w/ point_distance() if you try to go beyond the room height.
- if cutY+argument3 > argument2 {
- cutY += point_distance(0,cutY,0,argument2)
- }
- else {
- cutY += argument3
- }
- }
- //Uncomment this for debugging, the debug message triggers when an 'old' instance is not detected under a new instance, which should be impossible if the script worked right.
- //Feel free to replace the debug message with something else to help you debug.
- /*with(argument0) {
- if collisionMesh = true and collisionID != -1 {
- with(argument0) {
- if collisionMesh = false and collisionID = other.collisionID {
- if !collision_rectangle(bbox_left,bbox_top,bbox_right,bbox_bottom,other,false,true) {
- show_debug_message("Collision mesh error with collision ID "+string(collisionID))
- }
- }
- }
- }
- }*/
- //Now that you have fancy collision meshes, we can go ahead and destroy all of the old instances for the defined object index
- //Uses collisionMesh to make sure the newly made instances aren't destroyed.
- with(argument0) {
- if collisionMesh = false {
- instance_destroy();
- }
- }
- //notify compile window
- show_debug_message("Completed collision mesh for object index "+object_get_name(argument0))
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement