0 votes

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.

in Engine by (15 points)

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.

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)

1 Answer

0 votes
Best answer

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.

by (7,898 points)
selected by

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

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 webmaster@godotengine.org with your username.