基于Java实现的潜艇大战游戏

news2024/11/29 6:35:46

基于Java实现的潜艇大战游戏

一.需求分析

1.1 设计任务

本次游戏课程设计小组成员团队合作的方式,通过游戏总体分析设计,场景画面的绘制,游戏事件的处理,游戏核心算法的分析实现,游戏的碰撞检测,游戏的反复测试,游戏的打包运行等一个完整的游戏设计编码实现的整个过程。进一步提高编写结构清晰,扩展性好,风格良好的应用程序,进一步提高思考解决实际问题的工程能力。

1.2 功能需求

  • 玩家进入游戏,退出游戏的功能,没有过关重玩的功能
  • 玩家开始游戏,暂停游戏,查看游戏规则
  • 玩家键盘A,D(快捷键)鼠标操作实现战舰的移动和投导弹攻击潜艇
  • 潜艇左面出,向右移动,每一个时间间隔向上投鱼雷攻击战舰
  • 战舰和潜艇被攻击后有相应的爆炸特效和对应的音效
  • 玩家的得分统计,进入前十就提示输入姓名,当前最高分的查看
  • 玩家通过的关口统计,下一关口难度增加的设置

1.3 用例模型

  • Actor主要为玩家和游戏系统
  • 玩家 user case 包括 开始游戏,操作战舰,退出游戏,暂停游戏,得分关卡,进入排行榜
  • 游戏系统 user case 潜艇出击,爆炸效果,积分榜重置,结束游戏,场景画面

1.4 性能需求

技术可行性

Windows8.1下的开发平台,Windows 8.1的运行平台,使用Java Swing+AWT图形界面制作客户端程序的技术,界面友好,功能齐全,音效动感,操作简单,的一款潜艇大战游戏.

经济可行性

游戏的关卡设计,使游戏的趣味性高,音效设计,都是基于素材网上的免费资源,单机游戏,开发平台在本地,一台装有JAVA的PC即可提供硬件环境,成本极低。

操作可性性

键盘操作,加快捷键和鼠标结合,提供完整游戏规则,查看即可学习,立刻就可以玩起来,操作非常简单。

1.5 系统结构图

1.6 系统流程图

二.游戏功能内容设计

2.1 工程结构图

2.2 游戏界面绘制

2.2.1 进入游戏界面绘制

首先使用Swing组件的JFrame完成窗口的绘制,包括大小,位置,背景图片,按钮的排放,布局采用BorderLayout的边框布局方式.窗口图标采用Toolkit.getDefaultToolkit().getImage(imgUrl)

2.2.2 游戏主界面的绘制

上面的进入游戏的界面点击进入游戏后切换至主界面里面后,完成主界面的颜色背景绘制,主要使用Graphics2D设置相应的颜色代码完成实现。上面的菜单栏采用JMenuBar,JMenu,JMenuItem来完成绘制。至于得分,关数是在指定的位置绘制的。那个游戏的最高分是从游戏玩家排行榜里面读取出来然后绘制的,命数是自定义的3条。在程序里面设置好的。然后就是战舰和导弹的绘制了的.战舰封装一个战舰对象然后结合Image对象加载图片设置位置来实现的.导弹是初始设置五个,通过线程的方式指定的时间内绘制即可。最多为5个,最小为0个.绘制的时候要注意判断当前的导弹数量来绘制的。

2.2.3 游戏对话框的绘制

实现的方法就是继承JDialog对话框+Graphics2D设置宽高和位置就可以设置的,例如帮助对话框的实现。

private static final long serialVersionUID = 1L;
protected JFrame    frame1;
private MyPanel panel;
private boolean   flag = false;
private boolean   isDraw = false;
private boolean   isOutDraw = false;
/** 设置对话框为圆角矩形*/
public void setVisiableRigeon(int width,int height)
{
    Shape shape = new RoundRectangle2D.Float(20,20,this.getWidth() - 40,this.getHeight()-40,15.0f,15.0f);
    Shape shape2 = new Ellipse2D.Double(this.getWidth() - 40, 10,30,30);
    Area area = new Area(shape);
    Area area2 = new Area(shape2);
    area.add(area2);
    AWTUtilities.setWindowShape(this,area);
}

