0基础学java-day18-( 坦克大战【2】)

课件资源放在文末

1.线程-应用到坦克大战

1.1 坦克大战 0.3

【坦克类:包括坦克的基本属性,以及坦克的移动方法】 

package com.hspedu.tankgame03;/*** @author 韩顺平* @version 1.0*/
public class Tank {private int x;//坦克的横坐标private int y;//坦克的纵坐标private int direct = 0;//坦克方向 0 上1 右 2下 3左private int speed = 1;public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}//上右下左移动方法public void moveUp() {y -= speed;}public void moveRight() {x += speed;}public void moveDown() {y += speed;}public void moveLeft() {x -= speed;}public int getDirect() {return direct;}public void setDirect(int direct) {this.direct = direct;}public Tank(int x, int y) {this.x = x;this.y = y;}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;}
}

 【我方坦克类】继承了坦克类,在这个版本中增加了发射子弹的方法【其实就是创建一个子弹对象,并且每一个子弹对象就是一个线程】

package com.hspedu.tankgame03;/*** @author 韩顺平* @version 1.0* 自己的坦克*/
public class Hero extends Tank {//定义一个Shot对象Shot shot =null;public Hero(int x, int y) {super(x, y);}//射击public void shotEnemyTank(){//创建 Shou 对象,根据当前Hero对象的位置和方向来创建switch (getDirect()){//得到hero方向case 0://向上shot =new Shot(getX()+20,getY(),0);break;case 1://向右shot=new Shot(getX()+60,getY()+20,1);break;case 2://向下shot=new Shot(getX()+20,getY()+60,2);break;case 3://向左shot=new Shot(getX(),getY()+20,3);break;}//启动子弹线程new Thread(shot).start();}
}

【敌方坦克类】

package com.hspedu.tankgame03;/*** @author 韩顺平* @version 1.0* 敌人的坦克*/
public class EnemyTank extends Tank {public EnemyTank(int x, int y) {super(x, y);}
}

【子弹类】包括子弹的基本属性 ,以及子弹进程什么时候结束及其运动过程的变化

package com.hspedu.tankgame03;/*** @author 林然* @version 1.0*/
public class Shot implements Runnable{//设计子弹int x;//子弹x坐标int y;//子弹y坐标int direction =0;//子弹方向int speed = 2;//子弹宿舍boolean isLive = true;//是否存活//构造器public Shot(int x, int y, int direction) {this.x = x;this.y = y;this.direction = direction;}@Overridepublic void run() {while (true){try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}//根据方向来改变switch (direction){case 0:y-=speed;break;//上case 1:x+=speed;break;//右case 2:y+=speed;break;//下case 3:x-=speed;break;//左}System.out.println("子弹x="+x+"子弹y="+y);if(!(x>=0&&x<=1000&&y>=0&&y<=750)){isLive=false;break;}}}
}

【面板类:主要在之前的基础上新增了绘制子弹的功能以及将面板也作为一个线程,实现Runnable,每隔一段时间进行面板重绘】

