jQuery游戏引擎插件gameQuery js代码

版权:原创 更新时间:1年以上
[该文章底部包含文件资源,可根据自己情况,决定是否下载资源使用,时间>金钱,如有需要,立即查看资源]

以下是 jQuery游戏引擎插件gameQuery js代码 的示例演示效果:

当前平台(PC电脑)
  • 平台:

部分效果截图:

jQuery游戏引擎插件gameQuery js代码

HTML代码(index.html):

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr">
<head>
    <title>jQuery��Ϸ������gameQuery</title>
    <script type="text/javascript" src="js/jquery.js"></script>
    <script type="text/javascript" src="js/jquery.gamequery.js"></script>
    <script type="text/javascript" src="js/tutorial.js"></script>
    <style type="text/css">
        html, body {
            margin: 0;
            padding: 0;
            background: black;
        }
    </style>
</head>
<body>
    <div align="center" style="width:700px; margin:0 auto">
        <div id="playground" style="width: 700px; height: 250px; background: black;">
            <div id="welcomeScreen" style="width: 700px; height: 250px; position: absolute; z-index: 100; background-image: url(images/logo.png); font-family: verdana, sans-serif;">
                <div style="position: absolute; top: 120px; width: 700px; color: white;">
                    <div id="loadingBar" style="position: relative; left: 100px; height: 15px; width: 0px; background: red;"></div><br />
                    <center><a style="cursor: pointer;" id="startbutton">Click here to start!</a></center>
                </div>
            </div>
        </div>
    </div>
</body>
</html>

JS代码(tutorial.js):

// Global constants:var PLAYGROUND_WIDTH= 700;
	var PLAYGROUND_HEIGHT= 250;
	var REFRESH_RATE= 15;
	var GRACE= 2000;
	var MISSILE_SPEED = 10;
	//px per frame/*Constants for the gameplay*/