2.3 游戏音效制作

JAVA的AWT下面的AudioClip类播放音乐.wav格式的音乐,音乐文件使用的地方有两个:一个是战舰发射导弹命中潜艇,潜艇发射鱼雷命中战舰的,先展示爆炸图片然后在播放背景音效。

2.4 游戏爆炸场景的设计

类如下

关键方法

private MyPanel panel;
private Image   image;
/** 爆炸效果显示的时间默认为700毫秒*/
private int    liveTime = 700;
/** 位置 x y*/
private int    beginX  = 0;
private int    beginY= 0;
/** 游戏是否正在运行标志*/
private boolean isRunning = false;

/*绘制爆炸效果图片*/
public void drawHitting(Graphics2D g)
{
	g.drawImage(this.image, this.beginX, this.beginY, this.panel);
	MusicUtil musicUtil = new MusicUtil();
	musicUtil.playMissile();
}

/**圆的半径集合**/
private int[] r = {2,3,5,8,12,15,18,20,25,30,33,25,17,15,13,9,5};
/**集合中圆的位置起始标记**/
private int step = 0;

鱼雷命中潜艇是通过一个动态设置圆半径来实现先从小到大在到小的过程结合音效,效果还是不错的。

2.5 碰撞检测分析实现

碰撞的对象有两对的,分别是潜艇和导弹,鱼雷和战舰。通过位置坐标来判断(核心代码如下)当前战舰的位置坐标和窗体的高度来做一个判断后就取其一半,添加到爆炸绘制数组里面的。绘制的时候都设置和相应的位置坐标的。

/** 判断是否击中战舰 **/
public void hitting()
{
    if(this.X > (this.ship.getBeginX() - this.weight) && this.X < (this.ship.getBeginX() + this.ship.getWidth()-this.getWeight()))
    {

        int num = this.panel.getLiveNum();
        blast  = new Blast(this.ship.getBeginX() + this.ship.getWidth() /2, this.ship.getBeginY() + this.ship.getHeight() / 2);
        Thread t = new Thread(blast);
        this.panel.getBlastArray().add(blast);
        t.start();
        num --;
        this.panel.setLiveNum(num);
        this.panel.loseGmae();
    }
}


/** 根据集合中对象的位置参数判断潜艇和战舰是否被击中*/
public void explode()
{
    // this.updateScreen();
    if(!this.bumbArray.isEmpty() && !this.submarineArray.isEmpty())
    {
        for(int i = 0; i < this.bumbArray.size(); i ++)
        {
            if(((Bumb)this.bumbArray.get(i)).flag == false)
            {
                for(int j = 0; j < this.submarineArray.size(); j ++)
                {
                    if(((Submarine)this.submarineArray.get(j)).flag == false)
                    {
                        int by =((Bumb)this.bumbArray.get(i)).getBeginY();
                        int syStart = ((Submarine)this.submarineArray.get(j)).getY() - ((Bumb)this.bumbArray.get(i)).getHeight();
                        int syEnd   = ((Submarine)this.submarineArray.get(j)).getY() + ((Submarine)this.submarineArray.get(j)).getHeight();

                        int bx = ((Bumb)this.bumbArray.get(i)).getBeginX();

                        int sxStart =   ((Submarine)this.submarineArray.get(j)).getX() - ((Bumb)this.bumbArray.get(i)).getWidth();
                        int sxEnd   =   ((Submarine)this.submarineArray.get(j)).getX() + ((Submarine)this.submarineArray.get(j)).getWeight();
                        if( by >= syStart && by <= syEnd && bx >= sxStart && bx <= sxEnd)
                        {
                            this.bumbArray.get(i).flag = true;
                            this.submarineArray.get(j).flag = true;
                            this.hitX   = this.bumbArray.get(i).getBeginX() + 10;
                            this.hitY   = this.bumbArray.get(i).getBeginY() + 30;
                            //this.hitFlag  = true;
                            Hit hit = new Hit(this.hitX,this.hitY,this);
                            this.hitArray.add(hit);
                            Thread  t = new Thread(hit);
                            t.start();
                            this.score += 10;
                            this.addPass(this.score);
                        }
                    }
                }
            }
        }
    }
}

