Skip to content

Minecraft Block Wrapper wrapper

Hey, ever played Minecraft?

Just between us, Codfish here is an old-timer, even published a map on Bahamut back in the day. (´,,•ω•,,)

Not long ago, Google dropped a Minecraft 15th Anniversary Easter egg.

Minecraft 15th Anniversary Easter Egg

Haven't seen it? Check it out quick! ˋ( ° ▽、° )

I was so touched, I decided to make my own version! Though, my tech skills weren't quite there, so it took ages to whip up... (›´ω`‹ )

Let's turn web elements into Minecraft blocks together and dig, dig, dig away on our little webpage! ᕕ( ゚ ∀。)ᕗ

Turn up the volume! 🔊

Makes digging blocks feel even better! ◝(≧∀≦)◟

Tech Keywords

NameDescription
Babylon.js3D engine
Particle SystemSpawns large numbers of small objects, commonly used to simulate smoke, fire, rain, and snow
Constructive Solid GeometryBuilds complex shapes by combining simple geometries with boolean operations (union, subtraction, intersection)

Examples

Basic Usage

Hold down the mouse button to start digging an element. Keep holding, and after a bit, you'll dig it away.

Double-click the hole to put the element back. ( ´ ▽ ` )ノ

其實我是方塊 (´,,•ω•,,)
View Example Source Code
vue
<template>
  <div class="w-full flex flex-col items-center gap-14 example-wrap">
    <wrapper-minecraft-block class="w-1/2">
      <div class="select-none border py-20 text-center">
        {{ t('我是方塊') }}
      </div>
    </wrapper-minecraft-block>

    <!-- 必須放置一個 world 元件 -->
    <wrapper-minecraft-world />
  </div>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import WrapperMinecraftBlock from '../wrapper-minecraft-block.vue'
import WrapperMinecraftWorld from '../wrapper-minecraft-world.vue'

const { t } = useI18n()
</script>

More Blocks

You can specify different block types too! ( ´ ▽ ` )ノ

《Minecraft》,又譯我的世界、當個創世神、麥塊,是微軟旗下 Mojang Studios開發的沙盒遊戲。遊戲中,玩家能在一個3D世界內與方塊或生物進行互動。遊戲中的特色玩法包括探索世界、採集資源、合成物品及生存冒險等。
View Example Source Code
vue
<template>
  <div class="grid grid-cols-2 w-full items-center justify-center gap-4 p-6">
    <wrapper-minecraft-block
      class="col-span-2"
      block-type="stone"
    >
      <div class="border p-10">
        {{ t('description') }}
      </div>
    </wrapper-minecraft-block>

    <wrapper-minecraft-block>
      <img
        src="/low/profile.webp"
        alt=""
        class="pointer-events-none select-none border rounded"
      >
    </wrapper-minecraft-block>

    <wrapper-minecraft-block block-type="sand">
      <img
        src="/low/profile-2.webp"
        alt=""
        class="pointer-events-none select-none border rounded"
      >
    </wrapper-minecraft-block>

    <!-- 必須放置一個 world 元件 -->
    <wrapper-minecraft-world />
  </div>
</template>

<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import WrapperMinecraftBlock from '../wrapper-minecraft-block.vue'
import WrapperMinecraftWorld from '../wrapper-minecraft-world.vue'

const { t } = useI18n()
</script>

How It Works

It's mainly composed of two components: World and Block.

  • World provides the 3D scene.

  • Block handles the interactions.

Here's the concept:

We use babylon.js to create a 3D scene covering the entire webpage. Then, we use CSG (Constructive Solid Geometry) to cut meshes, creating a "hole" effect, and initialize the particle systems needed for each block.

The Block component manages interactions, sounds, crack animations, and state, notifying the World of various events via an EventBus.

Source Code

API

Props

interface Props {
  /** 方塊種類。初始化後不可變更 */
  blockType?: BlockType;
  /** 初始化是否為挖掉的狀態 */
  isInitDug?: boolean;
}

Emits

const emit = defineEmits<{
  digging: [];
  dug: [];
  place: [];
}>()

Slots

defineSlots<{
  default?: () => unknown;
}>()

v0.70.3