Java 小游戏《超级马里奥》

news2024/10/19 18:33:06

文章目录

  • 一、效果展示
  • 二、代码编写
    • 1. 素材准备
    • 2. 创建窗口类
    • 3. 创建常量类
    • 4. 创建动作类
    • 5. 创建关卡类
    • 6. 创建障碍物类
    • 7. 创建马里奥类
    • 8. 编写程序入口

一、效果展示

在这里插入图片描述

二、代码编写

1. 素材准备

首先创建一个基本的 java 项目,并将本游戏需要用到的图片素材 image 导入。

图片素材如下:
https://pan.baidu.com/s/1db_IcPvPKWKbVPtodPWO5Q?pwd=03kv
提取码:03kv

在这里插入图片描述

2. 创建窗口类

在这里插入图片描述

① Java 内部已经给我们封装了窗口的各种方法,我们只需创建一个窗口类并重写父类的方法,即可使用;
② Alt + Enter 键 → implement methods 可一键补全所有的重写方法;
③ 实现多线程有两种方法,分别是继承 Thread 类和实现 Runnable 接口,这里我们用 Runnable 方法,因为 Java 不支持多继承。

重写 paint 方法,实现场景、物体的绘制,使用多线程无限绘制窗口。

完整代码如下:

package com.zxe.beans;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.ArrayList;
import java.util.List;

/**
 * 窗口类
 */
public class MyFrame extends JFrame implements KeyListener, Runnable {

    //定义一个集合用于所有的关卡
    private List<LevelMap> levelMaps = new ArrayList<>();
    //定义一个变量,存放当前背景
    private LevelMap levelMap = new LevelMap();
    //定义变量,记录马里奥
    private Mario mario;

    //重写paint方法,实现场景、物体的绘制
    @Override
    public void paint(Graphics g) {
        //创建一张图片
        Image image = createImage(1045, 500);
        //设置图片
        Graphics graphics = image.getGraphics();
        graphics.drawImage(levelMap.getBg(), 0, 0, 1045, 500, this);
        //绘制障碍物
        for (Obstacle obstacle : levelMap.getObstacles()){
            graphics.drawImage(obstacle.getObstacleImage(), obstacle.getX(), obstacle.getY(), this);
        }
        //绘制马里奥
        graphics.drawImage(mario.getMarioImage(), mario.getX(), mario.getY(), this);

        //将图片描绘到当前窗口中
        g.drawImage(image, 0, 0, this);
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode() == 37) {
            mario.runLeft();
        } else if (e.getKeyCode() == 39) {
            mario.runRight();
        } else if (e.getKeyCode() == 38) {
            mario.jump();
        }
    }

    public Mario getMario() {
        return mario;
    }

    public void setMario(Mario mario) {
        this.mario = mario;
    }

    @Override
    public void keyReleased(KeyEvent e) {
        if (e.getKeyCode() == 37) {
            mario.runLeftStop();
        } else if (e.getKeyCode() == 39) {
            mario.runRightStop();
        } else if (e.getKeyCode() == 38) {
            mario.jumpDown();
        }
    }

    @Override
    public void run() {
        //无限次绘制马里奥
        while (true) {
            repaint();
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
            //判断一下马里奥是否通关
            if (mario.getX() > 1040) {
                levelMap = levelMaps.get(levelMap.getLevel());
                mario.setLevelMap(levelMap);
                mario.setX(50);
                mario.setY(420);
            }
        }
    }

    public List<LevelMap> getLevelMaps() {
        return levelMaps;
    }

    public void setLevelMaps(List<LevelMap> levelMaps) {
        this.levelMaps = levelMaps;
    }

    public LevelMap getLevelMap() {
        return levelMap;
    }

    public void setLevelMap(LevelMap levelMap) {
        this.levelMap = levelMap;
    }
}

3. 创建常量类

小游戏中的各种元素画面其实都是一张张的图片,而这些图片路径的定义都将放在常量类中完成。

package com.zxe.beans;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * 常量类
 */
