fc坦克大战游戏完美复刻

news2024/11/28 6:29:31

文章目录

  • 一、 介绍
  • 二、 制作基本物体
  • 三、 控制玩家坦克移动、转向
  • 四、 子弹脚本、爆炸脚本
  • 五、 敌人AI寻路算法
  • 六、 坦克生成点脚本
  • 七、 用链表实例化地图
  • 八、 玩家游戏控制器脚本
  • 九、 添加音效
  • 十、 资源包


一、 介绍

儿时经典游戏《坦克大战》完整复刻
发射子弹、生成敌人、消灭敌人、保护老巢、记录生命值。

在这里插入图片描述

在这里插入图片描述


二、 制作基本物体

制作玩家坦克
制作敌人坦克
制作玩家心脏
制作玩家保护罩
制作河流
制作砖头墙
制作铁墙
制作出生位置
制作出生动画

在这里插入图片描述


三、 控制玩家坦克移动、转向

wsad移动
数组控制转向
定义子弹发射时间间隔
发射子弹
坦克死亡效果

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Player : MonoBehaviour {

  //定义坦克的移动速度属性
public float moveSpeed=3;

//定义子弹的旋转角度
private Vector3 bullectEulerAngles;

//定义攻击CD时间
private float timeVal;

//定义无敌状态持续时间
private float defendTimeVal=3;

//定义是否处于无敌状态
private bool isDefended=true;

//引用组件
private SpriteRenderer sr; //获取坦克的SpriteRenderer组件
public Sprite[] tankSprite; //存储坦克的四个方向的图片
public GameObject bullectPrefab; //存储子弹的预制体
public GameObject explosionPrefab; //存储爆炸特效的预制体
public GameObject defendEffectPrefab; //存储无敌特效的预制体
public AudioSource moveAudio; //获取坦克的AudioSource组件
public AudioClip[] tankAudio; //存储坦克的音效

    private void Awake()
    {
        sr = GetComponent<SpriteRenderer>();
    }

    // Use this for initialization
    void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        //是否处于无敌状态
        if (isDefended)
        {
            defendEffectPrefab.SetActive(true);
            defendTimeVal -= Time.deltaTime;
            if (defendTimeVal<=0)
            {
                isDefended = false;
                defendEffectPrefab.SetActive(false);
            }
        }

        
       
    }

    private void FixedUpdate()
    {
        if (PlayerManager.Instance.isDefeat)
        {
            return;
        }
        Move();
        //攻击的CD
        if (timeVal >= 0.4f)
        {
            Attack();
        }
        else
        {
            timeVal += Time.fixedDeltaTime;
        }


    }

    //坦克的攻击方法
    private void Attack()
    {
        if (Input.GetKeyDown(KeyCode.Space))
        {

            //子弹产生的角度:当前坦克的角度+子弹应该旋转的角度。
            Instantiate(bullectPrefab, transform.position,Quaternion.Euler(transform.eulerAngles+bullectEulerAngles));
            timeVal = 0;
        }
    }


    //坦克的移动方法
    private void Move()
    {
        float v = Input.GetAxisRaw("Vertical");


        transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);

        if (v < 0)
        {
            sr.sprite = tankSprite[2];
            bullectEulerAngles = new Vector3(0, 0, -180);
        }

        else if (v > 0)
        {
            sr.sprite = tankSprite[0];
            bullectEulerAngles = new Vector3(0, 0, 0);
        }

        if (Mathf.Abs(v)>0.05f)
        {
            moveAudio.clip = tankAudio[1];
            
            if (!moveAudio.isPlaying)
            {
                moveAudio.Play();
            }
        }

        if (v != 0)
        {
            return;
        }

        float h = Input.GetAxisRaw("Horizontal");
        transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);
        if (h < 0)
        {
            sr.sprite = tankSprite[3];
            bullectEulerAngles = new Vector3(0, 0, 90);
        }

        else if (h > 0)
        {
            sr.sprite = tankSprite[1];
            bullectEulerAngles = new Vector3(0, 0, -90);
        }

        if (Mathf.Abs(h) > 0.05f)
        {
            moveAudio.clip = tankAudio[1];

            if (!moveAudio.isPlaying)
            {
                moveAudio.Play();
            }
        }
        else
        {
            moveAudio.clip = tankAudio[0];

            if (!moveAudio.isPlaying)
            {
                moveAudio.Play();
            }
        }
    }

    //坦克的死亡方法
    private void Die()
    {
        if (isDefended)
        {
            return;
        }

        PlayerManager.Instance.isDead = true;

        //产生爆炸特效
        Instantiate(explosionPrefab, transform.position, transform.rotation);
        //死亡
        Destroy(gameObject);
    }	
}





