javaSwing飞机大战

  1. 概述

1.1 项目简介

本次Java课程设计是做一个飞机大战的游戏,应用Swing编程,完成一个界面简洁流畅、游戏方式简单,玩起来易于上手的桌面游戏。该飞机大战项目运用的主要技术即是Swing编程中的一些窗口类库、事件监听以及贴图技术。

1.2 实训功能说明

1.2.1 基本功能

(1)通过键盘,方向键和ASWD键可控制战机的位置,空格键和鼠标左键发射子弹。

(2)界面中敌机出现的位置,以及敌机和Boss炸弹的发射均为随机的,敌机与敌机炸弹、Boss炸弹均具有一定的速度,且随着关卡难度的增大,数量和速度均随着关卡数增加而增加。

(3)对于随机产生的敌机和敌机炸弹,若超过矩形区域,则释放该对象。

(4)添加碰撞效果,包括战机子弹打中敌机爆炸、敌机炸弹打中战机爆炸、战机与敌机相撞爆炸、战机子弹与敌机炸弹相撞爆炸、战机子弹打中Boss、战机与Boss碰撞以及战机吃到血包七种碰撞效果。且碰撞发生后子弹、炸弹、血包均消失,战机生命值减一,敌机和Boss生命值减少当前战机炮弹威力的生命值,若敌机或Boss生命值归零,则删除敌机或Boss。

(5)血包:随着关卡游戏进程的进行,会出现一定量的血包供战机补给生命值,血包会在客户区矩形框内运动,10秒后消失;若战机在10秒内吃到血包,则会增加5点生命值知道生命值上限。

(6)每关中战机有三条命,每条命10点生命值,生命使用完后,会进入GameOver界面显示得分数,并提供重新开始游戏和退出功能。

(7)游戏提供10个关卡,每个关卡需要打死相应关卡的敌机数量才能进入Boss模式,打败Boss之后将会进入下一关。10关通关后,显示通关界面,并提供重新开始游戏和退出游戏的功能选项。

(8)暂停功能:游戏进行过程中按下Z键可进入暂停模式,再按Z则返回游戏。

(9)无敌模式:游戏进行过程中按下Y键可进入无敌模式,再按Y则返回正常游戏。该模式下战机生命值不会减少,可供测试使用。

(10)魔法值:游戏进行过程中,战机魔法值会随着时间递增到上限10,魔法值供战机道具功能的使用,过一个关卡魔法值不清零。

(11)战机大招:当战机魔法值为10满状态时,按下X键消耗所有魔法值可发动大招,对屏幕中的敌机进行清屏,Boss扣50点血量。

(12)防护罩:当魔法值不为0时,按下C键可打开防护罩道具,该状态下战机处于无敌状态,不会损失生命值,但魔法值会随着防护罩开启慢慢降低。

(13)战机升级功能:战机子弹单个威力为1,在魔法值不为0时,按下V键开启升级战机模式,战机图标变为动画,子弹威力变成两倍。(若同时开启防护罩和战机升级,则魔法值递减速度翻倍)。

1.2.2 附加功能

(1) 为游戏界面每个关卡添加了滚动背景图片和背景音乐,并在敌机发送炮弹、战机发射子弹、战机击中敌机、敌机击中战机、战机敌机相撞、敌机战机子弹相撞、战机吃到血包、战机大招、战机升级、战机防护罩、游戏结束时均添加了音效。

(2)为美化游戏界面,采用了一部分全民飞机大战图标,并添加了爆炸动画和升级战机动画特效,背景音乐采用微信飞机大战背景音乐和相关特效音效。

(3)为游戏设置了不同的关卡,每个关卡难度不同,敌机与敌机炸弹的速度随着关卡增大而加快,进入第五关以后敌机从上下方均会随机出现,且随机发射炸弹。

(4)前五关卡敌机从上方飞出,速度一定,战机每打掉一架敌机则增加一分,当战机得分超过该关卡所需分数(和关卡数相关)则可进入Boss模式,打败Boss进入下一关;进入第六关以后,敌机分别从上下两方飞出。随着关卡数增加,敌机数量增加,速度增快,敌机炮弹数量和速度也相应增加,进入Boss所需分数增加,Boss生命值和火力也随着关卡数的增加而增加,游戏难度陡然直升。