public class Constant {
    //给窗口定义一张图片
    public static BufferedImage bg;
    //右跳图片
    public static BufferedImage jumpR;
    //左跳图片
    public static BufferedImage jumpL;
    //右边站立
    public static BufferedImage standR;
    //左边站立
    public static BufferedImage standL;
    //定义一个集合,存放右跑动作
    public static List<BufferedImage> runR = new ArrayList<>();
    //定义一个集合,存放左跑动作
    public static List<BufferedImage> runL = new ArrayList<>();
    //为障碍物定义一个集合
    public static List<BufferedImage> onstacles = new ArrayList<>();

    //定义一个变量,记录文件路径前缀
    public static String prefix = "C:\\Users\\Lenovo\\Desktop\\demo\\file\\image\\";

    //初始化图片到系统中
    public static void initImage() {
        try {
            //加载图片
            bg = ImageIO.read(new File(prefix + "bg2.jpeg"));
            jumpR = ImageIO.read(new File(prefix + "mario_jump_r.png"));
            jumpL = ImageIO.read(new File(prefix + "mario_jump_l.png"));
            standR = ImageIO.read(new File(prefix + "mario_stand_r.png"));
            standL = ImageIO.read(new File(prefix + "mario_stand_l.png"));
            runR.add(ImageIO.read(new File(prefix + "mario_run_r1.png")));
            runR.add(ImageIO.read(new File(prefix + "mario_run_r2.png")));
            runL.add(ImageIO.read(new File(prefix + "mario_run_l1.png")));
            runL.add(ImageIO.read(new File(prefix + "mario_run_l2.png")));
            for (int i = 1; i <= 6; i++) {
                onstacles.add(ImageIO.read(new File(prefix + "ob" + i + ".png")));
            }
        } catch (IOException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    }

}

常量用 static 修饰,外部可直接通过类名调用常量,而无需创建对象。

4. 创建动作类

记录玛丽的动作状态,具体的常量名与代码分离,可以降低代码的耦合度,更规范化。

在这里插入图片描述

5. 创建关卡类

每个关卡的障碍物是不一样的,这里需要外部传入关卡号,在关卡类中把不同的障碍物拼成自定义的关卡。

完整代码如下:

package com.zxe.beans;

import com.zxe.utils.Constant;

import java.awt.image.BufferedImage;
import java.util.ArrayList;
import java.util.List;

/**
 * 关卡地图类
 */
public class LevelMap {
    //记录当前场景需要的图片
    private BufferedImage bg;
    //记录当前关卡
    private int level;
    //创建一个集合,用于存放障碍物
    private List<Obstacle> obstacles = new ArrayList<>();

    public LevelMap() {
    }

    public LevelMap(int level) {
        this.level = level;
        bg = Constant.bg;
        if (level == 1) {
            //绘制方块
            obstacles.add(new Obstacle(100, 370, 0, this));
            obstacles.add(new Obstacle(130, 370, 1, this));
            obstacles.add(new Obstacle(160, 370, 0, this));
            obstacles.add(new Obstacle(190, 370, 1, this));
            obstacles.add(new Obstacle(300, 260, 0, this));
            obstacles.add(new Obstacle(330, 260, 1, this));
            obstacles.add(new Obstacle(360, 260, 1, this));
            obstacles.add(new Obstacle(800, 300, 0, this));
            obstacles.add(new Obstacle(830, 300, 0, this));
            obstacles.add(new Obstacle(860, 300, 1, this));
            obstacles.add(new Obstacle(890, 300, 1, this));
            //绘制水管
            obstacles.add(new Obstacle(420, 420, 4, this));
            obstacles.add(new Obstacle(450, 420, 5, this));
            obstacles.add(new Obstacle(415, 390, 2, this));
            obstacles.add(new Obstacle(435, 390, 2, this));
            obstacles.add(new Obstacle(455, 390, 3, this));
            obstacles.add(new Obstacle(600, 420, 4, this));
            obstacles.add(new Obstacle(630, 420, 5, this));
            obstacles.add(new Obstacle(600, 390, 4, this));
            obstacles.add(new Obstacle(630, 390, 5, this));
            obstacles.add(new Obstacle(595, 360, 2, this));
            obstacles.add(new Obstacle(615, 360, 2, this));
            obstacles.add(new Obstacle(635, 360, 3, this));

        } else if (level == 2) {
            int i = 0;
            for (int y = 420; y >= 300; y -= 30) {
                for (int x = 100; x <= 190 - 30 * i; x += 30) {
                    obstacles.add(new Obstacle(x + 30 * i, y, 0, this));
                }
                for (int x = 300; x <= 390 - 30 * i; x += 30) {
                    obstacles.add(new Obstacle(x, y, 0, this));
                }
                for (int x = 550; x <= 640 - 30 * i; x += 30) {
                    obstacles.add(new Obstacle(x + 30 * i, y, 0, this));
                }
                for (int x = 670; x <= 790 - 30 * i; x += 30) {
                    obstacles.add(new Obstacle(x, y, 0, this));
                }
                i++;
            }
        }
    }