四、 子弹脚本、爆炸脚本

子弹撞击不同的物体,会有不同的效果
播放爆炸动画效果
设置子弹移动速度
检测是否为玩家子弹
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Bullect : MonoBehaviour {

    public float moveSpeed = 10;

    public bool isPlayerBullect;


	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        transform.Translate(transform.up * moveSpeed * Time.deltaTime, Space.World);
	}


    private void OnTriggerEnter2D(Collider2D collision)
    {
        switch (collision.tag)
        {
            case "Tank":
                if (!isPlayerBullect)
                {
                    collision.SendMessage("Die");
                    Destroy(gameObject);
                }
                break;
            case "Heart":
                collision.SendMessage("Die");
                Destroy(gameObject);
                break;
            case "Enemy":
                if (isPlayerBullect)
                {
                    collision.SendMessage("Die");
                    Destroy(gameObject);
                }
                
                break;
            case "Wall":
                Destroy(collision.gameObject);
                Destroy(gameObject);
                break;
            case "Barrier":
                if (isPlayerBullect)
                {
                    collision.SendMessage("PlayAudio");
                }
                Destroy(gameObject);
                break;
            default:
                break;
        }
    }

}

爆炸效果
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Explosion : MonoBehaviour {

	// Use this for initialization
	void Start () {
        Destroy(gameObject, 0.167f);
	}
	
	// Update is called once per frame
	void Update () {
		
	}
}


五、 敌人AI寻路算法

