├── .import ├── BarrelSlices.png-0d67c320b22a2d4bbf5825e49667a6f3.md5 ├── BarrelSlices.png-0d67c320b22a2d4bbf5825e49667a6f3.stex ├── BarrelSlices.png-3cc2fd567540e587533b9fd349cea9d3.md5 ├── BarrelSlices.png-3cc2fd567540e587533b9fd349cea9d3.stex ├── CarSlices.png-43bd8ae8fbcfb0b6fbe38f7719ba3bcf.md5 ├── CarSlices.png-43bd8ae8fbcfb0b6fbe38f7719ba3bcf.stex ├── icon.png-487276ed1e3a0c39cad0279d744ee560.md5 └── icon.png-487276ed1e3a0c39cad0279d744ee560.stex ├── Car.gd ├── Car.tscn ├── CarSlices.png ├── CarSlices.png.import ├── README.md ├── StackedSprite.gd ├── StackedSprite.tscn ├── default_env.tres ├── icon.png ├── icon.png.import └── project.godot /.import/BarrelSlices.png-0d67c320b22a2d4bbf5825e49667a6f3.md5: -------------------------------------------------------------------------------- 1 | source_md5="d93b3ff532b4e4465564028515cf8a5c" 2 | dest_md5="a924736c05b3a338b1ea51cf1ed4e7eb" 3 | 4 | -------------------------------------------------------------------------------- /.import/BarrelSlices.png-0d67c320b22a2d4bbf5825e49667a6f3.stex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontopielski/sprite-stacking-tutorial/8c9a88d807a4464ed9e4c1d8c449e94fb33ffb4e/.import/BarrelSlices.png-0d67c320b22a2d4bbf5825e49667a6f3.stex -------------------------------------------------------------------------------- /.import/BarrelSlices.png-3cc2fd567540e587533b9fd349cea9d3.md5: -------------------------------------------------------------------------------- 1 | source_md5="d93b3ff532b4e4465564028515cf8a5c" 2 | dest_md5="a924736c05b3a338b1ea51cf1ed4e7eb" 3 | 4 | -------------------------------------------------------------------------------- /.import/BarrelSlices.png-3cc2fd567540e587533b9fd349cea9d3.stex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontopielski/sprite-stacking-tutorial/8c9a88d807a4464ed9e4c1d8c449e94fb33ffb4e/.import/BarrelSlices.png-3cc2fd567540e587533b9fd349cea9d3.stex -------------------------------------------------------------------------------- /.import/CarSlices.png-43bd8ae8fbcfb0b6fbe38f7719ba3bcf.md5: -------------------------------------------------------------------------------- 1 | source_md5="486de4b433181333005381db4b22862e" 2 | dest_md5="578dc21c04406ee93a833925bae4c664" 3 | 4 | -------------------------------------------------------------------------------- /.import/CarSlices.png-43bd8ae8fbcfb0b6fbe38f7719ba3bcf.stex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontopielski/sprite-stacking-tutorial/8c9a88d807a4464ed9e4c1d8c449e94fb33ffb4e/.import/CarSlices.png-43bd8ae8fbcfb0b6fbe38f7719ba3bcf.stex -------------------------------------------------------------------------------- /.import/icon.png-487276ed1e3a0c39cad0279d744ee560.md5: -------------------------------------------------------------------------------- 1 | source_md5="0167658bc4406f0d0fe437e0197c415a" 2 | dest_md5="64b0613b3173e1e1c96dd18b6569e62d" 3 | 4 | -------------------------------------------------------------------------------- /.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontopielski/sprite-stacking-tutorial/8c9a88d807a4464ed9e4c1d8c449e94fb33ffb4e/.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex -------------------------------------------------------------------------------- /Car.gd: -------------------------------------------------------------------------------- 1 | extends KinematicBody2D 2 | 3 | const SPEED = 130 4 | const ACCELERATION = 5 5 | 6 | var velocity = Vector2.ZERO 7 | 8 | func _physics_process(delta): 9 | var input = Vector2.ZERO 10 | input.x = Input.get_action_strength("ui_right") - Input.get_action_strength("ui_left") 11 | input.y = Input.get_action_strength("ui_down") - Input.get_action_strength("ui_up") 12 | velocity = lerp(velocity, input * SPEED, ACCELERATION * delta) 13 | move_and_slide(velocity) 14 | if input != Vector2.ZERO: 15 | $StackedSprite.set_rotation(velocity.angle() - deg2rad(90)) 16 | -------------------------------------------------------------------------------- /Car.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=4 format=2] 2 | 3 | [ext_resource path="res://StackedSprite.tscn" type="PackedScene" id=1] 4 | [ext_resource path="res://Car.gd" type="Script" id=2] 5 | 6 | [sub_resource type="RectangleShape2D" id=1] 7 | extents = Vector2( 10, 17 ) 8 | 9 | [node name="Car" type="KinematicBody2D"] 10 | position = Vector2( 155, 125 ) 11 | script = ExtResource( 2 ) 12 | 13 | [node name="CollisionShape2D" type="CollisionShape2D" parent="."] 14 | shape = SubResource( 1 ) 15 | 16 | [node name="StackedSprite" parent="." instance=ExtResource( 1 )] 17 | -------------------------------------------------------------------------------- /CarSlices.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontopielski/sprite-stacking-tutorial/8c9a88d807a4464ed9e4c1d8c449e94fb33ffb4e/CarSlices.png -------------------------------------------------------------------------------- /CarSlices.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/CarSlices.png-43bd8ae8fbcfb0b6fbe38f7719ba3bcf.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://CarSlices.png" 13 | dest_files=[ "res://.import/CarSlices.png-43bd8ae8fbcfb0b6fbe38f7719ba3bcf.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=false 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=false 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # sprite-stacking-tutorial 2 | 3 | code for tutorial: https://youtu.be/_Z5eg9UvLRw 4 | -------------------------------------------------------------------------------- /StackedSprite.gd: -------------------------------------------------------------------------------- 1 | tool 2 | extends Sprite 3 | 4 | export(bool) var show_sprites = false setget set_show_sprites 5 | export(bool) var rotate_sprites = false setget set_rotate_sprites 6 | 7 | func set_show_sprites(_show_sprites): 8 | show_sprites = _show_sprites 9 | if show_sprites: 10 | render_sprites() 11 | else: 12 | clear_sprites() 13 | 14 | func set_rotation(_rotation): 15 | for sprite in get_children(): 16 | sprite.rotation = _rotation 17 | 18 | func set_rotate_sprites(_rotate_sprites): 19 | rotate_sprites = _rotate_sprites 20 | 21 | func _process(delta): 22 | if rotate_sprites: 23 | for sprite in get_children(): 24 | sprite.rotation += delta 25 | 26 | func clear_sprites(): 27 | for sprite in get_children(): 28 | sprite.queue_free() 29 | 30 | func _ready(): 31 | render_sprites() 32 | 33 | func render_sprites(): 34 | clear_sprites() 35 | for i in range(0, hframes): 36 | var next_sprite = Sprite.new() 37 | next_sprite.texture = texture 38 | next_sprite.hframes = hframes 39 | next_sprite.frame = i 40 | next_sprite.position.y = -i 41 | add_child(next_sprite) 42 | -------------------------------------------------------------------------------- /StackedSprite.tscn: -------------------------------------------------------------------------------- 1 | [gd_scene load_steps=3 format=2] 2 | 3 | [ext_resource path="res://CarSlices.png" type="Texture" id=1] 4 | [ext_resource path="res://StackedSprite.gd" type="Script" id=2] 5 | 6 | [node name="StackedSprite" type="Sprite"] 7 | self_modulate = Color( 1, 1, 1, 0 ) 8 | texture = ExtResource( 1 ) 9 | hframes = 11 10 | frame = 5 11 | script = ExtResource( 2 ) 12 | show_sprites = true 13 | -------------------------------------------------------------------------------- /default_env.tres: -------------------------------------------------------------------------------- 1 | [gd_resource type="Environment" load_steps=2 format=2] 2 | 3 | [sub_resource type="ProceduralSky" id=1] 4 | 5 | [resource] 6 | background_mode = 2 7 | background_sky = SubResource( 1 ) 8 | -------------------------------------------------------------------------------- /icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jontopielski/sprite-stacking-tutorial/8c9a88d807a4464ed9e4c1d8c449e94fb33ffb4e/icon.png -------------------------------------------------------------------------------- /icon.png.import: -------------------------------------------------------------------------------- 1 | [remap] 2 | 3 | importer="texture" 4 | type="StreamTexture" 5 | path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" 6 | metadata={ 7 | "vram_texture": false 8 | } 9 | 10 | [deps] 11 | 12 | source_file="res://icon.png" 13 | dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] 14 | 15 | [params] 16 | 17 | compress/mode=0 18 | compress/lossy_quality=0.7 19 | compress/hdr_mode=0 20 | compress/bptc_ldr=0 21 | compress/normal_map=0 22 | flags/repeat=0 23 | flags/filter=true 24 | flags/mipmaps=false 25 | flags/anisotropic=false 26 | flags/srgb=2 27 | process/fix_alpha_border=true 28 | process/premult_alpha=false 29 | process/HDR_as_SRGB=false 30 | process/invert_color=false 31 | stream=false 32 | size_limit=0 33 | detect_3d=true 34 | svg/scale=1.0 35 | -------------------------------------------------------------------------------- /project.godot: -------------------------------------------------------------------------------- 1 | ; Engine configuration file. 2 | ; It's best edited using the editor UI and not directly, 3 | ; since the parameters that go here are not all obvious. 4 | ; 5 | ; Format: 6 | ; [section] ; section goes between [] 7 | ; param=value ; assign values to parameters 8 | 9 | config_version=4 10 | 11 | _global_script_classes=[ ] 12 | _global_script_class_icons={ 13 | } 14 | 15 | [application] 16 | 17 | config/name="Sprite Stacking Tutorial" 18 | run/main_scene="res://Car.tscn" 19 | config/icon="res://icon.png" 20 | 21 | [display] 22 | 23 | window/size/width=320 24 | window/size/height=240 25 | window/size/test_width=640 26 | window/size/test_height=480 27 | window/stretch/mode="viewport" 28 | window/stretch/aspect="keep" 29 | 30 | [importer_defaults] 31 | 32 | texture={ 33 | "compress/bptc_ldr": 0, 34 | "compress/hdr_mode": 0, 35 | "compress/lossy_quality": 0.7, 36 | "compress/mode": 0, 37 | "compress/normal_map": 0, 38 | "detect_3d": false, 39 | "flags/anisotropic": false, 40 | "flags/filter": false, 41 | "flags/mipmaps": false, 42 | "flags/repeat": 0, 43 | "flags/srgb": 2, 44 | "process/HDR_as_SRGB": false, 45 | "process/fix_alpha_border": true, 46 | "process/invert_color": false, 47 | "process/premult_alpha": false, 48 | "size_limit": 0, 49 | "stream": false, 50 | "svg/scale": 1.0 51 | } 52 | 53 | [input] 54 | 55 | ui_left={ 56 | "deadzone": 0.5, 57 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777231,"unicode":0,"echo":false,"script":null) 58 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":14,"pressure":0.0,"pressed":false,"script":null) 59 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":65,"unicode":0,"echo":false,"script":null) 60 | ] 61 | } 62 | ui_right={ 63 | "deadzone": 0.5, 64 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777233,"unicode":0,"echo":false,"script":null) 65 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":15,"pressure":0.0,"pressed":false,"script":null) 66 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":68,"unicode":0,"echo":false,"script":null) 67 | ] 68 | } 69 | ui_up={ 70 | "deadzone": 0.5, 71 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777232,"unicode":0,"echo":false,"script":null) 72 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":12,"pressure":0.0,"pressed":false,"script":null) 73 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":87,"unicode":0,"echo":false,"script":null) 74 | ] 75 | } 76 | ui_down={ 77 | "deadzone": 0.5, 78 | "events": [ Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":16777234,"unicode":0,"echo":false,"script":null) 79 | , Object(InputEventJoypadButton,"resource_local_to_scene":false,"resource_name":"","device":0,"button_index":13,"pressure":0.0,"pressed":false,"script":null) 80 | , Object(InputEventKey,"resource_local_to_scene":false,"resource_name":"","device":0,"alt":false,"shift":false,"control":false,"meta":false,"command":false,"pressed":false,"scancode":83,"unicode":0,"echo":false,"script":null) 81 | ] 82 | } 83 | 84 | [rendering] 85 | 86 | 2d/snapping/use_gpu_pixel_snap=true 87 | environment/default_environment="res://default_env.tres" 88 | quality/2d/use_pixel_snap=true 89 | --------------------------------------------------------------------------------