    public BufferedImage getBg() {
        return bg;
    }

    public void setBg(BufferedImage bg) {
        this.bg = bg;
    }

    public int getLevel() {
        return level;
    }

    public void setLevel(int level) {
        this.level = level;
    }

    public List<Obstacle> getObstacles() {
        return obstacles;
    }

    public void setObstacles(List<Obstacle> obstacles) {
        this.obstacles = obstacles;
    }
}

6. 创建障碍物类

障碍物的属性包括图片以及横纵坐标。

完整代码如下:

package com.zxe.beans;

import com.zxe.utils.Constant;

import java.awt.image.BufferedImage;

/**
 * 障碍物类
 */
public class Obstacle {
    //记录障碍物的坐标
    private int x;
    private int y;
    //定义一个变量,记录当前障碍物的图片信息
    private BufferedImage obstacleImage;
    //定义障碍物类型
    private int type;
    //定义变量存放当前的背景
    private LevelMap bg;

    public Obstacle(int x, int y, int type, LevelMap bg) {
        this.x = x;
        this.y = y;
        this.type = type;
        this.bg = bg;
        //根据障碍物的编号,从常量中的障碍物集合中获取对应的图片
        this.obstacleImage = Constant.onstacles.get(type);
    }

    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public BufferedImage getObstacleImage() {
        return obstacleImage;
    }

    public void setObstacleImage(BufferedImage obstacleImage) {
        this.obstacleImage = obstacleImage;
    }

    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    public LevelMap getBg() {
        return bg;
    }

    public void setBg(LevelMap bg) {
        this.bg = bg;
    }
}

7. 创建马里奥类

马里奥的无限行走动作由多线程实现,定义一个状态量status,用于标记马里奥当前的运动状态,以便进行不同动作的来回切换。

完整代码如下:

package com.zxe.beans;

import com.zxe.utils.Action;
import com.zxe.utils.Constant;

import java.awt.image.BufferedImage;

/**
 * 马里奥类
 */
public class Mario implements Runnable {
    //记录马里奥坐标信息
    private  int x;
    private int y;
    //记录马里奥状态
    private String status;
    //定义一个变量,记录马里奥当前动作所对应的图片信息
    private BufferedImage marioImage;
    //定义变量,记录当前的关卡地图,也可以获取障碍物的信息
    private LevelMap levelMap = new LevelMap();

    //创建线程执行马里奥的动作
    private Thread thread;
    //定义变量,记录马里奥的移动速度
    private int xSpeed;
    //定义变量,记录马里奥的跳跃速度
    private int ySpeed;
    //定义变量,记录马里奥的上升状态
    private int up;

    public Mario() {}

    public Mario(int x, int y) {
        this.x = x;
        this.y = y;
        //默认马里奥的动作是朝右站立
        status = Action.STAND_RIGHT;
        marioImage = Constant.standR;
        thread = new Thread(this);
        thread.start();
    }

    //马里奥向左移动的方法
    public void runLeft() {
        //判断当前是否为跳跃状态,如果不是,就改变状态
        if ( !status.contains("jump") ) {
            status = Action.RUN_LEFT;
        } else {
            status = Action.JUMP_LEFT;
        }
        xSpeed = -5;
    }

    //马里奥向右移动的方法
    public void runRight() {
        //判断当前是否为跳跃状态,如果不是,就改变状态
        if ( !status.contains("jump") ) {
            status = Action.RUN_RIGHT;
        } else {
            status = Action.JUMP_RIGHT;
        }
        xSpeed = 5;
    }

    public void jump() {
        if (status.contains("left")) {
            status = Action.JUMP_LEFT;
        } else {
            status = Action.JUMP_RIGHT;
        }
            ySpeed = -12;
    }

    public void jumpDown() {
        ySpeed = 12;
    }