package com.hspedu.tankgame03;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;/*** @author 韩顺平* @version 1.0* 坦克大战的绘图区域*///为了监听 键盘事件, 实现KeyListener//为了让Panel 不停地重绘子弹,需要将MyPanelRunnable,当做一个线程使用
public class MyPanel extends JPanel implements KeyListener,Runnable {//定义我的坦克Hero hero = null;//定义敌人坦克,放入到VectorVector<EnemyTank> enemyTanks = new Vector<>();int enemyTankSize = 3;public MyPanel() {hero = new Hero(100, 100);//初始化自己坦克//初始化敌人坦克for (int i = 0; i < enemyTankSize; i++) {//创建一个敌人的坦克EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);//设置方向enemyTank.setDirect(2);//加入enemyTanks.add(enemyTank);}}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色//画出自己坦克-封装方法drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);//画出hero射击的子弹if(hero.shot!=null&&hero.shot.isLive!=false){g.draw3DRect(hero.shot.x,hero.shot.y,5,5,false);}//画出敌人的坦克, 遍历Vectorfor (int i = 0; i < enemyTanks.size(); i++) {//取出坦克EnemyTank enemyTank = enemyTanks.get(i);drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);}}//编写方法,画出坦克/*** @param x      坦克的左上角x坐标* @param y      坦克的左上角y坐标* @param g      画笔* @param direct 坦克方向(上下左右)* @param type   坦克类型*/public void drawTank(int x, int y, Graphics g, int direct, int type) {//根据不同类型坦克,设置不同颜色switch (type) {case 0: //敌人的坦克g.setColor(Color.cyan);break;case 1: //我的坦克g.setColor(Color.yellow);break;}//根据坦克方向,来绘制对应形状坦克//direct 表示方向(0: 向上 1 向右 2 向下 3 向左 )//switch (direct) {case 0: //表示向上g.fill3DRect(x, y, 10, 60, false);//画出坦克左边轮子g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边轮子g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒break;case 1: //表示向右g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒break;case 2: //表示向下g.fill3DRect(x, y, 10, 60, false);//画出坦克左边轮子g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边轮子g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒break;case 3: //表示向左g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒break;default:System.out.println("暂时没有处理");}}@Overridepublic void keyTyped(KeyEvent e) {}//处理wdsa 键按下的情况@Overridepublic void keyPressed(KeyEvent e) {System.out.println(e.getKeyCode());if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键//改变坦克的方向hero.setDirect(0);////修改坦克的坐标 y -= 1hero.moveUp();} else if (e.getKeyCode() == KeyEvent.VK_D) {//D键, 向右hero.setDirect(1);hero.moveRight();} else if (e.getKeyCode() == KeyEvent.VK_S) {//S键hero.setDirect(2);hero.moveDown();} else if (e.getKeyCode() == KeyEvent.VK_A) {//A键hero.setDirect(3);hero.moveLeft();}if(e.getKeyCode()==KeyEvent.VK_J){hero.shotEnemyTank();}//让面板重绘this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void run() {while (true){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}this.repaint();}}
}

【主方法类:将面板作为一个线程启动】

package com.hspedu.tankgame03;import javax.swing.*;/*** @author 韩顺平* @version 1.0*/
public class HspTankGame03 extends JFrame {//定义MyPanelMyPanel mp = null;public static void main(String[] args) {HspTankGame03 hspTankGame01 = new HspTankGame03();}public HspTankGame03() {mp = new MyPanel();Thread thread =new Thread(mp);thread.start();this.add(mp);//把面板(就是游戏的绘图区域)this.setSize(1000, 750);this.addKeyListener(mp);//让JFrame 监听mp的键盘事件this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}
}

1.2 坦克大战 0.4

在本次项目中大量在使用线程,我们也要知道即使线程结束了,但是其对象也是依然存在的,对于不同的逻辑操作我们可以在对应的类中写出对应的方法并不断重绘,对于需要反复判断的我们也要在Mypanel的run方法中不断进行调用 

