The code in the documentation and the code that you posted is misleading.
canvas_item = load("res://icon.png")
The documentation names this variable "sprite". It is neither a CanvasItem nor a Sprite. By calling get_class(),
canvas_item = load("res://icon.png")
print(canvas_item.get_class())
we can see that it is a StreamTexture. To make the code easier to understand, I recommend renaming it to texture.
var texture
func _body_moved(state, index):
VisualServer.canvas_item_set_transform(texture, state.transform)
func _ready():
# create sprite
var ci_rid = VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
texture = load("res://icon.png")
VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(texture.get_size() / 2, texture.get_size()), texture)
Now, the problem is more apparent. VisualServer.canvasitemset_transform takes a CanvasItem's RID as its first argument, but we're giving it a StreamTexture. We can fix this by making ci_rid a member variable. Here's what the code looked like when I was done with it:
extends Node2D
var body
var shape
var texture
var ci_rid
func _body_moved(state, index):
VisualServer.canvas_item_set_transform(ci_rid, state.transform)
func _ready():
# create sprite
ci_rid = VisualServer.canvas_item_create()
VisualServer.canvas_item_set_parent(ci_rid, get_canvas_item())
texture = load("res://icon.png")
VisualServer.canvas_item_add_texture_rect(ci_rid, Rect2(texture.get_size() / 2, texture.get_size()), texture)
var xform = Transform2D().rotated(deg2rad(45)).translated(Vector2(20, 30))
VisualServer.canvas_item_set_transform(ci_rid, xform)
# create rigidbody
body = Physics2DServer.body_create()
Physics2DServer.body_set_mode(body, Physics2DServer.BODY_MODE_RIGID)
shape = RectangleShape2D.new()
shape.extents = Vector2(10, 10)
Physics2DServer.body_add_shape(body, shape)
Physics2DServer.body_set_space(body, get_world_2d().space)
Physics2DServer.body_set_state(body, Physics2DServer.BODY_STATE_TRANSFORM, Transform2D(0, Vector2(10, 20)))
Physics2DServer.body_set_force_integration_callback(body, self, "_body_moved", 0)