commit aaad9674768cadccede9045a099836fa161a115c Author: Nitsud Yarg Date: Thu Apr 25 20:13:25 2024 -0700 Should have done this a while ago. diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..8ad74f7 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Normalize EOL for all files that Git considers text files. +* text=auto eol=lf diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..1c2fbd5 --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +# Godot 4+ specific ignores +.godot/ +.import/ +.mono/ +addons/ \ No newline at end of file diff --git a/Enemy-KinematicBody2D.gd b/Enemy-KinematicBody2D.gd new file mode 100644 index 0000000..c791314 --- /dev/null +++ b/Enemy-KinematicBody2D.gd @@ -0,0 +1,140 @@ +class_name Enemy extends KinematicBody2D + +enum STATE {IDLE, WANDER, JUMP, FALL, HURT, ATTACK} +enum STATE_SECONDARY {NONE, SHOOT} + +#const WALK_FORCE = 600 +const WALK_MAX_SPEED = (30*2) +#const STOP_FORCE = 1300 +const JUMP_SPEED = 270 + +var velocity = Vector2() + +var gravity = 60*9.8 +var player_state = STATE.IDLE +var player_last_state = null +var animation_play_finished = true +var flip_direction = false + +onready var _animated_sprite = $AnimatedSprite + + +func _physics_process(delta): + # Horizontal movement + if player_state != STATE.WANDER and $IdleTimeout.time_left == 0: + if flip_direction: + velocity.x = (1 * WALK_MAX_SPEED) + flip_direction = false + else: + velocity.x = (-1 * WALK_MAX_SPEED) + flip_direction = true + + # Vertical movement code. Apply gravity. + velocity.y += gravity * delta + + # Move based on the velocity and snap to the ground. + #velocity = move_and_slide_with_snap(velocity, Vector2.DOWN, Vector2.UP) + velocity = move_and_slide(velocity, Vector2(0, -1)) + + # Animate based on last state and velocity + if velocity.x > 0 and _animated_sprite.flip_h != true: + _animated_sprite.flip_h = true + _animated_sprite.offset.x = 0 + $PlayerDetection.cast_to = Vector2(20,0) + if velocity.x < 0 and _animated_sprite.flip_h != false: + _animated_sprite.flip_h = false + _animated_sprite.offset.x = -18 + $PlayerDetection.cast_to = Vector2(-20,0) + + # forced state changes like falling an gitting hurt + if velocity.y > 0 and player_state != STATE.JUMP and player_state != STATE.FALL: + print("STATE_TRANSITION: Fall") + player_state = STATE.FALL + + if $PlayerDetection.is_colliding(): + player_state = STATE.ATTACK + player_last_state = null + velocity.x = 0 + + # Each state should trigger its own animation + match player_state: + STATE.IDLE: + # Transitions + if velocity.y == -JUMP_SPEED: + print("STATE_TRANSITION: Jump") + player_last_state = STATE.IDLE + player_state = STATE.JUMP + elif velocity.x != 0: + print("STATE_TRANSITION: Wander") + player_last_state = STATE.IDLE + player_state = STATE.WANDER + # Animation + if player_last_state != STATE.IDLE: + _animated_sprite.play("idle") + player_last_state = STATE.IDLE + $IdleTimeout.start() + + STATE.JUMP: + # Transitions + if is_on_floor(): + print("STATE_TRANSITION: Idle") + _animated_sprite.play("idle") + player_last_state = STATE.JUMP + player_state = STATE.IDLE + # Animation + if player_last_state != STATE.JUMP: + _animated_sprite.play("jump") + player_last_state = STATE.JUMP + + STATE.FALL: + # Transitions + if is_on_floor(): + print("STATE_TRANSITION: Idle") + _animated_sprite.play("idle") + player_last_state = STATE.FALL + player_state = STATE.IDLE + # Animation + if player_last_state != STATE.FALL: + #_animated_sprite.animation = "jump" + _animated_sprite.frame = 8 + _animated_sprite.stop() + player_last_state = STATE.FALL + + STATE.WANDER: + # print (_animated_sprite.animation ) # apparentl playing doesn't stop when loop is disabled. + # Transitions + if velocity.y == -JUMP_SPEED: + print("STATE_TRANSITION: Jump") + player_last_state = STATE.WANDER + player_state = STATE.JUMP + elif velocity.x == 0: + print("STATE_TRANSITION: Idle") + player_last_state = STATE.WANDER + player_state = STATE.IDLE + # Animation + if player_last_state != STATE.WANDER: + $IdleTimeout.start() + _animated_sprite.play("walk") + player_last_state = STATE.WANDER + if $IdleTimeout.time_left == 0: + $IdleTimeout.start() + velocity.x = 0 + player_last_state = STATE.WANDER + player_state = STATE.IDLE + + STATE.ATTACK: + # Animation + if player_last_state != STATE.ATTACK: + $IdleTimeout.start() + _animated_sprite.play("attack") + player_last_state = STATE.ATTACK + if $IdleTimeout.time_left == 0: + $IdleTimeout.start() + velocity.x = 0 + player_last_state = STATE.ATTACK + player_state = STATE.IDLE + + +func _on_AnimatedSprite_animation_finished(): + animation_play_finished = true + #print($AnimatedSprite.animation," anim over ", $IdleTimeout.time_left, animation_play_finished) diff --git a/Enemy.tscn b/Enemy.tscn new file mode 100644 index 0000000..b00075a --- /dev/null +++ b/Enemy.tscn @@ -0,0 +1,159 @@ +[gd_scene load_steps=24 format=2] + +[ext_resource path="res://Enemy-KinematicBody2D.gd" type="Script" id=1] + +[sub_resource type="StreamTexture" id=75] +load_path = "res://.import/botEnemy.png-46efd539a38730ff15fb4ddb087329c6.stex" + +[sub_resource type="AtlasTexture" id=76] +atlas = SubResource( 75 ) +region = Rect2( 192, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=77] +atlas = SubResource( 75 ) +region = Rect2( 0, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=78] +atlas = SubResource( 75 ) +region = Rect2( 48, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=79] +atlas = SubResource( 75 ) +region = Rect2( 96, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=80] +atlas = SubResource( 75 ) +region = Rect2( 144, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=81] +atlas = SubResource( 75 ) +region = Rect2( 0, 144, 48, 48 ) + +[sub_resource type="AtlasTexture" id=82] +atlas = SubResource( 75 ) +region = Rect2( 48, 144, 48, 48 ) + +[sub_resource type="AtlasTexture" id=83] +atlas = SubResource( 75 ) +region = Rect2( 96, 144, 48, 48 ) + +[sub_resource type="AtlasTexture" id=84] +atlas = SubResource( 75 ) +region = Rect2( 192, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=85] +atlas = SubResource( 75 ) +region = Rect2( 0, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=86] +atlas = SubResource( 75 ) +region = Rect2( 48, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=87] +atlas = SubResource( 75 ) +region = Rect2( 96, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=88] +atlas = SubResource( 75 ) +region = Rect2( 144, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=89] +atlas = SubResource( 75 ) +region = Rect2( 192, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=90] +atlas = SubResource( 75 ) +region = Rect2( 0, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=91] +atlas = SubResource( 75 ) +region = Rect2( 48, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=92] +atlas = SubResource( 75 ) +region = Rect2( 96, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=93] +atlas = SubResource( 75 ) +region = Rect2( 144, 48, 48, 48 ) + +[sub_resource type="SpriteFrames" id=94] +animations = [ { +"frames": [ SubResource( 76 ), SubResource( 77 ), SubResource( 78 ), SubResource( 79 ), SubResource( 80 ) ], +"loop": true, +"name": "attack", +"speed": 10.0 +}, { +"frames": [ SubResource( 81 ), SubResource( 82 ), SubResource( 83 ) ], +"loop": true, +"name": "death", +"speed": 10.0 +}, { +"frames": [ SubResource( 84 ) ], +"loop": true, +"name": "hurt", +"speed": 10.0 +}, { +"frames": [ SubResource( 85 ), SubResource( 86 ), SubResource( 87 ) ], +"loop": true, +"name": "idle", +"speed": 10.0 +}, { +"frames": [ SubResource( 88 ), SubResource( 89 ), SubResource( 90 ), SubResource( 91 ), SubResource( 92 ), SubResource( 93 ) ], +"loop": true, +"name": "walk", +"speed": 10.0 +} ] + +[sub_resource type="RectangleShape2D" id=74] +extents = Vector2( 12, 18.5 ) + +[sub_resource type="RectangleShape2D" id=95] +extents = Vector2( 9, 16.5 ) + +[node name="Enemy" type="KinematicBody2D"] +collision_layer = 4 +script = ExtResource( 1 ) + +[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +position = Vector2( 8, -8 ) +frames = SubResource( 94 ) +animation = "idle" +playing = true +flip_h = true +__meta__ = { +"_aseprite_wizard_config_": { +"layer": "", +"o_ex_p": "", +"o_folder": "res://assets", +"o_name": "", +"only_visible": true, +"op_exp": false, +"slice": "", +"source": "E:/Godot/Art/botEnemy.aseprite" +} +} + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2( -1, -3.5 ) +shape = SubResource( 74 ) + +[node name="IdleTimeout" type="Timer" parent="."] +wait_time = 2.0 +one_shot = true + +[node name="PlayerDetection" type="RayCast2D" parent="."] +enabled = true +cast_to = Vector2( 20, 0 ) +collision_mask = 2 + +[node name="HurtHitbox" type="Area2D" parent="."] +collision_layer = 160 +collision_mask = 64 + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="HurtHitbox"] +modulate = Color( 1, 0, 0, 1 ) +position = Vector2( -1, -3.5 ) +shape = SubResource( 95 ) + +[connection signal="animation_finished" from="AnimatedSprite" to="." method="_on_AnimatedSprite_animation_finished"] diff --git a/Enemy2-KinematicBody2D.gd b/Enemy2-KinematicBody2D.gd new file mode 100644 index 0000000..5fccf6d --- /dev/null +++ b/Enemy2-KinematicBody2D.gd @@ -0,0 +1,76 @@ +class_name Enemy2 extends KinematicBody2D + +var velocity = Vector2(0,0) +var direction = Vector2(1,0) + +export var player_number: int = 1 + +onready var movement_animations: AnimatedSprite = $AnimatedSprite + +onready var movement_state_machine: Node = $Controllers/state_machine + +onready var player_move_component = $Controllers/decision_component + +onready var player_hurtbox = $Hurtbox/CollisionShape2D + +onready var enemy_hitbox = $Hitbox/CollisionShape2D + +onready var player_detection = $PlayerDetection + +onready var gun = $Gun + +func _ready() -> void: + movement_state_machine.init(self, movement_animations, player_move_component) + +func _physics_process(delta: float) -> void: + movement_state_machine.process_physics(delta) +# #TODO: So much hack +# if direction.x != 0: +# gun.set_scale( Vector2(direction.x,1)) + if direction.x < 0: + var t = Transform2D() + # Translation + t.origin = Vector2(gun.offset_position.x * -1, gun.offset_position.y) + gun.transform = t + player_detection.cast_to = Vector2(-20,0) + #var t2 = Transform2D.FLIP_Y + #enemy_hitbox.transform = Transform2D.FLIP_Y + $Hitbox.transform = Transform2D.FLIP_X + elif direction.x > 0: + var t = Transform2D() + # Translation + t.origin = Vector2(gun.offset_position.x, gun.offset_position.y) + gun.transform = t + player_detection.cast_to = Vector2(20,0) + #enemy_hitbox.transform = Transform2D.IDENTITY + $Hitbox.transform = Transform2D.IDENTITY + +func _process(delta: float) -> void: + movement_state_machine.process_frame(delta) + player_move_component.current_state_name = movement_state_machine.current_state.name + +func _on_AnimatedSprite_animation_finished(): + if movement_animations.frames.get_animation_loop(movement_animations.animation) == false: + movement_state_machine.current_state.animation_index += 1 + +func set_hurtbox(enabled: bool): + #player_hurtbox.disabled = enabled #nope + player_hurtbox.set_deferred("disabled", !enabled) #WTF Apparently this is how to do it + #$Hurtbox.monitoring = enabled #nope + #$Hurtbox.set_deferred("monitoring", enabled) #works + #$Hurtbox.monitoring = false #nope + #$Hurtbox.set_monitoring(enabled) # Nope + +func set_hitbox(enabled: bool): + #player_hurtbox.disabled = enabled #nope + enemy_hitbox.set_deferred("disabled", !enabled) #WTF Apparently this is how to do it + + +func shoot_projectile(): + var is_shooting = false + is_shooting = gun.shoot(direction.x) + + +func _on_Hurtbox_body_entered(body): + print("Body Ouch. (Enemy)",body) + movement_state_machine.change_state($Controllers/state_machine/hurt) diff --git a/Enemy2.tscn b/Enemy2.tscn new file mode 100644 index 0000000..6b9024a --- /dev/null +++ b/Enemy2.tscn @@ -0,0 +1,257 @@ +[gd_scene load_steps=35 format=2] + +[ext_resource path="res://Enemy2-KinematicBody2D.gd" type="Script" id=1] +[ext_resource path="res://src/states/enemy/fall.gd" type="Script" id=2] +[ext_resource path="res://state_machine.gd" type="Script" id=3] +[ext_resource path="res://src/states/enemy/jump.gd" type="Script" id=4] +[ext_resource path="res://src/states/enemy/move.gd" type="Script" id=5] +[ext_resource path="res://src/states/enemy/wander.gd" type="Script" id=6] +[ext_resource path="res://src/states/enemy/idle.gd" type="Script" id=7] +[ext_resource path="res://src/states/enemy/attack.gd" type="Script" id=8] +[ext_resource path="res://Gun.gd" type="Script" id=9] +[ext_resource path="res://src/states/enemy/hurt.gd" type="Script" id=10] +[ext_resource path="res://enemy_move_component.gd" type="Script" id=11] + +[sub_resource type="StreamTexture" id=149] +load_path = "res://.import/botEnemy.png-46efd539a38730ff15fb4ddb087329c6.stex" + +[sub_resource type="AtlasTexture" id=150] +atlas = SubResource( 149 ) +region = Rect2( 192, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=151] +atlas = SubResource( 149 ) +region = Rect2( 0, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=152] +atlas = SubResource( 149 ) +region = Rect2( 48, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=153] +atlas = SubResource( 149 ) +region = Rect2( 96, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=154] +atlas = SubResource( 149 ) +region = Rect2( 144, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=155] +atlas = SubResource( 149 ) +region = Rect2( 0, 144, 48, 48 ) + +[sub_resource type="AtlasTexture" id=156] +atlas = SubResource( 149 ) +region = Rect2( 48, 144, 48, 48 ) + +[sub_resource type="AtlasTexture" id=157] +atlas = SubResource( 149 ) +region = Rect2( 96, 144, 48, 48 ) + +[sub_resource type="AtlasTexture" id=158] +atlas = SubResource( 149 ) +region = Rect2( 192, 96, 48, 48 ) + +[sub_resource type="AtlasTexture" id=159] +atlas = SubResource( 149 ) +region = Rect2( 0, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=160] +atlas = SubResource( 149 ) +region = Rect2( 48, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=161] +atlas = SubResource( 149 ) +region = Rect2( 96, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=162] +atlas = SubResource( 149 ) +region = Rect2( 144, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=163] +atlas = SubResource( 149 ) +region = Rect2( 192, 0, 48, 48 ) + +[sub_resource type="AtlasTexture" id=164] +atlas = SubResource( 149 ) +region = Rect2( 0, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=165] +atlas = SubResource( 149 ) +region = Rect2( 48, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=166] +atlas = SubResource( 149 ) +region = Rect2( 96, 48, 48, 48 ) + +[sub_resource type="AtlasTexture" id=167] +atlas = SubResource( 149 ) +region = Rect2( 144, 48, 48, 48 ) + +[sub_resource type="SpriteFrames" id=168] +animations = [ { +"frames": [ SubResource( 150 ), SubResource( 151 ), SubResource( 152 ), SubResource( 153 ), SubResource( 154 ) ], +"loop": true, +"name": "attack", +"speed": 10.0 +}, { +"frames": [ SubResource( 155 ), SubResource( 156 ), SubResource( 157 ) ], +"loop": true, +"name": "death", +"speed": 10.0 +}, { +"frames": [ SubResource( 158 ) ], +"loop": true, +"name": "hurt", +"speed": 10.0 +}, { +"frames": [ SubResource( 159 ), SubResource( 160 ), SubResource( 161 ) ], +"loop": true, +"name": "idle", +"speed": 10.0 +}, { +"frames": [ SubResource( 162 ), SubResource( 163 ), SubResource( 164 ), SubResource( 165 ), SubResource( 166 ), SubResource( 167 ) ], +"loop": true, +"name": "walk", +"speed": 10.0 +} ] + +[sub_resource type="RectangleShape2D" id=74] +extents = Vector2( 13.5, 16.5 ) + +[sub_resource type="RectangleShape2D" id=148] +extents = Vector2( 11.5, 14.5 ) + +[sub_resource type="RectangleShape2D" id=169] +extents = Vector2( 10, 3.5 ) + +[node name="Enemy" type="KinematicBody2D"] +collision_layer = 4 +script = ExtResource( 1 ) + +[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +position = Vector2( 8, -8 ) +frames = SubResource( 168 ) +animation = "idle" +frame = 2 +playing = true +flip_h = true +__meta__ = { +"_aseprite_wizard_config_": { +"layer": "", +"o_ex_p": "", +"o_folder": "res://assets", +"o_name": "", +"only_visible": true, +"op_exp": false, +"slice": "", +"source": "E:/Godot/Art/botEnemy.aseprite" +} +} + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2( -0.5, -2.5 ) +shape = SubResource( 74 ) + +[node name="Controllers" type="Node" parent="."] + +[node name="state_machine" type="Node" parent="Controllers"] +script = ExtResource( 3 ) +starting_state = NodePath("idle") + +[node name="idle" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 7 ) +animation_name = "idle" +timeout_seconds = 1.0 +jump_node = NodePath("../jump") +fall_node = NodePath("../fall") +fire_node = NodePath("../attack") +wander_node = NodePath("../wander") +attack_node = NodePath("../attack") + +[node name="jump" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 4 ) +animation_name = "idle" +idle_node = NodePath("../idle") +fall_node = NodePath("../fall") +move_node = NodePath("../move") + +[node name="move" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 5 ) +animation_name = "walk" +jump_node = NodePath("../jump") +fall_node = NodePath("../fall") +idle_node = NodePath("../idle") + +[node name="wander" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 6 ) +animation_name = "walk" +timeout_seconds = 1.0 +jump_node = NodePath("../jump") +fall_node = NodePath("../fall") +idle_node = NodePath("../idle") +attack_node = NodePath("../attack") + +[node name="fall" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 2 ) +animation_name = "idle" +idle_node = NodePath("../idle") +move_node = NodePath("../move") + +[node name="hurt" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 10 ) +animation_name = "hurt" +idle_node = NodePath("../idle") + +[node name="attack" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 8 ) +animation_name = "attack" +idle_node = NodePath("../idle") + +[node name="decision_component" type="Node" parent="Controllers"] +script = ExtResource( 11 ) + +[node name="IdleTimeout" type="Timer" parent="Controllers/decision_component"] +wait_time = 2.0 +one_shot = true +autostart = true + +[node name="Hurtbox" type="Area2D" parent="." groups=["enemy_hitboxes"]] +collision_layer = 160 +collision_mask = 64 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hurtbox"] +self_modulate = Color( 1, 0, 0, 1 ) +position = Vector2( 0, -1 ) +shape = SubResource( 148 ) + +[node name="Gun" type="Position2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2( 25, -5 ) +script = ExtResource( 9 ) + +[node name="Cooldown" type="Timer" parent="Gun"] +wait_time = 0.5 +one_shot = true + +[node name="Line2D" type="Line2D" parent="Gun"] +points = PoolVector2Array( -5, 0, 5, 0 ) +width = 2.0 +default_color = Color( 1, 0.607843, 0, 1 ) + +[node name="PlayerDetection" type="RayCast2D" parent="."] +enabled = true +cast_to = Vector2( 20, 0 ) +collision_mask = 2 + +[node name="Hitbox" type="Area2D" parent="."] +collision_layer = 128 +collision_mask = 0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hitbox"] +modulate = Color( 1, 0, 0, 1 ) +position = Vector2( 20, -10 ) +shape = SubResource( 169 ) +disabled = true + +[connection signal="animation_finished" from="AnimatedSprite" to="." method="_on_AnimatedSprite_animation_finished"] +[connection signal="body_entered" from="Hurtbox" to="." method="_on_Hurtbox_body_entered"] diff --git a/Floor.tscn b/Floor.tscn new file mode 100644 index 0000000..a37d4a9 --- /dev/null +++ b/Floor.tscn @@ -0,0 +1,16 @@ +[gd_scene load_steps=2 format=2] + +[sub_resource type="RectangleShape2D" id=1] +extents = Vector2( 135.5, 12.5 ) + +[node name="Floor" type="ColorRect"] +margin_left = 23.0 +margin_top = 162.0 +margin_right = 294.0 +margin_bottom = 187.0 + +[node name="StaticBody2D" type="StaticBody2D" parent="."] + +[node name="CollisionShape2D" type="CollisionShape2D" parent="StaticBody2D"] +position = Vector2( 135.5, 12.5 ) +shape = SubResource( 1 ) diff --git a/Gun.gd b/Gun.gd new file mode 100644 index 0000000..8b7e5c2 --- /dev/null +++ b/Gun.gd @@ -0,0 +1,47 @@ +class_name Gun +extends Position2D +# Represents a weapon that spawns and shoots bullets. +# The Cooldown timer controls the cooldown duration between shots. + + +const BULLET_VELOCITY = 350 +const Bullet = preload("res://Projectile.tscn") + +#onready var sound_shoot = $Shoot +onready var timer = $Cooldown +onready var offset_position = Vector2(transform.origin.x, transform.origin.y) + +# This method is only called by Player.gd. +func shoot(direction = 1): + #self.set_position(Vector2(position.x * direction, position.y)) + #transform.x = transform.x * direction + #Transform2D.FLIP_Y + #transform.origin.x = transform.origin.x * direction +# if direction < 0: +# var t = Transform2D() +# # Translation +# t.origin = Vector2(position.x * -1, position.y) +# transform = t +# elif direction > 0: +# var t = Transform2D() +# # Translation +# t.origin = Vector2(position.x, position.y) +# transform = t + + print("Fire Debug: ", direction, " Gun position: ", position, transform.origin) +# position.x = position.x * direction #shifting position before fire was unreliable + if not timer.is_stopped(): + return false + var bullet = Bullet.instance() +# if (direction > 0): +# bullet.global_position = global_position +# else: +# bullet.global_position = global_position - Vector2(position.x * 2, 0) + bullet.global_position = global_position + bullet.linear_velocity = Vector2(direction * BULLET_VELOCITY, 0) + + bullet.set_as_toplevel(true) + add_child(bullet) +# sound_shoot.play() + timer.start() + return true diff --git a/KinematicBody2D-bak.gd b/KinematicBody2D-bak.gd new file mode 100644 index 0000000..ae69061 --- /dev/null +++ b/KinematicBody2D-bak.gd @@ -0,0 +1,98 @@ +extends KinematicBody2D + +enum STATE {IDLE, RUN, JUMP, FALL, HURT} +enum STATE_SECONDARY {NONE, SHOOT} + +class StateMachine: + var primary = STATE.IDLE + var secondary = STATE_SECONDARY.NONE + +onready var player_state = StateMachine.new() +onready var player_last_state = StateMachine.new() + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" +onready var gravity = 60*9.8 + +onready var speed = Vector2((30*5), (gravity * 1/2)) +#onready var gravity = ProjectSettings.get("physics/2d/default_gravity") + +onready var _animated_sprite = $AnimatedSprite + +var velocity = Vector2.ZERO + + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +func get_direction(): + return Vector2( + Input.get_axis("ui_left", "ui_right"), + -1 if is_on_floor() and Input.is_action_just_pressed("ui_accept") else 0 + ) + +func calculate_move_velocity( + linear_velocity, + direction, + speed + ): + var velocity = linear_velocity + velocity.x = speed.x * direction.x + if direction.y != 0.0: + velocity.y = speed.y * direction.y + return velocity + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _physics_process(delta): + var direction = get_direction() +# if not is_on_floor(): +# velocity.y += gravity * delta +# +# # Handle jump. +# if Input.is_action_just_pressed("ui_accept") and is_on_floor(): +# velocity.y += (gravity * -1) * delta +# +# # Get the input direction and handle the movement/deceleration. +# # As good practice, you should replace UI actions with custom gameplay actions. +# var direction = Input.get_axis("ui_left", "ui_right") +# if direction: +# velocity.x = direction * SPEED +# else: +# velocity.x = move_toward(velocity.x, 0, SPEED) + velocity = calculate_move_velocity(velocity, direction, speed) + move_and_slide(velocity, Vector2(0, -1)) + # Apply Gravity + velocity.y += gravity * delta + + #Animation + + if direction.x > 0 and _animated_sprite.flip_h != true: + _animated_sprite.flip_h = true + if direction.x < 0 and _animated_sprite.flip_h != false: + _animated_sprite.flip_h = false + + + player_state.primary = STATE.IDLE + + match player_state.primary: + STATE.IDLE: + if direction.y == 0: + player_state.primary = STATE.FALL + STATE.FALL: + print("Fall") + STATE.RUN: + print("Idle") + + if not is_on_floor(): + if _animated_sprite.animation != "jump": + _animated_sprite.play("jump") + else: + if direction and _animated_sprite.animation != "run": + print(_animated_sprite.animation, direction) + _animated_sprite.play("run") + elif not direction: + _animated_sprite.play("idle") diff --git a/Main.gd b/Main.gd new file mode 100644 index 0000000..ed1a164 --- /dev/null +++ b/Main.gd @@ -0,0 +1,22 @@ +extends Node2D + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" +var camera :Camera2D + +# Called when the node enters the scene tree for the first time. + +func _ready(): + camera = $Path2D/PathFollow2D/Camera2D + camera.make_current() + for child in get_children(): + print(child) + if child is Player: + camera = child.get_node("Camera2D") + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(delta): + pass diff --git a/Main.tscn b/Main.tscn new file mode 100644 index 0000000..bd42e49 --- /dev/null +++ b/Main.tscn @@ -0,0 +1,194 @@ +[gd_scene load_steps=18 format=2] + +[ext_resource path="res://Player.tscn" type="PackedScene" id=1] +[ext_resource path="res://assets/Tiles/Assets/Assets.png" type="Texture" id=3] +[ext_resource path="res://Position2D.gd" type="Script" id=5] +[ext_resource path="res://Enemy2.tscn" type="PackedScene" id=6] + +[sub_resource type="ConvexPolygonShape2D" id=2] +points = PoolVector2Array( 16, 16, 0, 16, 0, 0, 16, 0 ) + +[sub_resource type="ConvexPolygonShape2D" id=3] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=4] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=5] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=6] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=7] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=8] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=9] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=10] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=11] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="ConvexPolygonShape2D" id=12] +points = PoolVector2Array( 0, 0, 16, 0, 16, 16, 0, 16 ) + +[sub_resource type="TileSet" id=1] +0/name = "Assets.png 0" +0/texture = ExtResource( 3 ) +0/tex_offset = Vector2( 0, 0 ) +0/modulate = Color( 1, 1, 1, 1 ) +0/region = Rect2( 16, 0, 192, 96 ) +0/tile_mode = 2 +0/autotile/icon_coordinate = Vector2( 0, 0 ) +0/autotile/tile_size = Vector2( 16, 16 ) +0/autotile/spacing = 0 +0/autotile/occluder_map = [ ] +0/autotile/navpoly_map = [ ] +0/autotile/priority_map = [ ] +0/autotile/z_index_map = [ ] +0/occluder_offset = Vector2( 0, 0 ) +0/navigation_offset = Vector2( 0, 0 ) +0/shape_offset = Vector2( 0, 0 ) +0/shape_transform = Transform2D( 1, 0, 0, 1, 0, 0 ) +0/shape = SubResource( 2 ) +0/shape_one_way = false +0/shape_one_way_margin = 1.0 +0/shapes = [ { +"autotile_coord": Vector2( 1, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 2 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 2, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 3 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 3, 0 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 4 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 3, 1 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 5 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 2, 1 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 6 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 2, 1 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 7 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 1, 1 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 8 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 0, 1 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 9 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 0, 1 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 10 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 4, 1 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 11 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +}, { +"autotile_coord": Vector2( 5, 3 ), +"one_way": false, +"one_way_margin": 1.0, +"shape": SubResource( 12 ), +"shape_transform": Transform2D( 1, 0, 0, 1, 0, 0 ) +} ] +0/z_index = 0 + +[sub_resource type="SegmentShape2D" id=13] +a = Vector2( -1, -68 ) +b = Vector2( -1, 349 ) + +[node name="Main" type="Node2D"] + +[node name="TileMap" type="TileMap" parent="."] +tile_set = SubResource( 1 ) +cell_size = Vector2( 16, 16 ) +show_collision = true +format = 1 +tile_data = PoolIntArray( -65536, 0, 196613, 0, 0, 196613, 79, 0, 196613, 65536, 0, 196613, 65615, 0, 196613, 131072, 0, 196613, 131151, 0, 196613, 196608, 0, 196613, 196687, 0, 196613, 262144, 0, 196613, 262223, 0, 196613, 327680, 0, 196613, 327759, 0, 196613, 393216, 0, 196613, 393260, 0, 196613, 393261, 0, 196613, 393295, 0, 196613, 458752, 0, 196613, 458792, 0, 196613, 458793, 0, 196613, 458794, 0, 196613, 458795, 0, 196613, 458796, 0, 196613, 458797, 0, 196613, 458831, 0, 196613, 524288, 0, 196613, 524307, 0, 196613, 524308, 0, 196613, 524327, 0, 196613, 524328, 0, 196613, 524329, 0, 196613, 524330, 0, 196613, 524334, 0, 196613, 524367, 0, 196613, 589824, 0, 196613, 589843, 0, 196613, 589844, 0, 196613, 589863, 0, 196613, 589864, 0, 196613, 589870, 0, 196613, 589903, 0, 196613, 655360, 0, 196613, 655361, 0, 2, 655362, 0, 2, 655363, 0, 2, 655364, 0, 2, 655365, 0, 2, 655366, 0, 2, 655367, 0, 2, 655368, 0, 2, 655369, 0, 2, 655370, 0, 2, 655371, 0, 2, 655372, 0, 2, 655373, 0, 2, 655374, 0, 2, 655375, 0, 2, 655376, 0, 2, 655377, 0, 2, 655378, 0, 2, 655379, 0, 196613, 655380, 0, 196613, 655381, 0, 196613, 655382, 0, 196613, 655383, 0, 196613, 655384, 0, 196613, 655385, 0, 196613, 655386, 0, 196613, 655387, 0, 196613, 655388, 0, 196613, 655389, 0, 196613, 655390, 0, 196613, 655391, 0, 196613, 655392, 0, 196613, 655393, 0, 196613, 655394, 0, 196613, 655395, 0, 196613, 655396, 0, 196613, 655397, 0, 196613, 655398, 0, 196613, 655399, 0, 196613, 655400, 0, 196613, 655406, 0, 196613, 655407, 0, 196613, 655408, 0, 196613, 655409, 0, 196613, 655410, 0, 196613, 655411, 0, 196613, 655412, 0, 196613, 655413, 0, 196613, 655414, 0, 196613, 655415, 0, 196613, 655416, 0, 196613, 655417, 0, 196613, 655418, 0, 196613, 655419, 0, 196613, 655420, 0, 196613, 655421, 0, 196613, 655422, 0, 196613, 655423, 0, 196613, 655424, 0, 196613, 655425, 0, 196613, 655426, 0, 196613, 655427, 0, 196613, 655428, 0, 196613, 655439, 0, 196613, 720896, 0, 196613, 720897, 0, 65538, 720898, 0, 65538, 720899, 0, 65538, 720900, 0, 65538, 720901, 0, 65538, 720902, 0, 65538, 720903, 0, 65538, 720904, 0, 65538, 720905, 0, 65538, 720906, 0, 65538, 720907, 0, 65538, 720908, 0, 65538, 720909, 0, 65538, 720910, 0, 65538, 720911, 0, 65538, 720912, 0, 65538, 720913, 0, 65538, 720914, 0, 65538, 720915, 0, 196613, 720916, 0, 196613, 720917, 0, 196613, 720918, 0, 196613, 720919, 0, 196613, 720920, 0, 196613, 720921, 0, 196613, 720959, 0, 0, 720961, 0, 196613, 720962, 0, 196613, 720963, 0, 196613, 720964, 0, 196613, 720965, 0, 196613, 720975, 0, 196613, 786432, 0, 196613, 786495, 0, 0, 786511, 0, 196613, 851968, 0, 196613, 852002, 0, 196613, 852031, 0, 0, 852047, 0, 196613, 917504, 0, 196613, 917583, 0, 196613, 983040, 0, 196613, 983119, 0, 196613, 1048576, 0, 196613, 1048655, 0, 196613, 1114112, 0, 196613, 1114167, 0, 196613, 1114168, 0, 196613, 1114169, 0, 196613, 1114170, 0, 196613, 1114171, 0, 196613, 1114191, 0, 196613, 1179648, 0, 196613, 1179701, 0, 196613, 1179702, 0, 196613, 1179703, 0, 196613, 1179707, 0, 196613, 1179708, 0, 196613, 1179709, 0, 196613, 1179727, 0, 196613, 1245184, 0, 196613, 1245236, 0, 196613, 1245237, 0, 196613, 1245245, 0, 196613, 1245246, 0, 196613, 1245247, 0, 196613, 1245263, 0, 196613, 1310720, 0, 196613, 1310771, 0, 196613, 1310772, 0, 196613, 1310783, 0, 196613, 1310784, 0, 196613, 1310799, 0, 196613, 1376256, 0, 196613, 1376257, 0, 196613, 1376258, 0, 196613, 1376259, 0, 196613, 1376260, 0, 196613, 1376261, 0, 196613, 1376262, 0, 196613, 1376263, 0, 196613, 1376264, 0, 196613, 1376265, 0, 196613, 1376266, 0, 196613, 1376267, 0, 196613, 1376268, 0, 196613, 1376269, 0, 196613, 1376270, 0, 196613, 1376271, 0, 196613, 1376272, 0, 196613, 1376273, 0, 196613, 1376274, 0, 196613, 1376275, 0, 196613, 1376276, 0, 196613, 1376277, 0, 196613, 1376278, 0, 196613, 1376279, 0, 196613, 1376280, 0, 196613, 1376281, 0, 196613, 1376282, 0, 196613, 1376283, 0, 196613, 1376284, 0, 196613, 1376285, 0, 196613, 1376286, 0, 196613, 1376287, 0, 196613, 1376288, 0, 196613, 1376289, 0, 196613, 1376290, 0, 196613, 1376291, 0, 196613, 1376292, 0, 196613, 1376293, 0, 196613, 1376294, 0, 196613, 1376295, 0, 196613, 1376296, 0, 196613, 1376297, 0, 196613, 1376298, 0, 196613, 1376299, 0, 196613, 1376300, 0, 196613, 1376301, 0, 196613, 1376302, 0, 196613, 1376303, 0, 196613, 1376304, 0, 196613, 1376305, 0, 196613, 1376306, 0, 196613, 1376307, 0, 196613, 1376308, 0, 196613, 1376309, 0, 196613, 1376310, 0, 196613, 1376311, 0, 196613, 1376312, 0, 196613, 1376313, 0, 196613, 1376314, 0, 196613, 1376315, 0, 196613, 1376316, 0, 196613, 1376317, 0, 196613, 1376318, 0, 196613, 1376319, 0, 196613, 1376320, 0, 196613, 1376321, 0, 196613, 1376322, 0, 196613, 1376323, 0, 196613, 1376324, 0, 196613, 1376325, 0, 196613, 1376326, 0, 196613, 1376327, 0, 196613, 1376328, 0, 196613, 1376329, 0, 196613, 1376330, 0, 196613, 1376331, 0, 196613, 1376332, 0, 196613, 1376333, 0, 196613, 1376334, 0, 196613, 1376335, 0, 196613, 1441792, 0, 196613, 1441793, 0, 196613, 1441794, 0, 196613, 1441795, 0, 196613, 1441796, 0, 196613, 1441797, 0, 196613, 1441798, 0, 196613, 1441799, 0, 196613, 1441800, 0, 196613, 1441801, 0, 196613, 1441802, 0, 196613, 1441803, 0, 196613, 1441804, 0, 196613, 1441805, 0, 196613, 1441806, 0, 196613, 1441807, 0, 196613, 1441808, 0, 196613, 1441809, 0, 196613, 1441810, 0, 196613, 1441811, 0, 196613, 1441812, 0, 196613, 1441813, 0, 196613, 1441814, 0, 196613, 1441815, 0, 196613, 1441816, 0, 196613, 1441817, 0, 196613, 1441818, 0, 196613, 1441819, 0, 196613, 1441820, 0, 196613, 1441821, 0, 196613, 1441822, 0, 196613, 1441823, 0, 196613, 1441824, 0, 196613, 1441825, 0, 196613, 1441826, 0, 196613, 1441827, 0, 196613, 1441828, 0, 196613, 1441829, 0, 196613, 1441830, 0, 196613, 1441831, 0, 196613, 1441832, 0, 196613, 1441833, 0, 196613, 1441834, 0, 196613, 1441835, 0, 196613, 1441836, 0, 196613, 1441837, 0, 196613, 1441838, 0, 196613, 1441839, 0, 196613, 1441840, 0, 196613, 1441841, 0, 196613, 1441842, 0, 196613, 1441843, 0, 196613, 1441844, 0, 196613, 1441845, 0, 196613, 1441846, 0, 196613, 1441847, 0, 196613, 1441848, 0, 196613, 1441849, 0, 196613, 1441850, 0, 196613, 1441851, 0, 196613, 1441852, 0, 196613, 1441853, 0, 196613, 1441854, 0, 196613, 1441855, 0, 196613, 1441856, 0, 196613, 1441857, 0, 196613, 1441858, 0, 196613, 1441859, 0, 196613, 1441860, 0, 196613, 1441861, 0, 196613, 1441862, 0, 196613, 1441863, 0, 196613, 1441864, 0, 196613, 1441865, 0, 196613, 1441866, 0, 196613, 1441867, 0, 196613, 1441868, 0, 196613, 1441869, 0, 196613, 1441870, 0, 196613, 1441871, 0, 196613 ) +__meta__ = { +"_edit_lock_": true +} + +[node name="Player" parent="." instance=ExtResource( 1 )] +position = Vector2( 154, 27 ) + +[node name="CameraControl" type="Position2D" parent="."] +process_priority = 1 +script = ExtResource( 5 ) + +[node name="Line2D" type="Line2D" parent="CameraControl"] +visible = false +points = PoolVector2Array( 0, 0, 160, 160, 241, 217, 406, 261, 358, 359, 43, 412, 53, 279, 250, 121, 355, -64, -4, 167, -141, -162, -274, -190, -321, 55, -211, 196, 564, 205, -325, -173, 174, -15 ) +width = 3.0 + +[node name="Camera2D" type="Camera2D" parent="CameraControl"] +process_priority = 1 +anchor_mode = 0 +current = true +smoothing_speed = 30.0 + +[node name="Left" type="RayCast2D" parent="CameraControl"] +position = Vector2( 160, 90 ) +enabled = true +cast_to = Vector2( -160, 0 ) +collision_mask = 256 +collide_with_areas = true +collide_with_bodies = false + +[node name="Right" type="RayCast2D" parent="CameraControl"] +position = Vector2( 160, 90 ) +enabled = true +cast_to = Vector2( 160, 0 ) +collision_mask = 256 +collide_with_areas = true +collide_with_bodies = false + +[node name="CameraBoundaries" type="Area2D" parent="."] +collision_layer = 256 +collision_mask = 0 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="CameraBoundaries"] +position = Vector2( 0, 66 ) +shape = SubResource( 13 ) + +[node name="CollisionShape2D2" type="CollisionShape2D" parent="CameraBoundaries"] +position = Vector2( 1281, 68 ) +shape = SubResource( 13 ) + +[node name="NewEnemy" parent="." instance=ExtResource( 6 )] +position = Vector2( 400, 81 ) diff --git a/Player-KinematicBody2D.gd b/Player-KinematicBody2D.gd new file mode 100644 index 0000000..5188c12 --- /dev/null +++ b/Player-KinematicBody2D.gd @@ -0,0 +1,179 @@ +class_name Player extends KinematicBody2D + +var velocity = Vector2(0,0) +var direction = Vector2(0,0) + +export var player_number: int = 1 + +onready var movement_animations: AnimatedSprite = $AnimatedSprite + +onready var movement_state_machine: Node = $Controllers/state_machine + +onready var player_move_component = $Controllers/move_component + +onready var player_hurtbox = $Hurtbox/CollisionShape2D + +onready var gun = $Gun + +func _ready() -> void: + movement_state_machine.init(self, movement_animations, player_move_component) + player_move_component.player_number = player_number + +func _unhandled_input(event: InputEvent) -> void: + movement_state_machine.process_input(event) + +func _physics_process(delta: float) -> void: + movement_state_machine.process_physics(delta) +# #TODO: So much hack +# if direction.x != 0: +# gun.set_scale( Vector2(direction.x,1)) + if direction.x < 0: + var t = Transform2D() + # Translation + t.origin = Vector2(gun.offset_position.x * -1, gun.offset_position.y) + gun.transform = t + elif direction.x > 0: + var t = Transform2D() + # Translation + t.origin = Vector2(gun.offset_position.x, gun.offset_position.y) + gun.transform = t + +func _process(delta: float) -> void: + movement_state_machine.process_frame(delta) + PlayerInfo.player_position = global_position + +func _on_AnimatedSprite_animation_finished(): + if movement_animations.frames.get_animation_loop(movement_animations.animation) == false: + movement_state_machine.current_state.animation_index += 1 + +func _on_Hurtbox_area_entered(area): + print("Ouch.",area) + movement_state_machine.change_state($Controllers/state_machine/hurt) + +func set_hurtbox(enabled: bool): + #player_hurtbox.disabled = enabled #nope + player_hurtbox.set_deferred("disabled", !enabled) #WTF Apparently this is how to do it + #$Hurtbox.monitoring = enabled #nope + #$Hurtbox.set_deferred("monitoring", enabled) #works + #$Hurtbox.monitoring = false #nope + #$Hurtbox.set_monitoring(enabled) # Nope + +func shoot_projectile(): + var is_shooting = false + is_shooting = gun.shoot(direction.x) + +#func _ready(): +# # Static types are necessary here to avoid warnings. +# var camera: Camera2D = $Camera2D +# camera.custom_viewport = $"../.." +# yield(get_tree(), "idle_frame") +# camera.make_current() + +# +#func _physics_process(delta): +# # Horizontal movement +# velocity.x = (Input.get_axis("ui_left", "ui_right") * WALK_MAX_SPEED) +# +# # Vertical movement code. Apply gravity. +# velocity.y += gravity * delta +# +# # Move based on the velocity and snap to the ground. +# #velocity = move_and_slide_with_snap(velocity, Vector2.DOWN, Vector2.UP) +# velocity = move_and_slide(velocity, Vector2(0, -1)) +# +# # Check for jumping. is_on_floor() must be called after movement code. +# # Apply Jump velocity +# if is_on_floor() and Input.is_action_just_pressed("ui_accept"): +# velocity.y = -JUMP_SPEED +# +# # Animate based on last state and velocity +# if velocity.x > 0 and _animated_sprite.flip_h != true: +# _animated_sprite.flip_h = true +# if velocity.x < 0 and _animated_sprite.flip_h != false: +# _animated_sprite.flip_h = false +# +# # forced state changes like falling an gitting hurt +# if velocity.y > 0 and player_state != STATE.JUMP and player_state != STATE.FALL: +# print("STATE_TRANSITION: Fall") +# player_state = STATE.FALL +# +# +# # Each state should trigger its own animation +# match player_state: +# STATE.IDLE: +# # Transitions +# if velocity.y == -JUMP_SPEED: +# print("STATE_TRANSITION: Jump") +# player_last_state = STATE.IDLE +# player_state = STATE.JUMP +# elif velocity.x != 0: +# print("STATE_TRANSITION: Run") +# player_last_state = STATE.IDLE +# player_state = STATE.RUN +# # Animation +# if player_last_state != STATE.IDLE: +# $IdleTimeout.start() +# _animated_sprite.play("idle") +# player_last_state = STATE.IDLE +# if $IdleTimeout.time_left == 0 and _animated_sprite.animation != 'blink': +# _animated_sprite.play("blink") +# animation_play_finished = false +# if $IdleTimeout.time_left == 0 and animation_play_finished == true: +# $IdleTimeout.start() +# _animated_sprite.play("idle") +# print("blink over") +# +# STATE.JUMP: +# # Transitions +# if is_on_floor(): +# print("STATE_TRANSITION: Idle") +# _animated_sprite.play("idle") +# player_last_state = STATE.JUMP +# player_state = STATE.IDLE +# # Animation +# if player_last_state != STATE.JUMP: +# _animated_sprite.play("jump") +# player_last_state = STATE.JUMP +# +# STATE.FALL: +# # Transitions +# if is_on_floor(): +# print("STATE_TRANSITION: Idle") +# _animated_sprite.play("idle") +# player_last_state = STATE.FALL +# player_state = STATE.IDLE +# # Animation +# if player_last_state != STATE.FALL: +# _animated_sprite.animation = "jump" +# _animated_sprite.frame = 8 +# _animated_sprite.stop() +# player_last_state = STATE.FALL +# +# STATE.RUN: +# # print (_animated_sprite.animation ) # apparentl playing doesn't stop when loop is disabled. +# # Transitions +# if velocity.y == -JUMP_SPEED: +# print("STATE_TRANSITION: Jump") +# _animated_sprite.play("jump") +# player_last_state = STATE.RUN +# player_state = STATE.JUMP +# elif velocity.x == 0: +# print("STATE_TRANSITION: Idle") +# _animated_sprite.play("idle") +# player_last_state = STATE.RUN +# player_state = STATE.IDLE +# # Animation +# if player_last_state == STATE.IDLE: +# _animated_sprite.play("step") +# animation_play_finished = false +# player_last_state = STATE.RUN +# elif animation_play_finished == true: +# _animated_sprite.play("run") +# animation_play_finished = false +# +# +#func _on_AnimatedSprite_animation_finished(): +# animation_play_finished = true +# print($AnimatedSprite.animation," anim over ", $IdleTimeout.time_left, animation_play_finished) + + diff --git a/Player.tscn b/Player.tscn new file mode 100644 index 0000000..d684d40 --- /dev/null +++ b/Player.tscn @@ -0,0 +1,512 @@ +[gd_scene load_steps=86 format=2] + +[ext_resource path="res://Player-KinematicBody2D.gd" type="Script" id=1] +[ext_resource path="res://idle.gd" type="Script" id=2] +[ext_resource path="res://state_machine.gd" type="Script" id=3] +[ext_resource path="res://fall.gd" type="Script" id=4] +[ext_resource path="res://move.gd" type="Script" id=5] +[ext_resource path="res://player_move_component.gd" type="Script" id=6] +[ext_resource path="res://jump.gd" type="Script" id=7] +[ext_resource path="res://hurt.gd" type="Script" id=8] +[ext_resource path="res://Gun.gd" type="Script" id=9] +[ext_resource path="res://fire.gd" type="Script" id=10] + +[sub_resource type="StreamTexture" id=75] +load_path = "res://.import/MegaMan.png-dc2c293e5a0f5d183ee961942ac90e4a.stex" + +[sub_resource type="AtlasTexture" id=76] +atlas = SubResource( 75 ) +region = Rect2( 256, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=77] +atlas = SubResource( 75 ) +region = Rect2( 384, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=78] +atlas = SubResource( 75 ) +region = Rect2( 448, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=79] +atlas = SubResource( 75 ) +region = Rect2( 320, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=80] +atlas = SubResource( 75 ) +region = Rect2( 384, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=81] +atlas = SubResource( 75 ) +region = Rect2( 448, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=82] +atlas = SubResource( 75 ) +region = Rect2( 512, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=83] +atlas = SubResource( 75 ) +region = Rect2( 0, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=84] +atlas = SubResource( 75 ) +region = Rect2( 64, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=85] +atlas = SubResource( 75 ) +region = Rect2( 128, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=86] +atlas = SubResource( 75 ) +region = Rect2( 320, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=87] +atlas = SubResource( 75 ) +region = Rect2( 384, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=88] +atlas = SubResource( 75 ) +region = Rect2( 448, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=89] +atlas = SubResource( 75 ) +region = Rect2( 256, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=90] +atlas = SubResource( 75 ) +region = Rect2( 320, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=91] +atlas = SubResource( 75 ) +region = Rect2( 384, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=92] +atlas = SubResource( 75 ) +region = Rect2( 448, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=93] +atlas = SubResource( 75 ) +region = Rect2( 64, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=94] +atlas = SubResource( 75 ) +region = Rect2( 512, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=95] +atlas = SubResource( 75 ) +region = Rect2( 0, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=96] +atlas = SubResource( 75 ) +region = Rect2( 64, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=97] +atlas = SubResource( 75 ) +region = Rect2( 128, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=98] +atlas = SubResource( 75 ) +region = Rect2( 192, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=99] +atlas = SubResource( 75 ) +region = Rect2( 0, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=100] +atlas = SubResource( 75 ) +region = Rect2( 192, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=101] +atlas = SubResource( 75 ) +region = Rect2( 256, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=102] +atlas = SubResource( 75 ) +region = Rect2( 320, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=103] +atlas = SubResource( 75 ) +region = Rect2( 384, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=104] +atlas = SubResource( 75 ) +region = Rect2( 448, 320, 64, 64 ) + +[sub_resource type="AtlasTexture" id=105] +atlas = SubResource( 75 ) +region = Rect2( 128, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=106] +atlas = SubResource( 75 ) +region = Rect2( 192, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=107] +atlas = SubResource( 75 ) +region = Rect2( 320, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=108] +atlas = SubResource( 75 ) +region = Rect2( 128, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=109] +atlas = SubResource( 75 ) +region = Rect2( 192, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=110] +atlas = SubResource( 75 ) +region = Rect2( 256, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=111] +atlas = SubResource( 75 ) +region = Rect2( 320, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=112] +atlas = SubResource( 75 ) +region = Rect2( 384, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=113] +atlas = SubResource( 75 ) +region = Rect2( 448, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=114] +atlas = SubResource( 75 ) +region = Rect2( 512, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=115] +atlas = SubResource( 75 ) +region = Rect2( 0, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=116] +atlas = SubResource( 75 ) +region = Rect2( 64, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=117] +atlas = SubResource( 75 ) +region = Rect2( 64, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=118] +atlas = SubResource( 75 ) +region = Rect2( 128, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=119] +atlas = SubResource( 75 ) +region = Rect2( 192, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=120] +atlas = SubResource( 75 ) +region = Rect2( 256, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=121] +atlas = SubResource( 75 ) +region = Rect2( 320, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=122] +atlas = SubResource( 75 ) +region = Rect2( 384, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=123] +atlas = SubResource( 75 ) +region = Rect2( 448, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=124] +atlas = SubResource( 75 ) +region = Rect2( 512, 192, 64, 64 ) + +[sub_resource type="AtlasTexture" id=125] +atlas = SubResource( 75 ) +region = Rect2( 0, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=126] +atlas = SubResource( 75 ) +region = Rect2( 128, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=127] +atlas = SubResource( 75 ) +region = Rect2( 192, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=128] +atlas = SubResource( 75 ) +region = Rect2( 256, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=129] +atlas = SubResource( 75 ) +region = Rect2( 320, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=130] +atlas = SubResource( 75 ) +region = Rect2( 384, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=131] +atlas = SubResource( 75 ) +region = Rect2( 448, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=132] +atlas = SubResource( 75 ) +region = Rect2( 0, 0, 64, 64 ) + +[sub_resource type="AtlasTexture" id=133] +atlas = SubResource( 75 ) +region = Rect2( 512, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=134] +atlas = SubResource( 75 ) +region = Rect2( 512, 384, 64, 64 ) + +[sub_resource type="AtlasTexture" id=135] +atlas = SubResource( 75 ) +region = Rect2( 0, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=136] +atlas = SubResource( 75 ) +region = Rect2( 64, 448, 64, 64 ) + +[sub_resource type="AtlasTexture" id=137] +atlas = SubResource( 75 ) +region = Rect2( 512, 64, 64, 64 ) + +[sub_resource type="AtlasTexture" id=138] +atlas = SubResource( 75 ) +region = Rect2( 0, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=139] +atlas = SubResource( 75 ) +region = Rect2( 64, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=140] +atlas = SubResource( 75 ) +region = Rect2( 128, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=141] +atlas = SubResource( 75 ) +region = Rect2( 192, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=142] +atlas = SubResource( 75 ) +region = Rect2( 256, 128, 64, 64 ) + +[sub_resource type="AtlasTexture" id=143] +atlas = SubResource( 75 ) +region = Rect2( 64, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=144] +atlas = SubResource( 75 ) +region = Rect2( 128, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=145] +atlas = SubResource( 75 ) +region = Rect2( 192, 256, 64, 64 ) + +[sub_resource type="AtlasTexture" id=146] +atlas = SubResource( 75 ) +region = Rect2( 256, 256, 64, 64 ) + +[sub_resource type="SpriteFrames" id=147] +animations = [ { +"frames": [ SubResource( 76 ), SubResource( 77 ), SubResource( 78 ) ], +"loop": true, +"name": "blink", +"speed": 10.0 +}, { +"frames": [ SubResource( 79 ), SubResource( 80 ), SubResource( 81 ), SubResource( 82 ) ], +"loop": true, +"name": "climb", +"speed": 10.0 +}, { +"frames": [ SubResource( 83 ), SubResource( 84 ) ], +"loop": true, +"name": "climb_end", +"speed": 10.0 +}, { +"frames": [ SubResource( 85 ) ], +"loop": true, +"name": "climb_fire", +"speed": 10.0 +}, { +"frames": [ SubResource( 86 ), SubResource( 87 ), SubResource( 88 ), SubResource( 86 ) ], +"loop": true, +"name": "fire", +"speed": 10.0 +}, { +"frames": [ SubResource( 89 ), SubResource( 90 ), SubResource( 89 ), SubResource( 91 ), SubResource( 92 ) ], +"loop": true, +"name": "hit", +"speed": 10.0 +}, { +"frames": [ SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 76 ), SubResource( 77 ), SubResource( 78 ) ], +"loop": true, +"name": "idle", +"speed": 10.0 +}, { +"frames": [ SubResource( 93 ), SubResource( 94 ), SubResource( 95 ), SubResource( 96 ), SubResource( 97 ), SubResource( 98 ), SubResource( 98 ), SubResource( 97 ), SubResource( 96 ), SubResource( 95 ), SubResource( 94 ), SubResource( 93 ) ], +"loop": true, +"name": "jump", +"speed": 10.0 +}, { +"frames": [ SubResource( 99 ), SubResource( 100 ), SubResource( 101 ), SubResource( 102 ), SubResource( 103 ), SubResource( 104 ) ], +"loop": true, +"name": "jump_fire", +"speed": 10.0 +}, { +"frames": [ SubResource( 105 ), SubResource( 106 ), SubResource( 105 ), SubResource( 76 ), SubResource( 107 ) ], +"loop": true, +"name": "look", +"speed": 10.0 +}, { +"frames": [ SubResource( 93 ), SubResource( 108 ), SubResource( 109 ), SubResource( 110 ), SubResource( 111 ), SubResource( 112 ), SubResource( 113 ), SubResource( 114 ), SubResource( 115 ), SubResource( 116 ) ], +"loop": true, +"name": "run", +"speed": 10.0 +}, { +"frames": [ SubResource( 99 ), SubResource( 117 ), SubResource( 118 ), SubResource( 119 ), SubResource( 120 ), SubResource( 121 ), SubResource( 122 ), SubResource( 123 ), SubResource( 124 ), SubResource( 125 ) ], +"loop": true, +"name": "run_fire", +"speed": 10.0 +}, { +"frames": [ SubResource( 126 ), SubResource( 127 ), SubResource( 126 ), SubResource( 128 ) ], +"loop": true, +"name": "slide", +"speed": 10.0 +}, { +"frames": [ SubResource( 129 ), SubResource( 130 ), SubResource( 131 ) ], +"loop": true, +"name": "slide_hit", +"speed": 10.0 +}, { +"frames": [ SubResource( 132 ) ], +"loop": false, +"name": "step", +"speed": 10.0 +}, { +"frames": [ SubResource( 133 ) ], +"loop": true, +"name": "stepfire", +"speed": 10.0 +}, { +"frames": [ SubResource( 134 ), SubResource( 135 ), SubResource( 136 ), SubResource( 135 ) ], +"loop": true, +"name": "stun", +"speed": 10.0 +}, { +"frames": [ SubResource( 137 ), SubResource( 138 ), SubResource( 139 ), SubResource( 140 ), SubResource( 141 ), SubResource( 142 ) ], +"loop": true, +"name": "teleport", +"speed": 10.0 +}, { +"frames": [ SubResource( 143 ), SubResource( 144 ), SubResource( 145 ), SubResource( 146 ) ], +"loop": true, +"name": "throw", +"speed": 10.0 +} ] + +[sub_resource type="RectangleShape2D" id=74] +extents = Vector2( 14, 18.5 ) + +[sub_resource type="RectangleShape2D" id=148] +extents = Vector2( 11.5, 14.5 ) + +[node name="Player" type="KinematicBody2D"] +collision_layer = 2 +script = ExtResource( 1 ) + +[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +frames = SubResource( 147 ) +animation = "idle" +frame = 6 +playing = true +flip_h = true +__meta__ = { +"_aseprite_wizard_config_": { +"layer": "", +"o_ex_p": "", +"o_folder": "res://assets", +"o_name": "", +"only_visible": true, +"op_exp": false, +"slice": "", +"source": "E:/Godot/Art/MegaMan.aseprite" +} +} + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +position = Vector2( 0, -3.5 ) +shape = SubResource( 74 ) + +[node name="Controllers" type="Node" parent="."] + +[node name="state_machine" type="Node" parent="Controllers"] +script = ExtResource( 3 ) +starting_state = NodePath("idle") + +[node name="idle" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 2 ) +animation_name = "idle" +move_speed = 90.0 +jump_node = NodePath("../jump") +fall_node = NodePath("../fall") +move_node = NodePath("../move") +fire_node = NodePath("../fire") + +[node name="jump" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 7 ) +animation_name = "jump" +move_speed = 90.0 +idle_node = NodePath("../idle") +fall_node = NodePath("../fall") +move_node = NodePath("../move") +jump_force = 270.0 + +[node name="move" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 5 ) +move_speed = 90.0 +animation_sequence = [ "step", "run" ] +jump_node = NodePath("../jump") +fall_node = NodePath("../fall") +idle_node = NodePath("../idle") +dash_node = NodePath(".") + +[node name="fall" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 4 ) +animation_name = "jump" +move_speed = 90.0 +idle_node = NodePath("../idle") +move_node = NodePath("../move") + +[node name="hurt" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 8 ) +animation_name = "hit" +move_speed = -25.0 +timeout_seconds = 1.0 +idle_node = NodePath("../idle") + +[node name="fire" type="Node" parent="Controllers/state_machine"] +script = ExtResource( 10 ) +animation_name = "fire" +timeout_seconds = 1.0 +idle_node = NodePath("../idle") + +[node name="move_component" type="Node" parent="Controllers"] +script = ExtResource( 6 ) + +[node name="Hurtbox" type="Area2D" parent="."] +collision_layer = 16 +collision_mask = 128 + +[node name="CollisionShape2D" type="CollisionShape2D" parent="Hurtbox"] +self_modulate = Color( 1, 0, 0, 1 ) +position = Vector2( 0, -4 ) +shape = SubResource( 148 ) + +[node name="Gun" type="Position2D" parent="."] +physics_interpolation_mode = 1 +position = Vector2( 25, -5 ) +script = ExtResource( 9 ) + +[node name="Cooldown" type="Timer" parent="Gun"] +wait_time = 0.5 +one_shot = true + +[node name="Line2D" type="Line2D" parent="Gun"] +points = PoolVector2Array( -5, 0, 5, 0 ) +width = 2.0 +default_color = Color( 1, 0.607843, 0, 1 ) + +[connection signal="animation_finished" from="AnimatedSprite" to="." method="_on_AnimatedSprite_animation_finished"] +[connection signal="area_entered" from="Hurtbox" to="." method="_on_Hurtbox_area_entered"] diff --git a/Position2D.gd b/Position2D.gd new file mode 100644 index 0000000..5d66a83 --- /dev/null +++ b/Position2D.gd @@ -0,0 +1,95 @@ +extends Position2D + +export(String) var LINE_COLOR_HEX = '#FFEB3B' + +var grid_position = Vector2() +var grid_size = Vector2() +var t = 0.0 + +onready var parent = get_node("../Player") +#onready var parent = $Player + +func _ready(): + # If you drag the camera from the OffsetPivot node, + # its position will not be (0, 0) + #$Camera2D.global_position = Vector2(160,90) # when doing grid snapping + #$Left.position = Vector2(160,90) + $Camera2D.position = Vector2(0,-4) + #grid_size = OS.get_screen_size() + grid_size = get_node("/root").size + #grid_size = get_node("/root").get_visible_rect().size + print(grid_size) + set_as_toplevel(true) + update_grid_position() + print("Camera Set: ",grid_position, position) + print("Ray Left: ", $Left.global_position, $Left.cast_to) + + + +func _physics_process(delta): + t += delta * 0.4 + #print(parent.position.x) + update_grid_position() + #draw_line( Vector2(0, -half_line_length), Vector2(0, half_line_length), color, 3.0) + +#func _draw(): +# var color = Color(LINE_COLOR_HEX) +# draw_line( $Left.position, $Left.cast_to, color, 3.0) +# draw_line( Vector2(0,0), Vector2(200,200), color, 3.0) + + +func update_grid_position(): + var new_grid_position = calculate_grid_position() +# if $Left.is_colliding(): +# print("Oh God! No!") +# if grid_position == new_grid_position: +# return + grid_position = new_grid_position + jump_to_grid_position() + #$Left.position = Vector2(grid_position * grid_size) + #print("Ray Left: ", $Left.global_position, $Left.cast_to) + + +func calculate_grid_position(): + # this needs to heavily round off the parents position + var x_offset = floor(parent.position.x / grid_size.x) + var y_offset = floor(parent.position.y / grid_size.y) + var x = round(x_offset) + #var x = (((grid_position.x * grid_size.x) + ((grid_position.x + 1) * grid_size.x))/2) + var y = round(y_offset) + #var y = round(parent.position.y / grid_size.y) + return Vector2(x, y) + + +func jump_to_grid_position(): + #var x_pos = (((grid_position.x * grid_size.x) + ((grid_position.x + 1) * grid_size.x))/2) + # rounding or flooring position seems to just cause a lot of jitter + var x_pos = (parent.position.x - grid_size.x/2) +# if (x_pos - grid_size.x/2) < 0: +# x_pos = grid_size.x/2 +# if x_pos < 0: +# x_pos = 0 + if $Left.is_colliding(): + #print("Oh God! No! ", $Left.get_collision_point().x, $Left.global_position) + $Camera2D.limit_left = $Left.get_collision_point().x + # attempts to just change the position to the collision point created a + # ghosting behavior, now I just set the limit of the camera to the point + + #x_pos = $Left.get_collision_point().x+1 + #position = Vector2($Left.get_collision_point().x+1, grid_position.y * grid_size.y) + else: + $Camera2D.limit_left = -10000000 + if $Right.is_colliding(): + print("Oh God! No! ", $Right.get_collision_point().x, $Right.global_position) + $Camera2D.limit_right = $Right.get_collision_point().x + else: + $Camera2D.limit_right = 10000000 + position = Vector2( x_pos ,grid_position.y * grid_size.y) + #$Camera2D.force_update_scroll() + #position = Vector2( grid_position * grid_size) + #print("Camera Move: ",grid_position, position) + + +#func _physics_process(delta): +# +# $Sprite2D.position = $A.position.lerp($B.position, t) diff --git a/Projectile.gd b/Projectile.gd new file mode 100644 index 0000000..93c7591 --- /dev/null +++ b/Projectile.gd @@ -0,0 +1,18 @@ +extends RigidBody2D + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" + + +# Called when the node enters the scene tree for the first time. + +# Called every frame. 'delta' is the elapsed time since the previous frame. +func _process(_delta): + if $Timer.time_left == 0: + queue_free() + + +func _on_Projectile_body_entered(body): + queue_free() diff --git a/Projectile.tscn b/Projectile.tscn new file mode 100644 index 0000000..debb251 --- /dev/null +++ b/Projectile.tscn @@ -0,0 +1,36 @@ +[gd_scene load_steps=5 format=2] + +[ext_resource path="res://assets/bullet.png" type="Texture" id=1] +[ext_resource path="res://Projectile.gd" type="Script" id=2] + +[sub_resource type="SpriteFrames" id=1] +animations = [ { +"frames": [ ExtResource( 1 ) ], +"loop": true, +"name": "default", +"speed": 5.0 +} ] + +[sub_resource type="CircleShape2D" id=2] +radius = 4.0 + +[node name="Projectile" type="RigidBody2D"] +collision_layer = 64 +collision_mask = 33 +gravity_scale = 0.0 +contacts_reported = 2 +contact_monitor = true +script = ExtResource( 2 ) + +[node name="AnimatedSprite" type="AnimatedSprite" parent="."] +frames = SubResource( 1 ) + +[node name="CollisionShape2D" type="CollisionShape2D" parent="."] +shape = SubResource( 2 ) + +[node name="Timer" type="Timer" parent="."] +wait_time = 3.0 +one_shot = true +autostart = true + +[connection signal="body_entered" from="." to="." method="_on_Projectile_body_entered"] diff --git a/Smiley.png b/Smiley.png new file mode 100644 index 0000000..88a0ca8 Binary files /dev/null and b/Smiley.png differ diff --git a/Smiley.png.import b/Smiley.png.import new file mode 100644 index 0000000..297364a --- /dev/null +++ b/Smiley.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Smiley.png-21025cc2924b94a90cc7095293287091.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://Smiley.png" +dest_files=[ "res://.import/Smiley.png-21025cc2924b94a90cc7095293287091.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/MegaMan.png b/assets/MegaMan.png new file mode 100644 index 0000000..4661388 Binary files /dev/null and b/assets/MegaMan.png differ diff --git a/assets/MegaMan.png.import b/assets/MegaMan.png.import new file mode 100644 index 0000000..87ae1a6 --- /dev/null +++ b/assets/MegaMan.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/MegaMan.png-dc2c293e5a0f5d183ee961942ac90e4a.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/MegaMan.png" +dest_files=[ "res://.import/MegaMan.png-dc2c293e5a0f5d183ee961942ac90e4a.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/Tiles/Assets/Assets.png b/assets/Tiles/Assets/Assets.png new file mode 100644 index 0000000..a5eab06 Binary files /dev/null and b/assets/Tiles/Assets/Assets.png differ diff --git a/assets/Tiles/Assets/Assets.png.import b/assets/Tiles/Assets/Assets.png.import new file mode 100644 index 0000000..579dbc9 --- /dev/null +++ b/assets/Tiles/Assets/Assets.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Assets.png-f03a88d0aba2c7e14cf1d8ccdd16c54e.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Tiles/Assets/Assets.png" +dest_files=[ "res://.import/Assets.png-f03a88d0aba2c7e14cf1d8ccdd16c54e.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/Tiles/Assets/Background_1.png b/assets/Tiles/Assets/Background_1.png new file mode 100644 index 0000000..f1ca948 Binary files /dev/null and b/assets/Tiles/Assets/Background_1.png differ diff --git a/assets/Tiles/Assets/Background_1.png.import b/assets/Tiles/Assets/Background_1.png.import new file mode 100644 index 0000000..b3807dd --- /dev/null +++ b/assets/Tiles/Assets/Background_1.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Background_1.png-600dd5a1e98ec11e29cfe251fc823b28.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Tiles/Assets/Background_1.png" +dest_files=[ "res://.import/Background_1.png-600dd5a1e98ec11e29cfe251fc823b28.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/Tiles/Assets/Background_2.png b/assets/Tiles/Assets/Background_2.png new file mode 100644 index 0000000..d676d65 Binary files /dev/null and b/assets/Tiles/Assets/Background_2.png differ diff --git a/assets/Tiles/Assets/Background_2.png.import b/assets/Tiles/Assets/Background_2.png.import new file mode 100644 index 0000000..fb0c5ac --- /dev/null +++ b/assets/Tiles/Assets/Background_2.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Background_2.png-cbaf6c4c26cf00b90452d6cbf7c69b70.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Tiles/Assets/Background_2.png" +dest_files=[ "res://.import/Background_2.png-cbaf6c4c26cf00b90452d6cbf7c69b70.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/Tiles/Autor_note.txt b/assets/Tiles/Autor_note.txt new file mode 100644 index 0000000..6e8e15e --- /dev/null +++ b/assets/Tiles/Autor_note.txt @@ -0,0 +1,11 @@ +all the assets here are totally free for commercial use and the like. + +credits are optional but appreciated. + +if there is any change of shape or color, no credit shall be given to the original creator (I) + +characters, monsters as well as boss and other types of creatures will be distributed exclusively to patron's subscribers above 5 dollars + +the patreon: https://www.patreon.com/Anokolisa + +each month two new packages are distributed to patreons above 3 dollars diff --git a/assets/Tiles/Social/Assets.png b/assets/Tiles/Social/Assets.png new file mode 100644 index 0000000..47ab33b Binary files /dev/null and b/assets/Tiles/Social/Assets.png differ diff --git a/assets/Tiles/Social/Assets.png.import b/assets/Tiles/Social/Assets.png.import new file mode 100644 index 0000000..7226d5f --- /dev/null +++ b/assets/Tiles/Social/Assets.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Assets.png-7e32500502bf22704b43171f4c163c27.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Tiles/Social/Assets.png" +dest_files=[ "res://.import/Assets.png-7e32500502bf22704b43171f4c163c27.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/Tiles/Social/Mine.png b/assets/Tiles/Social/Mine.png new file mode 100644 index 0000000..dd9631a Binary files /dev/null and b/assets/Tiles/Social/Mine.png differ diff --git a/assets/Tiles/Social/Mine.png.import b/assets/Tiles/Social/Mine.png.import new file mode 100644 index 0000000..0fc690e --- /dev/null +++ b/assets/Tiles/Social/Mine.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/Mine.png-8b11efea6fd046fa6c9da946e8741d9c.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Tiles/Social/Mine.png" +dest_files=[ "res://.import/Mine.png-8b11efea6fd046fa6c9da946e8741d9c.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/Tiles/Social/entrance.png b/assets/Tiles/Social/entrance.png new file mode 100644 index 0000000..f7e909f Binary files /dev/null and b/assets/Tiles/Social/entrance.png differ diff --git a/assets/Tiles/Social/entrance.png.import b/assets/Tiles/Social/entrance.png.import new file mode 100644 index 0000000..9e4c949 --- /dev/null +++ b/assets/Tiles/Social/entrance.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/entrance.png-1d00c022b610d166b8cdaa56ef893a27.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Tiles/Social/entrance.png" +dest_files=[ "res://.import/entrance.png-1d00c022b610d166b8cdaa56ef893a27.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/Tiles/Social/trees.png b/assets/Tiles/Social/trees.png new file mode 100644 index 0000000..43005c2 Binary files /dev/null and b/assets/Tiles/Social/trees.png differ diff --git a/assets/Tiles/Social/trees.png.import b/assets/Tiles/Social/trees.png.import new file mode 100644 index 0000000..fc1c6af --- /dev/null +++ b/assets/Tiles/Social/trees.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/trees.png-e262d7dea8f1c2c97d5cab0a124f6a24.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/Tiles/Social/trees.png" +dest_files=[ "res://.import/trees.png-e262d7dea8f1c2c97d5cab0a124f6a24.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/botEnemy.png b/assets/botEnemy.png new file mode 100644 index 0000000..0f895fb Binary files /dev/null and b/assets/botEnemy.png differ diff --git a/assets/botEnemy.png.import b/assets/botEnemy.png.import new file mode 100644 index 0000000..d9f6f1b --- /dev/null +++ b/assets/botEnemy.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/botEnemy.png-46efd539a38730ff15fb4ddb087329c6.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/botEnemy.png" +dest_files=[ "res://.import/botEnemy.png-46efd539a38730ff15fb4ddb087329c6.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/assets/bullet.png b/assets/bullet.png new file mode 100644 index 0000000..f8e0168 Binary files /dev/null and b/assets/bullet.png differ diff --git a/assets/bullet.png.import b/assets/bullet.png.import new file mode 100644 index 0000000..bf3b55e --- /dev/null +++ b/assets/bullet.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/bullet.png-c68d06721d4ad8b0013707b0a51654af.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://assets/bullet.png" +dest_files=[ "res://.import/bullet.png-c68d06721d4ad8b0013707b0a51654af.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=false +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/dash.gd b/dash.gd new file mode 100644 index 0000000..f71787f --- /dev/null +++ b/dash.gd @@ -0,0 +1,45 @@ +# You could also declare a class_name for the move state +# so you don't have to reference the script directly +extends 'res://src/state_machine/states/move.gd' + +@export +var move_state: State + +@export +var time_to_dash := 0.5 + +var dash_timer := 0.0 +var direction := 1.0 + +func enter() -> void: + super() + dash_timer = time_to_dash + + # Simple check for which direction to dash towards + if animations.flip_h: + direction = -1 + else: + direction = 1 + +# Just to be safe, disable any other inputs +func process_input(event: InputEvent) -> State: + return null + +func process_physics(delta: float) -> State: + dash_timer -= delta + if dash_timer <= 0.0: + # Fall back on the default input implementation to + # determine where to go next + if super.get_movement_input() != 0.0: + return move_state + return idle_state + + # At this point, run 'process_physics' in the move script as written + return super(delta) + +# Override movement inputs +func get_movement_input() -> float: + return direction + +func get_jump() -> bool: + return false diff --git a/default_env.tres b/default_env.tres new file mode 100644 index 0000000..20207a4 --- /dev/null +++ b/default_env.tres @@ -0,0 +1,7 @@ +[gd_resource type="Environment" load_steps=2 format=2] + +[sub_resource type="ProceduralSky" id=1] + +[resource] +background_mode = 2 +background_sky = SubResource( 1 ) diff --git a/enemy_move_component.gd b/enemy_move_component.gd new file mode 100644 index 0000000..7abca35 --- /dev/null +++ b/enemy_move_component.gd @@ -0,0 +1,46 @@ +extends Node + +export var flipped_sprite: bool = true +onready var idle_timeout = $IdleTimeout + +var desired_movement_vector: Vector2 + +var flip_flop = false +var wandering = false +var current_state_name: String = "" + +# Return the desired direction of movement for the character +# in the range [-1, 1], where positive values indicate a desire +# to move to the right and negative values to the left. +func get_movement_direction() -> float: + #return Input.get_axis('move_left', 'move_right') + if current_state_name == "idle" and idle_timeout.time_left == 0: + if flip_flop: + flip_flop = false + desired_movement_vector.x = 1.0 + idle_timeout.start() + else: + flip_flop = true + desired_movement_vector.x = -1.0 + idle_timeout.start() + if current_state_name == "move" and idle_timeout.time_left == 0: + idle_timeout.start() + desired_movement_vector.x = 0.0 + return 0.0 + +# Return a boolean indicating if the character wants to jump +func wants_jump() -> bool: + return false +# if Input.is_action_just_pressed("jump_" + str(player_number)): +# desired_movement_vector.y = 1 +# return true +# else: +# return false + +# Return a boolean indicating if the character wants to jump +func wants_shoot() -> bool: +# if Input.is_action_just_pressed("shoot_" + str(player_number)): +# return true +# else: +# return false + return false diff --git a/fall.gd b/fall.gd new file mode 100644 index 0000000..77dc706 --- /dev/null +++ b/fall.gd @@ -0,0 +1,42 @@ +extends State + +export (NodePath) var idle_node +export (NodePath) var move_node + +onready var idle_state: State = get_node(idle_node) +onready var move_state: State = get_node(move_node) + +func enter() -> void: + .enter() + animations.frame = 6 + + +func process_input(_event: InputEvent) -> State: + move_component.get_movement_direction() + return null + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + +# if parent.velocity.x != 0.0: +# parent.direction.x = parent.velocity.x + + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + else: + animations.flip_h = parent.direction.x < 0 + + if parent.is_on_floor(): + if parent.velocity.x == 0: + return move_state + return idle_state + return null diff --git a/fire.gd b/fire.gd new file mode 100644 index 0000000..4f24349 --- /dev/null +++ b/fire.gd @@ -0,0 +1,47 @@ +extends State + +export (NodePath) var idle_node + +onready var idle_state: State = get_node(idle_node) +var can_fire = true + +func enter() -> void: + .enter() + parent.set_hurtbox(false) + state_timeout.start() + can_fire = true + +func process_input(_event: InputEvent) -> State: +# if move_component.get_movement_direction() != 0.0: +# return move_state + +# move_component.wants_jump() + move_component.get_movement_direction() + +# if Input.is_action_just_pressed('dash'): +# return dash_state + return null + +func process_frame(delta: float) -> State: + if state_timeout.time_left == 0: + return idle_state + return null + + +func process_physics(delta: float) -> State: + + if can_fire: # trying to do this in the physics because irrecular behavior + parent.shoot_projectile() + can_fire = false + + parent.velocity.y += gravity * delta + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + +# if move_component.flipped_sprite == true: +# animations.flip_h = parent.direction.x > 0 +# else: +# animations.flip_h = parent.direction.x < 0 + + + return null + diff --git a/hurt.gd b/hurt.gd new file mode 100644 index 0000000..e58c070 --- /dev/null +++ b/hurt.gd @@ -0,0 +1,36 @@ +extends State + +export (NodePath) var idle_node + +onready var idle_state: State = get_node(idle_node) + +func enter() -> void: + .enter() + parent.velocity.x = 0 + parent.set_hurtbox(false) + #TODO: Error check if timer was actually instanced + state_timeout.start() + +func process_input(_event: InputEvent) -> State: +# move_component.wants_jump() + move_component.get_movement_direction() + + return null + + +func process_frame(delta: float) -> State: + if state_timeout.time_left == 0: + return idle_state + return null + + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + #parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + if (parent.direction.x > 0): + parent.velocity.x = 1 * move_speed + else: + parent.velocity.x = -1 * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + return null diff --git a/icon.png b/icon.png new file mode 100644 index 0000000..c98fbb6 Binary files /dev/null and b/icon.png differ diff --git a/icon.png.import b/icon.png.import new file mode 100644 index 0000000..a4c02e6 --- /dev/null +++ b/icon.png.import @@ -0,0 +1,35 @@ +[remap] + +importer="texture" +type="StreamTexture" +path="res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" +metadata={ +"vram_texture": false +} + +[deps] + +source_file="res://icon.png" +dest_files=[ "res://.import/icon.png-487276ed1e3a0c39cad0279d744ee560.stex" ] + +[params] + +compress/mode=0 +compress/lossy_quality=0.7 +compress/hdr_mode=0 +compress/bptc_ldr=0 +compress/normal_map=0 +flags/repeat=0 +flags/filter=true +flags/mipmaps=false +flags/anisotropic=false +flags/srgb=2 +process/fix_alpha_border=true +process/premult_alpha=false +process/HDR_as_SRGB=false +process/invert_color=false +process/normal_map_invert_y=false +stream=false +size_limit=0 +detect_3d=true +svg/scale=1.0 diff --git a/idle.gd b/idle.gd new file mode 100644 index 0000000..739298d --- /dev/null +++ b/idle.gd @@ -0,0 +1,47 @@ +extends State + +export (NodePath) var jump_node +export (NodePath) var fall_node +export (NodePath) var move_node +export (NodePath) var fire_node + +onready var jump_state: State = get_node(jump_node) +onready var fall_state: State = get_node(fall_node) +onready var move_state: State = get_node(move_node) +onready var fire_state: State = get_node(fire_node) + +func enter() -> void: + .enter() + parent.set_hurtbox(true) + parent.velocity.x = 0 + +func process_input(_event: InputEvent) -> State: +# if get_jump() and parent.is_on_floor(): +# return jump_state + + if move_component.wants_jump() and parent.is_on_floor(): + return jump_state +# if move_component.get_movement_direction() != 0.0: +# return move_state + if move_component.wants_shoot(): + return fire_state + +# move_component.wants_jump() + move_component.get_movement_direction() + +# if Input.is_action_just_pressed('dash'): +# return dash_state + return null + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + #parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if parent.velocity.x != 0.0: + return move_state + + if !parent.is_on_floor(): + return fall_state + return null diff --git a/jump.gd b/jump.gd new file mode 100644 index 0000000..92e170d --- /dev/null +++ b/jump.gd @@ -0,0 +1,47 @@ +extends State + +export (NodePath) var idle_node +export (NodePath) var fall_node +export (NodePath) var move_node + +onready var idle_state: State = get_node(idle_node) +onready var fall_state: State = get_node(fall_node) +onready var move_state: State = get_node(move_node) + + +export var jump_force: float = 900.0 + +func enter() -> void: + .enter() + parent.velocity.y = -jump_force + +func process_input(_event: InputEvent) -> State: + move_component.get_movement_direction() + return null + + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + + if parent.velocity.y > 0: + return fall_state + + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + else: + animations.flip_h = parent.direction.x < 0 + + if parent.is_on_floor(): + if parent.velocity.x == 0: + return move_state + return idle_state + + return null diff --git a/move.gd b/move.gd new file mode 100644 index 0000000..4d313d1 --- /dev/null +++ b/move.gd @@ -0,0 +1,61 @@ +extends State + +export (NodePath) var jump_node +export (NodePath) var fall_node +export (NodePath) var idle_node +export (NodePath) var dash_node + +onready var jump_state: State = get_node(jump_node) +onready var fall_state: State = get_node(fall_node) +onready var idle_state: State = get_node(idle_node) +onready var dash_state: State = get_node(dash_node) + +func process_input(_event: InputEvent) -> State: + if move_component.wants_jump() and parent.is_on_floor(): + return jump_state + + move_component.get_movement_direction() + + return null + + +func process_physics(delta: float) -> State: +# if move_component.wants_jump() and parent.is_on_floor(): +# return jump_state + + parent.velocity.y += gravity * delta + +# var movement = move_component.get_movement_direction() * move_speed +# +# # only detecting input not actual movement +# if movement == 0: +# return idle_state + +# parent.velocity.x = movement +# parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if parent.velocity.x == 0.0: + return idle_state + else: + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + else: + animations.flip_h = parent.direction.x < 0 + + + # Another approach of changing state based on actual achieved velocity +# if parent.velocity.x == 0: +# return idle_state + + if !parent.is_on_floor(): + return fall_state + return null diff --git a/player_move_component.gd b/player_move_component.gd new file mode 100644 index 0000000..6b4ead9 --- /dev/null +++ b/player_move_component.gd @@ -0,0 +1,32 @@ +class_name Movement +extends Node + +export var flipped_sprite: bool = true + +export var player_number: int = 1 + +var desired_movement_vector: Vector2 + +# Return the desired direction of movement for the character +# in the range [-1, 1], where positive values indicate a desire +# to move to the right and negative values to the left. +func get_movement_direction() -> float: + #return Input.get_axis('move_left', 'move_right') + desired_movement_vector.x = Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number)) + return Input.get_axis("move_left_" + str(player_number), "move_right_" + str(player_number)) + +# Return a boolean indicating if the character wants to jump +func wants_jump() -> bool: + + if Input.is_action_just_pressed("jump_" + str(player_number)): + desired_movement_vector.y = 1 + return true + else: + return false + +# Return a boolean indicating if the character wants to jump +func wants_shoot() -> bool: + if Input.is_action_just_pressed("shoot_" + str(player_number)): + return true + else: + return false diff --git a/project.godot b/project.godot new file mode 100644 index 0000000..f6cfe76 --- /dev/null +++ b/project.godot @@ -0,0 +1,146 @@ +; Engine configuration file. +; It's best edited using the editor UI and not directly, +; since the parameters that go here are not all obvious. +; +; Format: +; [section] ; section goes between [] +; param=value ; assign values to parameters + +config_version=4 + +_global_script_classes=[ { +"base": "KinematicBody2D", +"class": "Enemy", +"language": "GDScript", +"path": "res://Enemy-KinematicBody2D.gd" +}, { +"base": "KinematicBody2D", +"class": "Enemy2", +"language": "GDScript", +"path": "res://Enemy2-KinematicBody2D.gd" +}, { +"base": "Position2D", +"class": "Gun", +"language": "GDScript", +"path": "res://Gun.gd" +}, { +"base": "Node", +"class": "Movement", +"language": "GDScript", +"path": "res://player_move_component.gd" +}, { +"base": "KinematicBody2D", +"class": "Player", +"language": "GDScript", +"path": "res://Player-KinematicBody2D.gd" +}, { +"base": "Node", +"class": "State", +"language": "GDScript", +"path": "res://state.gd" +} ] +_global_script_class_icons={ +"Enemy": "", +"Enemy2": "", +"Gun": "", +"Movement": "", +"Player": "", +"State": "" +} + +[application] + +config/name="Mega Moves" +run/main_scene="res://Main.tscn" +config/icon="res://icon.png" + +[autoload] + +PlayerInfo="*res://src/singleton_autoloads/PlayerInfo.gd" + +[debug] + +shapes/collision/shape_color=Color( 1, 1, 1, 0.419608 ) + +[display] + +window/size/width=320 +window/size/height=180 +window/size/test_width=960 +window/size/test_height=540 +window/stretch/mode="viewport" +window/stretch/aspect="keep" + +[editor_plugins] + +enabled=PoolStringArray( "res://addons/AsepriteWizard/plugin.cfg" ) + +[gui] + +common/drop_mouse_on_gui_input_disabled=true + +[input] + +move_left_1={ +"deadzone": 0.5, +"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,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} +move_right_1={ +"deadzone": 0.5, +"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,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} +jump_1={ +"deadzone": 0.5, +"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":0,"physical_scancode":32,"unicode":0,"echo":false,"script":null) + ] +} +move_left_2={ +"deadzone": 0.5, +"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":65,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} +move_right_2={ +"deadzone": 0.5, +"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":68,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} +jump_2={ +"deadzone": 0.5, +"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":74,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} +shoot_1={ +"deadzone": 0.5, +"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":77,"physical_scancode":0,"unicode":0,"echo":false,"script":null) + ] +} +shoot_2={ +"deadzone": 0.5, +"events": [ ] +} + +[layer_names] + +2d_physics/layer_1="World" +2d_physics/layer_2="Player" +2d_physics/layer_3="Enemies" +2d_physics/layer_5="PlayerHurtbox" +2d_physics/layer_6="EnemyHurtbox" +2d_physics/layer_7="PlayerHitbox" +2d_physics/layer_8="EnemyHitbox" + +[mono] + +project/assembly_name="Sprite Template" + +[physics] + +common/enable_pause_aware_picking=true +2d/default_gravity=600 + +[rendering] + +quality/driver/driver_name="GLES2" +environment/default_environment="res://default_env.tres" diff --git a/src/singleton_autoloads/PlayerInfo.gd b/src/singleton_autoloads/PlayerInfo.gd new file mode 100644 index 0000000..c65333b --- /dev/null +++ b/src/singleton_autoloads/PlayerInfo.gd @@ -0,0 +1,17 @@ +extends Node + + +# Declare member variables here. Examples: +# var a = 2 +# var b = "text" +var player_position: Vector2 +var player_health: int + +# Called when the node enters the scene tree for the first time. +func _ready(): + pass # Replace with function body. + + +# Called every frame. 'delta' is the elapsed time since the previous frame. +#func _process(delta): +# pass diff --git a/src/states/enemy/attack.gd b/src/states/enemy/attack.gd new file mode 100644 index 0000000..6d34d45 --- /dev/null +++ b/src/states/enemy/attack.gd @@ -0,0 +1,33 @@ +extends State + +export (NodePath) var idle_node + +onready var idle_state: State = get_node(idle_node) +var can_fire = true + +func enter() -> void: + .enter() + parent.velocity.x = 0 + parent.set_hitbox(false) + +func process_frame(_delta: float) -> State: + if parent.player_detection.is_colliding() == false: + return idle_state + + if animations.frame > 1: + parent.set_hitbox(true) + else: + parent.set_hitbox(false) + + + return null + + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + #parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + return null + +func exit() -> void: + parent.set_hitbox(false) diff --git a/src/states/enemy/fall.gd b/src/states/enemy/fall.gd new file mode 100644 index 0000000..2bf88a8 --- /dev/null +++ b/src/states/enemy/fall.gd @@ -0,0 +1,42 @@ +extends State + +export (NodePath) var idle_node +export (NodePath) var move_node + +onready var idle_state: State = get_node(idle_node) +onready var move_state: State = get_node(move_node) + +func enter() -> void: + .enter() + animations.frame = 6 + + +func process_frame(_delta: float) -> State: + move_component.get_movement_direction() + return null + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + +# if parent.velocity.x != 0.0: +# parent.direction.x = parent.velocity.x + + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + else: + animations.flip_h = parent.direction.x < 0 + + if parent.is_on_floor(): + if parent.velocity.x == 0: + return move_state + return idle_state + return null diff --git a/src/states/enemy/hurt.gd b/src/states/enemy/hurt.gd new file mode 100644 index 0000000..a0ac275 --- /dev/null +++ b/src/states/enemy/hurt.gd @@ -0,0 +1,34 @@ +extends State + +export (NodePath) var idle_node + +onready var idle_state: State = get_node(idle_node) + +func enter() -> void: + .enter() + parent.velocity.x = 0 + parent.set_hurtbox(false) + state_timeout = Timer.new() + state_timeout.wait_time = 1.0 + state_timeout.one_shot = true + state_timeout.autostart = true + add_child(state_timeout) + +func process_frame(delta: float) -> State: +# move_component.wants_jump() + move_component.get_movement_direction() + if state_timeout.time_left == 0: + return idle_state + return null + + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + #parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + if (parent.direction.x > 0): + parent.velocity.x = 1 * move_speed + else: + parent.velocity.x = -1 * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + return null diff --git a/src/states/enemy/idle.gd b/src/states/enemy/idle.gd new file mode 100644 index 0000000..397bfac --- /dev/null +++ b/src/states/enemy/idle.gd @@ -0,0 +1,54 @@ +extends State + +export (NodePath) var jump_node +export (NodePath) var fall_node +#export (NodePath) var move_node +export (NodePath) var fire_node +export (NodePath) var wander_node +export (NodePath) var attack_node + +onready var jump_state: State = get_node(jump_node) +onready var fall_state: State = get_node(fall_node) +#onready var move_state: State = get_node(move_node) +onready var fire_state: State = get_node(fire_node) +onready var wander_state: State = get_node(wander_node) +onready var attack_state: State = get_node(attack_node) + +func enter() -> void: + .enter() + parent.set_hurtbox(true) + parent.velocity.x = 0 + state_timeout.start() + +func process_frame(_delta: float) -> State: + + if state_timeout.time_left == 0: + return wander_state + + if parent.player_detection.is_colliding(): + return attack_state + +# if get_jump() and parent.is_on_floor(): +# return jump_state +# +# if move_component.wants_jump() and parent.is_on_floor(): +# return jump_state +## if move_component.get_movement_direction() != 0.0: +## return move_state +# if move_component.wants_shoot(): +# return fire_state +# +## move_component.wants_jump() +# move_component.get_movement_direction() + +# if Input.is_action_just_pressed('dash'): +# return dash_state + return null + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + #parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if !parent.is_on_floor(): + return fall_state + return null diff --git a/src/states/enemy/jump.gd b/src/states/enemy/jump.gd new file mode 100644 index 0000000..0742ba0 --- /dev/null +++ b/src/states/enemy/jump.gd @@ -0,0 +1,47 @@ +extends State + +export (NodePath) var idle_node +export (NodePath) var fall_node +export (NodePath) var move_node + +onready var idle_state: State = get_node(idle_node) +onready var fall_state: State = get_node(fall_node) +onready var move_state: State = get_node(move_node) + + +export var jump_force: float = 900.0 + +func enter() -> void: + .enter() + parent.velocity.y = -jump_force + +func process_frame(_delta: float) -> State: + move_component.get_movement_direction() + return null + + +func process_physics(delta: float) -> State: + parent.velocity.y += gravity * delta + + if parent.velocity.y > 0: + return fall_state + + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + else: + animations.flip_h = parent.direction.x < 0 + + if parent.is_on_floor(): + if parent.velocity.x == 0: + return move_state + return idle_state + + return null diff --git a/src/states/enemy/move.gd b/src/states/enemy/move.gd new file mode 100644 index 0000000..827b966 --- /dev/null +++ b/src/states/enemy/move.gd @@ -0,0 +1,64 @@ +extends State + +export (NodePath) var jump_node +export (NodePath) var fall_node +export (NodePath) var idle_node + +onready var jump_state: State = get_node(jump_node) +onready var fall_state: State = get_node(fall_node) +onready var idle_state: State = get_node(idle_node) + +func process_frame(_delta: float) -> State: + if move_component.wants_jump() and parent.is_on_floor(): + return jump_state + + move_component.get_movement_direction() + + return null + + +func process_physics(delta: float) -> State: +# if move_component.wants_jump() and parent.is_on_floor(): +# return jump_state + + parent.velocity.y += gravity * delta + +# var movement = move_component.get_movement_direction() * move_speed +# +# # only detecting input not actual movement +# if movement == 0: +# return idle_state + +# parent.velocity.x = movement +# parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if parent.velocity.x == 0.0: + return idle_state + else: + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + if parent.direction.x < 0: + animations.offset.x = -18 + else: + animations.offset.x = 0 + else: + animations.flip_h = parent.direction.x < 0 + animations.offset.x = 0 + + + # Another approach of changing state based on actual achieved velocity +# if parent.velocity.x == 0: +# return idle_state + + if !parent.is_on_floor(): + return fall_state + return null diff --git a/src/states/enemy/wander.gd b/src/states/enemy/wander.gd new file mode 100644 index 0000000..b1d2f68 --- /dev/null +++ b/src/states/enemy/wander.gd @@ -0,0 +1,81 @@ +extends State + +export (NodePath) var jump_node +export (NodePath) var fall_node +export (NodePath) var idle_node +export (NodePath) var attack_node + +onready var jump_state: State = get_node(jump_node) +onready var fall_state: State = get_node(fall_node) +onready var idle_state: State = get_node(idle_node) +onready var attack_state: State = get_node(attack_node) + +var flip_flop = false +var move_direction_x = 1.0 + +func enter() -> void: + .enter() + parent.set_hurtbox(true) + state_timeout.start() + if flip_flop: + flip_flop = false + move_direction_x = 1.0 + else: + flip_flop = true + move_direction_x = -1.0 + +func process_frame(_delta: float) -> State: + + if parent.player_detection.is_colliding(): + return attack_state + + if state_timeout.time_left == 0: + return idle_state + +# if move_component.wants_jump() and parent.is_on_floor(): +# return jump_state +# +# move_component.get_movement_direction() + + return null + + +func process_physics(delta: float) -> State: +# if move_component.wants_jump() and parent.is_on_floor(): +# return jump_state + + parent.velocity.y += gravity * delta + +# var movement = move_component.get_movement_direction() * move_speed +# +# # only detecting input not actual movement +# if movement == 0: +# return idle_state + +# parent.velocity.x = movement +# parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + parent.velocity.x = move_direction_x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if parent.velocity.x == 0.0: + return idle_state + else: + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + if parent.direction.x < 0: + animations.offset.x = -18 + else: + animations.offset.x = 0 + else: + animations.flip_h = parent.direction.x < 0 + animations.offset.x = 0 + + if !parent.is_on_floor(): + return fall_state + return null diff --git a/state.gd b/state.gd new file mode 100644 index 0000000..3fd1ce5 --- /dev/null +++ b/state.gd @@ -0,0 +1,62 @@ +class_name State +extends Node + +export var animation_name: String +export var move_speed: float = 60 +export var timeout_seconds: float = 0.0 + +export(Array, String) var animation_sequence +var animation_index: int = 0 +var current_animation_sequence: int = 0 + +var gravity: int = ProjectSettings.get_setting("physics/2d/default_gravity") + +var animations: AnimatedSprite +var move_component: Node +var parent: KinematicBody2D + +#var animation_sequence_timer: Timer + +var state_timeout: Timer + +func _ready(): + if(timeout_seconds > 0.0): + state_timeout = Timer.new() + state_timeout.wait_time = timeout_seconds + state_timeout.one_shot = true + state_timeout.autostart = false + add_child(state_timeout) + + +func enter() -> void: + print(parent.name, " entering State: ", self.name) + if animation_name != '': + animations.play(animation_name) + elif animation_sequence.size() > 0: + animation_index = 0 + current_animation_sequence = 0 + animations.play(animation_sequence[animation_index]) + +func exit() -> void: + pass + +func process_input(_event: InputEvent) -> State: + return null + +func process_frame(_delta: float) -> State: + if animation_sequence.size() > 0 and current_animation_sequence != animation_index: + if animation_index >= animation_sequence.size(): + animation_index = 0 + animations.play(animation_sequence[animation_index]) + print("An animation sequence: ", animations.animation , animation_index) + current_animation_sequence = animation_index + return null + +func process_physics(_delta: float) -> State: + return null + +#func get_movement_input() -> float: +# return move_component.get_movement_direction() +# +#func get_jump() -> bool: +# return move_component.wants_jump() diff --git a/state_machine.gd b/state_machine.gd new file mode 100644 index 0000000..c2c64b2 --- /dev/null +++ b/state_machine.gd @@ -0,0 +1,41 @@ +extends Node + +export (NodePath) var starting_state + +var current_state: State + +# Initialize the state machine by giving each child state a reference to the +# parent object it belongs to and enter the default starting_state. +func init(parent: KinematicBody2D, animations: AnimatedSprite, move_component) -> void: + for child in get_children(): + child.parent = parent + child.animations = animations + child.move_component = move_component + + # Initialize to the default state + change_state(get_node(starting_state)) + +# Change to the new state by first calling any exit logic on the current state. +func change_state(new_state: State) -> void: + if current_state: + current_state.exit() + + current_state = new_state + current_state.enter() + +# Pass through functions for the Player to call, +# handling state changes as needed. +func process_physics(delta: float) -> void: + var new_state = current_state.process_physics(delta) + if new_state: + change_state(new_state) + +func process_input(event: InputEvent) -> void: + var new_state = current_state.process_input(event) + if new_state: + change_state(new_state) + +func process_frame(delta: float) -> void: + var new_state = current_state.process_frame(delta) + if new_state: + change_state(new_state) diff --git a/wander.gd b/wander.gd new file mode 100644 index 0000000..4d313d1 --- /dev/null +++ b/wander.gd @@ -0,0 +1,61 @@ +extends State + +export (NodePath) var jump_node +export (NodePath) var fall_node +export (NodePath) var idle_node +export (NodePath) var dash_node + +onready var jump_state: State = get_node(jump_node) +onready var fall_state: State = get_node(fall_node) +onready var idle_state: State = get_node(idle_node) +onready var dash_state: State = get_node(dash_node) + +func process_input(_event: InputEvent) -> State: + if move_component.wants_jump() and parent.is_on_floor(): + return jump_state + + move_component.get_movement_direction() + + return null + + +func process_physics(delta: float) -> State: +# if move_component.wants_jump() and parent.is_on_floor(): +# return jump_state + + parent.velocity.y += gravity * delta + +# var movement = move_component.get_movement_direction() * move_speed +# +# # only detecting input not actual movement +# if movement == 0: +# return idle_state + +# parent.velocity.x = movement +# parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + parent.velocity.x = move_component.desired_movement_vector.x * move_speed + parent.velocity = parent.move_and_slide(parent.velocity, Vector2(0, -1)) + + if parent.velocity.x == 0.0: + return idle_state + else: + if parent.velocity.x > 0: + parent.direction.x = 1 + elif parent.velocity.x < 0: + parent.direction.x = -1 + + + if move_component.flipped_sprite == true: + animations.flip_h = parent.direction.x > 0 + else: + animations.flip_h = parent.direction.x < 0 + + + # Another approach of changing state based on actual achieved velocity +# if parent.velocity.x == 0: +# return idle_state + + if !parent.is_on_floor(): + return fall_state + return null