2.6 游戏对象绘制

2.6.1 潜艇对象绘制

通过随机产生随机数,0,1,2分别对应不同的潜艇图片,方向是自左向右的(使用0和1代表)。移动的步长是一个1个单位(初始),还有一个是否运行的标记的,后面线程绘制暂停要使用的。使用Timer计时器来每隔一段时间产生潜艇来不断绘制。

// 计时器方法
public TimeManager(WarShip ship, MyPanel panel)
{
    this.ship = ship;
    this.panel    = panel;
}
@Override
public void run()
{
    Random r = new Random();

    while(this.panel.isRunning())
    {
        if(this.panel.isStop() == true)
        {
            synchronized(MyPanel.subLock)
            {
                try
                {
                    MyPanel.subLock.wait();
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                    //this.flag = true;
                    this.panel.endGame();
                }
            }
        }
        Submarine sm = new Submarine(this.ship,this.panel);
        this.panel.getSubmarineArray().add(sm);
        Thread t = new Thread(sm);
        t.start();
        try
        {
            Thread.sleep(this.speed + r.nextInt(this.speed * 3));
        }
        catch(Exception e)
        {
            e.printStackTrace();
        }
    }
}

// 计时器每隔一段时间产生鱼雷对象
TimeManager2 tm2 = new TimeManager2(this,this.panel,this.ship,this.panel.getTorpedoArray());
Thread  t = new Thread(tm2);
t.start();

// 绘制方法
public void drawSubmarine(Graphics2D g)
{
    g.drawImage(image,this.X, this.Y, panel);
}

向左向右移动就是增加减少当前的坐标X值.然后重新绘制面板即可判断一下X值的范围。

public void moveLeft()
{
    this.X -= dx;
    this.panel.repaint();
    if(this.X < 0)
    {
        this.flag = true;
    }
}

2.6.2 战舰对象绘制

首先是封装一个战舰对象类。

/** 战舰初始位置和高度,宽度*/
private int beginX ;
private int beginY ;
private int width ;
private int height;
/** 初始炸弹数量*/
private int bombNum  = 5;
private MyPanel panel;
/** 图片对象*/
private Image image;

就一句话,使用给出初始时刻的位置坐标X,Y,然后就是加载战舰的图片类,X值为相应窗体宽度的一半,高度就是指定一定的高度。同样也有相应的左移和右移的方法实现,指定每次一定的步长为5个单位。

/** 绘制战舰*/
public void drawShip(Graphics2D g)
{   g.drawImage(image,this.beginX ,this.beginY,this.panel);
}
/** 战舰右移动,步长为五*/
public void moveRight()
{
    this.beginX +=5;
    if((this.beginX + this.width) > this.panel.getWidth())
    {
        System.out.println("panel:"+this.panel.getWidth());
        this.beginX = this.panel.getWidth() - this.width;
    }
}
/** 战舰左移动,步长为五*/
public void moveLeft()
{
    this.beginX -= 5;
    if(this.beginX < 0)
    {
        this.beginX = 0;
    }
}

2.6.3 鱼雷对象绘制

原来和前面相似就不做介绍了的,关键方法如下,移动的距离,鱼雷向上移动。

/** 潜艇对象*/
private WarShip ship;
/** 鱼雷的坐标和宽高*/
private int  beginX;
private int  beginY;
private int  width = 5;
private int  height = 15;
public  boolean flag = false;
private MyPanel panel;
private Image image;

public Bumb(MyPanel p, WarShip ship)
{
    this.beginX= ship.getBeginX()+20;
    this.beginY = ship.getBeginY()+20;
    this.panel = p;
    this.ship  = ship;
    URL imgUrl=this.getClass().getResource("/images/炸弹.png");
    image = Toolkit.getDefaultToolkit().getImage(imgUrl);
    image = new ImageIcon(image).getImage();
    this.width = image.getWidth(panel);
    this.height = image.getHeight(panel);
}
/** 绘制鱼雷*/
public void drawBumb(Graphics2D g)
{
    g.drawImage(image, this.beginX, this.beginY,  this.panel);
}
/** 鱼雷向下移动*/
public void moveDown()
{

    this.beginY += 1;
    if(this.beginY > (this.panel.getHeight() - this.height2))
    {
        flag = true;
    }
    // this.panel.repaint();
}
// 鱼雷向上移动
public void upMove()
{
    this.Y -= this.dy;
    if(this.Y <= 150)
    {
        this.hitting();
        this.flag = true;
    }
    if(this.sm.flag == true)
    {
        if(this.Y < 150)
        {
            this.flag = true;
        }
    }
}

