diff --git a/Main.tscn b/Main.tscn index 5362bf4..dbfd82f 100644 --- a/Main.tscn +++ b/Main.tscn @@ -1,6 +1,7 @@ -[gd_scene load_steps=18 format=2] +[gd_scene load_steps=19 format=2] [ext_resource path="res://src/playerB/Player.tscn" type="PackedScene" id=1] +[ext_resource path="res://src/playerC/Player.tscn" type="PackedScene" id=2] [ext_resource path="res://assets/Tiles/Assets/Assets.png" type="Texture" id=3] [ext_resource path="res://src/CameraControl-Position2D.gd" type="Script" id=5] [ext_resource path="res://src/enemyB/Enemy2.tscn" type="PackedScene" id=6] @@ -147,6 +148,10 @@ __meta__ = { [node name="Player" parent="." instance=ExtResource( 1 )] position = Vector2( 154, 27 ) +[node name="Player2" parent="." instance=ExtResource( 2 )] +position = Vector2( 81, 27 ) +player_number = 2 + [node name="CameraControl" type="Position2D" parent="."] process_priority = 1 script = ExtResource( 5 ) diff --git a/project.godot b/project.godot index b273654..1b693a8 100644 --- a/project.godot +++ b/project.godot @@ -15,25 +15,10 @@ _global_script_classes=[ { "path": "res://src/enemy/Enemy-KinematicBody2D.gd" }, { "base": "Reference", -"class": "Enemy2", -"language": "GDScript", -"path": "res://src/enemyB/Enemy2-KinematicBody2D.gd" -}, { -"base": "Position2D", -"class": "Gun", -"language": "GDScript", -"path": "res://src/playerB/Gun.gd" -}, { -"base": "Reference", "class": "Movement", "language": "GDScript", "path": "res://src/playerB/player_move_component.gd" }, { -"base": "Reference", -"class": "Player", -"language": "GDScript", -"path": "res://src/playerB/Player-KinematicBody2D.gd" -}, { "base": "Node", "class": "State", "language": "GDScript", @@ -41,10 +26,7 @@ _global_script_classes=[ { } ] _global_script_class_icons={ "Enemy": "", -"Enemy2": "", -"Gun": "", "Movement": "", -"Player": "", "State": "" } diff --git a/src/enemyB/Enemy2-KinematicBody2D.gd b/src/enemyB/Enemy2-KinematicBody2D.gd index 5fccf6d..c4d7a76 100644 --- a/src/enemyB/Enemy2-KinematicBody2D.gd +++ b/src/enemyB/Enemy2-KinematicBody2D.gd @@ -1,4 +1,4 @@ -class_name Enemy2 extends KinematicBody2D +extends KinematicBody2D var velocity = Vector2(0,0) var direction = Vector2(1,0) diff --git a/src/enemyB/Enemy2.tscn b/src/enemyB/Enemy2.tscn index 7ffb66f..2038f30 100644 --- a/src/enemyB/Enemy2.tscn +++ b/src/enemyB/Enemy2.tscn @@ -132,7 +132,7 @@ script = ExtResource( 1 ) position = Vector2( 8, -8 ) frames = SubResource( 168 ) animation = "idle" -frame = 2 +frame = 1 playing = true flip_h = true __meta__ = { diff --git a/src/playerB/Gun.gd b/src/playerB/Gun.gd index cc1abac..90af6ed 100644 --- a/src/playerB/Gun.gd +++ b/src/playerB/Gun.gd @@ -1,4 +1,3 @@ -class_name Gun extends Position2D # Represents a weapon that spawns and shoots bullets. # The Cooldown timer controls the cooldown duration between shots. diff --git a/src/playerB/Player-KinematicBody2D.gd b/src/playerB/Player-KinematicBody2D.gd index 5188c12..79df14b 100644 --- a/src/playerB/Player-KinematicBody2D.gd +++ b/src/playerB/Player-KinematicBody2D.gd @@ -1,4 +1,4 @@ -class_name Player extends KinematicBody2D +extends KinematicBody2D var velocity = Vector2(0,0) var direction = Vector2(0,0) diff --git a/src/playerB/Player.tscn b/src/playerB/Player.tscn index 4b98764..4ce7d36 100644 --- a/src/playerB/Player.tscn +++ b/src/playerB/Player.tscn @@ -409,7 +409,7 @@ script = ExtResource( 1 ) [node name="AnimatedSprite" type="AnimatedSprite" parent="."] frames = SubResource( 147 ) animation = "idle" -frame = 13 +frame = 20 playing = true flip_h = true __meta__ = { diff --git a/src/playerC/Gun.gd b/src/playerC/Gun.gd new file mode 100644 index 0000000..90af6ed --- /dev/null +++ b/src/playerC/Gun.gd @@ -0,0 +1,46 @@ +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://src/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/src/playerC/Player-KinematicBody2D.gd b/src/playerC/Player-KinematicBody2D.gd new file mode 100644 index 0000000..79df14b --- /dev/null +++ b/src/playerC/Player-KinematicBody2D.gd @@ -0,0 +1,179 @@ +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/src/playerC/Player.tscn b/src/playerC/Player.tscn new file mode 100644 index 0000000..9806bbf --- /dev/null +++ b/src/playerC/Player.tscn @@ -0,0 +1,512 @@ +[gd_scene load_steps=86 format=2] + +[ext_resource path="res://src/playerC/Player-KinematicBody2D.gd" type="Script" id=1] +[ext_resource path="res://src/playerC/states/idle.gd" type="Script" id=2] +[ext_resource path="res://src/state_machine.gd" type="Script" id=3] +[ext_resource path="res://src/playerC/states/fall.gd" type="Script" id=4] +[ext_resource path="res://src/playerC/states/move.gd" type="Script" id=5] +[ext_resource path="res://src/playerB/player_move_component.gd" type="Script" id=6] +[ext_resource path="res://src/playerC/states/jump.gd" type="Script" id=7] +[ext_resource path="res://src/playerC/states/hurt.gd" type="Script" id=8] +[ext_resource path="res://src/playerC/Gun.gd" type="Script" id=9] +[ext_resource path="res://src/playerC/states/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 = 26 +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/src/playerC/states/dash.gd b/src/playerC/states/dash.gd new file mode 100644 index 0000000..f71787f --- /dev/null +++ b/src/playerC/states/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/src/playerC/states/fall.gd b/src/playerC/states/fall.gd new file mode 100644 index 0000000..77dc706 --- /dev/null +++ b/src/playerC/states/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/src/playerC/states/fire.gd b/src/playerC/states/fire.gd new file mode 100644 index 0000000..4f24349 --- /dev/null +++ b/src/playerC/states/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/src/playerC/states/hurt.gd b/src/playerC/states/hurt.gd new file mode 100644 index 0000000..e58c070 --- /dev/null +++ b/src/playerC/states/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/src/playerC/states/idle.gd b/src/playerC/states/idle.gd new file mode 100644 index 0000000..739298d --- /dev/null +++ b/src/playerC/states/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/src/playerC/states/jump.gd b/src/playerC/states/jump.gd new file mode 100644 index 0000000..92e170d --- /dev/null +++ b/src/playerC/states/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/src/playerC/states/move.gd b/src/playerC/states/move.gd new file mode 100644 index 0000000..4d313d1 --- /dev/null +++ b/src/playerC/states/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