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.mfbz.cn/a/433933.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

coqui-ai/TTS 安装使用

Coqui AI的TTS是一款开源深度学习文本转语音工具&#xff0c;以高质量、多语言合成著称。它提供超过1100种语言的预训练模型库&#xff0c;能够轻松集成到各种应用中&#xff0c;并允许用户通过简单API进行个性化声音训练与微调。其技术亮点包括但不限于低资源适应性&#xff0…

golang中go build 后读取配置文件

golang打包后读取配置文件 在用go写代码的时候&#xff0c;为了好用经常使用go build 打包&#xff0c;如果我们用到了配置文件&#xff0c;就总是导致不能找到文件所在位置了出现bug&#xff0c;所以以下代码就解决了这个问题。 核心代码&#xff1a; file, err : exec.Look…

【C++ vscode 环境问题】vscode编译的时候:未定义标识符 thread mingw-w64安装支持c++11中thread

重新下载 MinGW64 https://sourceforge.net/projects/mingw-w64/files/mingw-w64/mingw-w64-release/往下滑动 最下面 找到这个版本下载解压并且记住下载的位置搜环境 添加你的MinGW64安装的位置 路径模仿我这样写 然后应用报存修改vscode配置文件 问题解决

【JSON2WEB】08 Amis的事件和校验

【JSON2WEB】01 WEB管理信息系统架构设计 【JSON2WEB】02 JSON2WEB初步UI设计 【JSON2WEB】03 go的模板包html/template的使用 【JSON2WEB】04 amis低代码前端框架介绍 【JSON2WEB】05 前端开发三件套 HTML CSS JavaScript 速成 【JSON2WEB】06 JSON2WEB前端框架搭建 【J…

Python(NetOps)前传-网络设备开局配置

背景 我们知道用Python在cli配置网络设备的前提是&#xff1a; 网络设备与Python主机网络可达网络设备已开启并完成ssh相关配置 目标 本文已华为S5720S-52P-LI-AC交换机为例&#xff0c;完成&#xff1a; 完成网络设备开局配置&#xff1b;用Python脚本验证ssh登录 配置 …

整流二极管:电路图、符号、功能与其它二极管的区别

整流二极管是 一种用于将交流电转换为直流电的半导体器件。二极管最重要的特性是单向导电性。在电路中&#xff0c;电流只能从二极管的正极流入&#xff0c;从负极流出。通常&#xff0c;它包含一个带有正极和负极端子的 PN 结。其结构如下图所示。 P区的载流子是空穴&#xf…

【Mysql】执行sql语句后,mysql都做了什么?

查数据大家都经常干&#xff0c;但是你知道从执行sql到看到结果&#xff0c;mysql背后都做了什么事情吗&#xff1f; 一、mysql的架构 client/server 这种客户端到服务端的架构&#xff0c;大家一定都很熟悉&#xff0c;其实 mysql 也与之类似。 可以有多个客户端与服务端连…

突破编程_前端_JS编程实例(简单树结构组件)

1 开发目标 实现如下简单树结构组件&#xff1a; 再点击树节点后&#xff0c;会调用客户端传入的回调函数&#xff1a; 2 详细需求 简单树结构组件需根据客户端提供的参数创建&#xff0c;具备动态构建树形结构节点、选项卡切换及自定义内容显示等功能&#xff1a; &#xf…

DR模式LVS负载均衡部署

实验&#xff1a;7-1做调度器&#xff1b;7-2和7-3做真实服务器&#xff1b;7-4做客户端&#xff1b; 1.先关闭所有的防火墙和selinux [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 [rootlocalhost ~]# 2.怎么看selinux状态 [rootlocalhost…

docker拉取镜像报错permission denied

ocker pull apache/causeway-app-helloworld:latest permission denied while trying to connect to the Docker daemon socket at unix:///var/run/docker.sock: Post “http://%2Fvar%2Frun%2Fdocker.sock/v1.24/images/create?fromImageapache%2Fcauseway-app-helloworld&a…

Vue:双token无感刷新

