3785439628 发表于 2026-8-19 19:44:58

[MTR-4.0.4+,JCM]上海地铁风格的pids

本帖最后由 3785439628 于 2026-8-19 21:38 编辑

上海地铁风格PIDS


Tips:我真的不是抄的天津地铁PIDS,因为当前作者技术有限,同时刚学习写JavaScript,做不了上海那种:”车厢显示””七段数码管倒计时”那种高端的显示屏,以后会研究,请谅解众所周知,原版JCM的PIDS风格可能并不适合所有人的城市风格,相信你也看腻了原版JCM的那种只有四行文字预报的PID,那么,上海地铁风格的PIDS ta来了!效果图:
这效果图怎么发不出来啊……
[真的不是我懒得发]
作者:
Bilibili:
部分代码,技术支持,辅助:UID:3493285494524348
提出项目,主要代码编写:UID:3546659074082839

PIDS特色:
您可以自定义广告图片;滚动字幕,我们内置了16张上海航拍图的照片供您欣赏,使用,但您也许觉得这些默认广告图太单调了,所以……,以下是具体的自定义广告图片的教程:

一:自定义广告图片 教程:
首先,你得有一张广告图(废话文学)
然后,找到你下载的PIDS文件,按照以下路径点下去
这里以PCL II启动器的文件摆放位置作参考,橙色为你已经将资源包放入游戏资源包文件夹中的情况,淡蓝色为你刚在浏览器下载好时的情况
.minecraft>versions>你的游戏版本名称>resourcepacks>上海地铁-PIDS>assets>jsblock>ad_textures
把你自己的广告图片放进去,记住你放入的广告图片名称,格式png!png!png!,待会儿要考,然后开始写.javascript
这是上海地铁风格的PIDS的JavaScript代码原文件内容:

