implement block break particles, version 1.0.2
This commit is contained in:
@@ -31,6 +31,7 @@ Click [here](https://labystudio.de/page/minecraft/) for a demo!
|
||||
- Arm swing animation
|
||||
- Walking animation
|
||||
- Crouch animation
|
||||
- Block break particles
|
||||
- World
|
||||
- 16x16x16 Chunks
|
||||
- Block type, data, sky & block lightning
|
||||
|
||||
@@ -15,10 +15,11 @@ import GrassColorizer from "./render/GrassColorizer.js";
|
||||
import GuiMainMenu from "./gui/screens/GuiMainMenu.js";
|
||||
import GuiLoadingScreen from "./gui/screens/GuiLoadingScreen.js";
|
||||
import * as THREE from "../../../../../libraries/three.module.js";
|
||||
import ParticleRenderer from "./render/particle/ParticleRenderer.js";
|
||||
|
||||
export default class Minecraft {
|
||||
|
||||
static VERSION = "1.0.1"
|
||||
static VERSION = "1.0.2"
|
||||
static URL_GITHUB = "https://github.com/labystudio/js-minecraft";
|
||||
|
||||
/**
|
||||
@@ -65,6 +66,8 @@ export default class Minecraft {
|
||||
// Grass colorizer
|
||||
this.grassColorizer = new GrassColorizer(this);
|
||||
|
||||
this.particleRenderer = new ParticleRenderer(this);
|
||||
|
||||
// Update window size
|
||||
this.window.updateWindowSize();
|
||||
|
||||
@@ -219,6 +222,9 @@ export default class Minecraft {
|
||||
|
||||
// Tick the player
|
||||
this.player.onUpdate();
|
||||
|
||||
// Tick particle renderer
|
||||
this.particleRenderer.onTick();
|
||||
}
|
||||
|
||||
// Tick the screen
|
||||
@@ -293,6 +299,9 @@ export default class Minecraft {
|
||||
1.0
|
||||
);
|
||||
|
||||
// Spawn particle
|
||||
this.particleRenderer.spawnBlockBreakParticle(this.world, hitResult.x, hitResult.y, hitResult.z);
|
||||
|
||||
// Destroy block
|
||||
this.world.setBlockAt(hitResult.x, hitResult.y, hitResult.z, 0);
|
||||
}
|
||||
|
||||
@@ -1,11 +1,13 @@
|
||||
import BoundingBox from "../../util/BoundingBox.js";
|
||||
import MathHelper from "../../util/MathHelper.js";
|
||||
import Random from "../../util/Random.js";
|
||||
|
||||
export default class Entity {
|
||||
|
||||
constructor(minecraft, world) {
|
||||
this.minecraft = minecraft;
|
||||
this.world = world;
|
||||
this.random = new Random();
|
||||
|
||||
this.renderer = this.minecraft.worldRenderer.entityRenderManager.createEntityRendererByEntity(this);
|
||||
|
||||
@@ -13,10 +15,15 @@ export default class Entity {
|
||||
this.y = 0;
|
||||
this.z = 0;
|
||||
|
||||
this.width = 0.0;
|
||||
this.height = 0.0;
|
||||
|
||||
this.motionX = 0;
|
||||
this.motionY = 0;
|
||||
this.motionZ = 0;
|
||||
|
||||
this.stepHeight = 0.0;
|
||||
|
||||
this.onGround = false;
|
||||
this.sneaking = false;
|
||||
|
||||
@@ -35,8 +42,36 @@ export default class Entity {
|
||||
this.nextStepDistance = 1;
|
||||
|
||||
this.ticksExisted = 0;
|
||||
this.isDead = false;
|
||||
|
||||
this.boundingBox = new BoundingBox();
|
||||
this.setPosition(this.x, this.y, this.z);
|
||||
}
|
||||
|
||||
setPosition(x, y, z) {
|
||||
// Update position
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.z = z;
|
||||
|
||||
// Update bounding box
|
||||
let width = this.width / 2;
|
||||
this.boundingBox = new BoundingBox(
|
||||
x - width,
|
||||
y,
|
||||
z - width,
|
||||
x + width,
|
||||
y + this.height,
|
||||
z + width
|
||||
);
|
||||
|
||||
this.motionX = 0;
|
||||
this.motionY = 0;
|
||||
this.motionZ = 0;
|
||||
|
||||
this.prevX = this.x;
|
||||
this.prevY = this.y;
|
||||
this.prevZ = this.z;
|
||||
}
|
||||
|
||||
onUpdate() {
|
||||
@@ -67,4 +102,97 @@ export default class Entity {
|
||||
return this.boundingBox.height() * 0.8;
|
||||
}
|
||||
|
||||
moveCollide(targetX, targetY, targetZ) {
|
||||
// Target position
|
||||
let originalTargetX = targetX;
|
||||
let originalTargetY = targetY;
|
||||
let originalTargetZ = targetZ;
|
||||
|
||||
if (this.onGround && this.sneaking) {
|
||||
for (; targetX !== 0.0 && this.world.getCollisionBoxes(this.boundingBox.offset(targetX, -this.stepHeight, 0.0)).length === 0; originalTargetX = targetX) {
|
||||
if (targetX < 0.05 && targetX >= -0.05) {
|
||||
targetX = 0.0;
|
||||
} else if (targetX > 0.0) {
|
||||
targetX -= 0.05;
|
||||
} else {
|
||||
targetX += 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
for (; targetZ !== 0.0 && this.world.getCollisionBoxes(this.boundingBox.offset(0.0, -this.stepHeight, targetZ)).length === 0; originalTargetZ = targetZ) {
|
||||
if (targetZ < 0.05 && targetZ >= -0.05) {
|
||||
targetZ = 0.0;
|
||||
} else if (targetZ > 0.0) {
|
||||
targetZ -= 0.05;
|
||||
} else {
|
||||
targetZ += 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
for (; targetX !== 0.0 && targetZ !== 0.0 && this.world.getCollisionBoxes(this.boundingBox.offset(targetX, -this.stepHeight, targetZ)).length === 0; originalTargetZ = targetZ) {
|
||||
if (targetX < 0.05 && targetX >= -0.05) {
|
||||
targetX = 0.0;
|
||||
} else if (targetX > 0.0) {
|
||||
targetX -= 0.05;
|
||||
} else {
|
||||
targetX += 0.05;
|
||||
}
|
||||
|
||||
originalTargetX = targetX;
|
||||
|
||||
if (targetZ < 0.05 && targetZ >= -0.05) {
|
||||
targetZ = 0.0;
|
||||
} else if (targetZ > 0.0) {
|
||||
targetZ -= 0.05;
|
||||
} else {
|
||||
targetZ += 0.05;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get level tiles as bounding boxes
|
||||
let boundingBoxList = this.world.getCollisionBoxes(this.boundingBox.expand(targetX, targetY, targetZ));
|
||||
|
||||
// Move bounding box
|
||||
for (let aABB in boundingBoxList) {
|
||||
targetY = boundingBoxList[aABB].clipYCollide(this.boundingBox, targetY);
|
||||
}
|
||||
this.boundingBox.move(0.0, targetY, 0.0);
|
||||
|
||||
for (let aABB in boundingBoxList) {
|
||||
targetX = boundingBoxList[aABB].clipXCollide(this.boundingBox, targetX);
|
||||
}
|
||||
this.boundingBox.move(targetX, 0.0, 0.0);
|
||||
|
||||
for (let aABB in boundingBoxList) {
|
||||
targetZ = boundingBoxList[aABB].clipZCollide(this.boundingBox, targetZ);
|
||||
}
|
||||
this.boundingBox.move(0.0, 0.0, targetZ);
|
||||
|
||||
this.onGround = originalTargetY !== targetY && originalTargetY < 0.0;
|
||||
|
||||
// Stop motion on collision
|
||||
if (originalTargetX !== targetX) {
|
||||
this.motionX = 0.0;
|
||||
}
|
||||
if (originalTargetY !== targetY) {
|
||||
this.motionY = 0.0;
|
||||
}
|
||||
if (originalTargetZ !== targetZ) {
|
||||
this.motionZ = 0.0;
|
||||
}
|
||||
|
||||
// Update position
|
||||
this.x = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0;
|
||||
this.y = this.boundingBox.minY;
|
||||
this.z = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0;
|
||||
|
||||
// Horizontal collision?
|
||||
return originalTargetX !== targetX || originalTargetZ !== targetZ;
|
||||
}
|
||||
|
||||
kill() {
|
||||
this.isDead = true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,6 +1,5 @@
|
||||
import Inventory from "../inventory/Inventory.js";
|
||||
import EntityLiving from "./EntityLiving.js";
|
||||
import BoundingBox from "../../util/BoundingBox.js";
|
||||
import Block from "../world/block/Block.js";
|
||||
import MathHelper from "../../util/MathHelper.js";
|
||||
import Keyboard from "../../util/Keyboard.js";
|
||||
@@ -44,6 +43,9 @@ export default class PlayerEntity extends EntityLiving {
|
||||
this.cameraPitch = 0;
|
||||
this.prevCameraYaw = 0;
|
||||
this.prevCameraPitch = 0;
|
||||
|
||||
this.width = 0.6;
|
||||
this.height = 1.8;
|
||||
}
|
||||
|
||||
respawn() {
|
||||
@@ -51,28 +53,6 @@ export default class PlayerEntity extends EntityLiving {
|
||||
this.setPosition(spawn.x, spawn.y, spawn.z);
|
||||
}
|
||||
|
||||
setPosition(x, y, z) {
|
||||
let width = 0.3;
|
||||
let height = 0.9;
|
||||
this.boundingBox = new BoundingBox(
|
||||
x - width,
|
||||
y - height,
|
||||
z - width,
|
||||
x + width,
|
||||
y + height,
|
||||
z + width
|
||||
);
|
||||
|
||||
this.motionX = 0;
|
||||
this.motionY = 0;
|
||||
this.motionZ = 0;
|
||||
|
||||
// Update position
|
||||
this.x = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0;
|
||||
this.y = this.boundingBox.minY;
|
||||
this.z = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0;
|
||||
}
|
||||
|
||||
turn(motionX, motionY) {
|
||||
let sensitivity = this.minecraft.settings.sensitivity / 500;
|
||||
this.rotationYaw = this.rotationYaw + motionX * sensitivity;
|
||||
@@ -366,95 +346,6 @@ export default class PlayerEntity extends EntityLiving {
|
||||
this.sneaking = sneaking;
|
||||
}
|
||||
|
||||
moveCollide(targetX, targetY, targetZ) {
|
||||
// Target position
|
||||
let originalTargetX = targetX;
|
||||
let originalTargetY = targetY;
|
||||
let originalTargetZ = targetZ;
|
||||
|
||||
if (this.onGround && this.sneaking) {
|
||||
for (; targetX !== 0.0 && this.world.getCollisionBoxes(this.boundingBox.offset(targetX, -this.stepHeight, 0.0)).length === 0; originalTargetX = targetX) {
|
||||
if (targetX < 0.05 && targetX >= -0.05) {
|
||||
targetX = 0.0;
|
||||
} else if (targetX > 0.0) {
|
||||
targetX -= 0.05;
|
||||
} else {
|
||||
targetX += 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
for (; targetZ !== 0.0 && this.world.getCollisionBoxes(this.boundingBox.offset(0.0, -this.stepHeight, targetZ)).length === 0; originalTargetZ = targetZ) {
|
||||
if (targetZ < 0.05 && targetZ >= -0.05) {
|
||||
targetZ = 0.0;
|
||||
} else if (targetZ > 0.0) {
|
||||
targetZ -= 0.05;
|
||||
} else {
|
||||
targetZ += 0.05;
|
||||
}
|
||||
}
|
||||
|
||||
for (; targetX !== 0.0 && targetZ !== 0.0 && this.world.getCollisionBoxes(this.boundingBox.offset(targetX, -this.stepHeight, targetZ)).length === 0; originalTargetZ = targetZ) {
|
||||
if (targetX < 0.05 && targetX >= -0.05) {
|
||||
targetX = 0.0;
|
||||
} else if (targetX > 0.0) {
|
||||
targetX -= 0.05;
|
||||
} else {
|
||||
targetX += 0.05;
|
||||
}
|
||||
|
||||
originalTargetX = targetX;
|
||||
|
||||
if (targetZ < 0.05 && targetZ >= -0.05) {
|
||||
targetZ = 0.0;
|
||||
} else if (targetZ > 0.0) {
|
||||
targetZ -= 0.05;
|
||||
} else {
|
||||
targetZ += 0.05;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get level tiles as bounding boxes
|
||||
let boundingBoxList = this.world.getCollisionBoxes(this.boundingBox.expand(targetX, targetY, targetZ));
|
||||
|
||||
// Move bounding box
|
||||
for (let aABB in boundingBoxList) {
|
||||
targetY = boundingBoxList[aABB].clipYCollide(this.boundingBox, targetY);
|
||||
}
|
||||
this.boundingBox.move(0.0, targetY, 0.0);
|
||||
|
||||
for (let aABB in boundingBoxList) {
|
||||
targetX = boundingBoxList[aABB].clipXCollide(this.boundingBox, targetX);
|
||||
}
|
||||
this.boundingBox.move(targetX, 0.0, 0.0);
|
||||
|
||||
for (let aABB in boundingBoxList) {
|
||||
targetZ = boundingBoxList[aABB].clipZCollide(this.boundingBox, targetZ);
|
||||
}
|
||||
this.boundingBox.move(0.0, 0.0, targetZ);
|
||||
|
||||
this.onGround = originalTargetY !== targetY && originalTargetY < 0.0;
|
||||
|
||||
// Stop motion on collision
|
||||
if (originalTargetX !== targetX) {
|
||||
this.motionX = 0.0;
|
||||
}
|
||||
if (originalTargetY !== targetY) {
|
||||
this.motionY = 0.0;
|
||||
}
|
||||
if (originalTargetZ !== targetZ) {
|
||||
this.motionZ = 0.0;
|
||||
}
|
||||
|
||||
// Update position
|
||||
this.x = (this.boundingBox.minX + this.boundingBox.maxX) / 2.0;
|
||||
this.y = this.boundingBox.minY;
|
||||
this.z = (this.boundingBox.minZ + this.boundingBox.maxZ) / 2.0;
|
||||
|
||||
// Horizontal collision?
|
||||
return originalTargetX !== targetX || originalTargetZ !== targetZ;
|
||||
}
|
||||
|
||||
getEyeHeight() {
|
||||
return this.sneaking ? 1.50 : 1.62;
|
||||
}
|
||||
|
||||
@@ -117,6 +117,9 @@ export default class WorldRenderer {
|
||||
// Render target block
|
||||
this.renderBlockHitBox(player, partialTicks);
|
||||
|
||||
// Render particles
|
||||
this.minecraft.particleRenderer.renderParticles(player, partialTicks);
|
||||
|
||||
// Hide all entities and make them visible during rendering
|
||||
for (let entity of this.minecraft.world.entities) {
|
||||
entity.renderer.group.visible = false;
|
||||
@@ -615,7 +618,7 @@ export default class WorldRenderer {
|
||||
});
|
||||
|
||||
// Flush by rebuilding 8 chunk sections
|
||||
if(this.flushRebuild) {
|
||||
if (this.flushRebuild) {
|
||||
this.flushRebuild = false;
|
||||
|
||||
for (let i = 0; i < 8; i++) {
|
||||
|
||||
@@ -15,6 +15,9 @@ export default class EntityRenderManager {
|
||||
}
|
||||
|
||||
createEntityRendererByEntity(entity) {
|
||||
if (!(entity.constructor.name in this.renderers)) {
|
||||
return null;
|
||||
}
|
||||
return new this.renderers[entity.constructor.name].prototype.constructor(this.worldRenderer);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
import Entity from "../../entity/Entity.js";
|
||||
import * as THREE from "../../../../../../../libraries/three.module.js";
|
||||
import Tessellator from "../Tessellator.js";
|
||||
|
||||
export default class Particle extends Entity {
|
||||
|
||||
constructor(minecraft, world, x, y, z, motionX, motionY, motionZ) {
|
||||
super(minecraft, world);
|
||||
|
||||
this.setPosition(x, y, z);
|
||||
|
||||
this.textureIndex = 0;
|
||||
|
||||
this.randomX = this.random.nextFloat() * 3;
|
||||
this.randomY = this.random.nextFloat() * 3;
|
||||
this.randomZ = (this.random.nextFloat() * 0.5 + 0.5) * 2.0;
|
||||
|
||||
this.motionX = motionX + (Math.random() * 2 - 1.0) * 0.4;
|
||||
this.motionY = motionY + (Math.random() * 2 - 1.0) * 0.4;
|
||||
this.motionZ = motionZ + (Math.random() * 2 - 1.0) * 0.4;
|
||||
|
||||
let strength = (Math.random() + Math.random() + 1.0) * 0.15;
|
||||
let length = Math.sqrt(this.motionX * this.motionX + this.motionY * this.motionY + this.motionZ * this.motionZ);
|
||||
this.motionX = (this.motionX / length) * strength * 0.4;
|
||||
this.motionY = (this.motionY / length) * strength * 0.4 + 0.1;
|
||||
this.motionZ = (this.motionZ / length) * strength * 0.4;
|
||||
|
||||
this.maxTicksExisted = Math.floor(4 / (this.random.nextFloat() * 0.9 + 0.1))
|
||||
this.color = -1;
|
||||
|
||||
this.group = null;
|
||||
}
|
||||
|
||||
onUpdate() {
|
||||
super.onUpdate();
|
||||
|
||||
if (this.ticksExisted >= this.maxTicksExisted) {
|
||||
this.kill();
|
||||
}
|
||||
|
||||
this.motionY -= 0.04;
|
||||
|
||||
this.moveCollide(this.motionX, this.motionY, this.motionZ);
|
||||
|
||||
this.motionX *= 0.98;
|
||||
this.motionY *= 0.98;
|
||||
this.motionZ *= 0.98;
|
||||
|
||||
if (this.onGround) {
|
||||
this.motionX *= 0.7;
|
||||
this.motionZ *= 0.7;
|
||||
}
|
||||
}
|
||||
|
||||
render(rotationX, rotationY, rotationZ, partialTicks) {
|
||||
let x = ((this.prevX + (this.x - this.prevX) * partialTicks));
|
||||
let y = ((this.prevY + (this.y - this.prevY) * partialTicks));
|
||||
let z = ((this.prevZ + (this.z - this.prevZ) * partialTicks));
|
||||
|
||||
// Create mesh
|
||||
if (this.group === null) {
|
||||
this.rebuild();
|
||||
}
|
||||
|
||||
let factor = 0.1 * this.randomZ;
|
||||
this.group.scale.x = factor;
|
||||
this.group.scale.y = factor;
|
||||
this.group.scale.z = factor;
|
||||
|
||||
this.group.rotation.x = rotationX;
|
||||
this.group.rotation.y = rotationY;
|
||||
this.group.rotation.z = rotationZ;
|
||||
|
||||
this.group.position.x = x;
|
||||
this.group.position.y = y;
|
||||
this.group.position.z = z;
|
||||
this.group.updateMatrix();
|
||||
}
|
||||
|
||||
rebuild() {
|
||||
this.group = new THREE.Object3D();
|
||||
this.group.rotation.order = 'ZYX';
|
||||
|
||||
let tessellator = new Tessellator();
|
||||
tessellator.bindTexture(this.minecraft.worldRenderer.textureTerrain);
|
||||
|
||||
let minU = ((this.textureIndex % 16) + this.randomX / 4) / 16.0;
|
||||
let maxU = minU + (16 / 256 / 4);
|
||||
let minV = (Math.floor(this.textureIndex / 16) + this.randomX / 4) / 16.0;
|
||||
let maxV = minV + (16 / 256 / 4);
|
||||
|
||||
// Flip V
|
||||
minV = 1 - minV;
|
||||
maxV = 1 - maxV;
|
||||
|
||||
let red = (this.color >> 16 & 255) / 255.0;
|
||||
let green = (this.color >> 8 & 255) / 255.0;
|
||||
let blue = (this.color & 255) / 255.0;
|
||||
|
||||
let brightness = this.getEntityBrightness();
|
||||
|
||||
// Render particle
|
||||
tessellator.startDrawing();
|
||||
tessellator.setColor(red * brightness, green * brightness, blue * brightness);
|
||||
tessellator.addVertexWithUV(0, 1, 0, minU, minV);
|
||||
tessellator.addVertexWithUV(0, 0, 0, minU, maxV);
|
||||
tessellator.addVertexWithUV(1, 0, 0, maxU, maxV);
|
||||
tessellator.addVertexWithUV(1, 1, 0, maxU, minV);
|
||||
let mesh = tessellator.draw(this.group);
|
||||
mesh.geometry.center();
|
||||
|
||||
this.minecraft.worldRenderer.scene.add(this.group);
|
||||
}
|
||||
|
||||
kill() {
|
||||
super.kill();
|
||||
|
||||
if (this.group !== null) {
|
||||
this.minecraft.worldRenderer.scene.remove(this.group);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,79 @@
|
||||
import MathHelper from "../../../util/MathHelper.js";
|
||||
import Block from "../../world/block/Block.js";
|
||||
import ParticleDigging from "./particle/ParticleDigging.js";
|
||||
|
||||
export default class ParticleRenderer {
|
||||
|
||||
constructor(minecraft) {
|
||||
this.minecraft = minecraft;
|
||||
this.particles = [];
|
||||
}
|
||||
|
||||
spawnParticle(particle) {
|
||||
this.particles.push(particle);
|
||||
}
|
||||
|
||||
onTick() {
|
||||
for (let i = 0; i < this.particles.length; i++) {
|
||||
const particle = this.particles[i];
|
||||
particle.onUpdate();
|
||||
|
||||
if (particle.isDead) {
|
||||
this.particles.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderParticles(cameraEntity, partialTicks) {
|
||||
let yaw = cameraEntity.prevRotationYaw + (cameraEntity.rotationYaw - cameraEntity.prevRotationYaw) * partialTicks;
|
||||
let pitch = cameraEntity.prevRotationPitch + (cameraEntity.rotationPitch - cameraEntity.prevRotationPitch) * partialTicks;
|
||||
|
||||
let rotationX = MathHelper.toRadians(pitch);
|
||||
let rotationY = -MathHelper.toRadians(yaw);
|
||||
|
||||
for (let i = 0; i < this.particles.length; i++) {
|
||||
const particle = this.particles[i];
|
||||
|
||||
particle.render(rotationX, rotationY, 0, partialTicks);
|
||||
}
|
||||
}
|
||||
|
||||
spawnBlockBreakParticle(world, x, y, z) {
|
||||
let typeId = world.getBlockAt(x, y, z);
|
||||
if (typeId === 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let block = Block.getById(typeId);
|
||||
let range = 4;
|
||||
for (let offsetX = 0; offsetX < range; offsetX++) {
|
||||
for (let offsetY = 0; offsetY < range; offsetY++) {
|
||||
for (let offsetZ = 0; offsetZ < range; offsetZ++) {
|
||||
|
||||
let targetX = x + (offsetX + 0.5) / range;
|
||||
let targetY = y + (offsetY + 0.5) / range;
|
||||
let targetZ = z + (offsetZ + 0.5) / range;
|
||||
|
||||
let motionX = targetX - x - 0.5;
|
||||
let motionY = targetY - y - 0.5;
|
||||
let motionZ = targetZ - z - 0.5;
|
||||
|
||||
this.spawnParticle(new ParticleDigging(
|
||||
this.minecraft,
|
||||
world,
|
||||
targetX,
|
||||
targetY,
|
||||
targetZ,
|
||||
motionX,
|
||||
motionY,
|
||||
motionZ,
|
||||
block
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
import Particle from "../Particle.js";
|
||||
|
||||
export default class ParticleDigging extends Particle {
|
||||
|
||||
constructor(minecraft, world, x, y, z, motionX, motionY, motionZ, block) {
|
||||
super(minecraft, world, x, y, z, motionX, motionY, motionZ);
|
||||
|
||||
// Get color multiplier
|
||||
let color = block.getParticleColor(world, x, y, z);
|
||||
let red = color >> 16 & 0xFF;
|
||||
let green = color >> 8 & 0xFF;
|
||||
let blue = color & 0xFF;
|
||||
|
||||
red *= 0.6;
|
||||
green *= 0.6;
|
||||
blue *= 0.6;
|
||||
|
||||
this.color = red << 16 | green << 8 | blue;
|
||||
|
||||
this.textureIndex = block.getTextureForFace(block.getParticleTextureFace());
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,6 +31,10 @@ export default class Block {
|
||||
return BlockRenderType.BLOCK;
|
||||
}
|
||||
|
||||
getParticleTextureFace() {
|
||||
return EnumBlockFace.TOP;
|
||||
}
|
||||
|
||||
getTextureForFace(face) {
|
||||
return this.textureSlotId;
|
||||
}
|
||||
@@ -52,6 +56,10 @@ export default class Block {
|
||||
return 0xffffff;
|
||||
}
|
||||
|
||||
getParticleColor(world, x, y, z) {
|
||||
return this.getColor(world, x, y, z, this.getParticleTextureFace());
|
||||
}
|
||||
|
||||
getLightValue() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -26,6 +26,10 @@ export default class BlockGrass extends Block {
|
||||
return world.minecraft.grassColorizer.getColor(temperature, humidity);
|
||||
}
|
||||
|
||||
getParticleTextureFace() {
|
||||
return EnumBlockFace.NORTH;
|
||||
}
|
||||
|
||||
getTextureForFace(face) {
|
||||
switch (face) {
|
||||
case EnumBlockFace.TOP:
|
||||
|
||||
Reference in New Issue
Block a user