var smallStarSpeed= 1 //pixels per framevar mediumStarSpeed= 3 //pixels per framevar bigStarSpeed= 4 //pixels per frame// Gloabl animation holdervar playerAnimation = new Array();
	var missile = new Array();
	var enemies = new Array(3);
	// There are three kind of enemies in the game// Game statevar bossMode = false;
	var bossName = null;
	var playerHit = false;
	var timeOfRespawn = 0;
	var gameOver = false;
	// Some hellper functions:// Function to restart the game:function restartgame(){
	window.location.reload();
}
;
	function explodePlayer(playerNode){
	playerNode.children().hide();
	playerNode.addSprite("explosion",{
	animation:playerAnimation["explode"],width:100,height:26}
)playerHit = true;
}
// Game objects:function Player(node){
	this.node = node;
	//this.animations = animations;
	this.grace = false;
	this.replay = 3;
	this.shield = 3;
	this.respawnTime = -1;
	// This function damage the ship and return true if this cause the ship to diethis.damage = function(){
	if(!this.grace){
	this.shield--;
	if (this.shield == 0){
	return true;
}
return false;
}
return false;
}
;
	// this try to respawn the ship after a death and return true if the game is overthis.respawn = function(){
	this.replay--;
	if(this.replay==0){
	return true;
}
this.grace= true;
	this.shield= 3;
	this.respawnTime = (new Date()).getTime();
	$(this.node).fadeTo(0,0.5);
	return false;
}
;
	this.update = function(){
	if((this.respawnTime > 0) && (((new Date()).getTime()-this.respawnTime) > 3000)){
	this.grace = false;
	$(this.node).fadeTo(500,1);
	this.respawnTime = -1;
}
}
return true;
}
function Enemy(node){
	this.shield= 2;
	this.speedx= -5;
	this.speedy= 0;
	this.node = $(node);
	// deals with damage endured by an enemythis.damage = function(){
	this.shield--;
	if(this.shield == 0){
	return true;
}
return false;
}
;
	// updates the position of the enemythis.update = function(playerNode){
	this.updateX(playerNode);
	this.updateY(playerNode);
}
;
	this.updateX = function(playerNode){
	this.node.x(this.speedx,true);
}
;
	this.updateY= function(playerNode){
	var newpos = parseInt(this.node.css("top"))+this.speedy;
	this.node.y(this.speedy,true);
}
;
}
function Minion(node){
	this.node = $(node);
}
Minion.prototype = new Enemy();
	Minion.prototype.updateY = function(playerNode){
	if(this.node.y() > (PLAYGROUND_HEIGHT - 100)){
	this.node.y(-2,true)}
}
function Brainy(node){
	this.node = $(node);
	this.shield= 5;
	this.speedy = 1;
	this.alignmentOffset = 5;
}
Brainy.prototype = new Enemy();
	Brainy.prototype.updateY = function(playerNode){
	if((this.node.y()+this.alignmentOffset) > $(playerNode).y()){
	this.node.y(-this.speedy,true);
}
else if((this.node.y()+this.alignmentOffset) < $(playerNode).y()){
	this.node.y(this.speedy,true);
}
}
function Bossy(node){
	this.node = $(node);
	this.shield= 20;
	this.speedx = -1;
	this.alignmentOffset = 35;
}
Bossy.prototype = new Brainy();
	Bossy.prototype.updateX = function(){
	if(this.node.x() > (PLAYGROUND_WIDTH - 200)){
	this.node.x(this.speedx,true)}
}
// --------------------------------------------------------------------------------------------------------------------// -- the main declaration:--// --------------------------------------------------------------------------------------------------------------------$(function(){
	// Aniomations declaration:// The background:var background1 = new $.gQ.Animation({
	imageURL:"images/background1.png"}
);
	var background2 = new $.gQ.Animation({
	imageURL:"images/background2.png"}
);
	var background3 = new $.gQ.Animation({
	imageURL:"images/background3.png"}
);
	var background4 = new $.gQ.Animation({
	imageURL:"images/background4.png"}
);
	var background5 = new $.gQ.Animation({
	imageURL:"images/background5.png"}
);
	var background6 = new $.gQ.Animation({
	imageURL:"images/background6.png"}
);
	// Player space shipannimations:playerAnimation["idle"]= new $.gQ.Animation({
	imageURL:"images/player_spaceship.png"}
);
	playerAnimation["explode"]= new $.gQ.Animation({
	imageURL:"images/player_explode.png",numberOfFrame:4,delta:26,rate:60,type:$.gQ.ANIMATION_VERTICAL}
);
	playerAnimation["up"]= new $.gQ.Animation({
	imageURL:"images/boosterup.png",numberOfFrame:6,delta:14,rate:60,type:$.gQ.ANIMATION_HORIZONTAL}
);
	playerAnimation["down"]= new $.gQ.Animation({
	imageURL:"images/boosterdown.png",numberOfFrame:6,delta:14,rate:60,type:$.gQ.ANIMATION_HORIZONTAL}
);
	playerAnimation["boost"]= new $.gQ.Animation({
	imageURL:"images/booster1.png",numberOfFrame:6,delta:14,rate:60,type:$.gQ.ANIMATION_VERTICAL}
);
	playerAnimation["booster"]= new $.gQ.Animation({
	imageURL:"images/booster2.png",numberOfFrame:6,delta:14,rate:60,type:$.gQ.ANIMATION_VERTICAL}
);
	// List of enemies animations:// 1st kind of enemy:enemies[0] = new Array();
	// enemies have two animationsenemies[0]["idle"]= new $.gQ.Animation({
	imageURL:"images/minion_idle.png",numberOfFrame:5,delta:52,rate:60,type:$.gQ.ANIMATION_VERTICAL}
);
	enemies[0]["explode"]= new $.gQ.Animation({
	imageURL:"images/minion_explode.png",numberOfFrame:11,delta:52,rate:30,type:$.gQ.ANIMATION_VERTICAL | $.gQ.ANIMATION_CALLBACK}
);
	// 2nd kind of enemy:enemies[1] = new Array();
	enemies[1]["idle"]= new $.gQ.Animation({
	imageURL:"images/brainy_idle.png",numberOfFrame:8,delta:42,rate:60,type:$.gQ.ANIMATION_VERTICAL}
);
	enemies[1]["explode"]= new $.gQ.Animation({
	imageURL:"images/brainy_explode.png",numberOfFrame:8,delta:42,rate:60,type:$.gQ.ANIMATION_VERTICAL | $.gQ.ANIMATION_CALLBACK}
);
	// 3rd kind of enemy:enemies[2] = new Array();
	enemies[2]["idle"]= new $.gQ.Animation({
	imageURL:"images/bossy_idle.png",numberOfFrame:5,delta:100,rate:60,type:$.gQ.ANIMATION_VERTICAL}
);
	enemies[2]["explode"]= new $.gQ.Animation({
	imageURL:"images/bossy_explode.png",numberOfFrame:9,delta:100,rate:60,type:$.gQ.ANIMATION_VERTICAL | $.gQ.ANIMATION_CALLBACK}
);
	// Weapon missile:missile["player"] = new $.gQ.Animation({
	imageURL:"images/player_missile.png",numberOfFrame:6,delta:10,rate:90,type:$.gQ.ANIMATION_VERTICAL}
);
	missile["enemies"] = new $.gQ.Animation({
	imageURL:"images/enemy_missile.png",numberOfFrame:6,delta:15,rate:90,type:$.gQ.ANIMATION_VERTICAL}
);
	missile["playerexplode"] = new $.gQ.Animation({
	imageURL:"images/player_missile_explode.png",numberOfFrame:8,delta:23,rate:90,type:$.gQ.ANIMATION_VERTICAL | $.gQ.ANIMATION_CALLBACK}
);
	missile["enemiesexplode"] = new $.gQ.Animation({
	imageURL:"images/enemy_missile_explode.png",numberOfFrame:6,delta:15,rate:90,type:$.gQ.ANIMATION_VERTICAL | $.gQ.ANIMATION_CALLBACK}
);
	// Initialize the game:$("#playground").playground({
	height:PLAYGROUND_HEIGHT,width:PLAYGROUND_WIDTH,keyTracker:true}
);
	// Initialize the background$.playground().addGroup("background",{
	width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
).addSprite("background1",{
	animation:background1,width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
).addSprite("background2",{
	animation:background2,width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT,posx:PLAYGROUND_WIDTH}
).addSprite("background3",{
	animation:background3,width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
).addSprite("background4",{
	animation:background4,width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT,posx:PLAYGROUND_WIDTH}
).addSprite("background5",{
	animation:background5,width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
).addSprite("background6",{
	animation:background6,width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT,posx:PLAYGROUND_WIDTH}
).end().addGroup("actors",{
	width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
).addGroup("player",{
	posx:PLAYGROUND_WIDTH/2,posy:PLAYGROUND_HEIGHT/2,width:100,height:26}
).addSprite("playerBoostUp",{
	posx:37,posy:15,width:14,height:18}
).addSprite("playerBody",{
	animation:playerAnimation["idle"],posx:0,posy:0,width:100,height:26}
).addSprite("playerBooster",{
	animation:playerAnimation["boost"],posx:-32,posy:5,width:36,height:14}
).addSprite("playerBoostDown",{
	posx:37,posy:-7,width:14,height:18}
).end().end().addGroup("playerMissileLayer",{
	width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
).end().addGroup("enemiesMissileLayer",{
	width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
).end().addGroup("overlay",{
	width:PLAYGROUND_WIDTH,height:PLAYGROUND_HEIGHT}
);
	$("#player")[0].player = new Player($("#player"));
	//this is the HUD for the player life and shield$("#overlay").append("<div id='shieldHUD'style='color:white;
	width:100px;
	position:absolute;
	font-family:verdana,sans-serif;
	'></div><div id='lifeHUD'style='color:white;
	width:100px;
	position:absolute;
	right:0px;
	font-family:verdana,sans-serif;
	'></div>")// this sets the id of the loading bar:$.loadCallback(function(percent){
	$("#loadingBar").width(400*percent);
}
);
	//initialize the start button$("#startbutton").click(function(){
	$.playground().startGame(function(){
	$("#welcomeScreen").fadeTo(1000,0,function(){
	$(this).remove();
}
);
}
);
}
)// this is the function that control most of the game logic$.playground().registerCallback(function(){
	if(!gameOver){
	$("#shieldHUD").html("shield:"+$("#player")[0].player.shield);
	$("#lifeHUD").html("life:"+$("#player")[0].player.replay);
	//Update the movement of the ship:if(!playerHit){
	$("#player")[0].player.update();
	if(jQuery.gameQuery.keyTracker[65]){
	//this is left! (a)var nextpos = $("#player").x()-5;
	if(nextpos > 0){
	$("#player").x(nextpos);
}
}
if(jQuery.gameQuery.keyTracker[68]){
	//this is right! (d)var nextpos = $("#player").x()+5;
	if(nextpos < PLAYGROUND_WIDTH - 100){
	$("#player").x(nextpos);
}
}
if(jQuery.gameQuery.keyTracker[87]){
	//this is up! (w)var nextpos = $("#player").y()-3;
	if(nextpos > 0){
	$("#player").y(nextpos);
}
}
if(jQuery.gameQuery.keyTracker[83]){
	//this is down! (s)var nextpos = $("#player").y()+3;
	if(nextpos < PLAYGROUND_HEIGHT - 30){
	$("#player").y(nextpos);
}
}
}
else{
	var posy = $("#player").y()+5;
	var posx = $("#player").x()-5;
	if(posy > PLAYGROUND_HEIGHT){
	//Does the player did get out of the screen?if($("#player")[0].player.respawn()){
	gameOver = true;
	$("#playground").append('<div style="position:absolute;
	top:50px;
	width:700px;
	color:white;
	font-family:verdana,sans-serif;
	"><center><h1>Game Over</h1><br><a style="cursor:pointer;
	" id="restartbutton">Click here to restart the game!</a></center></div>');
	$("#restartbutton").click(restartgame);
	$("#actors,#playerMissileLayer,#enemiesMissileLayer").fadeTo(1000,0);
	$("#background").fadeTo(5000,0);
}
else{
	$("#explosion").remove();
	$("#player").children().show();
	$("#player").y(PLAYGROUND_HEIGHT / 2);
	$("#player").x(PLAYGROUND_WIDTH / 2);
	playerHit = false;
}
}
else{
	$("#player").y(posy);
	$("#player").x(posx);
}
}
//Update the movement of the enemies$(".enemy").each(function(){
	this.enemy.update($("#player"));
	var posx = $(this).x();
	if((posx + 100) < 0){
	$(this).remove();
	return;
}
//Test for collisionsvar collided = $(this).collision("#playerBody,."+$.gQ.groupCssClass);
	if(collided.length > 0){
	if(this.enemy instanceof Bossy){
	$(this).setAnimation(enemies[2]["explode"],function(node){
	$(node).remove();
}
);
	$(this).css("width",150);
}
else if(this.enemy instanceof Brainy){
	$(this).setAnimation(enemies[1]["explode"],function(node){
	$(node).remove();
}
);
	$(this).css("width",150);
}
else{
	$(this).setAnimation(enemies[0]["explode"],function(node){
	$(node).remove();
}
);
	$(this).css("width",200);
}
$(this).removeClass("enemy");
	//The player has been hit!if($("#player")[0].player.damage()){
	explodePlayer($("#player"));
}
}
//Make the enemy fireif(this.enemy instanceof Brainy){
	if(Math.random() < 0.05){
	var enemyposx = $(this).x();
	var enemyposy = $(this).y();
	var name = "enemiesMissile_"+Math.ceil(Math.random()*1000);
	$("#enemiesMissileLayer").addSprite(name,{
	animation:missile["enemies"],posx:enemyposx,posy:enemyposy + 20,width:30,height:15}
);
	$("#"+name).addClass("enemiesMissiles");
}
}
}
);
	//Update the movement of the missiles$(".playerMissiles").each(function(){
	var posx = $(this).x();
	if(posx > PLAYGROUND_WIDTH){
	$(this).remove();
	return;
}
$(this).x(MISSILE_SPEED,true);
	//Test for collisionsvar collided = $(this).collision(".enemy,."+$.gQ.groupCssClass);
	if(collided.length > 0){
	//An enemy has been hit!collided.each(function(){
	if($(this)[0].enemy.damage()){
	if(this.enemy instanceof Bossy){
	$(this).setAnimation(enemies[2]["explode"],function(node){
	$(node).remove();
}
);
	$(this).css("width",150);
}
else if(this.enemy instanceof Brainy){
	$(this).setAnimation(enemies[1]["explode"],function(node){
	$(node).remove();
}
);
	$(this).css("width",150);
}
else{
	$(this).setAnimation(enemies[0]["explode"],function(node){
	$(node).remove();
}
);
	$(this).css("width",200);
}
$(this).removeClass("enemy");
}
}
)$(this).setAnimation(missile["playerexplode"],function(node){
	$(node).remove();
}
);
	$(this).css("width",38);
	$(this).css("height",23);
	$(this).y(-7,true);
	$(this).removeClass("playerMissiles");
}
}
);
	$(".enemiesMissiles").each(function(){
	var posx = $(this).x();
	if(posx < 0){
	$(this).remove();
	return;
}
$(this).x(-MISSILE_SPEED,true);
	//Test for collisionsvar collided = $(this).collision("#playerBody,."+$.gQ.groupCssClass);
	if(collided.length > 0){
	//The player has been hit!collided.each(function(){
	if($("#player")[0].player.damage()){
	explodePlayer($("#player"));
}
}
)//$(this).remove();
	$(this).setAnimation(missile["enemiesexplode"],function(node){
	$(node).remove();
}
);
	$(this).removeClass("enemiesMissiles");
}
}
);
}
}
,REFRESH_RATE);
	//This function manage the creation of the enemies$.playground().registerCallback(function(){
	if(!bossMode && !gameOver){
	if(Math.random() < 0.4){
	var name = "enemy1_"+Math.ceil(Math.random()*1000);
	$("#actors").addSprite(name,{
	animation:enemies[0]["idle"],posx:PLAYGROUND_WIDTH,posy:Math.random()*PLAYGROUND_HEIGHT,width:150,height:52}
);
	$("#"+name).addClass("enemy");
	$("#"+name)[0].enemy = new Minion($("#"+name));
}
else if (Math.random() < 0.5){
	var name = "enemy1_"+Math.ceil(Math.random()*1000);
	$("#actors").addSprite(name,{
	animation:enemies[1]["idle"],posx:PLAYGROUND_WIDTH,posy:Math.random()*PLAYGROUND_HEIGHT,width:100,height:42}
);
	$("#"+name).addClass("enemy");
	$("#"+name)[0].enemy = new Brainy($("#"+name));
}
else if(Math.random() > 0.8){
	bossMode = true;
	bossName = "enemy1_"+Math.ceil(Math.random()*1000);
	$("#actors").addSprite(bossName,{
	animation:enemies[2]["idle"],posx:PLAYGROUND_WIDTH,posy:Math.random()*PLAYGROUND_HEIGHT,width:100,height:100}
);
	$("#"+bossName).addClass("enemy");
	$("#"+bossName)[0].enemy = new Bossy($("#"+bossName));
}
}
else{
	if($("#"+bossName).length == 0){
	bossMode = false;
}
}
}
,1000);
	//once per seconds is enough for this//This is for the background animation$.playground().registerCallback(function(){
	//Offset all the pane:var newPos = ($("#background1").x() - smallStarSpeed - PLAYGROUND_WIDTH) % (-2 * PLAYGROUND_WIDTH) + PLAYGROUND_WIDTH;
	$("#background1").x(newPos);
	newPos = ($("#background2").x() - smallStarSpeed - PLAYGROUND_WIDTH) % (-2 * PLAYGROUND_WIDTH) + PLAYGROUND_WIDTH;
	$("#background2").x(newPos);
	newPos = ($("#background3").x() - mediumStarSpeed - PLAYGROUND_WIDTH) % (-2 * PLAYGROUND_WIDTH) + PLAYGROUND_WIDTH;
	$("#background3").x(newPos);
	newPos = ($("#background4").x() - mediumStarSpeed - PLAYGROUND_WIDTH) % (-2 * PLAYGROUND_WIDTH) + PLAYGROUND_WIDTH;
	$("#background4").x(newPos);
	newPos = ($("#background5").x() - bigStarSpeed - PLAYGROUND_WIDTH) % (-2 * PLAYGROUND_WIDTH) + PLAYGROUND_WIDTH;
	$("#background5").x(newPos);
	newPos = ($("#background6").x() - bigStarSpeed - PLAYGROUND_WIDTH) % (-2 * PLAYGROUND_WIDTH) + PLAYGROUND_WIDTH;
	$("#background6").x(newPos);
}
,REFRESH_RATE);
	//this is where the keybinding occurs$(document).keydown(function(e){
	if(!gameOver && !playerHit){
	switch(e.keyCode){
	case 75://this is shoot (k)//shoot missile herevar playerposx = $("#player").x();
	var playerposy = $("#player").y();
	var name = "playerMissle_"+Math.ceil(Math.random()*1000);
	$("#playerMissileLayer").addSprite(name,{
	animation:missile["player"],posx:playerposx + 90,posy:playerposy + 14,width:36,height:10}
);
	$("#"+name).addClass("playerMissiles")break;
	case 65://this is left! (a)$("#playerBooster").setAnimation();
	break;
	case 87://this is up! (w)$("#playerBoostUp").setAnimation(playerAnimation["up"]);
	break;
	case 68://this is right (d)$("#playerBooster").setAnimation(playerAnimation["booster"]);
	break;
	case 83://this is down! (s)$("#playerBoostDown").setAnimation(playerAnimation["down"]);
	break;
}
}
}
);
	//this is where the keybinding occurs$(document).keyup(function(e){
	if(!gameOver && !playerHit){
	switch(e.keyCode){
	case 65://this is left! (a)$("#playerBooster").setAnimation(playerAnimation["boost"]);
	break;
	case 87://this is up! (w)$("#playerBoostUp").setAnimation();
	break;
	case 68://this is right (d)$("#playerBooster").setAnimation(playerAnimation["boost"]);
	break;
	case 83://this is down! (s)$("#playerBoostDown").setAnimation();
	break;
}
}
}
);
}
);
	
