1
votes

I was able to make a good assembly of what is happening and killing me for weeks, and I really wanted to know if it was my mistake or just the keys pressed too fast, or the rendering delayed? to deal with the problem, because I'm not finding the culprit for doing so.

This happens when for example I go from diagonal down-rigth to left, and right, then I go back down, I make moves like that, fast, it does not always happen, but enough to disrupt the game.

enter image description here

Movement Script:

extends KinematicBody2D

var velocity = 150
var direction = Vector2()

func _ready():
    set_fixed_process(true)

func _fixed_process(delta):
#-----------MOVIMENT-------------------------------
    direction = Vector2()
    #LEFT
    if Input.is_action_pressed("left"):
        direction += Vector2(-1, 0)
    #RIGHT
    elif Input.is_action_pressed("right"):
        direction += Vector2(1, 0)
    #UṔ
    if Input.is_action_pressed("up"):
        direction += Vector2(0, -1)
    #DOWN
    elif Input.is_action_pressed("down"):
        direction += Vector2(0, 1)

    if direction.x != 0 || direction.y != 0:
        direction = direction.normalized()*velocity
        move(direction*delta)

Paint Script:

extends Control

var map_size = 64
var preScriptUtils = preload("res://scripts/utils_fuctions.gd")
var utils_functions

onready var player = $"../Player"
onready var tile_map = $"../TileMap"
var posTileMap = Vector2()
var posWorld = Vector2()
var prevRect = Rect2()
var newRect = Rect2()

var distance_gen = 2048
var positionMap_rect = 0
var size_rectMap = 0

func _ready():
    utils_functions = preScriptUtils.utils_functions.new()
    set_fixed_process(true)
    posWorld = Vector2(0, 0)
    positionMap_rect = ((distance_gen/32)/2)
    size_rectMap = distance_gen/32
    surround_map(posWorld)

func _fixed_process(delta):
    var posPlayer = player.get_position()

    posTileMap = tile_map.world_to_map(posPlayer) - Vector2(positionMap_rect, positionMap_rect)
    newRect = Rect2(tile_map.map_to_world(posTileMap), Vector2(distance_gen, distance_gen))
    if prevRect.position != newRect.position:
        load_newMap()

func gen_data(var _posWorld=Vector2(0, 0), var _posTileMap=Vector2(0, 0), var size=Vector2(0, 0)):
    var x = 0
    var y = 0
    var pos_modx = 0
    var pos_mody = 0
    while  x < size.x:
        y = 0
        pos_modx = utils_functions.mod(_posWorld.x + x, map_size)
            #NOISE
            var result_noise
        while y < size.y:
            pos_mody = utils_functions.mod(_posWorld.y + y, map_size)
            if (pos_modx >= 0 && pos_mody >= 0) && (pos_modx < map_size && pos_mody < map_size):
                tile_map.set_cell(_posTileMap.x + x, _posTileMap.y + y, biomes(result_noise))
            y += 1
        x += 1

func load_newMap():
    var rectIntersection = newRect.clip(prevRect)
    var _x = 0
    var _y = 0
    #LEFT
    if player.direction.x < 0:
        if int((newRect.size.x - rectIntersection.size.x)/32) == 1:
            _x = int(newRect.position.x/32)
            _y = int(rectIntersection.position.y/32)
            posWorld.x -= 1
            gen_data(Vector2(posWorld.x, posWorld.y), Vector2(_x, _y), Vector2(1, size_rectMap))
    #RIGHT
    elif player.direction.x > 0:
        if int((newRect.size.x - rectIntersection.size.x)/32) == 1:
            _x = int(rectIntersection.end.x/32)
            _y = int(rectIntersection.position.y/32)
            posWorld.x += 1
            Vector2(_x, _y)
            gen_data(Vector2(posWorld.x - 1, posWorld.y), Vector2(_x, _y), Vector2(1, size_rectMap))
    #UP
    if player.direction.y < 0:
        if int((newRect.size.y - rectIntersection.size.y)/32) == 1:
            _x = int(newRect.position.x/32)
            _y = int(newRect.position.y/32)
            posWorld.y -= 1
            gen_data(Vector2(posWorld.x, posWorld.y), Vector2(_x, _y), Vector2(size_rectMap, 1))
    #DOWN
    elif player.direction.y > 0:
        if int((newRect.size.y - rectIntersection.size.y)/32) == 1:
            _x = int(rectIntersection.position.x/32)
            _y = int(rectIntersection.end.y/32)
            posWorld.y += 1
            gen_data(Vector2(posWorld.x, posWorld.y - 1), Vector2(_x, _y), Vector2(size_rectMap, 1))
    prevRect = newRect

func surround_map(var _posWorld=Vector2(0, 0)):
    posTileMap = - Vector2(positionMap_rect, positionMap_rect)
    prevRect = Rect2(tile_map.map_to_world(posTileMap), Vector2(distance_gen, distance_gen))
    gen_data(_posWorld, Vector2(-32, -32), Vector2(64, 64))

Do not be fussed with the codes, it's very simple what I'm trying to do, I want to move the player while I generate my world, it works perfectly in the 4 directions, but when it involves the diagonals, it does not go as expected. I'm painting like this, I have two rects that I compare to each frame, I take the retagunlo of the interception and calculate where I should paint or erase.

