Minecraft 方塊包裝器 wrapper
大家有玩過 Minecraft 嗎?
不瞞大家說,鱈魚我其實是老玩家了,還曾經在巴哈發表過地圖作品。(´,,•ω•,,)
前陣子 Google 發布了的 Minecraft 15 周年紀念彩蛋。
Minecraft 15 周年紀念彩蛋
沒看過的趕快來看看 ˋ( ° ▽、° )
大受感動的我決定也來做一個自己的版本,不過礙於技術力不足,搞了好久才做出來。...(›´ω`‹ )
讓我們一起把網頁元素變成 Minecraft 方塊,在小小的網頁裡挖呀挖呀挖!ᕕ( ゚ ∀。)ᕗ
記得開聲音!🔊
更有挖方塊的感覺喔!◝(≧∀≦)◟
使用範例
基本用法
按住滑鼠開始挖掘元素,持續一段時間後會將元素挖走。
對洞口雙擊則可將元素放回去。( ´ ▽ ` )ノ
其實我是方塊 (´,,•ω•,,)










查看範例原始碼
vue
<template>
<div class="w-full flex flex-col items-center gap-14 border border-gray-300 p-6">
<wrapper-minecraft-block class="w-1/2">
<div class="select-none border py-20 text-center">
其實我是方塊 (´,,•ω•,,)
</div>
</wrapper-minecraft-block>
<!-- 必須放置一個 world 元件 -->
<wrapper-minecraft-world />
</div>
</template>
<script setup lang="ts">
import WrapperMinecraftBlock from '../wrapper-minecraft-block.vue'
import WrapperMinecraftWorld from '../wrapper-minecraft-world.vue'
</script>
更多方塊
可以指定不同方塊喔。( ´ ▽ ` )ノ

































查看範例原始碼
vue
<template>
<div class="w-full flex flex-wrap justify-center gap-4 p-6">
<div class="flex flex-wrap justify-center gap-4">
<wrapper-minecraft-block>
<img
src="/profile.webp"
width="200"
height="200"
class="pointer-events-none select-none border rounded"
>
</wrapper-minecraft-block>
<wrapper-minecraft-block block-type="sand">
<img
src="/profile-2.webp"
width="200"
height="200"
class="pointer-events-none select-none border rounded"
>
</wrapper-minecraft-block>
</div>
<wrapper-minecraft-block block-type="stone">
<img
src="/painting-codfish-bakery.webp"
width="420"
height="260"
class="pointer-events-none select-none border rounded"
>
</wrapper-minecraft-block>
<!-- 必須放置一個 world 元件 -->
<wrapper-minecraft-world />
</div>
</template>
<script setup lang="ts">
import WrapperMinecraftBlock from '../wrapper-minecraft-block.vue'
import WrapperMinecraftWorld from '../wrapper-minecraft-world.vue'
</script>
原理
由 World 與 Block 兩個主要元件組成。
World 提供 3D 畫面。
Block 負責互動。
概念如下:
利用 babylon.js 建立一個覆蓋整個網頁的 3D 畫面,接著使用 CSG 裁切網格,製造出「凹洞」效果並初始化每個方塊所需的粒子系統。
Block 元件負責管理互動、聲音、裂痕動畫與狀態,並透過 EventBus 通知 World 各類事件。
原始碼
API
Props
interface Props {
/** 方塊種類。初始化後不可變更 */
blockType?: BlockType;
/** 初始化是否為挖掉的狀態 */
isInitDug?: boolean;
}
Emits
const emit = defineEmits<{
digging: [];
dug: [];
place: [];
}>()
Slots
defineSlots<{
default?: () => unknown;
}>()