敌人在上面有三个刷新点
出生后每三秒发射一枚子弹
敌人走动的方向,是random随机值,往下走的概率最大
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Enemy : MonoBehaviour {

    //属性值
    public float moveSpeed = 3;
    private Vector3 bullectEulerAngles; // 子弹的旋转角度
    private float v = -1; // 坦克的竖直方向的移动量
    private float h; // 坦克的水平方向的移动量

    //引用
    private SpriteRenderer sr; // 坦克的SpriteRenderer组件
    public Sprite[] tankSprite; // 坦克朝向四个方向的精灵
    public GameObject bullectPrefab; // 子弹的预制体
    public GameObject explosionPrefab; // 爆炸特效的预制体

    //计时器
    private float timeVal; // 攻击计时器
    private float timeValChangeDirection; // 改变方向计时器

    private void Awake()
    {
        sr = GetComponent<SpriteRenderer>(); // 获取坦克的SpriteRenderer组件
    }

    void Start()
    {

    }

    void Update()
    {
        //攻击的时间间隔
        if (timeVal >= 3) // 如果攻击计时器大于等于3秒
        {
            Attack(); // 调用坦克的攻击方法
        }
        else
        {
            timeVal += Time.deltaTime; // 否则,增加攻击计时器的值
        }

    }

    private void FixedUpdate()
    {
        Move(); // 每一帧调用坦克的移动方法
    }

    //坦克的攻击方法
    private void Attack()
    {
       //子弹产生的角度:当前坦克的角度+子弹应该旋转的角度。
       Instantiate(bullectPrefab, transform.position, Quaternion.Euler(transform.eulerAngles + bullectEulerAngles)); // 实例化子弹预制体
       timeVal = 0; // 重置攻击计时器的值
    }

   //坦克的移动方法
private void Move()
{
    // 当计时器 timeValChangeDirection 大于等于4时,改变坦克的移动方向
    if (timeValChangeDirection >= 4)
    {
        // 随机一个数值
        int num = Random.Range(0, 8);
        if (num > 5)
        {
            v = -1;
            h = 0;
        }
        else if (num == 0)
        {
            v = 1;
            h = 0;
        }
        else if (num > 0 && num <= 2)
        {
            h = -1;
            v = 0;
        }
        else if (num > 2 && num <= 4)
        {
            h = 1;
            v = 0;
        }
        // 重置计时器
        timeValChangeDirection = 0;
    }
    else
    {
        // 计时器加上时间差
        timeValChangeDirection += Time.fixedDeltaTime;
    }

    // 沿着当前方向移动坦克
    transform.Translate(Vector3.up * v * moveSpeed * Time.fixedDeltaTime, Space.World);

    // 根据当前方向改变坦克的朝向
    if (v < 0)
    {
        sr.sprite = tankSprite[2];
        bullectEulerAngles = new Vector3(0, 0, -180);
    }
    else if (v > 0)
    {
        sr.sprite = tankSprite[0];
        bullectEulerAngles = new Vector3(0, 0, 0);
    }

    // 如果坦克在竖直方向上,则不进行水平方向的移动
    if (v != 0)
    {
        return;
    }

    // 沿着当前方向移动坦克
    transform.Translate(Vector3.right * h * moveSpeed * Time.fixedDeltaTime, Space.World);

    // 根据当前方向改变坦克的朝向
    if (h < 0)
    {
        sr.sprite = tankSprite[3];
        bullectEulerAngles = new Vector3(0, 0, 90);
    }
    else if (h > 0)
    {
        sr.sprite = tankSprite[1];
        bullectEulerAngles = new Vector3(0, 0, -90);
    }
}

//坦克的死亡方法
private void Die()
{
    // 玩家得分加1
    PlayerManager.Instance.playerScore++;
    // 产生爆炸特效
    Instantiate(explosionPrefab, transform.position, transform.rotation);
    // 销毁坦克
    Destroy(gameObject);
}

// 当坦克与其他游戏对象发生碰撞时,检测是否为敌方坦克,如果是,则重置移动方向
private void OnCollisionEnter2D(Collision2D collision)
{
    if (collision.gameObject.tag == "Enemy")
    {
        timeValChangeDirection = 4;
    }
}

六、 坦克生成点脚本

上面三个出生点刷新敌人坦克,有两种坦克,随机产生一种
下面两个出生点刷新玩家坦克
延时调用
using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Born : MonoBehaviour {
    // 玩家坦克预制件
    public GameObject playerPrefab;
    // 敌人坦克预制件数组
    public GameObject[] enemyPrefabList;
    // 是否产生玩家坦克
    public bool createPlayer;

    // Use this for initialization
    void Start () {
        // 延迟1秒后执行 BornTank 方法
        Invoke("BornTank", 1f);
        // 一秒后销毁当前游戏对象
        Destroy(gameObject, 1);
    }
    
    // Update is called once per frame
    void Update () {
        
    }

    // 产生坦克的方法
    private void BornTank()
    {
        if (createPlayer)
        {
            // 产生玩家坦克
            Instantiate(playerPrefab, transform.position, Quaternion.identity);
        }
        else
        {
            // 随机选择一种敌人坦克类型
            int num = Random.Range(0, 2);
            // 产生敌人坦克
            Instantiate(enemyPrefabList[num], transform.position, Quaternion.identity);
        }
    }
}

七、 用链表实例化地图

游戏地图并不是预先设置好的,是随机生成的(除了心脏),每次都不一样

在这里插入图片描述

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class MapCreation : MonoBehaviour {

    // 用来装饰初始化地图所需物体的数组。
    // 0.老家 1.墙 2.障碍 3.出生效果 4.河流 5.草 6.空气墙
    public GameObject[] item;

    //已经有东西的位置列表
    private List<Vector3> itemPositionList = new List<Vector3>();

    private void Awake()
    {
        InitMap();
    }

    private void InitMap()
    {
        //实例化老家
        CreateItem(item[0], new Vector3(0, -8, 0), Quaternion.identity);
        //用墙把老家围起来
        CreateItem(item[1], new Vector3(-1, -8, 0), Quaternion.identity);
        CreateItem(item[1], new Vector3(1, -8, 0), Quaternion.identity);
        for (int i = -1; i < 2; i++)
        {
            CreateItem(item[1], new Vector3(i, -7, 0), Quaternion.identity);
        }
        //实例化外围墙
        for (int i = -11; i < 12; i++)
        {
            CreateItem(item[6], new Vector3(i, 9, 0), Quaternion.identity);
        }
        for (int i = -11; i < 12; i++)
        {
            CreateItem(item[6], new Vector3(i, -9, 0), Quaternion.identity);
        }
        for (int i = -8; i < 9; i++)
        {
            CreateItem(item[6], new Vector3(-11, i, 0), Quaternion.identity);
        }
        for (int i = -8; i < 9; i++)
        {
            CreateItem(item[6], new Vector3(11, i, 0), Quaternion.identity);
        }

        //初始化玩家
        GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);
        go.GetComponent<Born>().createPlayer = true;

        //产生敌人
        CreateItem(item[3], new Vector3(-10, 8, 0), Quaternion.identity);
        CreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity);
        CreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);

        InvokeRepeating("CreateEnemy", 4, 5);

        //实例化地图
        for (int i = 0; i < 60; i++)
        {
            CreateItem(item[1], CreateRandomPosition(), Quaternion.identity);
        }
        for (int i = 0; i < 20; i++)
        {
            CreateItem(item[2], CreateRandomPosition(), Quaternion.identity);
        }
        for (int i = 0; i < 20; i++)
        {
            CreateItem(item[4], CreateRandomPosition(), Quaternion.identity);
        }
        for (int i = 0; i < 20; i++)
        {
            CreateItem(item[5], CreateRandomPosition(), Quaternion.identity);
        }
    }

    // 创建物体的方法
    private void CreateItem(GameObject createCameObject, Vector3 createPosition, Quaternion createRotation)
    {
        GameObject itemGo = Instantiate(createCameObject, createPosition, createRotation);
        itemGo.transform.SetParent(gameObject.transform);
        itemPositionList.Add(createPosition);
    }

  // 产生随机位置的方法