(5)游戏界面中显示当前状态下的关卡数、当前命数、当前得分、战机血条、战机魔法条、无敌模式提醒和战机道具提醒,Boss模式下还有Boss血条。

(6)增加了鼠标控制战机位置这一效果,战绩的位置随着鼠标的移动而移动,并且点击鼠标左键可使得战机发射子弹。

(7)进入游戏先进入欢迎界面,欢迎界面中显示游戏使用说明,点击鼠标左键和空格键开始游戏。游戏过程中战机命数使用完、通关均有相应界面进行提醒,用户可选择重新开始游戏或退出游戏。

2. 相关技术

2.1 Timer定时器技术

本次项目采用了Java的Timer定时器和TimerTask任务,Timer周期性地在每经过一个指定的时间间隔后就通知TimerTask一次,让TimerTask按照Timer设定的周期循环地执行任务。本程序中使用多个定时器,分别控制不同的功能,分别是屏幕刷新Timer,敌机产生Timer,魔法值变化Timer,血包生命周期Timer。

2.2 透明贴图实现技术

绘制透明位图的关键就是创建一个“掩码”位图(mask bitmap),这个“掩码”位图是一个单色位图,它是位图中图像的一个单色剪影。

整个绘制过程需要使用到ImageUtil类的createImageByMaskColorEx静态方法,把传入的原图BufferedImage中的指定颜色的背景去掉,返回去掉背景的BufferedImage对象,传送到窗口进行展示。

2.3 游戏对象列表

Java类库中提供了丰富的List接口的实现方法,本项目采用ArrayList存放游戏运行过程中的游戏对象。

(1)滚动背景模块

private static BufferedImage titleImage;// 欢迎界面图像列表

public static Scene scene; //游戏背景对象

(2)各游戏对象

        public static MyPlane myplane = null;

    Enemy enemy = null;

    public static Boss boss = null;

    Bomb bomb = null;

    Ball ball = null;

    Explosion explosion = null;

    Blood blood = null;

(3)存储游戏对象的对象列表

        public static List<Enemy> enemyList = new ArrayList<Enemy>();

    public static List<MyPlane> meList = new ArrayList<MyPlane>();

    public static List<Bomb> bombList = new ArrayList<Bomb>();

    public static List<Ball> ballList = new ArrayList<Ball>();

    public static List<Explosion> explosionList = new ArrayList<Explosion>();

    public static List<Blood> bloodList = new ArrayList<Blood>();

(4)游戏运行相关参数:

    int speed;// 战机的速度,方向键控制

    public static int myLife;// 为战机设置生命值

    public static int lifeNum;// 战机命条数

    public static int myScore;// 战机的得分

    public static int passScore;// 当前关卡得分数

    public static int lifeCount;// 血包产生控制参数

    public static boolean bloodExist;// 标记屏幕中是否存在血包

    public static int magicCount;// 魔法值,控制能否发大招

    public static int bossBlood;// Boss血量

    public static int passNum;// 记录当前关卡

(5)游戏运行相关标志位

    public static boolean isPass;// 是否通关的标志

    public static boolean isPause;// 是否暂停

    public static boolean isBoss;// 标记是否进入Boss

    public static boolean bossLoaded;// 标记Boss出场完成

    public static boolean isProtect;// 标记是否开启防护罩

    public static boolean isUpdate;// 标记战机是否升级

    public static boolean test;// 无敌模式参数

    public static int isStop;// 标记游戏停止

    public static boolean isStarted;// 标记欢迎界面是否加载完成

2.4获取矩形区域

使用 Rectangle的intersects方法来判断两个源矩形是否有重合的部分。如果有重合,返回true,没有从何返回false。

2.5 List<BufferedImage>处理爆炸效果

爆炸效果是连续的显示一系列的图片。如果把每一张图片都在要显示的时候进行加载,占用的时间是非常多的,必然后导致程序的可行性下降。List<BufferedImage>是一个“图象列表”是相同大小图象的集合,每个图象都可由其基于零的索引来参考。可以用来存放爆炸效果的一组图片,通过Timer消息连续循环绘制出List<BufferedImage>中的多张图片做成的爆炸效果。

3. 总体设计与详细设计

