I am making a mix of open world and roguelike... Players go from the overworld into a dungeon.
I'm trying to figure out how to manage the turns and deal with the player input that is in the player script.
I've gotten a little bit further than I was before (Thanks fire7side). I haven't quite figured out where to use signals. I feel like my code is a mess already and needs a cleanup. I'm stuck again as when I try to move my character in the dungeon sometimes it'll move the full tilesize, sometimes it'll only move a pixel. The turns also don't alternate sometimes it'll do the player a few times in a row or the enemy a few times.
This is my player code:
extends KinematicBody2D
class_name Player
# MOVEMENT STUFF
const SPEED = 4
const TILESIZE = 16
var speed_buff = 1
var initial_position = Vector2.ZERO
var input_direction = Vector2.ZERO
var is_moving = false
var percent_moved_to_next_tile = 0.0
# COLLISION STUFF
onready var ray = $RayCast2D
# STATE MACHINE STUFF
enum {
IDLE, MOVE
}
var state = MOVE
func _ready():
initial_position = position
if Global.world_position != null:
position = Global.world_position
func _physics_process(delta):
match state:
MOVE:
if Global.dungeon_active == false:
move_state(delta)
IDLE:
idle_state(delta)
func move_state(delta):
if is_moving == false:
process_player_input()
elif input_direction != Vector2.ZERO:
move(delta)
else:
is_moving = true
func idle_state(delta):
pass
func process_player_input():
if input_direction.y == 0:
input_direction.x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
if input_direction.x == 0:
input_direction.y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
if input_direction != Vector2.ZERO:
initial_position = position
is_moving = true
func move(delta):
var desired_step: Vector2 = input_direction * TILESIZE / 2
ray.cast_to = desired_step
ray.force_raycast_update()
if !ray.is_colliding():
percent_moved_to_next_tile += SPEED * delta
if percent_moved_to_next_tile >= 1.0:
position = initial_position + (TILESIZE * input_direction)
percent_moved_to_next_tile = 0.0
is_moving = false
else:
position = initial_position + (TILESIZE * input_direction * percent_moved_to_next_tile)
else:
var object_collided_with = ray.get_collider()
if object_collided_with.is_in_group("Enemy") == true:
print("Ouch!")
is_moving = false
# SEE IF ENEMY
func play_turn(event):
if event.is_action_pressed("ui_up") or Input.is_action_pressed("ui_right") or Input.is_action_pressed("ui_down") or Input.is_action_pressed("ui_left"):
process_player_input()
move(self.get_process_delta_time())
else:
return
This is my dungeon code:
extends Node2D
const Player = preload("res://Player/Player.tscn")
const Exit = preload("res://ExitDoor.tscn")
const Enemy = preload("res://Enemies/Enemy.tscn")
onready var player = Player.instance()
onready var enemy = Enemy.instance()
enum {
IDLE, MOVE
}
var player_turn = true
var borders = Rect2(1, 1, 29, 15)
onready var tileMap = $TileMap
func _ready():
randomize()
generate_level()
Global.dungeon_active = true
func generate_level():
var walker = Walker.new(Vector2(15,8), borders)
var map = walker.walk(300)
add_child(player)
player.position = map.front() * 32
var exit = Exit.instance()
add_child(exit)
exit.position = walker.rooms.back().position * 32
add_child(enemy)
enemy.position = walker.rooms[3].position * 32
walker.queue_free()
for location in map:
tileMap.set_cellv(location, -1)
tileMap.update_bitmask_region(borders.position, borders.end)
func _input(event):
if player_turn:
player.play_turn(event)
end_turn()
else:
enemy.enemy_turn()
end_turn()
func end_turn():
var t = Timer.new()
t.set_wait_time(3)
t.set_one_shot(true)
self.add_child(t)
t.start()
yield(t, "timeout")
t.queue_free()
player_turn = !player_turn