private Vector3 CreateRandomPosition()
{
    // 不生成x=-10,10的两列,y=-8,8正两行的位置
    while (true)
    {
        Vector3 createPosition = new Vector3(Random.Range(-9, 10), Random.Range(-7, 8), 0);
        
        // 判断是否该位置是否已经存在
        if (!HasThePosition(createPosition))
        {
            return createPosition;
        }
    }
}

//用来判断位置列表中是否有这个位置
private bool HasThePosition(Vector3 createPos)
{
    // itemPositionList 是之前记录所有敌人和道具生成位置的列表
    for (int i = 0; i < itemPositionList.Count; i++)
    {
        if (createPos == itemPositionList[i])
        {
            return true;
        }
    }
    
    return false;
}

//产生敌人的方法
private void CreateEnemy()
{
    int num = Random.Range(0, 3);
    Vector3 EnemyPos = new Vector3();
    
    // 随机选择一个 Y 轴最高(即在顶部)的位置作为敌人的位置
    if (num == 0)
    {
        EnemyPos = new Vector3(-10, 8, 0);
    }
    else if (num == 1)
    {
        EnemyPos = new Vector3(0, 8, 0);
    }
    else
    {
        EnemyPos = new Vector3(10, 8, 0);
    }
    
    // 生成敌人
    CreateItem(item[3], EnemyPos, Quaternion.identity);
}

心脏周边的墙体不是随机的,每次都必须预先设定好

在这里插入图片描述

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Heart : MonoBehaviour {
    // SpriteRenderer组件,用于设置坦克被击中后显示的图片
    private SpriteRenderer sr;
    // 爆炸特效预制件
    public GameObject explosionPrefab;
    // 死亡音效
    public AudioClip dieAudio;
    // 被击中后显示的破碎图片
    public Sprite BrokenSprite;

    // Use this for initialization
    void Start () {
        // 获取SpriteRenderer组件
        sr = GetComponent<SpriteRenderer>();
    }
    
    // ...

    // 坦克死亡的方法
    public void Die()
    {
        // 将坦克的SpriteRenderer组件的图片设置为破碎图片
        sr.sprite = BrokenSprite;
        // 产生爆炸特效
        Instantiate(explosionPrefab, transform.position, transform.rotation);
        // 设置PlayerManager类中的isDefeat变量为true,表示游戏失败
        PlayerManager.Instance.isDefeat = true;
        // 在坦克死亡的位置播放死亡音效
        AudioSource.PlayClipAtPoint(dieAudio, transform.position);
    }
}