3.1 系统模块划分

该飞机大战游戏程序分为游戏滚动背景绘制模块、各游戏对象绘制模块、游戏对象之间的碰撞模块、爆炸效果产生模块、游戏界面输出玩家得分关卡信息模块、战机道具技能维护模块、消息处理模块、视图生命周期维护模块。

其中在游戏对象绘制模块中,战机是唯一对象,在游戏开始时产生该对象,赋予其固定的生命值,当其与敌机对象、敌机炸弹碰撞时使其生命值减一,直至生命值为零,便删除战机对象。敌机对象与敌机炸弹对象的绘制中采用定时器技术,定时产生。爆炸对象初始化为空,当游戏过程中即时发生碰撞时,在碰撞位置产生爆炸对象,添加到爆炸链表中,并根据爆炸素材图像分八帧进行输出,达到动画特效。

3.2 主要功能模块

3.2.1 系统对象类图

GameObject是各个游戏对象的抽象父类,继承自Object类,其他的类:战机类、敌机类、爆炸类、子弹类、炸弹类、血包类、文字类都继承了此类,Boss类继承敌机类。

每个游戏对象类中既继承了来自父类GameObject的属性,又有自己的特有属性和方法。

       GameObject类介绍:

              protected Point point;//该游戏对象在窗口中的坐标位置。

              public boolean draw(Graphics g, JPanel panel, boolean pause);//在窗口中绘制该游戏对象图标。

              public Rectangle getRect();//获取该游戏对象图标在窗口中的矩形框,进行碰撞检测时使用。

              public static boolean loadImage(BufferedImage image, String source);//加载该游戏对象对应的图像到内存,方便之后的显示调用。

       继承GameObject的其他游戏对象类也都重载了相关方法,以便于各个游戏对象在程序的调用过程中调用方式的一致性。

3.2.2 项目包和类层次结构图

MyPanel:JPanel的继承类,是飞机大战窗口的总显示面板,其中包含了游戏运行过程中的大量全局参数和全局标记位。

SpaceWar:程序的入口,窗口对象启动的位置,并在此对相关事件进行了监听。

Ball:敌机炮弹类,继承GameObject,有加载图片,获取矩形框,获取对象位置,绘制回想等游戏对象通用操作方法。

Blood:血包类,继承GameObject,有加载图片,获取矩形框,获取对象位置,绘制回想等游戏对象通用操作方法。

Bomb:战机炮弹类,继承GameObject,有加载图片,获取矩形框,获取对象位置,绘制回想等游戏对象通用操作方法。

Boss:Boss类,继承GameObject,有加载图片,获取矩形框,获取对象位置,绘制回想等游戏对象通用操作方法。

Enemy:敌机类,继承GameObject,有加载图片,获取矩形框,获取对象位置,绘制回想等游戏对象通用操作方法。

Explosion:爆炸效果类,继承GameObject,有加载图片,获取矩形框,获取对象位置,绘制图片等游戏对象通用操作方法。

GameObject:游戏对象基类,有加载图片,获取矩形框,获取对象位置,绘制图片的游戏对象统一的方法,统一游戏对象的操作方式。

MyPlane:战机类,继承GameObject,有加载图片,获取矩形框,获取对象位置,绘制图片等游戏对象通用操作方法。

Scene:场景类,实现了背景滚动,并根据关卡显示不同的背景图片。

EnemyTask:实现了TimerTask接口,随着Timer计时器的调用而随时间产生敌机对象和敌机炮弹对象,实现自动产生敌机的效果。

MagicTask:实现了TimerTask接口,随着Timer计时器的调用而随时间改变魔法值。

RefreshTask:实现了TimerTask接口,随着Timer计时器的调用而随时间刷新窗口界面。

AudioUtil:音频操作工具类,提供播放背景音乐和操作音效。

ImageUtil:图片加工工具类,实现了透明贴图方法和背景图片拼接。

3.2.3 系统主程序活动图

3.2.4 系统部分流程图

(1)飞机大战游戏执行流程图

(2)定时器产生敌机和炸弹流程图

(3)血包执行流程图

4. 编码实现

4.1 滚动背景

在滚动背景的初始化方法和释放方法添加背景音乐播放和释放

//场景类