package com.hspedu.tankgame04;import javax.swing.*;/*** @author 林然* @version 1.0*/
public class HspTankGame04 extends JFrame {//定义MyPanelMyPanel mp = null;public static void main(String[] args) {HspTankGame04 hspTankGame01 = new HspTankGame04();}public HspTankGame04() {mp = new MyPanel();Thread thread =new Thread(mp);thread.start();this.add(mp);//把面板(就是游戏的绘图区域)this.setSize(1000, 750);this.addKeyListener(mp);//让JFrame 监听mp的键盘事件this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}
}
package com.hspedu.tankgame04;import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Vector;/*** @author linran* @version 1.0* 坦克大战的绘图区域*///为了监听 键盘事件, 实现KeyListener//为了让Panel 不停地重绘子弹,需要将MyPanelRunnable,当做一个线程使用
public class MyPanel extends JPanel implements KeyListener,Runnable {//定义我的坦克Hero hero = null;//定义敌人坦克,放入到VectorVector<EnemyTank> enemyTanks = new Vector<>();int enemyTankSize = 3;//定义一个Vector用于存放炸弹//当子弹击中坦克时,就加入Vector<Bomb> bombs =new Vector<>();//定义三张图片用于显示爆炸效果Image image1 = null;Image image2 =null;Image image3 =null;public MyPanel() {hero = new Hero(100, 100);//初始化自己坦克//初始化敌人坦克for (int i = 0; i < enemyTankSize; i++) {//创建一个敌人的坦克EnemyTank enemyTank = new EnemyTank((100 * (i + 1)), 0);//设置方向enemyTank.setDirect(2);//启动坦克线程,让他动起来new Thread(enemyTank).start();//加入一颗子弹Shot shot = new Shot(enemyTank.getX() + 20, enemyTank.getY() + 60, enemyTank.getDirect());//加入enemyTank的Vector成员进行管理enemyTank.shots.add(shot);//启动shot对象new Thread(shot).start();//加入enemyTanks.add(enemyTank);}//初始化炸弹图片image1=Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/bomb_1.gif"));image2=Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/bomb_2.gif"));image3=Toolkit.getDefaultToolkit().getImage(MyPanel.class.getResource("/bomb_3.gif"));}@Overridepublic void paint(Graphics g) {super.paint(g);g.fillRect(0, 0, 1000, 750);//填充矩形,默认黑色//画出自己坦克-封装方法if(hero.isLife){drawTank(hero.getX(), hero.getY(), g, hero.getDirect(), 1);}//画出hero射击的子弹for (int i=0;i<hero.shots.size();i++){Shot shot = hero.shots.get(i);if(shot!=null&&shot.isLive!=false){g.draw3DRect(shot.x,shot.y,5,5,false);}else {//从vector移除hero.shots.remove(shot);}}for(int i=0;i<bombs.size();i++){Bomb bomb = bombs.get(i);//根据当前对象的life值去画图片if(bomb.life>6){g.drawImage(image1,bomb.x,bomb.y,60,60,this);}else if(bomb.life>3){g.drawImage(image2,bomb.x,bomb.y,60,60,this);}else {g.drawImage(image3,bomb.x,bomb.y,60,60,this);}//让炸弹生命值减少bomb.lifeDown();if(bomb.life==0){bombs.remove(i);//如果生命为0就删除}}//画出敌人的坦克, 遍历Vectorfor (int i = 0; i < enemyTanks.size(); i++) {//取出坦克EnemyTank enemyTank = enemyTanks.get(i);if(enemyTank.isLive){//当子弹存活才画出坦克drawTank(enemyTank.getX(), enemyTank.getY(), g, enemyTank.getDirect(), 0);//画出enemyTank的所有子弹for (int j=0;j<enemyTank.shots.size();j++){//取出子弹Shot shot = enemyTank.shots.get(j);if(shot.isLive!=false){g.draw3DRect(shot.x,shot.y,5,5,false);}else {enemyTank.shots.remove(shot);}}}}}//编写方法,画出坦克/*** @param x      坦克的左上角x坐标* @param y      坦克的左上角y坐标* @param g      画笔* @param direct 坦克方向(上下左右)* @param type   坦克类型*/public void drawTank(int x, int y, Graphics g, int direct, int type) {//根据不同类型坦克,设置不同颜色switch (type) {case 0: //敌人的坦克g.setColor(Color.cyan);break;case 1: //我的坦克g.setColor(Color.yellow);break;}//根据坦克方向,来绘制对应形状坦克//direct 表示方向(0: 向上 1 向右 2 向下 3 向左 )//switch (direct) {case 0: //表示向上g.fill3DRect(x, y, 10, 60, false);//画出坦克左边轮子g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边轮子g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子g.drawLine(x + 20, y + 30, x + 20, y);//画出炮筒break;case 1: //表示向右g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子g.drawLine(x + 30, y + 20, x + 60, y + 20);//画出炮筒break;case 2: //表示向下g.fill3DRect(x, y, 10, 60, false);//画出坦克左边轮子g.fill3DRect(x + 30, y, 10, 60, false);//画出坦克右边轮子g.fill3DRect(x + 10, y + 10, 20, 40, false);//画出坦克盖子g.fillOval(x + 10, y + 20, 20, 20);//画出圆形盖子g.drawLine(x + 20, y + 30, x + 20, y + 60);//画出炮筒break;case 3: //表示向左g.fill3DRect(x, y, 60, 10, false);//画出坦克上边轮子g.fill3DRect(x, y + 30, 60, 10, false);//画出坦克下边轮子g.fill3DRect(x + 10, y + 10, 40, 20, false);//画出坦克盖子g.fillOval(x + 20, y + 10, 20, 20);//画出圆形盖子g.drawLine(x + 30, y + 20, x, y + 20);//画出炮筒break;default:System.out.println("暂时没有处理");}}//判断我方子弹是否击中敌人坦克public  void hittank(Vector<Shot> shots,EnemyTank enemyTank){//判断s击中坦克for (int i=0;i<shots.size();i++){Shot s = shots.get(i);switch (enemyTank.getDirect()){case 0://上case 2://下if(s.x>enemyTank.getX()&&s.x<enemyTank.getX()+40&&s.y>enemyTank.getY()&&s.y<enemyTank.getY()+60){   s.isLive=false;enemyTank.isLive=false;//创建Bomb对象加入集合中Bomb bomb =new Bomb(enemyTank.getX(),enemyTank.getY());bombs.add(bomb);enemyTanks.remove(enemyTank);}break;case 1: //左右case 3:if(s.x>enemyTank.getX()&&s.x<enemyTank.getX()+60&&s.y>enemyTank.getY()&&s.y<enemyTank.getY()+40){   s.isLive=false;enemyTank.isLive=false;//创建Bomb对象加入集合中Bomb bomb =new Bomb(enemyTank.getX(),enemyTank.getY());bombs.add(bomb);enemyTanks.remove(enemyTank);}break;}}}//判断我方子弹是否击中敌人坦克public  void hitHero(Vector<Shot> shots,Hero hero){//判断s击中坦克for (int i=0;i<shots.size();i++){Shot s = shots.get(i);if(s.isLive&&hero.isLife){switch (hero.getDirect()){case 0://上case 2://下if(s.x>hero.getX()&&s.x<hero.getX()+40&&s.y>hero.getY()&&s.y<hero.getY()+60){   s.isLive=false;//创建Bomb对象加入集合中Bomb bomb =new Bomb(hero.getX(),hero.getY());bombs.add(bomb);hero.isLife=false;}break;case 1: //左右case 3:if(s.x>hero.getX()&&s.x<hero.getX()+60&&s.y>hero.getY()&&s.y<hero.getY()+40){   s.isLive=false;hero.isLife=false;//创建Bomb对象加入集合中Bomb bomb =new Bomb(hero.getX(),hero.getY());bombs.add(bomb);}break;}}}}@Overridepublic void keyTyped(KeyEvent e) {}//处理wdsa 键按下的情况@Overridepublic void keyPressed(KeyEvent e) {System.out.println(e.getKeyCode());if (e.getKeyCode() == KeyEvent.VK_W) {//按下W键//改变坦克的方向hero.setDirect(0);////修改坦克的坐标 y -= 1hero.moveUp();} else if (e.getKeyCode() == KeyEvent.VK_D) {//D键, 向右hero.setDirect(1);hero.moveRight();} else if (e.getKeyCode() == KeyEvent.VK_S) {//S键hero.setDirect(2);hero.moveDown();} else if (e.getKeyCode() == KeyEvent.VK_A) {//A键hero.setDirect(3);hero.moveLeft();}if(e.getKeyCode()==KeyEvent.VK_J){//if(!(hero.shot!=null&&hero.shot.isLive)) {发射一颗子弹if(hero.shots.size()<5)hero.shotEnemyTank();//发射多颗子弹,在面板最多有5g颗子弹//}}//让面板重绘this.repaint();}@Overridepublic void keyReleased(KeyEvent e) {}@Overridepublic void run() {while (true){try {Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();}//判断是否击中坦克if(hero.shots.size()>0){//当前我的子弹存活//遍历敌人所有坦克for (int i = 0; i < enemyTanks.size(); i++) {EnemyTank enemyTank =enemyTanks.get(i);hittank(hero.shots,enemyTank);}}//判断是否击中我方坦克for (int i=0;i<enemyTanks.size();i++){hitHero(enemyTanks.get(i).shots,hero);}this.repaint();}}
}
package com.hspedu.tankgame04;/*** @author 林然* @version 1.0*/
public class Tank {private int x;//坦克的横坐标private int y;//坦克的纵坐标private int direct = 0;//坦克方向 0 上1 右 2下 3左private int speed = 5;public int getSpeed() {return speed;}public void setSpeed(int speed) {this.speed = speed;}//上右下左移动方法public void moveUp() {if(y>0)//判断边界条件,个人感觉在这里设置的话我方和敌人坦克都可以直接控制{y -= speed;}}public void moveRight() {if(x<1000&&(x+80)<1000){x += speed;}}public void moveDown() {if(y<750&&(y+100)<750){y += speed;}}public void moveLeft() {if(x>0){x -= speed;}}public int getDirect() {return direct;}public void setDirect(int direct) {this.direct = direct;}public Tank(int x, int y) {this.x = x;this.y = y;}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;}
}
package com.hspedu.tankgame04;import java.util.Vector;/*** @author 林然* @version 1.0* 敌人的坦克*/
public class EnemyTank extends Tank implements Runnable{Vector <Shot> shots=new Vector<>();boolean isLive =true;public EnemyTank(int x, int y) {super(x, y);}//射击public void shotHeroTank(){//创建 Shou 对象,根据当前EnemyTank对象的位置和方向来创建Shot shot =null;switch (getDirect()){//得到EnemyTank方向case 0://向上shot =new Shot(getX()+20,getY(),0);break;case 1://向右shot=new Shot(getX()+60,getY()+20,1);break;case 2://向下shot=new Shot(getX()+20,getY()+60,2);break;case 3://向左shot=new Shot(getX(),getY()+20,3);break;}//加入子弹集合shots.add(shot);//启动子弹线程new Thread(shot).start();}@Overridepublic void run() {int count=0;while (isLive){if(shots.size()<5){shotHeroTank();}count++;//根据坦克方向来继续移动switch (getDirect()){case 0://向上moveUp();break;case 1://向右moveRight();break;case 2://向下moveDown();break;case 3://向左moveLeft();break;}try {Thread.sleep(1000);} catch (InterruptedException e) {e.printStackTrace();}//然后随机的改变坦克方向[0-4).连续走10步后换方向if(count%10==0){setDirect((int)(Math.random()*4));count=0;}//写并发程序一定要考虑线程什么时候结束}}
}
package com.hspedu.tankgame04;import java.util.Vector;/*** @author linran* @version 1.0* 自己的坦克*/
public class Hero extends Tank {//定义一个Shot对象Shot shot =null;boolean isLife =true;//可以发送多颗子弹Vector<Shot> shots =new Vector<>();public Hero(int x, int y) {super(x, y);}//射击public void shotEnemyTank(){//创建 Shou 对象,根据当前Hero对象的位置和方向来创建switch (getDirect()){//得到hero方向case 0://向上shot =new Shot(getX()+20,getY(),0);break;case 1://向右shot=new Shot(getX()+60,getY()+20,1);break;case 2://向下shot=new Shot(getX()+20,getY()+60,2);break;case 3://向左shot=new Shot(getX(),getY()+20,3);break;}//加入子弹集合shots.add(shot);//启动子弹线程new Thread(shot).start();}
}
package com.hspedu.tankgame04;/*** @author 林然* @version 1.0*/
public class Shot implements Runnable{//设计子弹int x;//子弹x坐标int y;//子弹y坐标int direction =0;//子弹方向int speed = 2;//子弹宿舍boolean isLive = true;//是否存活//构造器public Shot(int x, int y, int direction) {this.x = x;this.y = y;this.direction = direction;}@Overridepublic void run() {while (true){try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}//根据方向来改变switch (direction){case 0:y-=speed;break;//上case 1:x+=speed;break;//右case 2:y+=speed;break;//下case 3:x-=speed;break;//左}System.out.println("子弹x="+x+"子弹y="+y);//当子弹碰到面板边界时应该被销毁//当子弹碰到敌人坦克时,也应该结束进程if(!(x>=0&&x<=1000&&y>=0&&y<=750&&isLive)){isLive=false;break;}}}
}
package com.hspedu.tankgame04;/*** @author 林然* @version 1.0* 炸弹*/
public class Bomb {int x,y;//炸弹坐标int life = 9;//炸弹的生命周期boolean isLife =true;//是否还存活public Bomb(int x, int y) {this.x = x;this.y = y;}//减少生命值public void lifeDown(){if(life>0){life--;}else{isLife=false;}}
}