文章目录 初次授权与发放Token&#xff1a;Access Token的作用&#xff1a;Refresh Token的作用&#xff1a;无感刷新&#xff1a;安全机制&#xff1a;后端创建nest项目AppController 添加login、refresh、getinfo接口创建user.dto.tsAppController添加模拟数据 前端Hbuilder创…

node的使用和模块化认识

node使用 1. node运行文件 node执行js的方式是在cmd命令行运行运行方式两种 直接打开命令行输入node&#xff0c;进入node环境&#xff0c;书写javascript&#xff0c;这种方式书写javascript关闭命令行就需要在重新写一遍&#xff0c;一般开发不推荐使用这种方式。 退出node…

磁盘没有满 为什么提示磁盘空间不足?原来是inode惹的祸。

我为什么知道是inode 的问题呢&#xff1f; 接下备好瓜子花生来且听我分析 我一个免费开源根据ip获取用户地理位置的api 突然报错如下 failed to open stream: No space left on device in 然后登录linux 使用shell命令 自动补全功能竟然也提示磁盘空间不足 报错如下 cd /-b…

ES单节点部署

ES 拉取镜像 docker pull elasticsearch:7.10.1启动容器 docker run -d -p 9200:9200 -p 9300:9300 -e "discovery.typesingle-node" -e "ES_JAVA_OPTS-Xms1g -Xmx1g" -v /es_data:/usr/share/elasticsearch/data --name es 558380375f1a注&#xff1a…

微信小程序怎么盈利?探索微信小程序的盈利途径与建设流程

微信小程序自推出以来&#xff0c;凭借其无需下载安装、即用即走的特点&#xff0c;在移动互联网领域迅速占据了重要地位。商家和开发者们纷纷投入其中&#xff0c;希望借助这一平台实现商业价值的转化。那么&#xff0c;微信小程序是如何为开发者和商家带来盈利的呢&#xff1…

配置与管理防火墙

配置与管理防火墙 1&#xff0c;概念&#xff1a;设置在不同网络或网络安全域之间的一系列部件的组合。 2&#xff0c;功能&#xff1a;保护内网中易手攻击的服务&#xff1b;控制内外网之间网络系统的访问&#xff1b;隐藏内网的IP地址及结构的细节&#xff0c;提高网络保护…

【操作系统概念】 第5章:进程调度

文章目录 0.前言5.1 基本概念5.1.1 CPU-I/O 区间周期5.1.2 CPU程序调度5.1.3 抢占调度5.1.4 分派程序 5.2 调度准则5.3 调度算法5.3.1 先到先服务调度(First-Come&#xff0c;First-Served scheduling)5.3.2 最短作业优先调度(shortest-job-first scheduling,SJF)5.3.3 优先级调…

docker 安装 portainer

小编给友友们总结了一下 Portainer 的好处以下 Portainer是Docker的图形化管理工具&#xff0c;提供状态显示面板、应用模板快速部署、容器镜像网络数据卷的基本操作&#xff08;包括上传下载镜像&#xff0c;创建容器等操作&#xff09;、事件日志显示、容器控制台操作、Swar…

掘根宝典之C语言原码,反码,补码,位操作运算符(~,,|,^,<<,>>,=,|=,^=,>>=,<<=)

目录 二进制数 什么是二进制数 c语言中的二进制数 机器数 原码 正数计算 负数计算 反码 负数计算 跨零计算 补码 定义 跨零计算 总结 按位逻辑运算符&#xff08;~&#xff0c;&&#xff0c;&,|&#xff0c;|&#xff0c;^&#xff0c;^&#xff09; 按…

玩家至上:竞技游戏设计如何满足现代玩家的需求?

文章目录 一、现代玩家需求分析二、以玩家体验为核心的游戏设计三、个性化与定制化服务四、强化社交互动与社区建设五、持续更新与优化《游戏力&#xff1a;竞技游戏设计实战教程》亮点编辑推荐内容简介目录获取方式 随着科技的飞速发展和游戏产业的不断壮大&#xff0c;现代玩…
最新文章