public class Scene {

    private int beginY;// 背景的Y坐标

    private List<BufferedImage> images;

    public Scene() {

        this.images = new ArrayList<BufferedImage>();

    }

    // 初始化场景

    public boolean initScene() {

        // 加载开始图片

        BufferedImage buffer;

        try {

            buffer = ImageUtil.copyImage(ImageIO.read(new File(

                    "images/start.bmp")));

            this.images.add(buffer);

            // 如果加载失败, 返回false

            for (int i = 1; i <= 6; i++) {

                buffer = ImageUtil.copyImage(ImageIO.read(new File(

                        "images/background" + i + ".bmp")));

                this.images.add(buffer);

            }

        } catch (IOException e) {

            e.printStackTrace();

            return false;

        }

        // 背景起始坐标为0

        this.beginY = 0;

        // 播放背景音乐

        AudioUtil.playBackground();

        return true;

    }

    // 绘制场景

    public void stickScene(Graphics graphics, int index, ImageObserver observer) {

        if (index == -1)

            index = 0;

        else

            index = index % 6 + 1;

        BufferedImage image = images.get(index);

        // 窗口滑在图片中间

        if (beginY >= 0

                && beginY + SpaceWar.WINDOWS_HEIGHT <= image.getHeight()) {

            BufferedImage buffer = image.getSubimage(0, beginY,

                    image.getWidth(), SpaceWar.WINDOWS_HEIGHT);

            graphics.drawImage(buffer, 0, 0, SpaceWar.WINDOWS_WIDTH,

                    SpaceWar.WINDOWS_HEIGHT, observer);

        } else if (beginY < 0) {

            // 超出图片上界

            BufferedImage imageUp = image.getSubimage(0, image.getHeight()

                    + beginY, image.getWidth(), -beginY);

            graphics.drawImage(imageUp, 0, 0, SpaceWar.WINDOWS_WIDTH, -beginY,

                    observer);

            graphics.drawImage(image, 0, -beginY, SpaceWar.WINDOWS_WIDTH,

                    SpaceWar.WINDOWS_HEIGHT, observer);

            if (-beginY > SpaceWar.WINDOWS_HEIGHT) {

                beginY = image.getHeight() + beginY;

            }

        }

    }

    // 移动背景

    public void moveBg() {

        // 移动背景

        beginY -= 1;

    }

    // 释放内存资源

    public void releaseScene() {

        for (int i = 0; i < 7; i++)

            if (images.get(i) != null)

                images.get(i).flush();

        // 关闭背景音乐

        AudioUtil.stopBackground();

    }

    public int getBeginY() {

        return beginY;

    }

    public void setBeginY(int beginY) {

        this.beginY = beginY;

    }

}

//在MyPanel中刷新滚动

// 滚动背景

scene.stickScene(g, -1, this);

scene.moveBg();

4.2 显示战机

if (myplane != null) {

            myplane.draw(g, this, isPause, isProtect);

        }

4.3 随机产生敌机和敌机炮弹、Boss炮弹

//随机添加敌机,敌机随机发射炸弹,此时敌机速度与数量和关卡有关