enter image description here

Video of what is happening:

http://www.dailymotion.com/video/x6286px

But there are these flaws not only by pressing too fast, it also happens in slow motion, while being diagonally down-right and then left or left-right and then back to right, moving on the diagonals seems to be the problem, I've tried a lot of shapes, I have almost a notebook all scribble trying to figure this out, I tried with diagonal checks too and I get the same result, today I lost another day, and it does not leave the place, I'm weeks like this, when I think I fixed it, not really.

I'm using godot.

Up 1:

With @Ryan1729 response I realized that I was really thinking the wrong way, but I try to fix my logic by doing something like below and the error continues, I'm confused:

if direction.x != 0 || direction.y != 0:
        var vetor_normalized = direction.normalized()
        if abs(vetor_normalized.x) < 1 && abs(vetor_normalized.y) < 1:
            var vx = Vector2(direction.x, 0)
            var vy = Vector2(0, direction.y)
            vx = vx.normalized()*velocity
            move(vx*delta)
            vy = vy.normalized()*velocity
            move(vy*delta)

        else:
            direction = direction.normalized()*velocity
            move(direction*delta)

Up2:

Now I have done so, it seems that solved the flaws, but others appeared, which I still do not understand, this issue of 0 confuses me too much.

  var oldPosWorld = Vector2(0, 0)
  var rect_tileMap = Vector2(-32, -32) 

func load_newMap():
 var posPlayer = Vector2(int(player.get_position().x/32), int(player.get_position().y/32))
    #LEFT
    if posPlayer.x < oldPosWorld.x:
            pos_tileMap.x -= 1
            posWorld.x -= 1
            gen_data(Vector2(posWorld.x, posWorld.y), Vector2(pos_tileMap.x, pos_tileMap.y), Vector2(1, size_rectMap))
    #RIGHT
    elif posPlayer.x > oldPosWorld.x:
            pos_tileMap.x += 1
            posWorld.x += 1
            gen_data(Vector2(posWorld.x - 1, posWorld.y), Vector2(pos_tileMap.x + 63, pos_tileMap.y), Vector2(1, size_rectMap))
    #UP
    if posPlayer.y < oldPosWorld.y:
            pos_tileMap.y -= 1
            posWorld.y -= 1
            gen_data(Vector2(posWorld.x, posWorld.y), Vector2(pos_tileMap.x, pos_tileMap.y), Vector2(size_rectMap, 1))
    #DOWN
    elif posPlayer.y > oldPosWorld.y:
            pos_tileMap.y += 1
            posWorld.y += 1
            gen_data(Vector2(posWorld.x, posWorld.y - 1), Vector2(pos_tileMap.x, pos_tileMap.y + 63), Vector2(size_rectMap, 1))

oldPosWorld = posPlayer

enter image description here

enter image description here

The movements of the right and bottom are right, the problem is those of the left and above that is left over this empty space(ie dealing with the negatives ).

If I put x - 1 on the left to solve the problem, this happens to me:

enter image description here

I solved this by changing:

var posPlayer = Vector2(int(player.get_position().x/32), int(player.get_position().y/32))

by checks like this:

if ((player.get_position().x)/32)

but now I get this by going to the sides and then up:

enter image description here

Up 3:

I'm not going to put my mind to it, so as not to get frustrated if I'm mistaken, but by the tests I did the failure stopped. The code would look like this by assigning int (player.get_position (). X / 32) separately to oldPosWorld.x, this respectively for y as well, since before I was assigning the position to the player only once the postPlayer variable, this caused errors , when you entered the up-down if, as it was still with the previous position of x, doing so updates everything in its right time.

is still so to the left and up:

enter image description here

I do not quite understand why, and frankly not so soon will I know, I'm too tired to look at it. But I'd like to understand not to err. Apart from this it seems to be happening now as expected.

#LEFT
if int(player.get_position().x/32) < oldPosWorld.x:
            rect_tileMap.x -= 1
            posWorld.x -= 1
            gen_data(Vector2(posWorld.x, posWorld.y), Vector2(rect_tileMap.x, rect_tileMap.y), Vector2(1, size_rectMap))
            oldPosWorld.x = int(player.get_position().x/32)
2

2 Answers

1
votes

I think that the problem is that you want discrete movement (moving up and right moves 1 up and 1 right) but you're normalizing the vector to length 1 in the first code snippet. In the non-diagonal cases this does nothing because the vectors are length 1 already. But in the diagonal cases the vector is length sqrt(2) before normalization, (you can use the Pythagorean theorem to show this.) So your vector is getting shrunk down to something like Vector2(sqrt(2)/2, sqrt(2)/2)), (sqrt(2)/2 is about 0.707,) which causes the painting offset.

Edit: My best guess now is that the problem is that you are calling gen_data twice when the player moves diagonally. I think you want to figure out the x and y offsets then redraw the map.

0
votes

Summarizing the error was in the update(which in the case would be oldPosWorld), because they were two blocks of ifs, I would enter one after another, and without updating the position, paints the wrong way because it is in a late position:

Video working:

http://www.dailymotion.com/video/x62e6l9