This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
+1 vote

Hello!

I'm new to game development, but have done some tutorials for 2D platformer and top down game.

I'm trying to implement a point-and-click behavior with collision objects. The main point and click movement flow is described nicely here:
https://docs.godotengine.org/en/3.1/tutorials/2d/2d_movement.html#click-and-move

I'm using it in a similar way with moveandslide, however when bringing in some collision objects the KinematicBody2D still slides on a collision object if colliding it with a definitive size greater or lower than 90 deg angle. I'd like the player(KinematicBody2D) to stop or slide it across the colliding body(wall - StaticBody2D) without slowing down gradually.

Currently I'm detecting a moveandslide collision and forcing the KinematicBody2D to moveandcollide which nicely stop the player but I'm unable to get the player away from the collision object. It's just snapped to it and can't make it back to move.

How to make a player back to move after moveandcollide stopped it with a point and click moves used in my script? I tried it with setting a new position but seems I don't know how to use the 'set_position(value)' in Node2D

Here's my script:

extends KinematicBody2D

    var speed = 200
    # original starting point for character
    var targetPos = Vector2(980, 1200)

    var velocity = Vector2()
    var distance = 0

    var floor_normal = Vector2(0, 0)
    var max_bounces = 0
    var collision
    var collided = false

    func _input(event):
        if event.is_action_pressed('click'):
            targetPos = get_global_mouse_position()
            distance = position.distance_to(targetPos)

    func _physics_process(delta):
        velocity = (targetPos - position).normalized() * speed
        movePlayer(delta)

    func movePlayer(delta):
        for i in get_slide_count():
            collision = get_slide_collision(0)

        if get_slide_count() > 0:
            collided = true
        else:
            collided = false

        if collided:
            move_and_collide(velocity * 0 * delta)
            var newPosition = Vector2(668, 1031)
            # error
            # set_position(newPosition)

        # make it move to a target position
        elif (targetPos - position).length() > 5:
            move_and_slide(velocity, floor_normal, true)

        # need to stop movement if clicking too close to a character
        elif distance < 5:
            move_and_slide(velocity * 0, floor_normal, true)
in Engine by (27 points)

Ok, I know it's a noob question, but I haven't found the good way to solve this.

Anyhow now I've implemented a solution where I just set the player's target position to current position of a player when collision (actually a slide) occurred.

It kind of does the trick but for point and click game it still feels a bit weird. Anyone can comment on that?

Modified script (the part where it says 'if slided: ' ):

extends KinematicBody2D

var speed = 200
# original starting point for character
var targetPos = Vector2(980, 1200)

var velocity = Vector2()
var distance = 0

var floor_normal = Vector2(0, 0)
var max_bounces = 0
var collision
var slided = false

func _input(event):
    if event.is_action_pressed('click'):
        targetPos = get_global_mouse_position()
        distance = position.distance_to(targetPos)

func _physics_process(delta):
    velocity = (targetPos - position).normalized() * speed
    movePlayer(delta)

func movePlayer(delta):
    for i in get_slide_count():
        # last slide detected
        collision = get_slide_collision(0)

    if get_slide_count() > 0:
        slided = true
    else:
        slided = false

    if slided:
        targetPos = position
        move_and_slide(velocity, floor_normal, true)

    # make it move to a target position
    elif (targetPos - position).length() > 5:
        move_and_slide(velocity, floor_normal, true)

    # need to stop movement if clicking too close to a character
    elif distance < 5:
        move_and_slide(velocity * 0, floor_normal, true)

You can just assign a value to the position variable:

position = Vector2(200,100)
position.x += 200
position.y = 10

etc.

Thanks!

Seems to do the trick yes. I have found that for this current point and click solution it still better to reassign current position to target position and still use moveandslide because with point and click mechanics you mostly are clicking on collisions to move the player.

KidsCanCode has made this explanation of KinematicBody2dMovement (moveandslide and moveandcollide) that is pretty good. Just if you are looking for a deeper explanation and custom reactions for collisions.

Please log in or register to answer this question.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read Frequently asked questions and How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to [email protected] with your username.