// 根据关卡数产生敌机

        if (MyPanel.passNum <= 5) {

            // 前五关只有一个方向的敌机

            Enemy enemy = new Enemy(Enemy.ENEMY_SPEED, 1);// 设置敌机的方向,从上方飞出

            enemyList.add(enemy);// 随机产生敌机

            if (new Random().nextInt(2) == 0) {// 控制敌机炮弹发出频率

                Ball ball = new Ball(

                        enemy.getPoint().x + Enemy.ENEMY_WIDTH / 2,

                        enemy.getPoint().y + Enemy.ENEMY_HEIGHT,

                        enemy.getDirection());

                ball.setBallSpeed(enemy.getSpeed()+2);

                MyPanel.ballList.add(ball);

                // 音效

                AudioUtil.play(AudioUtil.AUDIO_BALL);

            }

        } else if (MyPanel.passNum > 5) {// 第五关之后,两个方向的敌机

            Enemy enemy1 = new Enemy(Enemy.ENEMY_SPEED, 1);// 设置敌机的方向,从上方飞出

            enemy1.setSpeed(Enemy.ENEMY_SPEED

                    + (new Random().nextInt(2) + MyPanel.passNum - 1));

            enemyList.add(enemy1);

            Enemy enemy2 = new Enemy(Enemy.ENEMY_SPEED, -1);// 设置敌机的方向,从下方飞出

            enemy2.setSpeed(Enemy.ENEMY_SPEED

                    + (new Random().nextInt(2) + MyPanel.passNum - 1));

            enemyList.add(enemy2);

            int rand = new Random().nextInt(3);

            if (rand == 0) {// 控制敌机炮弹发出频率

                Ball ball = new Ball(enemy1.getPoint().x + Enemy.ENEMY_WIDTH

                        / 2, enemy1.getPoint().y + Enemy.ENEMY_HEIGHT,

                        enemy1.getDirection());

                ball.setBallSpeed(enemy1.getSpeed()+2);

                MyPanel.ballList.add(ball);

                // 音效

                AudioUtil.play(AudioUtil.AUDIO_BALL);

            }

            if (rand == 1) {// 控制敌机炮弹发出频率

                Ball ball = new Ball(enemy2.getPoint().x + Enemy.ENEMY_WIDTH

                        / 2, enemy2.getPoint().y, enemy2.getDirection());

                ball.setBallSpeed(enemy2.getSpeed()+2);

                MyPanel.ballList.add(ball);

                // 音效

                AudioUtil.play(AudioUtil.AUDIO_BALL);

            }

        }

        if (MyPanel.isBoss) {

            // Boss发射子弹

            // 敌机炸弹产生定时器触发

            // 设置定时器产生敌机炸弹

            Ball ball1 = new Ball(MyPanel.boss.getPoint().x + Boss.BOSS_WIDTH

                    / 2, MyPanel.boss.getPoint().y + Boss.BOSS_HEIGHT, 1);

            ball1.setBallSpeed(Ball.BALL_SPEED + (MyPanel.passNum - 1) * 2);

            MyPanel.ballList.add(ball1);

            Ball ball2 = new Ball(MyPanel.boss.getPoint().x + 5,

                    MyPanel.boss.getPoint().y + Boss.BOSS_HEIGHT, 1);

            ball2.setBallSpeed(Ball.BALL_SPEED + (MyPanel.passNum - 1) * 2);

            MyPanel.ballList.add(ball2);

            Ball ball3 = new Ball(MyPanel.boss.getPoint().x + Boss.BOSS_WIDTH

                    - 5, MyPanel.boss.getPoint().y + Boss.BOSS_HEIGHT, 1);

            ball3.setBallSpeed(Ball.BALL_SPEED + (MyPanel.passNum - 1) * 2);

            MyPanel.ballList.add(ball3);

            Ball ball4 = new Ball(MyPanel.boss.getPoint().x + Boss.BOSS_WIDTH

                    / 2 + 85, MyPanel.boss.getPoint().y + Boss.BOSS_HEIGHT, 1);

            ball4.setBallSpeed(Ball.BALL_SPEED + (MyPanel.passNum - 1) * 2);

            MyPanel.ballList.add(ball4);

            Ball ball5 = new Ball(MyPanel.boss.getPoint().x + Boss.BOSS_WIDTH

                    / 2 - 85, MyPanel.boss.getPoint().y + Boss.BOSS_HEIGHT, 1);

            ball5.setBallSpeed(Ball.BALL_SPEED + (MyPanel.passNum - 1) * 2);

            MyPanel.ballList.add(ball5);

            // 音效

            AudioUtil.play(AudioUtil.AUDIO_BALL);

        }

4.4 显示战机发射子弹

for (int i = 0; i < bombList.size(); i++) {

            bomb = bombList.get(i);

            if (bomb == null)

                continue;

            bomb.setCurrentIndex(i);

            bomb.isUpdate = isUpdate;

            if (!bomb.draw(g, this, isPause))

                i--;

        }