2.6.4 炸弹对象绘制

/** 绘制炸弹*/
public void drawBombNum(Graphics2D g)
{
    for(int i = 0;i < this.ship.getBombNum();i ++)
    {

g.drawImage(this.bumbImage,this.getWidth()/4 + 25*i + 70, 0,this);
    }
}

2.7 战舰装弹实现

/** 装弹保持炸弹数量大于零小于五 并每隔一定时间装弹*/
public void addBomb() {
    int bn = this.ship.getBombNum();

    if(bn >= 0 && bn < 5)
    {
        bn ++;
        this.ship.setBombNum(bn);
    }
    if(bn < 0)
    {
        bn =0;
        this.ship.setBombNum(bn);
    }
    if(bn >= 5)
    {
        bn = 5;
        this.ship.setBombNum(bn);
    }
}

2.8 面板绘制

主面板里面绘制的对象非常多连接游戏各个组件的枢纽。

/** 战舰*/
private WarShip ship;
/** 命数默认为3*/
private int       liveNum= 3;
/** 通关数默认为0*/
private int       pass= 0;
/** 最高分默认为0*/
private int       higncore  = 0;
/** 玩家得分 默认为0*/
private int       score = 0;
/** 战舰装弹速度,默认为3000毫秒*/
private int       delay  = 3000;
/** 暂停标记*/
private boolean   suspendFlag = false;
/** 判断游戏是否正在运行标记*/
private boolean   isRunning   = false;
/** 潜艇是否被击中标记*/
private boolean   hitFlag  = false;
/** 击中位置潜艇x坐标*/
private int       hitX  = 0;
/** 击中位置潜艇y坐标*/
private int       hitY  = 0;
/** 炸弹图片*/
private Image     bumbImage;
/** 击中潜艇效果图片*/
private Image     hitImage;
/** 暂停游戏所有线程用到的*/
public static final Object subLock = new Object();
/** 用来不停绘制玩家剩余可用炸弹的计时器*/
private Timer timer;
/** 用来不停重绘面板和判断移动元素位置的计时器*/
private Timer timer3;
/** 用来管理产生潜艇对象的线程*/
private TimeManager tm = null;
/** 炸弹对象集合*/
private ArrayList<Bumb> bumbArray = new ArrayList<Bumb>();
/** 潜水艇对象集合*/
private ArrayList<Submarine> submarineArray  = new ArrayList<Submarine>();
/** 鱼雷对象集合*/
private ArrayList<Torpedo> torpedoArray = new ArrayList<Torpedo>();
/** 潜艇爆炸对象集合*/
private ArrayList<Hit> hitArray = new ArrayList<Hit>();
/** 战舰爆炸对象集合*/
private ArrayList<Blast> blastArray = new ArrayList<Blast>();

三.游戏场景创意相关设计

3.1 游戏关卡分数设计

具有挑战创意的分数关卡等你来战,每次多通过一关后,潜艇的速度会变快,就是绘制潜艇的速度会提高的,同时计时器的间隔会减低的。

/** 判断通关数量*/
public void addPass(int score)
{
    if(score < 100)
    {
        this.pass = 0;
    }
    else if(score >= 100 && score < 200)
    {
        this.pass = 1;
        this.tm.setSpeed(800);
        timer.setDelay(2800);
    }
    else if(score >= 200 && score < 300)
    {
        this.pass = 2;
        this.tm.setSpeed(600);
        timer.setDelay(2500);
    }
    else if(score >= 300 && score < 500)
    {
        this.pass = 3;
        this.tm.setSpeed(500);
        timer.setDelay(2300);
    }
    else if(score >= 500 && score < 800)
    {
        this.pass = 4;
        this.tm.setSpeed(400);
        timer.setDelay(2000);
    }
    else if(score >= 800 && score < 1000)
    {
        this.pass = 5;
        this.tm.setSpeed(300);
        timer.setDelay(1800);
    }
    else if(score >= 1000 && score < 1500)
    {
        this.pass = 6;
        this.tm.setSpeed(200);
        timer.setDelay(1500);

    }
    else if(score >= 1500 && score < 2000)
    {
        this.pass = 7;
        this.tm.setSpeed(100);
        timer.setDelay(1200);
    }
    else if(score >= 2000)
    {
        this.pass = 8;
        this.tm.setSpeed(50);
        timer.setDelay(1000);
    }
}

