
我会向你展示如何制作传奇游戏《乒乓球》。 场景设置 游戏分辨率将为640 x 400像素。这可以在项目设置中进行配置。标准背景颜色应为黑色:

在项目根目录创建Node2D节点。Node2D是2D引擎的基础类型。然后为左右球拍、分隔线和球添加精灵(Sprite节点)。你可以为每个节点自定义名称,并在检查器中为每个精灵指定图片。

设置节点位置: “left”节点:(67, 183) “right”节点:(57, 187) “separator”节点:(320, 200) “ball”节点:(320, 188) 上述操作的结果应大致如下【球在中心!】

将此场景保存为“pong.tscn”并在项目设置中将其指定为主场景。 设置动作响应 玩游戏可以使用不同的输入设备:键盘、鼠标、游戏手柄、摇杆、触摸屏等。在Godot中可以使用所有这些设备。无论如何,将输入数据定义为【Input Actions】比将其定义为设备操作并单独控制它们更有趣。因此,任何输入方法都只能通过将按键绑定到您在游戏中定义的操作来使用。 这是《乒乓球》。我们唯一需要的操作就是球拍的上下移动。 再次打开项目设置,但这次请进入“Input Map”(输入映射)选项卡。 在该选项卡中添加4个操作:【left_move_up】、【left_move_down】、【right_move_up】、【right_move_down】。请自行设置按键。A/Z(左侧玩家)和上/下(右侧玩家)在大多数情况下适用。

Код Создайте скрипт для главного узла сцены и откройте его (это показано в Добавление Скрипта). Этот скрипт наследует Node2D: 引用自 Script: extends Node2D func _ready(): passСначала нам нужно определить переменные, в которых мы будем хранить нужные значения. Такие как размер экрана, ракетки и начальное направление мячика 引用自 Script: extends Node2D # Member variables var screen_size var pad_size var direction = Vector2(1.0, 0.0) func _ready(): pass_ready() функция - первая функция, которая будет вызвана (после_enter_tree(),которая нам тут не нужна). В ней будут сделаны две вещи. Первая - начать обработку, это цель set_process(true) функции. Вторая - назначить две наши переменные. 引用自 Script:extends Node2D # Member variables var screen_size var pad_size var direction = Vector2(1.0, 0.0) func _ready(): screen_size = get_viewport_rect().size pad_size = get_node("left").get_texture().get_size() set_process(true)Мы назначили pad_size переменную, запросив одну из ракеток (здесь левая), и получив размер ее спрайта. screen_sizeназначается при помощи вызова get_viewport_rect() , которая возвращает Rect объект, содержащий прямоугольник по размерам окна. Теперь нам нужно добавить чуть больше переменных для того, чтобы заставить наш мячик двигаться. 引用自 Script:extends Node2D # Member variables var screen_size var pad_size var direction = Vector2(1.0, 0.0) # Constant for ball speed (in pixels/second) const INITIAL_BALL_SPEED = 80 # Speed of the ball (also in pixels/second) var ball_speed = INITIAL_BALL_SPEED # Constant for pads 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)Итак, функция _process(). Весь код ниже находится в этой функции. Мы создали несколько полезных переменных для вычислений. Первая - позиция мячика(из узла), вторая и третья - прямоугольники(Rect2) для каждой ракетки. Эти прямоугольники будут использоваться для обнаружения столкновений между мячиком и ракетками. Для корректировки центров спрайтов ракеток должен быть добавлен pad_size / 2 : 引用自 Script: 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 )Теперь, давайте добавим немного движения в функцию _process(). С того момента, как позиция мячика находится в переменной ball_pos, сделать это проще простого: 引用自 Script:# Integrate new ball position ball_pos += direction * ball_speed * deltaЭта строка вызывается на каждой итерации функции _process(). Это значит, что позиция мячика будет обновляться каждый кадр. Теперь, когда у мячика новое положение, нам нужно проверить, не соприкасается ли он с чем либо. Это будут рамки окна и ракетки, но для начала верхнее и нижнее ограничение: 引用自 SOSAL?: # Flip when touching roof or floor if ((ball_pos.y < 0 and direction.y < 0) or (ball_pos.y > screen_size.y and direction.y > 0)): direction.y = -direction.yПотом ракетки. Если мячик соприкоснулся с ракеткой, нам нужно изменить его направление по оси Х, чтобы он двигался обратно, и выбрать случайное направление по Y, используя функцию randf() . Также нам нужно немного увеличить скорость мячика: 引用自 author: # Flip, change direction and increase speed when touching pads 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Наконец, если мячик вышел за пределы экрана, игра заканчивается. То есть мы проверяем позицию мячика по X, меньше она нуля или больше величины экрана. Это так, то игра перезапускается : 引用自 author: # Check gameover 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)Как только все будет сделано, узел обновится с новым положением мячика, которое было рассчитано до этого: 引用自 author: get_node("ball").set_pos(ball_pos) Теперь, мы позволим ракеткам двигаться. Просто обновим их позицию, используя вводные данные игрока: 引用自 author:# Move left pad 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) # Move right pad 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)Мы используем четыре действия, которые мы определили с вами ранее в разделе Настройка действия. Когда игрок нажимает соответствующую кнопку на клавиатуре, действие срабатывает. Как только это происходит, мы просто вычисляем новое положение для ракетки в нужном направлении и применяем его к узлу. Вот и все, мы сделали игру PingPong за несколько строчек кода ! Конец и подержка Вот я сделал рукаводство ну я проверял своё рукаводство и всё работает (новерное будут руководства у меня по онлайну с друзьями) И НЕ ЗАБЫВАЙТЕ О ПОДЕРЖКУ АВТОРУ можно лайк поставить или очки стима подарить или даже можно подарить игру 0-0
2026-02-14 16:00:13 发布在
Godot Engine
说点好听的...
收藏
0
0