4.5 碰撞检测,以战机子弹集中敌机为例

    if (MyPanel.myplane != null && !MyPanel.isPause) {

            // 子弹打中敌机

            boolean flag = false;

            for (int i = 0; i < MyPanel.bombList.size(); i++) {

                Bomb bomb = MyPanel.bombList.get(i);

                if (bomb == null)

                    continue;

                Rectangle bombRectangle = bomb.getRect();

                for (int j = 0; j < MyPanel.enemyList.size(); j++) {

                    Enemy enemy = MyPanel.enemyList.get(j);

                    if (enemy == null)

                        continue;

                    Rectangle enemyRectangle = enemy.getRect();

                    if (enemyRectangle.intersects(bombRectangle)) {

                        Explosion explosion = new Explosion(

                                (bomb.getPoint().x + Bomb.BOMB_WIDTH / 2 - Explosion.EXPLOSION_WIDTH / 2),

                                (bomb.getPoint().y + Bomb.BOMB_HEIGHT / 2 - Explosion.EXPLOSION_WIDTH / 2));

                        MyPanel.explosionList.add(explosion);

                        // 音效

                        AudioUtil.play(AudioUtil.AUDIO_EXPLOSION);

                        // 爆炸后删除子弹

                        MyPanel.bombList.remove(i);

                        i--;

                        // 敌机生命值减少

                        enemy.life -= MyPanel.isUpdate ? 2 : 1;

                        if (enemy.life <= 0) {

                            // 增加得分

                            MyPanel.passScore++;

                            // 删除敌机

                            MyPanel.enemyList.remove(j);

                            j--;

                        }

                        // 炮弹已删除,直接跳出本循环

                        flag = true;

                        break;

                    }

                }

                if (flag)

                    continue;

                if (MyPanel.isBoss && bomb != null) {

                    // 获得战机子弹的矩形区域

                    Rectangle bombRect = bomb.getRect();

                    // 获得Boss的矩形区域

                    Rectangle bossRect = MyPanel.boss.getRect();

                    // 判断两个矩形区域是否有交接

                    if (bombRect.intersects(bossRect)) {

                        // 将爆炸对象添加到爆炸链表中

                        Explosion explosion = new Explosion(

                                (bomb.getPoint().x + Bomb.BOMB_WIDTH / 2 - Explosion.EXPLOSION_WIDTH / 2),

                                (bomb.getPoint().y + Bomb.BOMB_HEIGHT / 2 - Explosion.EXPLOSION_WIDTH / 2));

                        MyPanel.explosionList.add(explosion);

                        // 音效

                        AudioUtil.play(AudioUtil.AUDIO_EXPLOSION);

                        // 爆炸后删除子弹

                        MyPanel.bombList.remove(i);

                        i--;

                        bomb = null;

                        // 是Boss,不删除敌机,只扣血

                        MyPanel.bossBlood -= MyPanel.isUpdate ? 2 : 1;

                        if (MyPanel.bossBlood <= 0) {

                            Explosion explosion1 = new Explosion(

                                    MyPanel.boss.getPoint().x,

                                    MyPanel.boss.getPoint().y);

                            MyPanel.explosionList.add(explosion1);

                            Explosion explosion2 = new Explosion(

                                    (MyPanel.boss.getPoint().x + Boss.BOSS_WIDTH),

                                    (MyPanel.boss.getPoint().y + Boss.BOSS_HEIGHT));

                            MyPanel.explosionList.add(explosion2);

                            Explosion explosion3 = new Explosion(

                                    (MyPanel.boss.getPoint().x + Boss.BOSS_WIDTH),

                                    (MyPanel.boss.getPoint().y));

                            MyPanel.explosionList.add(explosion3);

                            Explosion explosion4 = new Explosion(

                                    (MyPanel.boss.getPoint().x),

                                    (MyPanel.boss.getPoint().y + Boss.BOSS_HEIGHT));

                            MyPanel.explosionList.add(explosion4);

                            Explosion explosion5 = new Explosion(

                                    (MyPanel.boss.getPoint().x

                                           + Boss.BOSS_WIDTH / 2 - Explosion.EXPLOSION_WIDTH / 2),

                                    (MyPanel.boss.getPoint().y

                                            + Boss.BOSS_HEIGHT / 2 - Explosion.EXPLOSION_WIDTH / 2));

                            explosion5.setBossDie(true);// 标记最后一个炸弹,炸完之后跳入下一关

                            MyPanel.explosionList.add(explosion5);

                            MyPanel.boss = null;

                            // 过关的标志变量

                            // isPause = TRUE;

                            // CMyPlane* temp = myplane;

                            // myplane = new CMyPlane(FALSE);

                            MyPanel.myplane = null;

                            MyPanel.isPass = true;

                            MyPanel.isBoss = false;

                        }

                    }

                }

            }

        }