还算不错的完成了功能.

3.2 读取游戏最高分

设计通过后判断是否进入前十了的。

/** 得到玩家的最高分*/
public int getHigeScore(InputStream inputStream)
{
    BufferedReader bf = null;
    int    tempNum = 0;
    try
    {
        bf = new BufferedReader(new InputStreamReader(inputStream));
        String temp = null;
        while((temp = bf.readLine()) != null)
        {
            String[] info = temp.split(" ");
            int    num    = Integer.valueOf(info[1]);
            if(num > tempNum)
            {
                tempNum = num;
            }
        }
        bf.close();
    }
    catch(IOException e)
    {
        e.printStackTrace();
    }
    finally
    {
        if(bf != null)
        {
            try
            {
                bf.close();
            }
            catch(IOException e)
            {
                e.printStackTrace();
            }
        }
    }
    return tempNum;
}

游戏界面绘制时要读取出当前的最高分数的,从玩家的排行榜里面读取出来的userInfo/user.txt文件读取。

计算机网络 630 4 2018-06-09
归来 570 3 2018-06-08
时间刺客 480 2 2018-06-07
图像处理 410 2 2018-06-05
深入浅出 390 3 2018-06-04
游戏设计 330 2 2018-06-03
数据挖掘 270 2 2018-06-03
多媒体技术 260 2 2018-06-07
数据结构 250 2 2018-06-10
集合对象 190 1 2018-06-09

下面是一些关键的代码.按照分数的降序来完成的。

