Error in user YAML: (<unknown>): could not find expected ':' while scanning a simple key at line 3 column 1
---
- oeasy Python 0738
- 这是 oeasy 系统化 Python 教程,从基础一步步讲,扎实、完整、不跳步。愿意花时间学,就能真正学会。
本教程同步发布在:
个人网站: `https://oeasy.org`
蓝桥云课: `https://www.lanqiao.cn/courses/3584`
GitHub: `https://github.com/overmind1980/oeasy-python-tutorial`
Gitee: `https://gitee.com/overmind1980/oeasypython`
---import bpy
import math
# --- 场景初始化 ---
bpy.ops.object.select_all(action='SELECT')
bpy.ops.object.delete(use_global=False)
bpy.context.scene.frame_set(1)
# --- 材质创建函数 ---
def create_material(name, color, alpha=1.0):
mat = bpy.data.materials.new(name=name)
mat.use_nodes = False # 禁用节点系统
mat.diffuse_color = (*color, alpha) # 设置漫反射颜色和透明度
if alpha < 1.0:
mat.blend_method = 'BLEND' # 透明材质需要启用混合模式
return mat
# --- 全局材质定义 ---
car_body_mat = create_material("CarBody", (1.0, 0.7, 0.85)) # 亮粉色车身
car_roof_mat = create_material("CarRoof", (0.9, 0.5, 0.7)) # 深粉色车顶
wheel_mat = create_material("Wheel", (0.2, 0.2, 0.2)) # 深灰车轮
window_mat = create_material("Window", (0.95, 0.85, 0.9), 0.3)# 浅粉车窗(带透明度)
light_mat = create_material("Light", (1.0, 0.9, 0.3)) # 车灯
road_mat = create_material("Road", (0.08, 0.08, 0.08)) # 近黑色马路
road_line_mat = create_material("RoadLine", (0.9, 0.9, 0.9)) # 白色马路线
tree_trunk_mat = create_material("TreeTrunk", (0.4, 0.2, 0.1))# 棕色树干
tree_leaves_mat = create_material("TreeLeaves", (0.1, 0.6, 0.1))# 绿色树叶
grass_mat = create_material("Grass", (0.2, 0.6, 0.2)) # 草地
# 车窗透明度
# 删除以下两行节点相关代码
# window_mat.blend_method = 'BLEND'
# window_mat.node_tree.nodes["Principled BSDF"].inputs[18].default_value = 0.3
# --- 粉色小车创建 ---
def create_cute_car():
# 删除此处重复的材质定义代码块
# 车身
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, 0.5))
car_body = bpy.context.active_object
car_body.name = "CarBody"
car_body.scale = (1.5, 0.8, 0.4)
bpy.ops.object.transform_apply(location=False, rotation=False, scale=True)
bpy.ops.object.mode_set(mode='EDIT')
bpy.ops.mesh.select_all(action='SELECT')
bpy.ops.mesh.subdivide(number_cuts=2)
bpy.ops.object.mode_set(mode='OBJECT')
bpy.ops.object.modifier_add(type='SUBSURF')
car_body.data.materials.append(car_body_mat)
# 车顶
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 1.2))
car_roof = bpy.context.active_object
car_roof.name = "CarRoof"
car_roof.scale = (1.0, 0.6, 0.5)
car_roof.data.materials.append(car_roof_mat)
# 球形车轮
wheel_positions = [(-1.0, -0.9, 0.3), (1.0, -0.9, 0.3), (-1.0, 0.9, 0.3), (1.0, 0.9, 0.3)]
wheels = []
for i, pos in enumerate(wheel_positions):
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.3, location=pos)
wheel = bpy.context.active_object
wheel.name = f"Wheel_{i+1}"
wheel.data.materials.append(wheel_mat)
wheels.append(wheel)
# 车窗、车灯
bpy.ops.mesh.primitive_cube_add(size=0.8, location=(0, 0, 1.3))
window = bpy.context.active_object
window.name = "Window"
window.scale = (0.8, 0.5, 0.3)
window.data.materials.append(window_mat)
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.1, location=(1.4, -0.3, 0.7))
light1 = bpy.context.active_object
light1.name = "Headlight1"
light1.data.materials.append(light_mat)
bpy.ops.mesh.primitive_uv_sphere_add(radius=0.1, location=(1.4, 0.3, 0.7))
light2 = bpy.context.active_object
light2.name = "Headlight2"
light2.data.materials.append(light_mat)
# 组合汽车部件
car_parts = [car_body, car_roof, window, light1, light2] + wheels
bpy.ops.object.empty_add(location=(0, 0, 0))
car_parent = bpy.context.active_object
car_parent.name = "CuteCar"
for part in car_parts:
part.parent = car_parent
return car_parent, wheels
# --- 马路创建 ---
def create_road(road_length):
# 马路主体
bpy.ops.mesh.primitive_cube_add(size=2, location=(0, 0, -0.1))
road = bpy.context.active_object
road.name = "Road"
road.scale = (road_length / 2, 4, 0.1)
road.data.materials.append(road_mat)
# 白色马路线
bpy.ops.mesh.primitive_cube_add(size=1, location=(0, 0, 0.01))
road_line = bpy.context.active_object
road_line.name = "RoadLine"
road_line.scale = (road_length - 2, 0.1, 0.01)
road_line.data.materials.append(road_line_mat)
return road, road_line # 返回马路对象以便设置父级
# --- 草地创建 ---
def create_grass():
bpy.ops.mesh.primitive_plane_add(size=300, location=(0, 0, -0.2))
grass = bpy.context.active_object
grass.name = "Grass"
grass.data.materials.append(grass_mat)
return grass
# --- 场景组合 ---
road_length = 160
# 创建顶级容器
background = bpy.data.objects.new("background", None)
bpy.data.collections["Collection"].objects.link(background)
trees_container = bpy.data.objects.new("trees", None)
trees_container.parent = background
bpy.context.collection.objects.link(trees_container)
lighting = bpy.data.objects.new("照明", None)
bpy.context.collection.objects.link(lighting)
# 创建场景元素并分配父级
grass = create_grass()
grass.parent = background
road, road_line = create_road(road_length)
road.parent = background
road_line.parent = background
car, wheels = create_cute_car()
# --- 树木创建 ---
def create_christmas_tree(location, tree_id):
# 树干
bpy.ops.mesh.primitive_cylinder_add(radius=0.2, depth=1.5, location=location)
trunk = bpy.context.active_object
trunk.name = f"TreeTrunk_{tree_id}"
trunk.location[2] += 0.75
trunk.data.materials.append(tree_trunk_mat)
tree_parts = [trunk]
# 树叶
bpy.ops.mesh.primitive_cone_add(radius1=1.5, radius2=0, depth=2, location=location)
bottom_layer = bpy.context.active_object
bottom_layer.name = f"TreeBottom_{tree_id}"
bottom_layer.location[2] += 2.5
bottom_layer.data.materials.append(tree_leaves_mat)
tree_parts.append(bottom_layer)
bpy.ops.mesh.primitive_cone_add(radius1=1.2, radius2=0, depth=1.8, location=location)
middle_layer = bpy.context.active_object
middle_layer.name = f"TreeMiddle_{tree_id}"
middle_layer.location[2] += 3.2
middle_layer.data.materials.append(tree_leaves_mat)
tree_parts.append(middle_layer)
bpy.ops.mesh.primitive_cone_add(radius1=0.8, radius2=0, depth=1.5, location=location)
top_layer = bpy.context.active_object
top_layer.name = f"TreeTop_{tree_id}"
top_layer.location[2] += 3.8
top_layer.data.materials.append(tree_leaves_mat)
tree_parts.append(top_layer)
# 组合树木
bpy.ops.object.empty_add(location=location)
tree_parent = bpy.context.active_object
tree_parent.name = f"ChristmasTree_{tree_id}"
for part in tree_parts:
part.parent = tree_parent
return tree_parent
# 树木分布
tree_spacing = 4
tree_distance_from_road = 3
num_trees = road_length // tree_spacing + 1
# 左侧树木
for i in range(num_trees):
x_pos = -road_length//2 + i * tree_spacing
tree_pos = (x_pos, -tree_distance_from_road, 0)
tree = create_christmas_tree(tree_pos, f"L_{i}")
tree.parent = trees_container
# 右侧树木
for i in range(num_trees):
x_pos = -road_length//2 + i * tree_spacing
tree_pos = (x_pos, tree_distance_from_road, 0)
tree = create_christmas_tree(tree_pos, f"R_{i}")
tree.parent = trees_container
# --- 相机与灯光 ---
camera = bpy.data.cameras.new('Camera')
camera = bpy.data.objects.new('Camera', camera)
bpy.data.collections["Collection"].objects.link(camera)
camera.location = (-20.6, -19.7, 29.3)
camera.rotation_euler = (0.8, 0, 0.8)
# 阳光
bpy.ops.object.light_add(type='SUN', location=(10, 10, 20))
sun = bpy.context.active_object
sun.data.energy = 3
sun.rotation_euler = (math.radians(60), math.radians(30), math.radians(45))
sun.parent = lighting
# 区域光
bpy.ops.object.light_add(type='AREA', location=(0, 0, 15))
area_light = bpy.context.active_object
area_light.data.energy = 2.5
area_light.data.size = 20
area_light.parent = lighting
# --- 动画设置 ---
frame_start = 1
frame_end = 800
bpy.context.scene.frame_start = frame_start
bpy.context.scene.frame_end = frame_end
# 小车移动
bpy.context.scene.frame_set(frame_start)
car.location = (-road_length//2 + 5, 0, 0)
car.keyframe_insert(data_path="location", index=-1, frame=frame_start)
bpy.context.scene.frame_set(frame_end)
car.location = (road_length//2 - 5, 0, 0)
car.keyframe_insert(data_path="location", index=-1, frame=frame_end)
# 车轮旋转
rotation_speed = 32
for wheel in wheels:
bpy.context.scene.frame_set(frame_start)
wheel.rotation_euler = (0, 0, 0)
wheel.keyframe_insert(data_path="rotation_euler", index=-1, frame=frame_start)
bpy.context.scene.frame_set(frame_end)
wheel.rotation_euler = (0, rotation_speed * 2 * math.pi, 0)
wheel.keyframe_insert(data_path="rotation_euler", index=-1, frame=frame_end)
# 线性插值确保匀速
for obj in bpy.data.objects:
if obj.animation_data and obj.animation_data.action:
for fcurve in obj.animation_data.action.fcurves:
for keyframe in fcurve.keyframe_points:
keyframe.interpolation = 'LINEAR'
# --- 兼容不同Blender版本的视图设置 ---
for area in bpy.context.screen.areas:
if area.type == 'VIEW_3D':
area.spaces[0].shading.type = 'SOLID'
area.spaces[0].shading.color_type = 'MATERIAL'
area.spaces[0].shading.show_object_outline = False
# 检查属性是否存在,兼容不同Blender版本
overlay = area.spaces[0].overlay
if hasattr(overlay, 'show_grid'):
overlay.show_grid = False # 旧版本属性
elif hasattr(overlay, 'grid_scale'):
overlay.grid_scale = 0 # 新版本替代方案
if hasattr(overlay, 'show_axis_x'):
overlay.show_axis_x = False
overlay.show_axis_y = False
overlay.show_axis_z = False
if hasattr(overlay, 'show_outline_selected'):
overlay.show_outline_selected = False
bpy.context.scene.frame_set(frame_start)
bpy.context.scene.camera = camera
bpy.context.scene.render.resolution_x = 640
bpy.context.scene.render.resolution_y = 480
bpy.context.scene.render.resolution_percentage = 50
# Set the render engine (e.g., CYCLES, BLENDER_EEVEE)
bpy.context.scene.render.engine = 'EEVEE'
# Set the output file path
bpy.context.scene.render.filepath = '/tmp/render2.png'
# Render the current view
bpy.ops.render.render(write_still=True)
print("已保留白色马路线,移除其他辅助线!")
print("在Layout视图中可看到:")
print("- 黑色马路中间有白色中心线")
print("- 无网格线、坐标轴等干扰元素")
print("- 粉色小车在马路上行驶,两侧是绿色树木")
print("按空格键播放动画查看效果")
- 小汽车的
- 顶视图
- 正面
- 背面
- 侧面
- 45度
- 动画的入画和出画
- 跟随 效果
- 跳切效果
- 本文来自 oeasy Python 系统教程。
- 想完整、扎实学 Python,
- 搜索 oeasy 即可。