    private void jumpStop() {
        if (status.contains("left")) {
            status = Action.STAND_LEFT;
        } else {
            status = Action.STAND_RIGHT;
        }
        ySpeed = 0;
    }

    //马里奥向左移动停止的方法
    public void runLeftStop() {
        if (!status.contains("jump")) {
            status = Action.STAND_LEFT;
        } else {
            status = Action.JUMP_LEFT;
        }
        xSpeed = 0;
    }

    //马里奥向右移动停止的方法
    public void runRightStop() {
        if (!status.contains("jump")) {
            status = Action.STAND_RIGHT;
        } else {
            status = Action.JUMP_RIGHT;
        }
        xSpeed = 0;
    }


    public int getX() {
        return x;
    }

    public void setX(int x) {
        this.x = x;
    }

    public int getY() {
        return y;
    }

    public void setY(int y) {
        this.y = y;
    }

    public String getStatus() {
        return status;
    }

    public void setStatus(String status) {
        this.status = status;
    }

    public BufferedImage getMarioImage() {
        return marioImage;
    }

    public void setMarioImage(BufferedImage marioImage) {
        this.marioImage = marioImage;
    }

    public LevelMap getLevelMap() {
        return levelMap;
    }

    public void setLevelMap(LevelMap levelMap) {
        this.levelMap = levelMap;
    }

    public Thread getThread() {
        return thread;
    }

    public void setThread(Thread thread) {
        this.thread = thread;
    }

    public int getxSpeed() {
        return xSpeed;
    }

    public void setxSpeed(int xSpeed) {
        this.xSpeed = xSpeed;
    }

    public int getySpeed() {
        return ySpeed;
    }

    public void setySpeed(int ySpeed) {
        this.ySpeed = ySpeed;
    }

    public int getUp() {
        return up;
    }

    public void setUp(int up) {
        this.up = up;
    }

    @Override
    public void run() {
        int index = 0;
        //控制马里奥无限移动
        while (true) {
            //判断当前是否移动,xSpeed<0左移动,xSpeed>0右移动
            if (xSpeed < 0 || xSpeed > 0) {
                x += xSpeed;
                if (x < 0) {
                    x = 0;
                }
            }

            if (ySpeed < 0 || ySpeed > 0) {
                y += ySpeed;
                if (y > 420) {
                    y = 420;
                    jumpStop();
                }
                if (y < 280) {
                    y = 280;
                }
            }

            //判断移动状态,跑步状态图片切换
            if (status.contains("run")) {
                index = index == 0 ? 1 : 0;
            }
            //根据马里奥的状态切换不同的图片
            if (Action.RUN_LEFT.equals(status)) {
                marioImage = Constant.runL.get(index);
            }
            if (Action.RUN_RIGHT.equals(status)) {
                marioImage = Constant.runR.get(index);
            }
            if (Action.STAND_LEFT.equals(status)) {
                marioImage = Constant.standL;
            }
            if (Action.STAND_RIGHT.equals(status)) {
                marioImage = Constant.standR;
            }
            if (Action.JUMP_LEFT.equals(status)) {
                marioImage = Constant.jumpL;
            }
            if (Action.JUMP_RIGHT.equals(status)) {
                marioImage = Constant.jumpR;
            }

            // 控制线程的速度
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                throw new RuntimeException(e);
            }
        }
    }

}

8. 编写程序入口

创建游戏窗口,并对窗口的基本属性进行设置,创建三个关卡,并调用 repaint 方法绘制场景。

package com.zxe;

import com.zxe.beans.LevelMap;
import com.zxe.beans.Mario;
import com.zxe.utils.Constant;
import com.zxe.beans.MyFrame;

import javax.swing.*;

public class Main {
    public static void main(String[] args) {
        //创建窗口对象
        MyFrame myFrame = new MyFrame();
        //设置窗口大小
        myFrame.setSize(1045,500);
        //设置窗口居中
        myFrame.setLocationRelativeTo(null);
        //设置窗口可见性
        myFrame.setVisible(true);
        //设置窗口关闭程序
        myFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //设置键盘监听事件
        myFrame.addKeyListener(myFrame);
        //设置窗口的大小不可改变
        myFrame.setResizable(false);
        //设置窗口标题
        myFrame.setTitle("超级玛丽");

        //加载图片
        Constant.initImage();
        //创建三个关卡地图
        for (int i = 1; i <= 3; i++) {
            myFrame.getLevelMaps().add(new LevelMap(i));
        }
        //设置当前关卡地图
        myFrame.setLevelMap(myFrame.getLevelMaps().get(0));

        //创建马里奥
        Mario mario = new Mario(50, 420);
        myFrame.setMario(mario);
        mario.setLevelMap(myFrame.getLevelMap());

        //绘制场景
        myFrame.repaint();

        Thread thread = new Thread(myFrame);
        thread.start();
    }
}

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

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