{
    // 得到用户信息
    String name = InputDialog.this.field.getText().trim();
    String score = Integer.toString(InputDialog.this.panel.getScore());
    String pass  = Integer.toString(InputDialog.this.panel.getPass());

    SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    String date = df.format(new Date());
    String args[] = date.split(" ");
    String time  = args[0];

    String user = name + " " + score + " " + pass + " " + time;
    //将数据文件中的用户信息取出,去掉最后一名,加入玩家信息,并按降序排序
    ArrayList<String> userList = new ArrayList<String>();
    BufferedReader br = null;
    BufferedWriter bw = null;

游戏结束执行isRecord方法来判断玩家是否进入前十来实现荣誉榜。

/** 判断玩家成绩是否进入前十名,是的话返回true*/
public boolean isRecord()
{
    boolean isRecord = false;
    InputStream inputStream=MyPanel.class.getClassLoader().getResourceAsStream("userInfo/user.txt");
    BufferedReader bf = null;
    int    num = 0;
    String temp = null;

四.游戏相关测试

4.1 功能测试

4.1.1 游戏测试

测试游戏结束中玩家3条命结束后游戏是否按照预期的就结束了的。正确的应该是弹出一个对话框提示重玩还是退出.错误的就是各种报错了的可以在控制台查看的。

这个测试的过程也同时测试了潜艇的正确运行,战舰的键盘事件,投弹爆炸,音效的测试.和一些功能按钮的测试的.

4.1.2 暂停游戏的测试

鼠标左键实现暂停游戏的功能正确的弹出串口的,查看控制台看是否报错的。

4.2 性能测试

4.2.1 测试战舰装弹的性能来实现

正确进入断点处执行,单步调试

4.2.2 测试战舰键盘事件是否向右移动正确

Debug运行单步调试

五.软件的运行的方式

直接运行

基于jar包的运行,我们使用项目构建工具Maven来快速打成jar包。

进入控制台

使用exe4J将jar打成了可执行文件.exe格式的

点击直接可以运行的。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2249572.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

课题组自主发展了哪些CMAQ模式预报相关的改进技术?

空气污染问题日益受到各级政府以及社会公众的高度重视&#xff0c;从实时的数据监测公布到空气质量数值预报及预报产品的发布&#xff0c;我国在空气质量监测和预报方面取得了一定进展。随着计算机技术的高速发展、空气污染监测手段的提高和人们对大气物理化学过程认识的深入&a…

深入解析下oracle date底层存储方式

之前我们介绍了varchar2和char的数据库底层存储格式&#xff0c;今天我们介绍下date类型的数据存储格式&#xff0c;并通过测试程序快速获取一个日期。 一、环境搭建 1.1&#xff0c;创建表 我们还是创建一个测试表t_code&#xff0c;并插入数据&#xff1a; 1.2&#xff0c;…

【论文复现】SRGAN

1. 项目结构 如何生成文件夹的文件目录呢? 按住shift键,右击你要生成目录的文件夹,选择“在此处打开Powershell窗口” 在命令窗口里输入命令“tree”,按回车。就会显示出目录结构。 ├─.idea │ └─inspectionProfiles ├─benchmark_results ├─data │ ├─test …

Kubernetes 之 Ingress 和 Service 的异同点

1. 概念与作用 1.1 Ingress Ingress 是什么&#xff1f; Ingress主要负责七层负载&#xff0c;将外部 HTTP/HTTPS 请求路由到集群内部的服务。它可以基于域名和路径定义规则&#xff0c;从而将外部请求分配到不同的服务。 ingress作用 提供 基于 HTTP/HTTPS 的路由。 支持 …

结构体详解+代码展示

系列文章目录 &#x1f388; &#x1f388; 我的CSDN主页:OTWOL的主页&#xff0c;欢迎&#xff01;&#xff01;&#xff01;&#x1f44b;&#x1f3fc;&#x1f44b;&#x1f3fc; &#x1f389;&#x1f389;我的C语言初阶合集&#xff1a;C语言初阶合集&#xff0c;希望能…

Springboot项目搭建(7)

1.概要 2.Layout主页布局 文件地址&#xff1a;src\views\Layout.vue 2.1 script行为模块 从elementUI中选取图标图案。 <script setup> import {Management,Promotion,UserFilled,User,Crop,EditPen,SwitchButton,CaretBottom } from "element-plus/icons-vue…

cocos creator 3.8 俄罗斯方块Demo 10

这里的表格是横行数列&#xff0c;也就是x是行&#xff0c;y是列&#xff0c;不要当x/y轴看。 1-1012-1012-1-1[-1,0]0[0,-1][0,0][0,1][0,2]0[0,0]11[1,0]22[2,0] -1012-1012-1-1[-1,0]0[0,-1][0,0][0,1][0,2]0[0,0]11[1,0]22[2,0] 2-1012-1012-1[-1,-1][-1,0]-1[-1,-1][-1…

Java安全—原生反序列化重写方法链条分析触发类

前言 在Java安全中反序列化是一个非常重要点&#xff0c;有原生态的反序列化&#xff0c;还有一些特定漏洞情况下的。今天主要讲一下原生态的反序列化&#xff0c;这部分内容对于没Java基础的来说可能有点难&#xff0c;包括我。 序列化与反序列化 序列化&#xff1a;将内存…

【Java 学习】面向程序的三大特性:封装、继承、多态

引言 1. 封装1.1 什么是封装呢&#xff1f;1.2 访问限定符1.3 使用封装 2. 继承2.1 为什么要有继承&#xff1f;2.2 继承的概念2.3 继承的语法2.4 访问父类成员2.4.1 子类中访问父类成员的变量2.4.2 访问父类的成员方法 2.5 super关键字2.6 子类的构造方法 3. 多态3.1 多态的概…

LeetCode—74. 搜索二维矩阵(中等)

仅供个人学习使用 题目描述&#xff1a; 给你一个满足下述两条属性的 m x n 整数矩阵&#xff1a; 每行中的整数从左到右按非严格递增顺序排列。 每行的第一个整数大于前一行的最后一个整数。 给你一个整数 target &#xff0c;如果 target 在矩阵中&#xff0c;返回 true…

uniapp关闭sourceMap的生成,提高编译、生产打包速度

警告信息&#xff1a;[警告⚠] packageF\components\mpvue-echarts\echarts.min.js 文件体积超过 500KB&#xff0c;已跳过压缩以及 ES6 转 ES5 的处理&#xff0c;手机端使用过大的js库影响性能。 遇到问题&#xff1a;由于微信小程序引入了mpvue-echarts\echarts.min.js&…

房屋出租出售预约系统支持微信小程序+H5+APP

核心功能有&#xff1a;新盘销售、房屋租赁、地图找房、小区找房&#xff0c;地铁找房等方式。 地图找房&#xff1a;通过地图标注查看附近房源&#xff0c;方便用户根据地理位置查找合适的房产。二手房资讯&#xff1a;提供租房及二手房市场的相关资讯&#xff0c;帮助用户了…

Axure农业农村数据可视化大屏模板分享

在当今信息技术飞速发展的时代&#xff0c;数据可视化已成为各行各业提升管理效率、优化决策过程的重要手段。Axure作为一款强大的原型设计工具&#xff0c;凭借其高度的自定义能力和丰富的交互设计功能&#xff0c;在农业农村数据可视化领域展现出强大的潜力。本文将详细介绍A…

【分享】PPT打开密码的设置与移除方法

设置和取消PPT的打开密码&#xff0c;是保障和移除文件访问权限的重要操作。以下将分别讲解如何为PPT设置密码&#xff0c;以及如何取消打开密码。 一、如何设置PPT打开密码 方法1&#xff1a; 1、在PowerPoint中打开目标文件&#xff0c;然后点击左上角的“文件”选项。在弹…

网络基础 - 地址篇

一、IP 地址 IP 协议有两个版本&#xff0c;IPv4 和 IPv6IP 地址(IPv4 地址)是一个 4 字节&#xff0c;32 位的正整数&#xff0c;通常使用 “点分十进制” 的字符串进行表示&#xff0c;例如 192.168.0.1&#xff0c;用点分割的每一个数字表示一个字节&#xff0c;范围是 0 ~…

在 Ubuntu 上部署 MediaWiki 开源维基平台

MediaWiki 是一个功能强大的开源维基软件&#xff0c;全球众多组织使用它来创建协作文档网站。本文将指导你如何在 Ubuntu 服务器上安装 MediaWiki&#xff0c;使用 Nginx 作为 Web 服务器&#xff0c;PostgreSQL 作为数据库管理系统。 简介 MediaWiki 是一个灵活且强大的维基…

Spring Boot整合EasyExcel

文章目录 EasyExcel简介Spring Boot整合EasyExcel一、单sheet写操作二、多sheet写数据三、读操作 EasyExcel简介 1、EasyExcel 是一个基于 Java 的简单、省内存的读写 Excel 的开源项目。在尽可能节约内存的情况下支持读写百 M 的 Excel&#xff08;没有一次性将数据读取到内存…

Java 基础面试题

&#x1f9d1; 博主简介&#xff1a;CSDN博客专家&#xff0c;历代文学网&#xff08;PC端可以访问&#xff1a;https://literature.sinhy.com/#/literature?__c1000&#xff0c;移动端可微信小程序搜索“历代文学”&#xff09;总架构师&#xff0c;15年工作经验&#xff0c;…

deepin 安装 chrome 浏览器

deepin 安装 chrome 浏览器 最近好多小伙伴儿和我说 deepin 无法安装最新的谷歌浏览器 其实是因为最新的 谷歌浏览器 其中的一个依赖需要提前安装 提前安装依赖然后再安装谷歌浏览器就可以了 安装 fonts-liberationsudo apt -y install fonts-liberation安装 chrome 浏览器sudo…

数据结构2:顺序表

目录 1.线性表 2.顺序表 2.1概念及结构 2.2接口实现 1.线性表 线性表是n个具有相同特性的数据元素的有限序列。线性表是一种在实际中广泛使用的数据结构&#xff0c;常见的线性表&#xff1a;顺序表、链表、栈、队列、字符串 线性表在逻辑上是线性结构&#xff0c;也就说…