5.程序截图

6.完整代码

q:969060742

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

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

相关文章

【个人账号体系设计】偏个人功能类账号功能模块设计

本文讨论了针对以个人功能为主的业务系统的账号能力设计&#xff0c;包括账号管理的总体需求、关键属性和设计要点。重点在于如何通过细致的设计实现账号的有效管理和安全性&#xff0c;确保系统既便于用户操作又能维持管理的严密性。 文章目录 需求能力模块设计 需求能力 在进…

计算机考研❗️这些院校(含985)性价比巨高

✅厦门大学 (985) 不歧视双非&#xff0c;全靠实力&#xff0c;校园环境还贼美 ✅重庆大学 (985) 信息公开透明&#xff0c;复试抽签 ✅北京师范大学 (985) 不歧视本科出身&#xff0c;面试抽签答题。 ✅东南大学 (985) 保护第一志愿&#xff0c;复试抽签 ✅吉林大学 (…

安捷伦DSA90254A示波器 AgilentDSA90254A

产品简介&#xff1a; •高性能实验室 •2.5 GHz 带宽 •4 个模拟通道&#xff0c;每个通道的采样率为 20 GSa/s •每个通道的数据速率为 20 Mpts 至 1 Gpts •很低的本底噪声&#xff1a;100 mV/格时为 3.01 mVrms •DSA90000A 系列示波器是以 Infiniium DSO90000A 系列…

ChatGPT:人工智能的革命与未来

引言 随着人工智能技术的飞速发展&#xff0c;ChatGPT作为OpenAI推出的一款语言模型&#xff0c;已经引起了广泛的关注和讨论。它不仅改变了我们与机器交流的方式&#xff0c;还为众多行业的发展带来了革命性的影响。本文将深入探讨ChatGPT的技术原理、应用场景以及它对未来的…

JavaEE进阶(14)Linux基本使用和程序部署(博客系统部署)

接上次博客&#xff1a;JavaEE进阶&#xff08;13&#xff09;案例综合练习——博客系统-CSDN博客 目录 程序配置文件修改和打包 构建项目并打包 分平台配置 数据准备 上传jar包到云服务器并运行 开放端口号 验证程序 如何查看日志得到报错信息 常见问题 关于Linux基…

串的匹配算法——KMP算法

目录 一.特点 二.算法思想 三.公式证明 四.next数组及其练习 五.找规律计算next[k] 六.代码实现 一.特点 BF算法的特点是i回退&#xff0c;KMP算法的最大特点是i不回退&#xff0c;由于i不回退&#xff0c;所以KMP算法的时间复杂度是O(nm)。 二.算法思想 在匹配主串和子…

浅谈社会工程学攻击

一、前言 1.1 社会工程学起源 社会工程学是黑客米特尼克在《欺骗的艺术》中所提出&#xff0c;其初始目的是让全球的网民们能够懂得网络安全&#xff0c;提高警惕&#xff0c;防止没必要的个人损失。但在我国黑客集体中还在不断使用其手段欺骗无知网民制造违法行为&#xff0c;…

String类,StringBuilder类,StringBuffer类

前言 String类&#xff0c;StringBuilder类&#xff0c;StringBuffer类都是java提供的定义字符串的类&#xff0c;下面是三种字符串类的异同介绍 String类&#xff1a;String类表示的字符串是是常量&#xff0c;一旦创建内容和长度都无法修改 StringBuilder类&#xff1a;St…

6个维度分析实时渲染和Webgl技术异同

在日常交流中&#xff0c;对Webgl技术熟悉的合作伙伴&#xff0c;在初次了解实时渲染技术时&#xff0c;都会问二者之间的异同。目前很多要求B/S架构的项目&#xff0c;很多在用webgl技术路线&#xff0c;而且这个方案在行业里比较普&#xff0c;业主方对这个也比较熟悉&#x…

JAVA实现图像取模