相关文章

华为 HCIP-Datacom H12-821 题库 (38)

&#x1f423;博客最下方微信公众号回复题库,领取题库和教学资源 &#x1f424;诚挚欢迎IT交流有兴趣的公众号回复交流群 &#x1f998;公众号会持续更新网络小知识&#x1f63c; 1.请对 2001:0DB8:0000:C030:0000:0000:09A0:CDEF 地址进行压缩。&#xff08; &#xff09;&…

阻塞I/O与非阻塞I/O

目录 一、基本概念 二、阻塞I/O的实现机制 —— 等待队列 一、基本概念 阻塞&#xff1a;在执行单元进行操作时&#xff0c;如果不能获得申请的资源&#xff0c;则执行单元挂起直至资源可用后再进行操作。 非阻塞&#xff1a;在执行单元进行操作时&#xff0c;如果不能获得申…

UDP反射放大攻击防范手册

UDP反射放大攻击是一种极具破坏力的恶意攻击手段。 一、UDP反射放大攻击的原理 UDP反射放大攻击主要利用了UDP协议的特性。攻击者会向互联网上大量的开放UDP服务的服务器发送伪造的请求数据包。这些请求数据包的源IP地址被篡改为目标受害者的IP地址。当服务器收到这些请求后&…

爬虫实战(黑马论坛)

1.定位爬取位置内容&#xff1a; # -*- coding: utf-8 -*- import requests import time import re# 请求的 URL 和头信息 url https://bbs.itheima.com/forum-425-1.html headers {user-agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like…

DBSwitch和Seatunel

一、DBSwitch 什么是DBSwitch?它主要用在什么场景&#xff1f; 通过步骤分析可以看到这个是通过配置数据源&#xff0c;采用一次性或定时方案&#xff0c;同步到数据仓库的指定表&#xff0c;并且指定映射关系的工具。有点类似于flinkcdc的增量同步。 参考&#xff1a; dbs…

【实战案例】SpringBoot项目中异常处理通用解决方案

项目中经常会出现一些异常&#xff0c;比如在新增项目的时候必要的字段没有填写。在springboot项目中&#xff0c;遇到异常会往上抛出给调用方&#xff0c;DAO层遇到异常抛给Service层&#xff0c;Service层遇到异常抛给Controller层&#xff0c;Controller层遇到异常就抛给了S…

Qt-系统网络HTTP客户端(66)

目录 描述 相关函数 使用 准备工作 处理响应 测试 代码 补充 描述 进⾏ Qt 开发时, 和服务器之间的通信很多时候也会⽤到 HTTP 协议 Qt 中提供了客户端&#xff0c;但是并没有提供相应的服务器的库&#xff0c;所以这里我们只讨论 客户端 • 通过 HTTP 从服务器获取…

Unity 2d UI 实时跟随场景3d物体

2d UI 实时跟随场景3d物体位置&#xff0c;显示 3d 物体头顶信息&#xff0c;看起来像是场景中的3dUI&#xff0c;实质是2d UIusing System.Collections; using System.Collections.Generic; using UnityEngine; using DG.Tweening; using UnityEngine.UI; /// <summary>…

RequestBody接收参数报错com.fasterxml.jackson.databind.exc.MismatchedInputException

目录&#xff1a; 1、错误现象2、解决办法3、最终验证 1、错误现象 报错的现象和代码如下&#xff1a; 2、解决办法 查了很多都说参数类型对不上&#xff0c;但是明明是对上的&#xff0c;没有问题&#xff0c;最后只有换接收方式后验证是可以的&#xff1b;最终想了一下&…

Flink状态一致性保证

