Should have done this a while ago.
2
.gitattributes
vendored
Normal file
|
|
@ -0,0 +1,2 @@
|
|||
# Normalize EOL for all files that Git considers text files.
|
||||
* text=auto eol=lf
|
||||
5
.gitignore
vendored
Normal file
|
|
@ -0,0 +1,5 @@
|
|||
# Godot 4+ specific ignores
|
||||
.godot/
|
||||
.import/
|
||||
.mono/
|
||||
addons/
|
||||
140
Enemy-KinematicBody2D.gd
Normal file
|
|
@ -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)
|
||||
159
Enemy.tscn
Normal file
|
|
@ -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"]
|
||||
76
Enemy2-KinematicBody2D.gd
Normal file
|
|
@ -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)
|
||||
257
Enemy2.tscn
Normal file
|
|
@ -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"]
|
||||
16
Floor.tscn
Normal file
|
|
@ -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 )
|
||||
47
Gun.gd
Normal file
|
|
@ -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
|
||||
98
KinematicBody2D-bak.gd
Normal file
|
|
@ -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")
|
||||
22
Main.gd
Normal file
|
|
@ -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
|
||||
179
Player-KinematicBody2D.gd
Normal file
|
|
@ -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)
|
||||
|
||||
|
||||
512
Player.tscn
Normal file
|
|
@ -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"]
|
||||
95
Position2D.gd
Normal file
|
|
@ -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)
|
||||
18
Projectile.gd
Normal file
|
|
@ -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()
|
||||
36
Projectile.tscn
Normal file
|
|
@ -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"]
|
||||
BIN
Smiley.png
Normal file
|
After Width: | Height: | Size: 508 B |
35
Smiley.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/MegaMan.png
Normal file
|
After Width: | Height: | Size: 39 KiB |
35
assets/MegaMan.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/Tiles/Assets/Assets.png
Normal file
|
After Width: | Height: | Size: 41 KiB |
35
assets/Tiles/Assets/Assets.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/Tiles/Assets/Background_1.png
Normal file
|
After Width: | Height: | Size: 3.9 KiB |
35
assets/Tiles/Assets/Background_1.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/Tiles/Assets/Background_2.png
Normal file
|
After Width: | Height: | Size: 2.3 KiB |
35
assets/Tiles/Assets/Background_2.png.import
Normal file
|
|
@ -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
|
||||
11
assets/Tiles/Autor_note.txt
Normal file
|
|
@ -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
|
||||
BIN
assets/Tiles/Social/Assets.png
Normal file
|
After Width: | Height: | Size: 750 KiB |
35
assets/Tiles/Social/Assets.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/Tiles/Social/Mine.png
Normal file
|
After Width: | Height: | Size: 52 KiB |
35
assets/Tiles/Social/Mine.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/Tiles/Social/entrance.png
Normal file
|
After Width: | Height: | Size: 55 KiB |
35
assets/Tiles/Social/entrance.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/Tiles/Social/trees.png
Normal file
|
After Width: | Height: | Size: 57 KiB |
35
assets/Tiles/Social/trees.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/botEnemy.png
Normal file
|
After Width: | Height: | Size: 11 KiB |
35
assets/botEnemy.png.import
Normal file
|
|
@ -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
|
||||
BIN
assets/bullet.png
Normal file
|
After Width: | Height: | Size: 146 B |
35
assets/bullet.png.import
Normal file
|
|
@ -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
|
||||
45
dash.gd
Normal file
|
|
@ -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
|
||||
7
default_env.tres
Normal file
|
|
@ -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 )
|
||||
46
enemy_move_component.gd
Normal file
|
|
@ -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
|
||||
42
fall.gd
Normal file
|
|
@ -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
|
||||
47
fire.gd
Normal file
|
|
@ -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
|
||||
|
||||
36
hurt.gd
Normal file
|
|
@ -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
|
||||
35
icon.png.import
Normal file
|
|
@ -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
|
||||
47
idle.gd
Normal file
|
|
@ -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
|
||||
47
jump.gd
Normal file
|
|
@ -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
|
||||
61
move.gd
Normal file
|
|
@ -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
|
||||
32
player_move_component.gd
Normal file
|
|
@ -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
|
||||
146
project.godot
Normal file
|
|
@ -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"
|
||||
17
src/singleton_autoloads/PlayerInfo.gd
Normal file
|
|
@ -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
|
||||
33
src/states/enemy/attack.gd
Normal file
|
|
@ -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)
|
||||
42
src/states/enemy/fall.gd
Normal file
|
|
@ -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
|
||||
34
src/states/enemy/hurt.gd
Normal file
|
|
@ -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
|
||||
54
src/states/enemy/idle.gd
Normal file
|
|
@ -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
|
||||
47
src/states/enemy/jump.gd
Normal file
|
|
@ -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
|
||||
64
src/states/enemy/move.gd
Normal file
|
|
@ -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
|
||||
81
src/states/enemy/wander.gd
Normal file
|
|
@ -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
|
||||
62
state.gd
Normal file
|
|
@ -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()
|
||||
41
state_machine.gd
Normal file
|
|
@ -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)
|
||||
61
wander.gd
Normal file
|
|
@ -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
|
||||