🎨 新增神秘药水道具及商店样式调整

This commit is contained in:
Flern 2025-01-06 18:57:56 +08:00
parent df95a72a5c
commit d8336a049e
18 changed files with 403 additions and 52 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 604 KiB

View File

@ -27,7 +27,7 @@ body {
}
.wrapper {
width: 800px;
width: 850px;
font-family: "hywhFont";
padding: 10px 0;
background-color: #fbe4e4;
@ -36,17 +36,19 @@ body {
.top-title {
color: #e87692;
font-size: 50px;
font-size: 85px;
text-align: center;
font-family: "fzrzFont";
margin-bottom: -30px;
}
.split {
background-image: url("./res/img/split.png");
background-size: contain;
background-repeat: no-repeat;
background-position: center;
height: 41px;
height: 15px;
margin-top: 70px;
margin-bottom: 30px;
}
.top-head {
@ -54,11 +56,23 @@ body {
background-size: contain;
background-repeat: no-repeat;
background-position: center;
height: 400px;
height: 586px;
}
.top-aaaa {
font-family: 'syhtFont';
font-size: 34px;
text-align: center;
color: #E87692;
height: 50px;
}
.shop-border {
margin-bottom: 50px;
}
.shop-item {
padding-top: 30px;
padding-top: 100px;
box-sizing: border-box;
}
@ -87,7 +101,7 @@ body {
.shop-item-left {
min-height: 460px;
position: relative;
width: 140px;
width: 158px;
}
.shop-item-left-qq {
@ -96,11 +110,14 @@ body {
}
.left-img {
left: 10px;
position: absolute;
left: 5px;
z-index: 10;
}
.shop-item-right {
width: 130px;
width: 210px;
position: relative;
}
.shop-item-right-zx {
@ -111,7 +128,9 @@ body {
}
.right-img {
right: 10px;
position: absolute;
right: -2px;
z-index: 10;
}
.shop-item-mid {
@ -279,10 +298,6 @@ body {
z-index: 4;
}
.bottom-s {
margin-top: 70px;
}
.goods-item-name {
font-size: 18px;
font-family: "syhtFont";
@ -295,3 +310,11 @@ body {
background-color: #731c1c;
border-radius: 10px;
}
.create-text {
position: absolute;
bottom: 1px;
right: 10px;
color: #97979c;
font-size: 15px;
}

View File

@ -15,7 +15,8 @@
<div class="top-title">
{{name}}的神秘商店
</div>
<div class="split"></div>
<div class="top-aaaa">“使用 '购买道具 [道具ID/道具名称]' 购买道具”</div>
<div class="split" style="margin-top: 30px;"></div>
<div class="top-head"></div>
<div class="shop-border">
{% for data in data_list %}
@ -25,8 +26,6 @@
</div>
<div class="shop-item-border">
<div class="shop-item-left">
<img src="./res/img/{{data.left_image[2]}}" class="{{data.left_image[1]}} left-img"
style="top:{{data.left_image[0]}}px" />
</div>
<div class="shop-item-mid">
<div class="shop-item-mid-bk-inner"></div>
@ -68,8 +67,6 @@
<img src="./res/img/bag2.png" class="shop-item-mid-bag2" />
</div>
<div class="shop-item-right">
<img src="./res/img/{{data.right_image[2]}}" class="{{data.right_image[1]}} right-img"
style="top:{{data.right_image[0]}}px" />
</div>
</div>
@ -121,7 +118,8 @@
</div>
{% endfor %}
</div>
<div class="split bottom-s"></div>
<div class="split"></div>
<div class="create-text">Create By ZhenXun</div>
</div>
</body>
<script type="text/javascript" src="main.js">

View File

@ -0,0 +1,183 @@
const leftElements = document.getElementsByClassName("shop-item-left")
const rightElements = document.getElementsByClassName("shop-item-right")
const defaultList = [
"1.png",
"2.png",
"3.png",
"4.png",
"5.png",
"qq.png",
"xx1.png",
"xx2.png",
]
const leftRightImgList = ["1.png", "2.png", "3.png", "4.png", "5.png"]
const leftRightImgList2 = ["qq.png", "xx1.png", "xx2.png"]
var leftRightImg = null
var leftRightImg2 = null
function randomImg() {
const randomIndex = Math.floor(Math.random() * leftRightImgList.length)
const randImg = leftRightImgList[randomIndex]
if (leftRightImg == randImg) {
return randomImg()
}
leftRightImg = randImg
return randImg
}
function randomImg2() {
const randomIndex = Math.floor(Math.random() * leftRightImgList2.length)
const randImg = leftRightImgList2[randomIndex]
if (leftRightImg == randImg) {
return randomImg2()
}
leftRightImg2 = randImg
return randImg
}
function getRandomInt(min, max) {
const mathMin = Math.ceil(min)
const mathMax = Math.floor(max)
return Math.floor(Math.random() * (mathMax - mathMin + 1)) + mathMin
}
function createImgElement(is_qq, is_left, start_height, height) {
const imgElement = document.createElement("img")
const className = is_left ? "left-img" : "right-img"
if (is_qq) {
imgElement.className = "shop-item-left-qq " + className
imgElement.src = "./res/img/left_right/" + randomImg2()
imgElement.style.top = getRandomInt(start_height, height - 20) + "px"
if (is_left) {
imgElement.style.left = getRandomInt(10, 40) + "px"
} else {
imgElement.style.right = getRandomInt(10, 40) + "px"
}
imgElement.style.height = getRandomInt(80, 120) + "px"
imgElement.style.transform = "rotate(" + getRandomInt(0, 45) + "deg)"
} else {
imgElement.className = "shop-item-right-zx " + className
imgElement.src = "./res/img/left_right/" + randomImg()
imgElement.style.top = getRandomInt(start_height, height - 20) + "px"
}
return imgElement
}
function getTop(dom) {
return parseInt(dom.style.top.slice(0, -2))
}
const randomIndex = Math.floor(Math.random() * defaultList.length)
const leftImg = defaultList[randomIndex]
var start = true
if (["qq.png", "xx1.png", "xx2.png"].includes(leftImg)) {
start = true
} else {
start = false
}
for (let i = 0; i < leftElements.length; i++) {
leftHeight = leftElements[i].offsetHeight
if (leftHeight <= 1000) {
// 长度不够,只增加一个
if (start) {
leftElements[i].appendChild(
createImgElement(true, true, 20, leftHeight - 50)
)
rightElements[i].appendChild(createImgElement(false, false, 10, 60))
} else {
leftElements[i].appendChild(createImgElement(false, true, 10, 60))
rightElements[i].appendChild(
createImgElement(true, false, 20, leftHeight - 50)
)
}
} else {
// 先添加一个气球
const firstDom = createImgElement(true, true, 20, 200)
leftElements[i].appendChild(firstDom)
let startHeight = 100 + getTop(firstDom)
let endHeight = 300 + getTop(firstDom)
let firstIsQq = false
let inx = 0
while (leftHeight - endHeight >= 200) {
// 避免过多重复
rand = Math.random()
if (inx >= 2) {
rand = 0.4
inx = 0
}
if (inx <= -1) {
rand = 0.6
inx = 0
}
// 真寻和气球随机加
if (rand > 0.5) {
firstIsQq = true
inx += 1
const imgDom = createImgElement(true, true, startHeight, endHeight)
leftElements[i].appendChild(imgDom)
startHeight = getRandomInt(250, 350) + getTop(imgDom)
endHeight = getRandomInt(450, 500) + getTop(imgDom)
} else {
if (leftHeight - startHeight < 700) {
continue
}
inx -= 1
const imgDom = createImgElement(false, true, startHeight, endHeight)
leftElements[i].appendChild(imgDom)
startHeight = getRandomInt(400, 700) + getTop(imgDom)
endHeight = getRandomInt(600, 900) + getTop(imgDom)
if (leftHeight - startHeight < 900) {
break
}
}
}
startHeight = 10
endHeight = 200
inx = 0
while (leftHeight - endHeight >= 200) {
// 真寻和气球随机加
rand = Math.random()
if (rand > 0.5 && firstIsQq) {
firstIsQq = false
rand = 0.4
}
// 避免过多重复
if (inx >= 2) {
rand = 0.4
inx = 0
}
if (inx <= -1) {
rand = 0.6
inx = 0
}
if (rand > 0.5) {
inx += 1
const imgDom = createImgElement(true, false, startHeight, endHeight)
rightElements[i].appendChild(imgDom)
startHeight = getRandomInt(250, 350) + getTop(imgDom)
endHeight = getRandomInt(450, 500) + getTop(imgDom)
} else {
if (leftHeight - startHeight < 700) {
continue
}
inx -= 1
const imgDom = createImgElement(false, false, startHeight, endHeight)
rightElements[i].appendChild(imgDom)
startHeight = getRandomInt(400, 700) + getTop(imgDom)
endHeight = getRandomInt(600, 900) + getTop(imgDom)
}
}
}
start = !start
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

View File

Before

Width:  |  Height:  |  Size: 122 KiB

After

Width:  |  Height:  |  Size: 122 KiB

View File

Before

Width:  |  Height:  |  Size: 142 KiB

After

Width:  |  Height:  |  Size: 142 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 257 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 236 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 278 KiB

View File

Before

Width:  |  Height:  |  Size: 4.8 KiB

After

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 48 KiB

View File

@ -25,6 +25,7 @@ from zhenxun.utils.message import MessageUtils
from zhenxun.utils.platform import PlatformUtils
from ._data_source import ShopManage, gold_rank
from .goods_register import * # noqa: F403
__plugin_meta__ = PluginMetadata(
name="商店",

View File

@ -0,0 +1,161 @@
from zhenxun.models.user_console import UserConsole
from zhenxun.utils.decorator.shop import shop_register
@shop_register(
name="神秘药水",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="小秘密",
icon="mysterious_potion.png",
)
async def _(user_id: str):
await UserConsole.add_gold(
user_id,
1000000,
"shop",
)
return "使用道具神秘药水成功!你滴金币+1000000"
@shop_register(
name="测试道具A1",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A2",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A3",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A4",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A5",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A6",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A7",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A8",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A9",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A10",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A11",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A12",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass
@shop_register(
name="测试道具A13",
price=999999,
des="鬼知道会有什么效果,要不试试?",
partition="TEST",
icon="mysterious_potion.png",
)
async def _(user_id: str):
pass

View File

@ -1,4 +1,3 @@
import random
import time
from nonebot_plugin_htmlrender import template_to_pic
@ -9,7 +8,7 @@ from zhenxun.configs.path_config import TEMPLATE_PATH
from zhenxun.models.goods_info import GoodsInfo
from zhenxun.utils._build_image import BuildImage
from .config import ICON_PATH, LEFT_RIGHT_IMAGE
from .config import ICON_PATH
class GoodsItem(BaseModel):
@ -17,30 +16,6 @@ class GoodsItem(BaseModel):
"""商品列表"""
partition: str
"""分区名称"""
left_image: tuple[int, str, str]
"""左图"""
right_image: tuple[int, str, str]
"""右图"""
def get_left_right_image() -> tuple[tuple[int, str, str], tuple[int, str, str]]:
qq_top = random.randint(0, 280)
img_top = random.randint(10, 80)
left_image = random.choice(LEFT_RIGHT_IMAGE)
right_image = None
if left_image == "qq.png":
left_top = qq_top
right_top = img_top
left_css = "shop-item-left-qq"
right_css = "shop-item-right-zx"
right_image = random.choice(LEFT_RIGHT_IMAGE[:-1])
else:
left_top = img_top
right_top = qq_top
right_image = "qq.png"
left_css = "shop-item-right-zx"
right_css = "shop-item-left-qq"
return (left_top, left_css, left_image), (right_top, right_css, right_image)
async def html_image() -> bytes:
@ -69,13 +44,10 @@ async def html_image() -> bytes:
)
data_list = []
for partition in partition_dict:
left, right = get_left_right_image()
data_list.append(
GoodsItem(
goods_list=partition_dict[partition],
partition=partition,
left_image=left,
right_image=right,
)
)
@ -84,7 +56,7 @@ async def html_image() -> bytes:
template_name="main.html",
templates={"name": BotConfig.self_nickname, "data_list": data_list},
pages={
"viewport": {"width": 800, "height": 1024},
"viewport": {"width": 850, "height": 1024},
"base_url": f"file://{TEMPLATE_PATH}",
},
wait=2,

View File

@ -46,6 +46,7 @@ class GoodsInfo(Model):
goods_limit_time: int = 0,
daily_limit: int = 0,
is_passive: bool = False,
partition: str | None = None,
icon: str | None = None,
) -> str:
"""添加商品
@ -58,6 +59,7 @@ class GoodsInfo(Model):
goods_limit_time: 商品限时
daily_limit: 每日购买限制
is_passive: 是否为被动道具
partition: 分区名称
icon: 图标
"""
if not await cls.exists(goods_name=goods_name):
@ -71,6 +73,7 @@ class GoodsInfo(Model):
goods_limit_time=goods_limit_time,
daily_limit=daily_limit,
is_passive=is_passive,
partition=partition,
icon=icon,
)
return str(uuid_)

View File

@ -17,6 +17,7 @@ class Goods(BaseModel):
daily_limit: int
icon: str | None = None
is_passive: bool
partition: str | None
func: Callable
kwargs: dict[str, str] = {}
send_success_msg: bool
@ -73,6 +74,7 @@ class ShopRegister(dict):
load_status: tuple[bool, ...],
daily_limit: tuple[int, ...],
is_passive: tuple[bool, ...],
partition: tuple[str, ...],
icon: tuple[str, ...],
send_success_msg: tuple[bool, ...],
max_num_limit: tuple[int, ...],
@ -89,6 +91,7 @@ class ShopRegister(dict):
load_status: 是否加载
daily_limit: 每日限购
is_passive: 是否被动道具
partition: 分区名称
icon: 图标
send_success_msg: 成功时发送消息
max_num_limit: 单次最大使用次数
@ -97,7 +100,7 @@ class ShopRegister(dict):
def add_register_item(func: Callable):
if name in self._data.keys():
raise ValueError("该商品已注册,请替换其他名称!")
for n, p, d, dd, lmt, s, dl, pa, i, ssm, mnl in zip(
for n, p, d, dd, lmt, s, dl, pa, par, i, ssm, mnl in zip(
name,
price,
des,
@ -106,6 +109,7 @@ class ShopRegister(dict):
load_status,
daily_limit,
is_passive,
partition,
icon,
send_success_msg,
max_num_limit,
@ -124,6 +128,7 @@ class ShopRegister(dict):
limit_time=lmt,
daily_limit=dl,
is_passive=pa,
partition=par,
func=func,
send_success_msg=ssm,
max_num_limit=mnl,
@ -135,6 +140,7 @@ class ShopRegister(dict):
goods.daily_limit = dl
goods.icon = i
goods.is_passive = pa
goods.partition = par
goods.func = func
goods.kwargs = _temp_kwargs
goods.send_success_msg = ssm
@ -162,6 +168,7 @@ class ShopRegister(dict):
goods.limit_time,
goods.daily_limit,
goods.is_passive,
goods.partition,
goods.icon,
)
if uuid:
@ -186,6 +193,7 @@ class ShopRegister(dict):
load_status: bool | tuple[bool, ...] = True,
daily_limit: int | tuple[int, ...] = 0,
is_passive: bool | tuple[bool, ...] = False,
partition: str | tuple[str, ...] | None = None,
icon: str | tuple[str, ...] = "",
send_success_msg: bool | tuple[bool, ...] = True,
max_num_limit: int | tuple[int, ...] = 1,
@ -202,11 +210,11 @@ class ShopRegister(dict):
load_status: 是否加载
daily_limit: 每日限购
is_passive: 是否被动道具
partition: 分区名称
icon: 图标
send_success_msg: 成功时发送消息
max_num_limit: 单次最大使用次数
"""
_tuple_list = []
_current_len = -1
for x in [name, price, des, discount, limit_time, load_status]:
if isinstance(x, tuple):
@ -226,6 +234,7 @@ class ShopRegister(dict):
_load_status = self.__get(load_status, _current_len)
_daily_limit = self.__get(daily_limit, _current_len)
_is_passive = self.__get(is_passive, _current_len)
_partition = self.__get(partition, _current_len)
_icon = self.__get(icon, _current_len)
_send_success_msg = self.__get(send_success_msg, _current_len)
_max_num_limit = self.__get(max_num_limit, _current_len)
@ -238,6 +247,7 @@ class ShopRegister(dict):
_load_status,
_daily_limit,
_is_passive,
_partition,
_icon,
_send_success_msg,
_max_num_limit,