带宽测试
这个提交包含在:
+79
-23
@@ -11,12 +11,24 @@
|
||||
|
||||
using namespace godot;
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// 视觉颜色常量 — 以后替换素材时删除本段
|
||||
// ═══════════════════════════════════════════════════════
|
||||
static const Color BALL_COLOR = Color(1.0f, 1.0f, 1.0f);
|
||||
|
||||
void PingPongBall::_bind_methods() {
|
||||
// 属性
|
||||
ClassDB::bind_method(D_METHOD("get_speed"), &PingPongBall::get_speed);
|
||||
ClassDB::bind_method(D_METHOD("set_speed", "value"), &PingPongBall::set_speed);
|
||||
ClassDB::add_property("PingPongBall", PropertyInfo(Variant::FLOAT, "speed"), "set_speed", "get_speed");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_initial_speed"), &PingPongBall::get_initial_speed);
|
||||
ClassDB::bind_method(D_METHOD("set_initial_speed", "value"), &PingPongBall::set_initial_speed);
|
||||
ClassDB::add_property("PingPongBall", PropertyInfo(Variant::FLOAT, "initial_speed"), "set_initial_speed", "get_initial_speed");
|
||||
|
||||
ClassDB::bind_method(D_METHOD("get_active"), &PingPongBall::get_active);
|
||||
ClassDB::bind_method(D_METHOD("set_active", "value"), &PingPongBall::set_active);
|
||||
|
||||
// 方法
|
||||
ClassDB::bind_method(D_METHOD("reset"), &PingPongBall::reset);
|
||||
|
||||
@@ -25,7 +37,9 @@ void PingPongBall::_bind_methods() {
|
||||
}
|
||||
|
||||
PingPongBall::PingPongBall() {
|
||||
speed = 400.0f;
|
||||
speed = 350.0f;
|
||||
initial_speed = 350.0f;
|
||||
is_active = false;
|
||||
}
|
||||
|
||||
PingPongBall::~PingPongBall() {
|
||||
@@ -35,78 +49,98 @@ void PingPongBall::_ready() {
|
||||
reset();
|
||||
}
|
||||
|
||||
// ═══════════════════════════════════════════════════════
|
||||
// 视觉层 — 球体 + 拖尾(几何体占位)
|
||||
// 替换方法:删除本方法 → 添加 Sprite2D 子节点
|
||||
// ═══════════════════════════════════════════════════════
|
||||
void PingPongBall::_draw() {
|
||||
// 画一个白色圆形表示球
|
||||
draw_circle(Vector2(0.0f, 0.0f), 12.0f, Color(1.0f, 1.0f, 1.0f));
|
||||
// 拖尾:从旧到新画渐隐圆
|
||||
int trail_count = (int)trail_positions.size();
|
||||
for (int i = 0; i < trail_count; i++) {
|
||||
float alpha = (float)(i + 1) / (float)BALL_TRAIL_LENGTH * 0.3f;
|
||||
float radius = BALL_RADIUS * (0.5f + 0.5f * (float)(i + 1) / (float)BALL_TRAIL_LENGTH);
|
||||
draw_circle(trail_positions[i], radius, Color(1.0f, 1.0f, 1.0f, alpha));
|
||||
}
|
||||
|
||||
// 球本体
|
||||
draw_circle(Vector2(0.0f, 0.0f), BALL_RADIUS, BALL_COLOR);
|
||||
}
|
||||
|
||||
void PingPongBall::_physics_process(double delta) {
|
||||
queue_redraw();
|
||||
|
||||
if (!is_active) {
|
||||
return;
|
||||
}
|
||||
|
||||
// 更新拖尾
|
||||
trail_positions.push_back(get_position());
|
||||
if ((int)trail_positions.size() > BALL_TRAIL_LENGTH) {
|
||||
trail_positions.erase(trail_positions.begin());
|
||||
}
|
||||
|
||||
Vector2 velocity = direction * speed * (float)delta;
|
||||
|
||||
Ref<KinematicCollision2D> collision = move_and_collide(velocity);
|
||||
|
||||
if (collision.is_valid()) {
|
||||
// 计算反弹方向
|
||||
Vector2 normal = collision->get_normal();
|
||||
direction = direction.bounce(normal);
|
||||
|
||||
// 根据碰撞法线判断碰撞对象类型
|
||||
// 法线主要水平 → 碰到球拍(左右反弹)
|
||||
// 法线主要垂直 → 碰到上下墙(上下反弹)
|
||||
// 如果法线接近水平且球已经接近左右边界 → 得分
|
||||
Object *collider = collision->get_collider();
|
||||
if (collider) {
|
||||
Node *collider_node = Object::cast_to<Node>(collider);
|
||||
if (collider_node) {
|
||||
StringName node_name = collider_node->get_name();
|
||||
// 判断是不是球拍(球拍名字包含 "Paddle")
|
||||
// 碰到球拍
|
||||
if (node_name.find("Paddle") != -1) {
|
||||
// 碰到球拍,微调角度(根据击中位置)
|
||||
Node2D *collider_2d = Object::cast_to<Node2D>(collider_node);
|
||||
if (collider_2d) {
|
||||
// 根据击中位置微调角度
|
||||
float hit_offset = (get_global_position().y - collider_2d->get_global_position().y) / 60.0f;
|
||||
hit_offset = CLAMP(hit_offset, -1.0f, 1.0f);
|
||||
direction.y += hit_offset * 0.5f;
|
||||
direction = direction.normalized();
|
||||
|
||||
// 速度递增
|
||||
speed *= BALL_SPEED_INCREMENT;
|
||||
if (speed > BALL_MAX_SPEED) {
|
||||
speed = BALL_MAX_SPEED;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 确保方向始终有效
|
||||
direction = direction.normalized();
|
||||
}
|
||||
|
||||
// 检测是否出界(得分判定)
|
||||
// 得分判定
|
||||
Viewport *viewport = get_viewport();
|
||||
if (viewport) {
|
||||
Vector2 screen_size = viewport->get_visible_rect().size;
|
||||
Vector2 pos = get_global_position();
|
||||
|
||||
if (pos.x < -50.0f) {
|
||||
// 球从左边出界,右边得分
|
||||
emit_signal("scored", 1);
|
||||
reset();
|
||||
} else if (pos.x > screen_size.x + 50.0f) {
|
||||
// 球从右边出界,左边得分
|
||||
emit_signal("scored", 0);
|
||||
reset();
|
||||
}
|
||||
|
||||
// Y 方向边界限制(防止飞出屏幕)
|
||||
if (pos.y < 0.0f) {
|
||||
set_global_position(Vector2(pos.x, 0.0f));
|
||||
// Y 边界限制
|
||||
if (pos.y < BALL_RADIUS) {
|
||||
set_global_position(Vector2(pos.x, BALL_RADIUS));
|
||||
direction.y = std::abs(direction.y);
|
||||
} else if (pos.y > screen_size.y) {
|
||||
set_global_position(Vector2(pos.x, screen_size.y));
|
||||
} else if (pos.y > screen_size.y - BALL_RADIUS) {
|
||||
set_global_position(Vector2(pos.x, screen_size.y - BALL_RADIUS));
|
||||
direction.y = -std::abs(direction.y);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void PingPongBall::reset() {
|
||||
// 回到屏幕中央
|
||||
Viewport *viewport = get_viewport();
|
||||
if (viewport) {
|
||||
Vector2 screen_size = viewport->get_visible_rect().size;
|
||||
@@ -115,18 +149,32 @@ void PingPongBall::reset() {
|
||||
set_global_position(Vector2(640.0f, 360.0f));
|
||||
}
|
||||
|
||||
// 随机方向(-45° 到 45° 之间,向左或向右随机)
|
||||
float angle = (UtilityFunctions::randf() - 0.5f) * Math_PI / 2.0f; // -45° ~ 45°
|
||||
// 重置速度
|
||||
speed = initial_speed;
|
||||
|
||||
// 清空拖尾
|
||||
trail_positions.clear();
|
||||
|
||||
// 随机方向
|
||||
float angle = (UtilityFunctions::randf() - 0.5f) * Math_PI / 2.0f;
|
||||
int side = (UtilityFunctions::randf() > 0.5f) ? 1 : -1;
|
||||
direction = Vector2((float)side * std::cos(angle), std::sin(angle)).normalized();
|
||||
|
||||
// 确保水平分量足够(避免球过于垂直)
|
||||
// 确保水平分量足够
|
||||
if (std::abs(direction.x) < 0.3f) {
|
||||
direction.x = (direction.x > 0 ? 1.0f : -1.0f) * 0.3f;
|
||||
direction = direction.normalized();
|
||||
}
|
||||
}
|
||||
|
||||
void PingPongBall::set_active(bool p_active) {
|
||||
is_active = p_active;
|
||||
}
|
||||
|
||||
bool PingPongBall::get_active() const {
|
||||
return is_active;
|
||||
}
|
||||
|
||||
void PingPongBall::set_speed(float p_speed) {
|
||||
speed = p_speed;
|
||||
}
|
||||
@@ -134,3 +182,11 @@ void PingPongBall::set_speed(float p_speed) {
|
||||
float PingPongBall::get_speed() const {
|
||||
return speed;
|
||||
}
|
||||
|
||||
void PingPongBall::set_initial_speed(float p_speed) {
|
||||
initial_speed = p_speed;
|
||||
}
|
||||
|
||||
float PingPongBall::get_initial_speed() const {
|
||||
return initial_speed;
|
||||
}
|
||||
|
||||
在新工单中引用
屏蔽一个用户