八、 玩家游戏控制器脚本

负责游戏的基本逻辑
设置玩家生命值
设置分数
using System.Collections; // 导入系统集合命名空间
using System.Collections.Generic; // 导入泛型集合命名空间
using UnityEngine; // 导入 Unity 引擎命名空间
using UnityEngine.UI; // 导入 Unity 引擎 UI 命名空间
using UnityEngine.SceneManagement; // 导入 Unity 引擎场景管理命名空间

public class PlayerManager : MonoBehaviour { // 声明一个名为 PlayerManager 的类并继承自 MonoBehaviour

    // 属性值
    public int lifeValue = 3; // 玩家生命值,默认为 3
    public int playerScore = 0; // 玩家分数,默认为 0
    public bool isDead; // 是否死亡,默认为 false
    public bool isDefeat; // 是否失败,默认为 false

    // 引用
    public GameObject born; // 出生点游戏对象
    public Text playerScoreText; // 显示玩家分数的文本对象
    public Text PlayerLifeValueText; // 显示玩家生命值的文本对象
    public GameObject isDefeatUI; // 显示失败界面的游戏对象

    // 单例
    private static PlayerManager instance; // 声明一个静态的 PlayerManager 对象

    public static PlayerManager Instance // 声明一个静态的 Instance 属性
    {
        get
        {
            return instance; // 返回 instance 对象
        }

        set
        {
            instance = value; // 设置 instance 对象
        }
    }

    private void Awake() // Awake 方法在脚本实例被加载时执行
    {
        Instance = this; // 设置 instance 对象为当前实例
    }

    // Use this for initialization
    void Start () { // Start 方法在脚本实例被启用时执行,本例中未实现
		
	}
	
	// Update is called once per frame
	void Update () { // Update 方法在每一帧渲染时执行
        if (isDefeat) // 如果失败
        {
            isDefeatUI.SetActive(true); // 显示失败界面
            Invoke("ReturnToTheMainMenu", 3); // 延迟 3 秒后返回主界面
            return; // 返回
        }
        if (isDead) // 如果死亡
        {
            Recover(); // 复活
        }
        playerScoreText.text = playerScore.ToString(); // 更新分数文本
        PlayerLifeValueText.text = lifeValue.ToString(); // 更新生命值文本
	}

    private void Recover() // 复活方法
    {
        if (lifeValue<=0) // 如果生命值小于等于 0
        {
            // 游戏失败,返回主界面
            isDefeat = true; // 设置失败状态为 true
            Invoke("ReturnToTheMainMenu", 3); // 延迟 3 秒后返回主界面
        }
        else // 如果生命值大于 0
        {
            lifeValue--; // 生命值减一
            GameObject go = Instantiate(born, new Vector3(-2, -8, 0), Quaternion.identity); // 在出生点位置实例化玩家
            go.GetComponent<Born>().createPlayer = true; // 设置出生点的 createPlayer 属性为 true
            isDead = false; // 设置死亡状态为 false
        }
    }

    private void ReturnToTheMainMenu() // 返回主界面方法
    {
        SceneManager.LoadScene(0); // 加载场景 0
    }
}

九、 添加音效

添加游戏音效、坦克行进音效、开火音效。
增加双人模式。
添加ui
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.SceneManagement;

public class Option : MonoBehaviour {

    private int choice = 1;
    public Transform posOne;
    public Transform posTwo;

	// Use this for initialization
	void Start () {
		
	}
	
