{"author_link":"\/users\/tricky-fat-cat","author_name":"Tricky_Fat_Cat","author_uid":"tricky-fat-cat","comments":[],"epoch":1571071395,"event":"LD45","format":"md","ldjam_node_id":175761,"likes":5,"metadata":{"p_key":"137215","p_author":"Tricky_Fat_Cat","p_authorkey":"1145628","p_urlkey":"353491","p_title":"Reap and tear without problems","p_cat":"LDJam ","p_event":"LD45","p_time":"1571071395","p_likes":"5","p_comments":"0","p_status":"WAYBACK","us_key":"1145628","us_name":"Artyom Volkov","us_username":"artyom-volkov","event_start":"1570147200","event_key":"78","event_name":"Ludum Dare 45"},"node":{"_collation":{"body_sanitizer":"TextUtils::SanitizeHTML via existing importer","event":"LD45","removed_author":false},"_superparent":159347,"_trust":8,"author":145628,"body":"Here is a short tutorial about bloody effect in [**HONK**](https:\/\/ldjam.com\/events\/ludum-dare\/45\/honk).\n\n![honk05.gif](\/\/\/raw\/cd8\/32\/z\/25d25.gif)\n\nFirst of all, this effect is based on this tutorial https:\/\/www.youtube.com\/watch?v=nz8FUMHEyAU\n\nHowever, I've made some slight changes to make it better for my game. I think, that my approach is still clunky and needs some upgrade in the future.\n\n# Step 0. Make movement system\nI use my movement system in this effect, I highly recommend to read about it. [**Movement**](https:\/\/ldjam.com\/events\/ludum-dare\/45\/honk\/movement-is-a-key).\n\n# Step 1. Setup surface object\nIn my game I use special object which is called obj_drawer, this object does one job - sorting sprites and drawing them in the order I need. It takes a lot of time to explain this, now you should create an empty object which will control surface for these bloody effects.\n\n**Create event**\n```\nsurfaceFloorEffects= surface_create(room_width, room_height);\n```\n\n**Draw event**\n```\nif (surface_exists(surfaceFloorEffects))\n{\n\tdraw_surface_ext(surfaceFloorEffects, 0, 0, 1.0, 1.0, 0, c_white, 1.0);\n}\nelse\n{\n\tsurfaceFloorEffects = surface_create(room_width, room_height);\n}\n```\n\n**Clear event**\n```\nsurface_free(surfaceFloorEffects);\n```\n\n# Step 2. Setup base object\nIn the project I use special base objects. They include some logic, which is shared by other objects, e.g. I have obj_sortable, which contain logic for sorting etc.\n\nIn this case this you need to create obj_floorEffect and place it on your level.\n\n**Destroy event**\n```\nvar _surface = obj_drawer.surfaceFloorEffects;\n\nif (surface_exists(_surface))\n{\n\tsurface_set_target(_surface);\n\t\n\tdraw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, direction, c_gray, image_alpha);\n\t\n\tsurface_reset_target();\n}\nelse\n{\n\t_surface = surface_create(room_width, room_height);\n}\n```\n\n# Step 3. Setup splatter object\nCreate object vfx_splatter without any sprite.\n\n**Variable definitions**\n\nYou need this variables to adjust child objects.\n\n![vfx_slplatter_vd.png](\/\/\/raw\/cd8\/32\/z\/29922.png)\n\n**Create event**\n```\nvelocityMax = 20;\n\n\/\/ Visual paarameters\nimage_speed = 0;\nimage_index = irandom_range(0, image_number - 1);\nimage_xscale = random_range(0.05, 1);\nimage_yscale = random_range(0.05, 1);\nimage_alpha = random_range(0.25, 1);\n\n\/\/ Movement parameters\ndirection = random_range(0, 359);\nimage_angle = direction;\nvelocityCurrent = random_range(0.4, velocityMax);\ngroundFriction = random_range(0.1, 0.2);\nvelocityX = 0;\nvelocityY = 0;\n\n\/\/ Smear parameters\nsmearTime = 3;\nsmearTimer = 0;\n```\n**Step event**\n```\n\/\/ Movement\nMoveObject();\n\nvelocityCurrent = CalculateDeceleratedVelocity(direction, velocityCurrent, groundFriction);\n\nif (velocityCurrent <= 0)\n{\n\tinstance_destroy()\n}\n\n\/\/ Smearing\nsmearTimer += global.TimeFactor;\n\nvar _checkTimer = check_timer(smearTimer, smearTime);\n\nif (_checkTimer)\n{\n\tsmearTimer = 0;\n\t\n\tinstance_create_layer(x, y, layer, smearObject);\n}\n```\n**check_timer script**\n\nBe aware, I use timefactor, it means you need to arrange global.TimeFactor somewhere at the very start of the game.\n``` gml\nglobal.TimeFactor = 1;\n```\n\n```\n\/\/\/ @param timer\n\/\/\/ @param time\n\nvar _timer = argument0;\nvar _time = argument1;\n\nreturn (floor(_timer) >= _time && floor(_timer - global.TimeFactor) != floor(_timer));\n```\n# Step 4. Setup smear object\nCreate object vfx_smear. It must not have any sprite as well as vfx_splatter.\n\n**Create event**\n```\nimage_speed = 0;\nimage_index = irandom_range(0, image_number - 1);\nimage_xscale = random_range(0.05, 0.5);\nimage_yscale = random_range(0.05, 0.5);\nimage_angle = irandom_range(0, 359);\nimage_alpha = random_range(0.25, 1);\n\ninstance_destroy();\n```\n# Step 5. Create sprites and child objects\nHere is an example of blood sprite.\n![spr_bloodSplatters_strip6.png](\/\/\/raw\/cd8\/32\/z\/29926.png)\n\nYep, it\u2019s small.\n\nAfter this, you need to create a new object for splatter and smear and make their parents vfx_splatter and vfx_smear relatively.\n\nDo not forget to set up variable definitions.\n\n# Step 6. Make a spawn script\nThis script will definitely make adjustments of the effect easier.\n\n```\n\/\/\/ @param x\n\/\/\/ @param y\n\/\/\/ @param splatterObject\n\/\/\/ @param count\n\/\/\/ @param velocityMax\n\nvar _x = argument0;\nvar _y = argument1;\nvar _object = argument2;\nvar _count = argument3;\nvar _velocity = argument4;\n\nfor (var i = 0; i < _count; i++)\n{\n\tvar _splatter = instance_create_layer(_x, _y, layer, _object);\n\t\n\twith (_splatter)\n\t{\n\t\tvelocityMax = _velocity;\n\t\tvelocityCurrent = random_range(0.4, velocityMax);\n\t}\n}\n```\n\n# Step 7. Use script\n\nNow you can place this script wherever you want, but be careful when you will use it in step events.\n\n# Step 8. ???\n\n# Step 9. PROFIT!\n\nNow you can reap and tear in your game with ease!","comments":1,"comments-timestamp":"2019-10-14T22:09:49Z","created":"2019-10-14T15:47:27Z","files":[],"files-timestamp":0,"id":175761,"love":5,"love-timestamp":"2019-10-14T22:09:21Z","meta":[],"modified":"2019-10-14T22:22:28Z","name":"Reap and tear without problems","node-timestamp":"2019-10-14T22:22:28Z","parent":160945,"parents":[1,5,9,159347,160945],"path":"\/events\/ludum-dare\/45\/honk\/reap-and-tear-without-problems","published":"2019-10-14T16:43:15Z","scope":"public","slug":"reap-and-tear-without-problems","subsubtype":"","subtype":"","type":"post","version":530044},"node_metadata":{"n_key":"175761","n_urlkey":"353491","n_parent":"160945","n_path":"\/events\/ludum-dare\/45\/honk\/reap-and-tear-without-problems","n_slug":"reap-and-tear-without-problems","n_type":"post","n_subtype":"","n_subsubtype":"","n_author":"145628","n_created":"1571068047","n_modified":"1571091748","n_version":"530044","n_status":"WAYBACK"},"source_url":"https:\/\/ldjam.com\/events\/ludum-dare\/45\/honk\/reap-and-tear-without-problems","text":"Here is a short tutorial about bloody effect in [**HONK**](https:\/\/ldjam.com\/events\/ludum-dare\/45\/honk).\n\n![honk05.gif](\/\/\/raw\/cd8\/32\/z\/25d25.gif)\n\nFirst of all, this effect is based on this tutorial https:\/\/www.youtube.com\/watch?v=nz8FUMHEyAU\n\nHowever, I've made some slight changes to make it better for my game. I think, that my approach is still clunky and needs some upgrade in the future.\n\n# Step 0. Make movement system\nI use my movement system in this effect, I highly recommend to read about it. [**Movement**](https:\/\/ldjam.com\/events\/ludum-dare\/45\/honk\/movement-is-a-key).\n\n# Step 1. Setup surface object\nIn my game I use special object which is called obj_drawer, this object does one job - sorting sprites and drawing them in the order I need. It takes a lot of time to explain this, now you should create an empty object which will control surface for these bloody effects.\n\n**Create event**\n```\nsurfaceFloorEffects= surface_create(room_width, room_height);\n```\n\n**Draw event**\n```\nif (surface_exists(surfaceFloorEffects))\n{\n\tdraw_surface_ext(surfaceFloorEffects, 0, 0, 1.0, 1.0, 0, c_white, 1.0);\n}\nelse\n{\n\tsurfaceFloorEffects = surface_create(room_width, room_height);\n}\n```\n\n**Clear event**\n```\nsurface_free(surfaceFloorEffects);\n```\n\n# Step 2. Setup base object\nIn the project I use special base objects. They include some logic, which is shared by other objects, e.g. I have obj_sortable, which contain logic for sorting etc.\n\nIn this case this you need to create obj_floorEffect and place it on your level.\n\n**Destroy event**\n```\nvar _surface = obj_drawer.surfaceFloorEffects;\n\nif (surface_exists(_surface))\n{\n\tsurface_set_target(_surface);\n\t\n\tdraw_sprite_ext(sprite_index, image_index, x, y, image_xscale, image_yscale, direction, c_gray, image_alpha);\n\t\n\tsurface_reset_target();\n}\nelse\n{\n\t_surface = surface_create(room_width, room_height);\n}\n```\n\n# Step 3. Setup splatter object\nCreate object vfx_splatter without any sprite.\n\n**Variable definitions**\n\nYou need this variables to adjust child objects.\n\n![vfx_slplatter_vd.png](\/\/\/raw\/cd8\/32\/z\/29922.png)\n\n**Create event**\n```\nvelocityMax = 20;\n\n\/\/ Visual paarameters\nimage_speed = 0;\nimage_index = irandom_range(0, image_number - 1);\nimage_xscale = random_range(0.05, 1);\nimage_yscale = random_range(0.05, 1);\nimage_alpha = random_range(0.25, 1);\n\n\/\/ Movement parameters\ndirection = random_range(0, 359);\nimage_angle = direction;\nvelocityCurrent = random_range(0.4, velocityMax);\ngroundFriction = random_range(0.1, 0.2);\nvelocityX = 0;\nvelocityY = 0;\n\n\/\/ Smear parameters\nsmearTime = 3;\nsmearTimer = 0;\n```\n**Step event**\n```\n\/\/ Movement\nMoveObject();\n\nvelocityCurrent = CalculateDeceleratedVelocity(direction, velocityCurrent, groundFriction);\n\nif (velocityCurrent <= 0)\n{\n\tinstance_destroy()\n}\n\n\/\/ Smearing\nsmearTimer += global.TimeFactor;\n\nvar _checkTimer = check_timer(smearTimer, smearTime);\n\nif (_checkTimer)\n{\n\tsmearTimer = 0;\n\t\n\tinstance_create_layer(x, y, layer, smearObject);\n}\n```\n**check_timer script**\n\nBe aware, I use timefactor, it means you need to arrange global.TimeFactor somewhere at the very start of the game.\n``` gml\nglobal.TimeFactor = 1;\n```\n\n```\n\/\/\/ @param timer\n\/\/\/ @param time\n\nvar _timer = argument0;\nvar _time = argument1;\n\nreturn (floor(_timer) >= _time && floor(_timer - global.TimeFactor) != floor(_timer));\n```\n# Step 4. Setup smear object\nCreate object vfx_smear. It must not have any sprite as well as vfx_splatter.\n\n**Create event**\n```\nimage_speed = 0;\nimage_index = irandom_range(0, image_number - 1);\nimage_xscale = random_range(0.05, 0.5);\nimage_yscale = random_range(0.05, 0.5);\nimage_angle = irandom_range(0, 359);\nimage_alpha = random_range(0.25, 1);\n\ninstance_destroy();\n```\n# Step 5. Create sprites and child objects\nHere is an example of blood sprite.\n![spr_bloodSplatters_strip6.png](\/\/\/raw\/cd8\/32\/z\/29926.png)\n\nYep, it\u2019s small.\n\nAfter this, you need to create a new object for splatter and smear and make their parents vfx_splatter and vfx_smear relatively.\n\nDo not forget to set up variable definitions.\n\n# Step 6. Make a spawn script\nThis script will definitely make adjustments of the effect easier.\n\n```\n\/\/\/ @param x\n\/\/\/ @param y\n\/\/\/ @param splatterObject\n\/\/\/ @param count\n\/\/\/ @param velocityMax\n\nvar _x = argument0;\nvar _y = argument1;\nvar _object = argument2;\nvar _count = argument3;\nvar _velocity = argument4;\n\nfor (var i = 0; i < _count; i++)\n{\n\tvar _splatter = instance_create_layer(_x, _y, layer, _object);\n\t\n\twith (_splatter)\n\t{\n\t\tvelocityMax = _velocity;\n\t\tvelocityCurrent = random_range(0.4, velocityMax);\n\t}\n}\n```\n\n# Step 7. Use script\n\nNow you can place this script wherever you want, but be careful when you will use it in step events.\n\n# Step 8. ???\n\n# Step 9. PROFIT!\n\nNow you can reap and tear in your game with ease!","title":"Reap and tear without problems","wayback_source":[]}