Coordinate system of get_pos() seems different from that used in node inspector, why?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By abfurrow
:warning: Old Version Published before Godot 3 was released.

I made Pong from http://docs.godotengine.org/en/stable/tutorials/step_by_step/simple_2d_game.html , using v2.1.2.stable.official on OSX El Capitan. The sprites initially show up in the positions they appear in in the scene editor, where (0,0) is the top left corner, but once the program starts objects move as if (0,0) is at the center of the window. Since the program never updates the X position of the paddles, the ball appears to sail right through them, but if you put the left paddle at just the right height you can see the ball bounce off its invisible twin at the same height but at the centerline of the screen. (Also, the ball bounces off the “top” of the screen at the midline halfway up.)

What am I missing? Was the tutorial written for an earlier version? Did I need to check a box somewhere that they didn’t specifically mention? I could just update all the math in the GDscript file to use the coordinate system the game is actually using, but it would be more fun to find out what went wrong.

Maybe you were reparenting things and some parts are locally translated, but can’t be sure, this need more details than a description, like the scene structure and local position of every node to start with something.

eons | 2017-04-11 23:26

Here’s my pong.tscn:

[gd_scene load_steps=6 format=1]

[ext_resource path="res://pong.gd" type="Script" id=1]
[ext_resource path="res://left_pallete.png" type="Texture" id=2]
[ext_resource path="res://right_pallete.png" type="Texture" id=3]
[ext_resource path="res://separator.png" type="Texture" id=4]
[ext_resource path="res://ball.png" type="Texture" id=5]

[node name="Node2D" type="Node2D"]

script/script = ExtResource( 1 )

[node name="left" type="Sprite" parent="."]

texture = ExtResource( 2 )
offset = Vector2( 67, 183 )

[node name="right" type="Sprite" parent="."]

texture = ExtResource( 3 )
offset = Vector2( 577, 187 )

[node name="separator" type="Sprite" parent="."]

texture = ExtResource( 4 )
offset = Vector2( 320, 200 )

[node name="ball" type="Sprite" parent="."]

texture = ExtResource( 5 )
offset = Vector2( 320, 188 )

engine.cfg:

[application]

name="Pong"
main_scene="res://pong.tscn"
icon="res://icon.png"

[display]

width=640
height=400

[input]

left_move_up=[key(P)]
left_move_down=[key(J)]
right_move_up=[key(G)]
right_move_down=[key(W)]

[render]

default_clear_color=#ff000000

and pong.gd, which as far as I can tell is exactly the same as in the tutorial:

extends Node2D

var screen_size
var pad_size
var direction = Vector2(1.0,0.0)

const INITIAL_BALL_SPEED = 80
var ball_speed = INITIAL_BALL_SPEED
const PAD_SPEED = 150

func _ready():
	screen_size = get_viewport_rect().size
	pad_size = get_node("left").get_texture().get_size()
	set_process(true)
	pass
	

func _process(delta):
	var ball_pos = get_node("ball").get_pos()
	var left_rect = Rect2( get_node("left").get_pos() - pad_size*0.5, pad_size )
	var right_rect = Rect2( get_node("right").get_pos() - pad_size*0.5, pad_size )
	
	ball_pos += direction * ball_speed * delta
	
	if ((ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > screen_size.y and direction.y > 0)):
		direction.y = -direction.y
	if ((left_rect.has_point(ball_pos) and direction.x < 0) or (right_rect.has_point(ball_pos) and direction.x > 0)):
		direction.x = -direction.x
		direction.y = randf()*2.0 - 1
		direction = direction.normalized()
		ball_speed *= 1.1
		
	if (ball_pos.x < 0 or ball_pos.x > screen_size.x):
		ball_pos = screen_size*0.5
		ball_speed = INITIAL_BALL_SPEED
		direction = Vector2(-1,  0)
		
	get_node("ball").set_pos(ball_pos)
	
	var left_pos = get_node("left").get_pos()
	
	if (left_pos.y > 0 and Input.is_action_pressed("left_move_up")):
		left_pos.y += -PAD_SPEED * delta
	if (left_pos.y < screen_size.y and Input.is_action_pressed("left_move_down")):
		left_pos.y += PAD_SPEED * delta
		
	get_node("left").set_pos(left_pos)
	
	var right_pos = get_node("right").get_pos()
	
	if (right_pos.y > 0 and Input.is_action_pressed("right_move_up")):
		right_pos.y += -PAD_SPEED * delta
	if (right_pos.y < screen_size.y and Input.is_action_pressed("right_move_down")):
		right_pos.y += PAD_SPEED * delta
		
	get_node("right").set_pos(right_pos)

abfurrow | 2017-04-11 23:36

:bust_in_silhouette: Reply From: eons

Now I remember, the pong example is a terrible one, I think that is being reworked by some people, also Pong could be pretty “complex” to make with modern engines (the mechanic is hard to simplify).


Ok, your scene structure is like:

Node2D [root, at (0,0)]
|-left [sprite,at (0,0) with texture offset, script]
|-right [sprite,at (0,0) with texture offset]
|-separator [sprite,at (0,0) with texture offset]
|-ball [sprite,at (0,0) with texture offset]

So, you see, the position of all your nodes are position (0,0), texture displaced on the offset value.
Your script works with the node’s position (not sprite’s texture offset) and there is where the logic could be failing.

Thanks, that is a much more complex and interesting failure mode than I imagined! I have learned something!

abfurrow | 2017-04-13 02:45