乒乓球游戏:C++ GDExtension 实现
这个提交包含在:
@@ -0,0 +1,110 @@
|
||||
#include "pingpong_paddle.h"
|
||||
|
||||
#include <godot_cpp/core/class_db.hpp>
|
||||
#include <godot_cpp/classes/input.hpp>
|
||||
#include <godot_cpp/classes/engine.hpp>
|
||||
#include <godot_cpp/classes/node.hpp>
|
||||
#include <godot_cpp/classes/scene_tree.hpp>
|
||||
#include <godot_cpp/classes/viewport.hpp>
|
||||
|
||||
using namespace godot;
|
||||
|
||||
void PingPongPaddle::_bind_methods() {
|
||||
// 属性
|
||||
ClassDB::bind_method(D_METHOD("get_speed"), &PingPongPaddle::get_speed);
|
||||
ClassDB::bind_method(D_METHOD("set_speed", "value"), &PingPongPaddle::set_speed);
|
||||
ClassDB::add_property("PingPongPaddle", PropertyInfo(Variant::FLOAT, "speed"), "set_speed", "get_speed");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_is_player"), &PingPongPaddle::get_is_player);
|
||||
ClassDB::bind_method(D_METHOD("set_is_player", "value"), &PingPongPaddle::set_is_player);
|
||||
ClassDB::add_property("PingPongPaddle", PropertyInfo(Variant::BOOL, "is_player"), "set_is_player", "get_is_player");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_ball_path"), &PingPongPaddle::get_ball_path);
|
||||
ClassDB::bind_method(D_METHOD("set_ball_path", "value"), &PingPongPaddle::set_ball_path);
|
||||
ClassDB::add_property("PingPongPaddle", PropertyInfo(Variant::NODE_PATH, "ball_path"), "set_ball_path", "get_ball_path");
|
||||
}
|
||||
|
||||
PingPongPaddle::PingPongPaddle() {
|
||||
speed = 350.0f;
|
||||
is_player = true;
|
||||
}
|
||||
|
||||
PingPongPaddle::~PingPongPaddle() {
|
||||
}
|
||||
|
||||
void PingPongPaddle::_draw() {
|
||||
// 画一个白色矩形表示球拍
|
||||
draw_rect(Rect2(Vector2(-10.0f, -60.0f), Vector2(20.0f, 120.0f)), Color(1.0f, 1.0f, 1.0f));
|
||||
}
|
||||
|
||||
void PingPongPaddle::_physics_process(double delta) {
|
||||
queue_redraw();
|
||||
float move_amount = 0.0f;
|
||||
|
||||
if (is_player) {
|
||||
// 玩家控制:读取上下输入
|
||||
Input *input = Input::get_singleton();
|
||||
if (input->is_action_pressed("ui_up")) {
|
||||
move_amount = -1.0f;
|
||||
} else if (input->is_action_pressed("ui_down")) {
|
||||
move_amount = 1.0f;
|
||||
}
|
||||
} else {
|
||||
// AI 控制:追踪球的位置
|
||||
if (!ball_path.is_empty()) {
|
||||
Node *node = get_node_or_null(ball_path);
|
||||
if (node) {
|
||||
Node2D *ball = Object::cast_to<Node2D>(node);
|
||||
if (ball) {
|
||||
float ball_y = ball->get_global_position().y;
|
||||
float paddle_y = get_global_position().y;
|
||||
if (ball_y < paddle_y - 20.0f) {
|
||||
move_amount = -1.0f;
|
||||
} else if (ball_y > paddle_y + 20.0f) {
|
||||
move_amount = 1.0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 移动
|
||||
Vector2 velocity = Vector2(0.0f, move_amount * speed * (float)delta);
|
||||
move_and_collide(velocity);
|
||||
|
||||
// 限制移动范围(不超出屏幕)
|
||||
Viewport *viewport = get_viewport();
|
||||
if (viewport) {
|
||||
Vector2 screen_size = viewport->get_visible_rect().size;
|
||||
Vector2 pos = get_global_position();
|
||||
if (pos.y < half_height) {
|
||||
set_global_position(Vector2(pos.x, half_height));
|
||||
} else if (pos.y > screen_size.y - half_height) {
|
||||
set_global_position(Vector2(pos.x, screen_size.y - half_height));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PingPongPaddle::set_speed(float p_speed) {
|
||||
speed = p_speed;
|
||||
}
|
||||
|
||||
float PingPongPaddle::get_speed() const {
|
||||
return speed;
|
||||
}
|
||||
|
||||
void PingPongPaddle::set_is_player(bool p_is_player) {
|
||||
is_player = p_is_player;
|
||||
}
|
||||
|
||||
bool PingPongPaddle::get_is_player() const {
|
||||
return is_player;
|
||||
}
|
||||
|
||||
void PingPongPaddle::set_ball_path(const NodePath &p_path) {
|
||||
ball_path = p_path;
|
||||
}
|
||||
|
||||
NodePath PingPongPaddle::get_ball_path() const {
|
||||
return ball_path;
|
||||
}
|
||||
在新工单中引用
屏蔽一个用户