2.课件资源

链接:https://pan.baidu.com/s/1anOddH3cE47HuAUHyAGiVg?pwd=msmz 
提取码:msmz

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

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

相关文章

一些AG10K FPGA 调试的建议-Douglas

PLL AGM FPGA 在配置成功时&#xff0c;PLL 已经完成锁定&#xff0c;lock 信号已经变高&#xff1b;如果原设计中用 lock 信号输出实现系统 reset 的复位功能&#xff0c;就不能正确完成上电复位&#xff1b;同时&#xff0c;为了保证 PLL 相移的稳定&#xff0c;我们需要在 P…

C++笔记之重载和重写辨别

C笔记之重载和重写辨别 code review! 文章目录 C笔记之重载和重写辨别重载&#xff08;overloading&#xff09;重写&#xff08;Overriding&#xff09; 在C中&#xff0c;重载&#xff08;overloading&#xff09;和重写&#xff08;overriding&#xff09;是面向对象编程中…

笔记69:Conv1d 和 Conv2d 之间的区别

笔记地址&#xff1a;D:\work_file\&#xff08;4&#xff09;DeepLearning_Learning\03_个人笔记\4. Transformer 网络变体 a a a a a a a a a a a

设计模式-门面模式(Facade)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、定义二、结构 前言 在组件构建过程中&#xff0c;某些接口之间直接依赖会带来很多问题&#xff0c;甚至无法直接实现。采用一层间接接口&#xff0c;来隔离…