[*]include(Resources.id("jsblock:scripts/pids_util.js"));
[*]
[*]var adImages = [
[*]    "jsblock:ad_textures/ad_1.png",
[*]    "jsblock:ad_textures/ad_2.png",
[*]    "jsblock:ad_textures/ad_3.png",
[*]    "jsblock:ad_textures/ad_4.png",
[*]    "jsblock:ad_textures/ad_5.png",
[*]    "jsblock:ad_textures/ad_6.png",
[*]    "jsblock:ad_textures/ad_7.png",
[*]    "jsblock:ad_textures/ad_8.png",
[*]    "jsblock:ad_textures/ad_9.png",
[*]    "jsblock:ad_textures/ad_10.png",
[*]    "jsblock:ad_textures/ad_11.png",
[*]    "jsblock:ad_textures/ad_12.png",
[*]    "jsblock:ad_textures/ad_13.png",
[*]    "jsblock:ad_textures/ad_14.png",
[*]    "jsblock:ad_textures/ad_15.png",
[*]    "jsblock:ad_textures/ad_16.png"
[*]];
[*]
[*]function create(ctx,state,pids) {
[*]    adIndex = 0;
[*]    adTimer = 0;
[*]    state.lastAdTick = MinecraftClient.worldDayTime();
[*]}
[*]
[*]function render(ctx,state,pids) {
[*]    Texture.create()
[*]      .texture("jsblock:textures/shanghai_metro_pids.png")
[*]      .pos(0,0)
[*]      .size(137,76)
[*]      .draw(ctx);
[*]    Text.create()
[*]      .text("安全是地铁运营的生命红线。乘客严禁携带易燃易爆物品;候车请站在黄线以外的区域。上下列车不冲抢,随身物品莫越界。应急按钮非儿戏,屏蔽门防夹需警惕。乘客请配合安检,遇突发情况听从指挥。一念之差关乎千万生命,请您时刻绷紧安全弦,共筑平安出行路。")
[*]      .color(0xFFFFFF)
[*]      .pos(15,65)
[*]      .size(80,10)
[*]      .scale(1.0)
[*]      .marquee(25.0)
[*]      .draw(ctx);
[*]
[*]    Text.create("Clock")
[*]      .text(PIDSUtil.formatTime(MinecraftClient.worldDayTime(), true))
[*]      .color(0xFFFFFF)
[*]      .pos(131, 67)
[*]      .scale(0.9)
[*]      .rightAlign()
[*]      .draw(ctx);
[*]
[*]    let weatherImg;
[*]    if(MinecraftClient.worldIsThundering()) {
[*]      weatherImg = "jsblock:textures/weather_thunder.png";
[*]    } else if(MinecraftClient.worldIsRaining()) {
[*]      weatherImg = "jsblock:textures/weather_raining.png";
[*]    } else {
[*]      weatherImg = "jsblock:textures/weather_sunny.png";
[*]    }
[*]
[*]    Texture.create("Weather Icon")
[*]      .texture(weatherImg)
[*]      .pos(2, 65)
[*]      .size(10, 10)
[*]      .draw(ctx);
[*]
[*]    let firstRowArrival = pids.arrivals().get(0);
[*]    if(firstRowArrival != null) {
[*]      let firstRowDestination = firstRowArrival.destination();
[*]      let parts = firstRowDestination.split("\\|");
[*]      let chinese = parts || firstRowDestination;
[*]      let english = parts || "";
[*]
[*]      Text.create("1st row destination CN")
[*]            .text(chinese)
[*]            .color(0xFFFFFF)
[*]            .marquee(3.0)
[*]            .size(48,20)
[*]            .scale(0.4)
[*]            .pos(112, 25)
[*]            .draw(ctx);
[*]
[*]      if(english) {
[*]            Text.create("1st row destination EN")
[*]                .text(english)
[*]                .color(0xFFFFFF)
[*]                .marquee(3.0)
[*]                .size(70,20)
[*]                .scale(0.3)
[*]                .pos(112, 29)
[*]                .draw(ctx);
[*]      }
[*]    }
[*]
[*]    let secondRowArrival = pids.arrivals().get(1);
[*]    if(secondRowArrival != null) {
[*]      let secondRowDestination = secondRowArrival.destination();
[*]      let parts = secondRowDestination.split("\\|");
[*]      let chinese = parts || secondRowDestination;
[*]      let english = parts || "";
[*]
[*]      Text.create("2nd row destination CN")
[*]            .text(chinese)
[*]            .color(0xFFFFFF)
[*]            .marquee(3.0)
[*]            .size(48,20)
[*]            .scale(0.4)
[*]            .pos(112, 56)
[*]            .draw(ctx);
[*]
[*]      if(english) {
[*]            Text.create("2nd row destination EN")
[*]                .text(english)
[*]                .color(0xFFFFFF)
[*]                .marquee(3.0)
[*]                .size(70,20)
[*]                .scale(0.3)
[*]                .pos(112, 60)
[*]                .draw(ctx);
[*]}
[*]
[*]    let firstRowArrival1 = pids.arrivals().get(0);
[*]    let secondRowArrival1 = pids.arrivals().get(1);
[*]    let firstRowArrivalTime = firstRowArrival1 ? (firstRowArrival1.arrivalTime() - Date.now()) / 1000 : 0;
[*]    let secondRowArrivalTime = secondRowArrival1 ? (secondRowArrival1.arrivalTime() - Date.now()) / 1000 : 0;
[*]
[*]    let seconds1 = Math.floor(firstRowArrivalTime);
[*]    let unit1 = (seconds1 % 10 < 5) ? " 秒" : " sec";
[*]    let XSfirstRowArrivalTime = (firstRowArrivalTime >= 1) ? seconds1 + unit1 : "已到站";
[*]
[*]    let seconds2 = Math.floor(secondRowArrivalTime);
[*]    let unit2 = (seconds2 % 10 < 5) ? " 秒" : " sec";
[*]    let XSsecondRowArrivalTime = (secondRowArrivalTime >= 1) ? seconds2 + unit2 : "已到站";
[*]
[*]    Text.create()
[*]      .text(XSfirstRowArrivalTime)
[*]      .color(0xFFFFFF)
[*]      .size(48,20)
[*]      .scale(0.7)
[*]      .pos(121, 16)
[*]      .centerAlign()
[*]      .draw(ctx);
[*]
[*]    Text.create()
[*]      .text(XSsecondRowArrivalTime)
[*]      .color(0xFFFFFF)
[*]      .size(48,20)
[*]      .scale(0.7)
[*]      .pos(121, 46)
[*]      .centerAlign()
[*]      .draw(ctx);
[*]
[*]    if(state.lastAdTick === undefined) {
[*]      state.lastAdTick = MinecraftClient.worldDayTime();
[*]}
[*]
[*]    var currentTick = MinecraftClient.worldDayTime();
[*]    if(currentTick - state.lastAdTick >= 200) {
[*]      state.lastAdTick = currentTick + 200;
[*]      adIndex = adIndex + 1;
[*]      if(adIndex >= adImages.length) {
[*]            adIndex = 0;
[*]    }
[*]}
[*]
[*]    Texture.create()
[*]      .texture(adImages)
[*]      .pos(2, 2)
[*]      .size(100, 60)
[*]      .draw(ctx);
[*]    }
[*]}
[*]
[*]function dispose(ctx,state,pids) {
[*]}