	// Update is called once per frame
	void Update () {
        if (Input.GetKeyDown(KeyCode.W))
        {
            choice = 1;
            transform.position = posOne.position;
        }
        else if (Input.GetKeyDown(KeyCode.S))
        {
            choice = 2;
            transform.position = posTwo.position;
        }
        if (choice==1&&Input.GetKeyDown(KeyCode.Space))
        {
            SceneManager.LoadScene(1);
        }
	}
}

在这里插入图片描述

十、 资源包

https://pan.baidu.com/s/1eGVzYU-pQLZntuGcFfm0Ww

密码:exqi

工程文件私






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

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

相关文章

「欧拉定理」[SDOI2008]仪仗队

[SDOI2008]仪仗队 https://ac.nowcoder.com/acm/problem/20313 题目描述 作为体育委员&#xff0c;C君负责这次运动会仪仗队的训练。 仪仗队是由学生组成的N * N的方阵&#xff0c;为了保证队伍在行进中整齐划一&#xff0c;C君会跟在仪仗队的左后方&#xff0c;根据其视线所…

Golang每日一练(leetDay0050)

目录 147. 对链表进行插入排序 Insertion Sort List &#x1f31f;&#x1f31f; 148. 排序链表 Sort List &#x1f31f;&#x1f31f; 149. 直线上最多的点数 Max Points On A Line &#x1f31f;&#x1f31f;&#x1f31f; 150. 逆波兰表达式求值 Evaluate Reverse …

DDS基本原理与FPGA实现

DDS基本原理与FPGA实现 定义&#xff1a;DDS是指DDS信号发生器&#xff0c;采用直接数字频率合成技术。是一种新型的频率合成技术&#xff0c;具有相对带宽大&#xff0c;频率转换时间短、分辨率高和相位连续性好等优点。较容易实现频率、相位以及幅度的数控调制&#xff0c;广…

服务运营| Healthcare Management Science 近期文章精选

作者&#xff1a;李舒湉 王畅 &#xff08;一&#xff09; Screening for preclinical Alzheimer’s disease: Deriving optimal policies using a partially observable Markov model nen Dumlu Z, Sayın S, Grvit İ H. Screening for preclinical Alzheimer’s disease: …

