Files
2025-10-03 16:49:53 +08:00

7.0 KiB
Raw Permalink Blame History

场景系统

PE引擎的场景系统是其核心特性之一它提供了一种结构化的方式来组织和管理应用的不同视图和状态。每个场景都是一个独立的单元包含模板、样式和逻辑代码。

场景的基本结构

PE场景由三个主要部分组成

  1. 模板Template - 定义场景的结构和元素
  2. 样式Style - 定义场景的外观和样式
  3. 脚本Script - 定义场景的逻辑和行为

场景文件结构

一个典型的PE场景目录结构如下

scenes/
├── home/
│   ├── index.pe      # 场景模板文件
│   └── index.less    # 场景样式文件
└── about/
    ├── index.pe
    └── index.less

场景模板文件(.pe

场景模板文件使用类似HTML的语法包含sence标签和script标签:

<sence>
  <!-- 场景元素定义 -->
  <sprite class="logo"></sprite>
  <box class="welcome-box">欢迎来到PE引擎!</box>
  <text class="description">这是一个简单的场景示例</text>
  
  <!-- 循环渲染元素 -->
  <box for="{item} in menuItems" 
       class="menu-item" 
       @click="handleMenuClick(item.id)">
    {{ item.label }}
  </box>
</sence>

<script>
// 场景数据和逻辑
const menuItems = [
  { id: 'home', label: '首页' },
  { id: 'about', label: '关于' },
  { id: 'contact', label: '联系' }
]

// 生命周期钩子
onLoad(() => {
  console.log('场景加载完成')
})

onShow(() => {
  console.log('场景显示')
})

// 事件处理函数
function handleMenuClick(id) {
  console.log('点击了菜单项:', id)
  PE.navigateTo(`/${id}`)
}
</script>

模板语法

PE场景模板支持以下语法特性

元素定义

<!-- 基本元素 -->
<sprite class="my-sprite" x="100" y="100" width="50" height="50"></sprite>
<box class="my-box">盒子内容</box>
<text class="my-text">文本内容</text>

事件绑定

使用@前缀绑定事件处理器:

<box @click="handleClick" @mouseenter="handleMouseEnter">点击我</box>

循环渲染

使用for指令循环渲染元素:

<box for="{item} in items" class="item">{{ item.name }}</box>

插值表达式

使用双大括号语法插入数据:

<text>当前计数: {{ count }}</text>

场景样式文件(.less

每个场景可以有对应的Less样式文件样式会自动作用于该场景内的元素

// home/index.less
.logo {
  width: 100px;
  height: 100px;
  background-color: #3498db;
  border-radius: 50%;
  position: absolute;
  top: 50px;
  left: 50px;
}

.welcome-box {
  width: 300px;
  height: 100px;
  background-color: #2c3e50;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  top: 200px;
  left: 50px;
  border-radius: 8px;
}

.description {
  color: #7f8c8d;
  font-size: 16px;
  position: absolute;
  top: 320px;
  left: 50px;
}

.menu-item {
  width: 150px;
  height: 40px;
  background-color: #e74c3c;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  left: 50px;
  border-radius: 4px;
  cursor: pointer;
  
  // 使用Less变量和嵌套
  &:hover {
    background-color: darken(#e74c3c, 10%);
  }
  
  &:nth-child(1) { top: 380px; }
  &:nth-child(2) { top: 430px; }
  &:nth-child(3) { top: 480px; }
}

场景路由配置

场景通过sences.json文件进行路由配置:

{
  "sence": [
    {
      "path": "/",
      "title": "首页"
    },
    {
      "path": "/about",
      "title": "关于我们"
    },
    {
      "path": "/products",
      "title": "产品"
    }
  ],
  "platform": "PC"
}

场景生命周期

每个场景都有完整的生命周期钩子,让你能够在适当的时机执行操作:

onLoad

场景加载时调用,只在场景首次加载时执行一次:

onLoad(() => {
  console.log('场景加载完成')
  // 初始化操作
  initializeData()
})

onShow

场景显示时调用,每次场景被显示时都会执行:

onShow(() => {
  console.log('场景显示')
  // 每次显示时的操作
  refreshData()
})

onHide

场景隐藏时调用:

onHide(() => {
  console.log('场景隐藏')
  // 清理操作
  pauseAnimations()
})

onDestory

场景销毁时调用:

onDestory(() => {
  console.log('场景销毁')
  // 最终清理操作
  clearInterval(timer)
})

场景间导航

PE提供了简单的API来在场景间进行导航

// 导航到指定路径的场景
PE.navigateTo('/about')

// 在模板中使用
<box @click="PE.navigateTo('/products')">查看产品</box>

完整示例

以下是一个完整的场景示例:

scenes/product/index.pe

<sence>
  <box class="header">产品列表</box>
  
  <box for="{product} in products" 
       class="product-card" 
       @click="viewProduct(product.id)">
    <text class="product-name">{{ product.name }}</text>
    <text class="product-price">¥{{ product.price }}</text>
  </box>
  
  <box class="back-button" @click="PE.navigateTo('/')">返回首页</box>
</sence>

<script>
// 产品数据
const products = [
  { id: 1, name: '产品A', price: 99.99 },
  { id: 2, name: '产品B', price: 149.99 },
  { id: 3, name: '产品C', price: 199.99 }
]

// 生命周期钩子
onLoad(() => {
  console.log('产品页面加载')
})

onShow(() => {
  console.log('产品页面显示')
})

// 事件处理函数
function viewProduct(id) {
  console.log('查看产品:', id)
  // 可以通过全局变量或事件传递数据
  window.currentProductId = id
  PE.navigateTo('/product-detail')
}
</script>

scenes/product/index.less

.header {
  width: 100%;
  height: 60px;
  background-color: #34495e;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  font-size: 20px;
  font-weight: bold;
}

.product-card {
  width: 300px;
  height: 100px;
  background-color: #ecf0f1;
  border: 1px solid #bdc3c7;
  border-radius: 8px;
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  display: flex;
  flex-direction: column;
  justify-content: center;
  padding: 0 20px;
  cursor: pointer;
  
  &:hover {
    background-color: #d5dbdb;
  }
  
  &:nth-child(2) { top: 100px; }  // 第一个产品卡
  &:nth-child(3) { top: 220px; }  // 第二个产品卡
  &:nth-child(4) { top: 340px; }  // 第三个产品卡
}

.product-name {
  color: #2c3e50;
  font-size: 18px;
  font-weight: bold;
  margin-bottom: 5px;
}

.product-price {
  color: #e74c3c;
  font-size: 16px;
  font-weight: bold;
}

.back-button {
  width: 100px;
  height: 40px;
  background-color: #95a5a6;
  color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  position: absolute;
  bottom: 20px;
  left: 20px;
  border-radius: 4px;
  cursor: pointer;
  
  &:hover {
    background-color: #7f8c8d;
  }
}

通过以上内容你已经了解了PE引擎的场景系统。在下一章节中我们将探讨样式处理的相关内容。