前言 一个Flink作业由一系列算子构成&#xff0c;每个算子可以有多个并行实例&#xff0c;这些实例被称为 subTask&#xff0c;每个subTask运行在不同的进程或物理机上&#xff0c;以实现作业的并行处理。在这个复杂的分布式场景中&#xff0c;任何一个节点故障都有可能导致 F…

智能算力中心万卡GPU集群架构深度解析

智能算力中心万卡GPU集群架构深度分析 自ChatGPT发布&#xff0c;科技界大模型竞赛如火如荼。数据成新生产要素&#xff0c;算力成新基础能源&#xff0c;大模型成新生产工具&#xff0c;“AI”转型势不可挡。模型参数量突破万亿&#xff0c;对算力需求升级&#xff0c;超万卡…

Docker学习笔记(2)- Docker的安装

1. Docker的基本组成 镜像&#xff08;image&#xff09;&#xff1a;Docker镜像就像是一个模板&#xff0c;可以通过这个模板来创建容器服务。通过一个镜像可以创建多个容器。最终服务运行或者项目运行就是在容器中。容器&#xff08;container&#xff09;&#xff1a;Docker…

Ansible概述

目录 一、ansible简介 二、absible的特点 三、ansible的工作原理以及流程 四、ansible环境安装部署 五、ansible命令行模块 六、inventory 主机清单 一、ansible简介 Ansible是一个基于Python开发的配置管理和应用部署工具&#xff0c;现在也在自动化管理领域大放异彩。…

MT1341-MT1350 码题集 (c 语言详解)

MT1341反比例函数 c 语言实现代码 #include <stdio.h>double f(double x) { return 1.0 / x; }double trapezoidal_integration(double a, double b, int n) {// computer step lengthdouble h (b - a) / n;// computer points valuedouble sum (f(a) f(b)) / 2.0;//…

初阶数据结构【2】--顺序表(详细且通俗易懂,不看一下吗?)

本章概述 线性表顺序表顺序表问题与思考彩蛋时刻&#xff01;&#xff01;&#xff01; 线性表 概念&#xff1a;一些在逻辑上成线性关系的数据结构的集合。线性表在逻辑上一定成线性结构&#xff0c;在物理层面上不一定成线性结构。常见的线性表&#xff1a;顺序表&#xff0…

Origin画图——百分比堆积柱状图(深度学习篇)

1.当数据有以下特征&#xff0c;不同特征在不同情况下的数值的时候就可以使用百分比柱状图表示。 1 2.将自己的数据导入到Origin中&#xff0c;本示例中以不同机器学习的方法的在不同测试集下的R2作为示例。数据如下所示。绘图百分比柱状图&#xff0c;两种都可以。 3.生成的…

推荐一个可以免费上传PDF产品图册的网站

​在数字化时代&#xff0c;企业将产品图册以PDF格式上传至网络&#xff0c;不仅便于客户浏览和下载&#xff0c;还能提升企业的专业形象。今天&#xff0c;就为您推荐一个可以免费上传PDF产品图册的网站——FLBOOK&#xff0c;轻松实现产品图册的在线展示。 1.注册登录&#x…

【xilinx-versal】【Petalinux】添加TMP75温度传感器Linux驱动

Xilinx versal添加TMP75温度传感器Linux驱动 I2C总线的内核配置打开Cadence I2C 控制器配置xilinx I2C配置(不使用)添加设备树总结I2C总线的内核配置 TMP75挂载第一个i2c总线上,地址是0x48。 petalinux-config -c kernel打开内核配置界面。 打开Cadence I2C 控制器配置 │…

Linux——用户/用户组

创建用户组groupadd groupadd 用户组 删除用户组groupdel groupdel 用户组 创建用户useradd useradd 用户名 - g 用户组 useradd 用户名 -d HOME路径 删除用户userdel userdel 用户 userdel -r 用户 &#xff08;删除用户的 HOME 目录&#xff0c;不使用 -r &#xff0…

FlinkCDC 实现 MySQL 数据变更实时同步

文章目录 1、基本介绍2、代码实战2.1、数据源准备2.2、代码实战2.3、数据格式 1、基本介绍 Flink CDC 是 Apache Flink 提供的一个功能强大的组件&#xff0c;用于实时捕获和处理数据库中的数据变更。可以实时地从各种数据库&#xff08;如MySQL、PostgreSQL、Oracle、MongoDB…