附件:下载该文件资源,减少时间成本(增值服务)
留言
该资源可下载
File Source
.rar
943.65 KB
jquery特效6
最新结算
jquery虚拟键盘中文打字效果js代码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
jquery虚拟键盘中文打字效果js代码
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
HTML5实现CSS滤镜图片切换特效代码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
jQuery头像裁剪插件cropbox js代码
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
jQuery头像裁剪插件cropbox js代码
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
CSS3制作3D图片立方体旋转特效
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
CSS3制作3D图片立方体旋转特效
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
CSS3制作3D图片立方体旋转特效
类型: .rar 金额: CNY 2.31¥ 状态: 待结算 详细>
CSS3制作3D图片立方体旋转特效
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
jQuery+css3实现信封效果
类型: .rar 金额: CNY 0.29¥ 状态: 待结算 详细>
我们力求给您提供有用的文章,再此基础上,会附加营收资源,不做任何广告,让平台可以更好发展 若您发现您的权利被侵害,或使用了您的版权,请发邮件联系 sunlifel@foxmail.com ggbig觉得 : 不提供源码的文章不是好文章
合作伙伴
联系我们
  • QQ:21499807
  • 邮箱:sunlifel@foxmail.com
  • QQ扫一扫加QQ
    QQ扫一扫
Copyright 2023-2024 ggbig.com·皖ICP备2023004211号-1
打赏文章