复制代码
你应该看到了开头的那些含有图片路径的数组,他是我们本教程的主角
刚才让你记住了你放入的广告图片的名称,你不会没记吧?如果你没记我现在给你1毫秒时间回去重记
如果你记了,注意:图片名称不要自己加一个.png,因为在系统眼里,你的照片本身就是.png格式,他会自己生成一个你看不到的后缀,如果你右键图片,点属性,就能看到他的图片全称;但如果你加了.png后缀,系统眼里的图片全称就是xxx.png.png,红色是你自己加的后缀,橙色是系统自己给你加的后缀,如果有请自己删掉,不然到时候图片成紫黑纹理了别怪我没告诉你
你应该看不懂,因为我这一块讲的确实不怎么清晰,以后会在Bilibili发视频教程,请追更UP:UID:3546659074082839
回到代码,看下面这一小块:

[*]var adImages = [
[*]"jsblock:ad_textures/ad_1.png",
[*]"jsblock:ad_textures/ad_2.png",
[*]"jsblock:ad_textures/ad_3.png",
[*]"jsblock:ad_textures/ad_4.png",
[*]"jsblock:ad_textures/ad_5.png",
[*]"jsblock:ad_textures/ad_6.png",
[*]"jsblock:ad_textures/ad_7.png",
[*]"jsblock:ad_textures/ad_8.png",
[*]"jsblock:ad_textures/ad_9.png",
[*]"jsblock:ad_textures/ad_10.png",
[*]"jsblock:ad_textures/ad_11.png",
[*]"jsblock:ad_textures/ad_12.png",
[*]"jsblock:ad_textures/ad_13.png",
[*]"jsblock:ad_textures/ad_14.png",
[*]"jsblock:ad_textures/ad_15.png",
[*]"jsblock:ad_textures/ad_16.png"
[*]];

复制代码
举个例子,假如你的广告名称叫:”广告1”,那数组应该是这样的
"jsblock:ad_textures/广告1.png"
刚才说了系统会自己加一个后缀,如果你忍不了,说:”我就要自己加后缀我有强迫症我不加我难受!”,那也不是没办法,数组这样写:
"jsblock:ad_textures/广告1.png.png"
就多加1个.png的事
差不多就这样了,详细教程以后见Bilibili
二:自定义滚动文字
找到这一行:

[*].text("安全是地铁运营的生命红线。乘客严禁携带易燃易爆物品;候车请站在黄线以外的区域。上下列车不冲抢,随身物品莫越界。应急按钮非儿戏,屏蔽门防夹需警惕。乘客请配合安检,遇突发情况听从指挥。一念之差关乎千万生命,请您时刻绷紧安全弦,共筑平安出行路。")

复制代码
这里面的文字自己可以自定义,只要不把引号删掉就行,比如:

[*].text("文字文字文字文字文字文字")

复制代码
下载链接:
https://wwbji.lanzoue.com/iTgXK43c2mcb
密码:shpids
没了,希望该帖子能帮到您,有问题或者bug反馈记得回复本帖子!



Eason424 发表于 2026-8-21 21:14:12

好活:D前来支持:)

3785439628 发表于 2026-8-21 22:24:57

Eason424 发表于 2026-8-21 21:14
好活前来支持

感谢支持~
页: [1]
查看完整版本: [MTR-4.0.4+,JCM]上海地铁风格的pids