UG NX二次开发(C#)-显示-更改对象颜色

文章目录 1、前言2、UG NX中的更换对象颜色的功能3、采用UG NX二次开发实现颜色修改3.1 采用直接赋值对象颜色不能直接更改对象颜色3.2 采用NewDisplayModification的方法如下:1、前言 当一个三维模型展现在我们面前时,总会有颜色赋予三维模型的对象上,比如红色、蓝色、银灰…

工具链与其他-移动端网络优化的指标和策略

目录 网络指标 一个请求的时间消耗 页面加载 常见性能指标 网络优化策略 缓存 压缩 请求合并 离线包 预加载&#xff08;前端大流量数据&#xff09; 网络指标 一个请求的时间消耗 一个请求的发生到返回回来&#xff1b;有3部分时间 1.Scheduling&#xff08;排队&…

初识C++之异常

目录 一、C中的常用处理错误方式 二、C异常的概念 1. throw 2. catch 3. try 三、异常的使用 1. 异常的抛出和捕获 1.1 异常的抛出和匹配原则 1.2 在函数调用链中异常栈展开匹配原则 四、异常体系 1. 自定义异常体系 2. C中的异常体系 五、 异常安全 六、异常规范…

Unity 热更新基础HybridCLR:Windows平台使用(HybridCLR手记二)

项目是根据官网的示例工程进行修改的,版本参数如下&#xff1a; unity&#xff1a;2021.2.20 wolong&#xff1a;v2.1.0 il2cpp_plus:v2021_2.1.0 ------------------------------------------------------------- 1、安装&#xff1a;参考&#xff1a;第一篇文章Unity 热…

pytest - Getting Start

前言 项目开发中有很多的功能&#xff0c;通常开发人员需要对自己编写的代码进行自测&#xff0c;除了借助postman等工具进行测试外&#xff0c;还需要编写单元测试对开发的代码进行测试&#xff0c;通过单元测试来判断代码是否能够实现需求&#xff0c;本文介绍的pytest模块是…

虚幻图文笔记:Substance Painter通过USD格式导入UE5的工作流

什么是USD格式 USD即Universal Scene Description&#xff0c;是著名的Pixar公司研发的一种开源的3D 场景说明和文件格式&#xff0c;如其名所示&#xff0c;相较于传统的FBX、Obj等3D格式&#xff0c;USD的具有更好的通用性和扩展性&#xff0c;现在已被非常多的厂商和平台所…

使用树莓派(zero2w + Camera Module 3 支持自动对焦 1200 万像素)拍照

拍照硬件 Raspberry Pi Camera Module 3Raspberry Pi Zero 2 W 1. 注意排线连接方向 2. 烧录系统 3. 进行系统更新需要联网&#xff0c;注意只支持最新的bullseye系统。每条指令大概需要10 分钟。 sudo apt-get update -y sudo apt-get upgrade -y4. 拍摄一张全像素的JPEG图像…

自己做小程序开个社区团购可行吗?

在如今的社交化时代&#xff0c;随着社区经济的发展&#xff0c;越来越多的人开始探索社区团购的商业模式。而随着小程序的普及&#xff0c;自己开发一个社区团购小程序也成为了一种可能。但是&#xff0c;自己做小程序开个社区团购真的可行吗&#xff1f;我们来一起分析一下。…

Spring整合MybatisJunit单元测试

Spring整合Mybatis&Junit单元测试 1. Spring整合Mybatis【重点】1.1 思路分析问题导入1.1.1 MyBatis程序核心对象分析1.1.2 整合MyBatis 1.2 代码实现【前置工作】【第一步】导入Spring整合Mybatis依赖【第二步】创建JdbcConfig配置DataSource数据源【第三步】创建MybatisC…

【ARMv8 编程】A64 内存访问指令——内存加载指令

与所有先前的 ARM 处理器一样&#xff0c;ARMv8 架构是一种加载/存储架构。这意味着没有数据处理指令直接对内存中的数据进行操作。数据必须首先被加载到寄存器中&#xff0c;修改&#xff0c;然后存储到内存中。该程序必须指定地址、要传输的数据大小以及源或目标寄存器。有额…

《使用深度神经网络对光电容积脉搏图进行归一化,以进行个体和群体比较》阅读笔记

目录 一、论文摘要 二、论文十问 Q1&#xff1a;论文试图解决什么问题&#xff1f; Q2&#xff1a;这是否是一个新的问题&#xff1f; Q3&#xff1a;这篇文章要验证一个什么科学假设&#xff1f; Q4&#xff1a;有哪些相关研究&#xff1f;如何归类&#xff1f;谁是这一…

symfonos 1(smtp注入webshell,配合文件文件包含)

目录 扫描 SMB 提权 扫描 SMB 让我们使用SMBMAP检查这些目录的权限。 smbmap -d workgroup -H www.example.com 可能/匿名帐户可访问。 使用smb尝试连接共享网络以访问/anonymous目录。[smb://192.168.59。129/]

ETL工具 - Kettle 介绍及基本使用

一、Kettle 介绍 在介绍 Kettle 前先了解下什么是 ETL&#xff0c;ETL是 Extract-Transform-Load 的缩写&#xff0c;即数据 抽取、转换、装载 的过程&#xff0c;对于企业或行业应用来说&#xff0c;经常会遇到各种异构数据的处理、转换、迁移等操作&#xff0c;这些操作有可…

java+mysql医院住院挂号缴费病房信息管理系统

手续办理&#xff1a;办理病人入院登记&#xff1b;提供病案首页建立与打印&#xff1b;交纳预交金及日结管理&#xff0c;并打印收据凭证&#xff1b;空床查询与统计&#xff1b;查询患者的住院信息&#xff1b;打印清单&#xff1b;出入院统计。 护士工作站&#xff1a;提供病…

Java每日一练(20230429)

目录 1. 二叉树的后序遍历 &#x1f31f;&#x1f31f; 2. 删除无效的括号 &#x1f31f;&#x1f31f;&#x1f31f; 3. 合并两个有序链表 &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每…

【Java笔试强训 1】

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f9be;&#x1f9be;&#x1f9be; 目录 一、选择题 二、编程题 &#x1f525;组队竞…