浅谈CompletableFuture

作者简介&#xff1a;大家好&#xff0c;我是smart哥&#xff0c;前中兴通讯、美团架构师&#xff0c;现某互联网公司CTO 联系qq&#xff1a;184480602&#xff0c;加我进群&#xff0c;大家一起学习&#xff0c;一起进步&#xff0c;一起对抗互联网寒冬 回顾FutureTask 之前我…

安全高效 江西变电站成功应用国家电网无人机巡检

随着电力需求的迅速增长&#xff0c;电网的巡检、维护与保养变得越来越重要。为迎接这一挑战&#xff0c;江西供电公司的一座变电站成功引入了复亚智能国家电网无人机巡检系统&#xff0c;在提升巡检水平、开创新型巡检模式方面做出了重要尝试&#xff0c;为电网设备的高效巡检…

EDA 数字时钟

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、数字时钟是什么&#xff1f;二、EDA里面数码管的显示1.元件模型2.参考程序3. 实验仿真波形4.实验现象5. 仿真问题 三、显示时钟1. 时钟电路模块2.参考程序3…

gRPC .net学习

学习helloworld server用.net client有.net的控制台 和 unity server端 直接使用vs2022创建(需自行看有无装asp.net哦),搜索gPRC,使用6.0吧&#xff0c;创建工程后直接F5跑起来,服务端到此完成 .net控制台client,创建新的控制台,使用NuGet,然后导入server端的Protos文件夹 学…