JAVA对图像取模 就是图片变成点阵 原图 取模效果图 代码如下&#xff1a; public static void main(String[] args) throws IOException {try {// 读取图像文件BufferedImage image ImageIO.read(new File("C:/Users/xiaol/Desktop/img/0.jpg"));// 定义阈值&am…

冬去春来天气阴晴不定 美食拿捏味蕾安稳换季

俗话说“春打六九头”&#xff0c;3月虽然已经入春&#xff0c;但是天气依然是凉飕飕的 &#xff0c;冬天春天的换季期&#xff0c;因为天气的变化&#xff0c;尤为痛苦。但是来到了换季期&#xff0c;天气也不总是那么稳定&#xff0c;随着气温的起伏&#xff0c;我们的食欲也…

Vue项目实战--空间论坛(1)

环境准备 安装好node.js,Vue后 添加插件 router---路由&#xff0c;多页面的应用 vuex---在多个组件之间维护同一个数据 添加依赖 bootstrap---美工 popperjs/core vue项目介绍 views-----对应vue文件&#xff0c;页面 router-----路由&#xff0c;页面&#xff0c;c…

leetCode刷题 4.寻找两个正序数组的中位数

目录 1. 思路 2. 解题方法 3. 复杂度 4. Code 题目&#xff1a; 给定两个大小分别为 m 和 n 的正序&#xff08;从小到大&#xff09;数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。 算法的时间复杂度应该为 O(log (mn)) 。 示例 1&#xff1a; 输入&…

1分钟带你搞定Python函数分类

python语言中&#xff0c;函数可以分为内置函数、自定义函数、有参数函数、无参数函数、有名字函数和匿名函数。其中&#xff0c;内置函数可以直接使用&#xff0c;自定义函数需要根据需求定义。有参数函数在定义时需要指定参数&#xff0c;调用时传入参数。无参数函数在定义时…

git远程仓库使用

赋值这个地址clone 克隆之后 cd slam_oncloud/ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/slam_oncloud.git 查看一下 linuxchenxiao:/media/linux/mydisk/cloud_slam/slam_oncloud$ git remote add chenxnew ssh://git192.168.3.40:1022/chenxiao/sla…

记录一次Dubbo远程调用的错误

情景&#xff1a;有一个生成PDF的接口中&#xff0c;如下&#xff1a; GET Path("/getPDF") public void getPDF(QueryParam("id") String id, Context HttpServletResponse response) {………… }之前实现的代码都写在了Controller里面&#xff0c;代码里…

北斗卫星助力无人机在沙漠播种,促进沙漠治理

北斗卫星助力无人机在沙漠播种&#xff0c;促进沙漠治理 近年来&#xff0c;随着科技的不断发展&#xff0c;北斗卫星和无人机技术的结合被广泛应用于沙漠治理领域&#xff0c;为解决沙漠化问题提供了全新的思路和解决方案。 近日&#xff0c;黄河“几字弯”北岸的内蒙古自治…

word打字后面的字消失是怎么回事

在使用Microsoft Word进行文档编辑时&#xff0c;很多用户可能会遇到一个令人困惑的问题&#xff1a;当在文档中打字时&#xff0c;后面的字却莫名其妙地消失了。这种情况不仅影响了编辑效率&#xff0c;还可能导致重要数据的丢失。那么&#xff0c;这一现象背后的原因是什么&a…

JVM3_数据库连接池虚引用ConnectionFinalizerPhantomReference引起的FullGC问题排查

背景 XOP服务运行期间&#xff0c;查看Grafana面板&#xff0c;发现堆内存周期性堆积&#xff0c;Full GC时间略长&#xff0c;需要调查下原因 目录 垃圾收集器概述 常见的垃圾收集器分区收集策略为什么CMS没成为默认收集器 查看JVM运行时环境分析快照 PhantomReference虚引用…

深度学习目标检测】二十二、基于深度学习的肺炎检测系统-含数据集、GUI和源码(python,yolov8)

肺炎尽管很常见&#xff0c;但准确诊断是一项困难的任务。它要求训练有素的专家对胸部X光片进行检查&#xff0c;并通过临床病史&#xff0c;生命体征和实验室检查进行确认。肺炎通常表现为胸部X光片上一个或多个区域的阴影(opacity)增加。但是&#xff0c;由于肺部有许多其他状…