You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Godot 4.0.beta5:星场动画仅在窗口调整大小时播放

问题

游戏启动画面的星场飞向效果,第一帧绘制正常,但后续帧只有窗口被主动调整大小时才会刷新。刚从Godot 3.5.1迁移到4.0.beta5,为适配版本做了代码重构。

主节点代码

extends Node2D

const WIDTH = 1920
const HEIGHT = 1080
const STAR_COUNT = 400
const PLANET_COUNT = 5

var splash_stars = []
var theta
var offsetz
var x
var dx
var y
var dy
var radius
var alpha
var planet_scale
var color

var rng


func _ready():
    rng = RandomNumberGenerator.new()
    rng.randomize()
    
    # 初始化星场动画
    var Star = load("res://stars.gd")
    
    for _i in range(STAR_COUNT):
        theta = rng.randi()%360
        offsetz = rng.randi()%(HEIGHT -1) + 1
        x = offsetz * cos(theta) + WIDTH / 2.0
        dx = 2.5 * cos(theta)
        y = offsetz * sin(theta) + HEIGHT / 2.0
        dy = 2.5 * sin(theta)
        radius = 100 / offsetz
        alpha = 0
        var star = Star.new(theta, offsetz, x, dx, y, dy, radius, alpha)
        splash_stars.append(star)


func update_star_coords():
    for splash_star in splash_stars:
        splash_star._dx = splash_star._dx * 1.005
        splash_star._dy = splash_star._dy * 1.005
        splash_star._x += splash_star._dx
        splash_star._y += splash_star._dy
        splash_star._radius += .025
        splash_star._alpha += .005
        
        if 0 > splash_star._x or splash_star._x > WIDTH or 0 > splash_star._y or splash_star._y > HEIGHT or splash_star._radius > 8:
            splash_star._theta = rng.randi()%360
            splash_star._theta = deg_to_rad(splash_star._theta)
            splash_star._offset = rng.randi()%(HEIGHT - 1) + 1
            splash_star._x = splash_star._offset * cos(splash_star._theta) + WIDTH / 2.0
            splash_star._dx = 2.5 * cos(splash_star._theta)
            splash_star._y = splash_star._offset * sin(splash_star._theta) + HEIGHT / 2.0
            splash_star._dy = 2.5 * sin(splash_star._theta)
            splash_star._radius = 100 / splash_star._offset
            if splash_star._radius < 1:
                splash_star._radius = 1
            splash_star._alpha = 0


func _draw():
    for splash_star in splash_stars:
        var center = Vector2(splash_star._x, splash_star._y)
        color = Color(1, 1, 0, splash_star._alpha)
        draw_circle(center, splash_star._radius, color)
    

func _process(delta):
    update_star_coords()

Star类代码

extends Node2D

var _theta
var _offset
var _x
var _dx
var _y
var _dy
var _radius
var _alpha


func _init(theta,offset,x,dx,y,dy,radius,alpha):
    self._theta = theta
    self._offset = offset
    self._x = x
    self._dx = dx
    self._y = y
    self._dy = dy
    self._radius = radius
    self._alpha = alpha

修复方案

核心问题

Godot 4中,_draw()不会自动每帧触发重绘,只有节点变换、可见性改变或窗口调整时才会触发。当前代码只更新了星坐标,但没有通知引擎需要重绘,所以只有窗口调整时才会刷新画面。

修复步骤

  1. 修改_process方法,在更新坐标后调用queue_redraw()强制触发重绘:
func _process(delta):
    update_star_coords()
    queue_redraw()  # 添加此行
  1. 优化Star类:因为Star只是数据容器,不需要继承Node2D,改用Reference类更节省资源:
extends Reference

var _theta
var _offset
var _x
var _dx
var _y
var _dy
var _radius
var _alpha


func _init(theta,offset,x,dx,y,dy,radius,alpha):
    self._theta = theta
    self._offset = offset
    self._x = x
    self._dx = dx
    self._y = y
    self._dy = dy
    self._radius = radius
    self._alpha = alpha
  1. 修正角度计算:Godot 4中cos()和sin()默认接受弧度值,初始化星星时需要将角度转为弧度,否则坐标计算错误:
    在_ready的循环中添加一行:
for _i in range(STAR_COUNT):
    theta = rng.randi()%360
    theta = deg_to_rad(theta)  # 添加此行
    offsetz = rng.randi()%(HEIGHT -1) + 1
    # 后续代码不变

内容的提问来源于stack exchange,提问作者Ian McCurdy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 06:46:06