基于Jedis来探讨池化技术

为什么需要池化技术 系统运行时必然是需要数据库连接、线程等一些重量级对象&#xff0c;频繁的创建这种对象对性能有着不小的开销&#xff0c;所以为了减少没必要的创建和开销&#xff0c;我们就用到了池化技术。 通过创建一个资源池来保存这些资源便于后续的复用&#xff0c…

【C++初阶】七、内存管理(C/C++内存分布、C++内存管理方式、operator new / delete 函数、定位new表达式)

相关代码gitee自取&#xff1a; C语言学习日记: 加油努力 (gitee.com) 接上期&#xff1a; 【C初阶】六、类和对象&#xff08;初始化列表、static成员、友元、内部类&#xff09;-CSDN博客 目录 一 . C/C内存分布 C/C中程序内存区域划分&#xff1a; 二 . C内存管理方式 …

16.Java程序设计-基于SSM框架的android餐厅在线点单系统App设计与实现

摘要&#xff1a; 本研究旨在设计并实现一款基于SSM框架的Android餐厅在线点单系统&#xff0c;致力于提升餐厅点餐流程的效率和用户体验。通过整合Android移动应用和SSM框架的优势&#xff0c;该系统涵盖了用户管理、菜单浏览与点单、订单管理、支付与结算等多个功能模块&…

