ItemInit.java
public static final Item BIRDWATCHER = registerItem("birdwatcher",
new Item(new FabricItemSettings().group(ModMain.ITEMTAB).maxCount(1)));
Zoom.java
package net.joy187.joyggd;
import org.lwjgl.glfw.GLFW;
import net.fabricmc.fabric.api.client.keybinding.v1.KeyBindingHelper;
import net.fabricmc.loader.api.FabricLoader;
import net.fabricmc.loader.api.ModContainer;
import net.fabricmc.loader.api.Version;
import net.joy187.joyggd.init.ItemInit;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.option.KeyBinding;
import net.minecraft.client.option.SimpleOption;
import net.minecraft.client.util.InputUtil;
import net.minecraft.util.math.MathHelper;
public enum Zoom
{
INSTANCE;
public static final MinecraftClient MC = MinecraftClient.getInstance();
private final double defaultLevel = 1;
private Double currentLevel;
private Double defaultMouseSensitivity;
//返回实时改变的放大倍率
public double changeFovBasedOnZoom(double fov)
{
SimpleOption<Double> mouseSensitivitySetting =
MC.options.getMouseSensitivity();
if(currentLevel == null)
currentLevel = defaultLevel;
if(!Screen.hasShiftDown() && (MC.player.getMainHandStack().getItem()!=ItemInit.BIRDWATCHER))
{
currentLevel = defaultLevel;
if(defaultMouseSensitivity != null)
{
mouseSensitivitySetting.setValue(defaultMouseSensitivity);
defaultMouseSensitivity = null;
}
return fov;
}
if(defaultMouseSensitivity == null)
defaultMouseSensitivity = mouseSensitivitySetting.getValue();
// Adjust mouse sensitivity in relation to zoom level.
// 1.0 / currentLevel is a value between 0.02 (50x zoom)
// and 1 (no zoom).
mouseSensitivitySetting
.setValue(defaultMouseSensitivity * (1.0 / currentLevel));
return fov / currentLevel;
}
//鼠标滚动来调整放大倍率
public void onMouseScroll(double amount)
{
if(isScope())
{
if(currentLevel == null)
currentLevel = defaultLevel;
if(amount > 0)
currentLevel *= 1.1;
else if(amount < 0)
currentLevel *= 0.9;
currentLevel = MathHelper.clamp(currentLevel, 1, 60);
}
return;
}
//判断是否开镜
public boolean isScope()
{
return Screen.hasShiftDown()
&& (MC.player.getMainHandStack().getItem()==ItemInit.BIRDWATCHER);
}
}
ClientEvents
:ClientEvents.java
package net.joy187.joyggd;
import java.awt.event.InputEvent;
import com.mojang.blaze3d.systems.RenderSystem;
import net.fabricmc.fabric.api.client.rendering.v1.HudRenderCallback;
import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents;
import net.fabricmc.fabric.api.client.screen.v1.ScreenMouseEvents.AfterMouseScroll;
import net.joy187.joyggd.init.ItemInit;
import net.minecraft.client.MinecraftClient;
import net.minecraft.client.gui.DrawableHelper;
import net.minecraft.client.gui.screen.Screen;
import net.minecraft.client.input.Input;
import net.minecraft.client.option.SimpleOption;
import net.minecraft.client.render.BufferBuilder;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.client.render.Tessellator;
import net.minecraft.client.util.math.MatrixStack;
import net.minecraft.util.Identifier;
import net.minecraft.util.math.Matrix4f;
public class ClientEvents implements HudRenderCallback {
//这个是我们望远镜的镜头贴图
private static final Identifier VIEWFINDER = new Identifier(ModMain.MOD_ID, "textures/gui/assassin.png");
public static final float MAX_FOV = 90F;
public static final float MIN_FOV = 5F;
//对贴图进行渲染
@Override
public void onHudRender(MatrixStack matrixStack, float tickDelta) {
int x = 0;
int y = 0;
//贴图的宽度
float imageWidth = 192F;
//贴图高度
float imageHeight = 100F;
float hnew=0;
float wnew=0;
MinecraftClient client = MinecraftClient.getInstance();
if (client != null) {
int width = client.getWindow().getScaledWidth();
int height = client.getWindow().getScaledHeight();
float rs = width / height;
float ri = imageWidth / imageHeight;
if (rs > ri) {
wnew = width;
hnew = height;
} else {
wnew = width;
hnew = height;
}
x = Math.round((height - hnew) / 2F);
y = Math.round((width - wnew) / 2F);
RenderSystem.setShader(GameRenderer::getPositionTexShader);
RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
RenderSystem.setShaderTexture(0, VIEWFINDER);
//如果玩家手持望远镜并且按下了shift键,就进行渲染
if(Screen.hasShiftDown() && client.player.getMainHandStack().getItem()==ItemInit.BIRDWATCHER)
{
for(int i = 0; i < 1; i++) {
DrawableHelper.drawTexture(matrixStack,x,y, 0 , 0,Math.round(wnew),Math.round(hnew),
Math.round(wnew),Math.round(hnew));
}
}
}
}
}
GameRendererMixin.java
,MouseMixin.java
,PlayerInventoryMixin.java
。GameRendererMixin.java
package net.joy187.joyggd.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
import net.joy187.joyggd.ClientEvents;
import net.joy187.joyggd.Zoom;
import net.minecraft.client.render.Camera;
import net.minecraft.client.render.GameRenderer;
import net.minecraft.resource.SynchronousResourceReloader;
@Mixin(GameRenderer.class)
public abstract class GameRendererMixin
implements AutoCloseable, SynchronousResourceReloader
{
@Inject(at = @At(value = "RETURN", ordinal = 1),
method = {"getFov(Lnet/minecraft/client/render/Camera;FZ)D"},
cancellable = true)
private void onGetFov(Camera camera, float tickDelta, boolean changingFov,
CallbackInfoReturnable<Double> cir)
{
cir.setReturnValue(
//渲染望远镜的放大效果
Zoom.INSTANCE.changeFovBasedOnZoom(cir.getReturnValueD()));
}
}
MouseMixin.java
package net.joy187.joyggd.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.joy187.joyggd.Zoom;
import net.minecraft.client.Mouse;
@Mixin(Mouse.class)
public class MouseMixin
{
@Inject(at = {@At("RETURN")}, method = {"onMouseScroll(JDD)V"})
private void onOnMouseScroll(long long_1, double double_1, double double_2,
CallbackInfo ci)
{
//改变鼠标滚轮效果
Zoom.INSTANCE.onMouseScroll(double_2);
}
}
PlayerInventoryMixin.java
package net.joy187.joyggd.mixin;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import net.joy187.joyggd.Zoom;
import net.minecraft.entity.player.PlayerInventory;
@Mixin(PlayerInventory.class)
public class PlayerInventoryMixin
{
@Inject(at = {@At("HEAD")},
method = {"scrollInHotbar(D)V"},
cancellable = true)
private void onScrollInHotbar(double scrollAmount, CallbackInfo ci)
{
//如果拿到放大镜,就锁定该物品栏
if(Zoom.INSTANCE.isScope())
ci.cancel();
}
}
{
"required": true,
"minVersion": "0.8",
"package": "net.joy187.joyggd.mixin",
"compatibilityLevel": "JAVA_17",
"mixins": [
],
"client": [
//加入这3个mixin文件名称
"GameRendererMixin",
"MouseMixin",
"PlayerInventoryMixin"
],
"injectors": {
"defaultRequire": 1
}
}
fabric.mod
,指定mixin的路径:fabric.mod.json
{
"schemaVersion": 1,
"id": "joyggd",
"version": "0.1",
"name": "Mine Goose Duck Mod",
"description": "Just have fun in the Goose Goose Duck world!",
"authors": [
"joy187"
],
"contact": {
"homepage": "https://fabricmc.net/",
"sources": "https://github.com/FabricMC/fabric-example-mod"
},
"license": "MIT License",
"icon": "assets/joyggd/icon.png",
"environment": "*",
"entrypoints": {
"main": [
"net.joy187.joyggd.ModMain"
],
"client": [
"net.joy187.joyggd.ModClient"
]
},
//指定上面minxin文件名称
"mixins": [
"joyggd.mixins.json"
],
"depends": {
"fabricloader": ">=0.14.8",
"fabric-api": "*",
"fabric": "*",
"minecraft": "~1.19",
"java": ">=17"
},
"suggests": {
"another-mod": "*"
}
}
en_us.json
"item.joyggd.birdwatcher":"Birdwatcher",
models/item
中添加物品模型:birdwatcher.json
{
"parent":"minecraft:item/generated",
"textures":{
"layer0":"joyggd:item/birdwatcher"
}
}