用户登录权限

文章目录 [TOC](文章目录) 前言一、 Cookie与session1.HTTP无状态2.cookie 和 session 的生命周期2.1 cookie 生命周期影响因素2.2 session 生命周期影响因素 3.cookie 和 session 的区别4.工作原理3 用户登录Node.js和Express验证session 二、JSON Web Token1. JWT 介绍2. JWT…

【算法系列篇】递归、搜索和回溯(二)

文章目录 前言1. 两两交换链表中的节点1.1 题目要求1.2 做题思路1.3 代码实现 2. Pow(X,N)2.1 题目要求2.2 做题思路2.3 代码实现 3. 计算布尔二叉树的值3.1 题目要求3.2 做题思路3.3 代码实现 4. 求根节点到叶结点数字之和4.1 题目要求4.2 做题思路4.3 代码实现 前言 前面为大…

计算机毕业设计springboot+ssm停车场车位预约系统java

管理员不可以注册账号 停车位包括车位所在楼层、车位编号、车位类型(全时间开放/高峰期开放)、预定状态等 用户预约时要求支付预约时间段的停车费用 违规行为&#xff1a;1.停车超过预约时间段 2.预约未使用 于系统的基本要求 &#xff08;1&#xff09;功能要求&am…

6G来袭,真的有必要吗?

6G来袭&#xff0c;6G标准将在2025年完成制定&#xff0c;2030年商用。当5G都还没玩明白的时候&#xff0c;6G又来了。 这次6G又提出了三个全新高大上场景&#xff0c;感知通信、人工智能通信、天地一体泛在物联&#xff0c;精英们还说&#xff0c;未来要连接很多机器人、元宇宙…

PHP基础 - 循环与条件语句

循环语句 1)for循环: 重复执行一个代码块指定的次数。 for ($i = 0; $i < 5; $i++) { // 初始化 $i 为 0,每次循环后将 $i 值增加 1,当 $i 小于 5 时执行循环echo "The number is: $i \n"; // 输出当前 $i 的值并换行 }// 循环输出结果为: // The number …

mysql字段设计规范:使用unsigned(无符号的)存储非负值

如果一个字段存储的是数值&#xff0c;并且是非负数&#xff0c;要设置为unsigned&#xff08;无符号的&#xff09;。 例如&#xff1a; 备注&#xff1a;对于类型是 FLOAT、 DOUBLE和 DECIMAL的&#xff0c;UNSIGNED属性已经废弃了&#xff0c;可能在mysql的未来某个版本去…

C++ //习题2.5 请写出下列表达式的值。

C程序设计 &#xff08;第三版&#xff09; 谭浩强 习题2.5 习题2.5 请写出下列表达式的值。 (1) 3.5 * 3 2 * 7 - ‘a’ (2) 26 / 3 34 % 3 2.5 (3) 45 / 2 (int)3.14159 / 2 (4) a b (c a 6) 设a的初值为3 (5) a 3 * 5, a b 3 * 2 (6) (int)(a 6.5) % 2 …

UI自动化测试工具的定义及重要性

UI自动化测试工具在现代软件开发中起着不可或缺的作用。它们能够提高测试效率、减少人为错误、提供全面的测试覆盖&#xff0c;并支持持续集成。通过有效使用UI自动化测试工具&#xff0c;开发团队可以提高软件质量&#xff0c;提供更可靠的应用程序&#xff0c;满足用户的需求…

C语言之数组精讲(2)

目录 数组的复制 输入数组元素的值 对数组的元素进行倒序排列 使用数组进行成绩处理 对象式宏 数组元素的最大值和最小值 赋值表达式的判断 数组的元素个数 结语 数组的复制 我们把数组中的元素全部复制到另一个数组中。 #include<stdio.h>int main() {int i;int…