经典游戏,用java实现的坦克大战小游戏
今天给大家分享一个使用java编写的坦克大战小游戏,整体还是挺好玩的,通过对这款游戏的简单实现,加深对java基础的深刻理解。
一、设计思路
1.坦克大战小游戏通过java实现,其第一步需要先绘制每一关对应的地图,地图包括河流、草地、砖块、铁块等。
2.需要绘制玩家坦克、敌方坦克、以及坦克移动过程中使用到的碰撞算法,子弹与坦克之间的碰撞,
包括击中敌方坦克后的爆炸效果,通过重绘实现坦克的移动,以及各种道具的随机生成算法。
实际运行效果如下:
二、代码实现
1.首先需要将游戏中涉及到的各种对象梳理清楚,由于Java面向对象的特征,可以将一些对象公共特性抽象出来,比如将坦克抽象出一个超类,代码如下:
public abstract class Tank{int x=0;int y=0;int tempX=0;int tempY=0;int size=32;int direct=Constant.UP;int speed=1;int lives=1;int frame=0;//控制敌方坦克切换方向的时间boolean isAI=false;//是否自动boolean hit;boolean isShooting=false;boolean isDestroyed=false;boolean isProtected=false;Map map;GameMain gameMain;Collision collision;Bullet bullet;int starNum=0; //星星数public Tank(int size,int speed,Collision collision,Map map,GameMain gameMain) {this.size=size;this.collision=collision;this.map=map;this.gameMain=gameMain;this.speed=speed; }public void move() {//如果是AI坦克,在一定时间或碰撞后切换方法if(this.isAI && gameMain.enemyStopTime>0) {return;}this.tempX=this.x;this.tempY=this.y;if(this.isAI) {this.frame++;if(this.frame%100==0 || this.hit) {this.direct=(int)(Math.random()*4);this.hit=false;this.frame=0;}}if(this.direct==Constant.UP) {this.tempY-=this.speed;}else if(this.direct==Constant.DOWN) {this.tempY+=this.speed;}else if(this.direct==Constant.LEFT) {this.tempX-=this.speed;}else if(this.direct==Constant.RIGHT) {this.tempX+=this.speed;}isHit();if(!this.hit) {this.x=this.tempX;this.y=this.tempY;}}public void isHit() {if(this.direct==Constant.LEFT) {if(this.x<=map.offsetX) {this.x=map.offsetX;this.hit=true;}}else if(this.direct==Constant.RIGHT) {if(this.x>=map.offsetX+map.mapWidth-this.size) {this.x=map.offsetX+map.mapWidth-this.size;this.hit=true;}}else if(this.direct==Constant.UP) {if(this.y<=map.offsetY) {this.y=map.offsetY;this.hit=true;}}else if(this.direct==Constant.DOWN) {if(this.y>=map.offsetY+map.mapHeight-this.size) {this.y=map.offsetY+map.mapHeight-this.size;this.hit=true;}}if(!this.hit) {if(collision.tankMapCollision(this, map)) {this.hit=true;}}}public abstract void drawTank(Graphics2D ctx2);public void shoot(int type,Graphics2D ctx2) {if(this.isAI && gameMain.enemyStopTime>0) {return;}if(this.isShooting) {return;}int tempX=this.x;int tempY=this.y;this.bullet=new Bullet(tempX, tempY, this.direct, gameMain, type, map, this, collision);if(!this.isAI) {if(this.starNum==0) {this.bullet.speed=3;this.bullet.fireNum=1;}if(this.starNum>0 && this.starNum<=3) {this.bullet.speed+=this.starNum;this.bullet.fireNum+=(this.starNum-1);}if(this.starNum>3) {this.bullet.speed+=3;this.bullet.fireNum+=3;}}if(this.direct==Constant.UP) {tempX = this.x + this.size/2 - this.bullet.size/2;tempY=this.y-this.bullet.size;}else if(this.direct==Constant.DOWN) {tempX = this.x + this.size/2 - this.bullet.size/2;tempY=this.y+this.bullet.size;}else if(this.direct==Constant.LEFT) {tempX=this.x-this.bullet.size;tempY=this.y + this.size/2 - this.bullet.size/2;}else if(this.direct==Constant.RIGHT) {tempX=this.x+this.bullet.size;tempY=this.y + this.size/2 - this.bullet.size/2;}this.bullet.x=tempX;this.bullet.y=tempY;if(!this.isAI) {//音乐Constant.executor.execute(new Runnable() {@Overridepublic void run() {Constant.ATTACK_AUDIO.play();}});}this.bullet.drawBullet(ctx2);gameMain.bulletArr.add(this.bullet);this.isShooting=true;}public void distroy() {this.isDestroyed=true;gameMain.crackArr.add(new CrackAnimation(gameMain, Constant.CRACK_TYPE_TANK, this));if(this.isAI) {Constant.executor.execute(new Runnable() {@Overridepublic void run() {Constant.TANK_DESTROY_AUDIO.play();}});gameMain.appearEnemy--;}else {Constant.executor.execute(new Runnable() {@Overridepublic void run() {Constant.PLAYER_DESTROY_AUDIO.play();}});this.starNum=0;}}
}
2.坦克子类实现
public class PlayTank extends Tank{int protectedTime = 0;//保护时间int offsetX=0; //坦克2与坦克1的距离int type; //玩家类型public PlayTank(int type,Collision collision, Map map, GameMain gameMain) {super(32, 2, collision, map, gameMain);this.lives = 3;//生命值this.isProtected = true;//是否受保护this.protectedTime = 500;//保护时间this.type=type;}@Overridepublic void drawTank(Graphics2D ctx2) {this.hit = false;if(this.type==1) {ctx2.drawImage(Constant.RESOURCE_IMAGE, this.x, this.y,this.x+this.size,this.y+this.size,Constant.POS.get("player").x+this.offsetX+this.direct*this.size, Constant.POS.get("player").y,Constant.POS.get("player").x+this.offsetX+this.direct*this.size+this.size, Constant.POS.get("player").y+this.size, null);}else {ctx2.drawImage(Constant.RESOURCE_IMAGE, this.x, this.y,this.x+this.size,this.y+this.size,Constant.POS.get("player").x+128+this.offsetX+this.direct*this.size, Constant.POS.get("player").y,Constant.POS.get("player").x+128+this.offsetX+this.direct*this.size+this.size, Constant.POS.get("player").y+this.size, null);}if(this.isProtected) {int temp=((500-protectedTime)/5)%2;ctx2.drawImage(Constant.RESOURCE_IMAGE, this.x, this.y,this.x+this.size,this.y+this.size,Constant.POS.get("protected").x, Constant.POS.get("protected").y+32*temp,Constant.POS.get("protected").x+this.size, Constant.POS.get("protected").y+this.size, null);this.protectedTime--;if(this.protectedTime==0) {this.isProtected=false;}}}/*** 玩家坦克复活* @param player*/public void renascenc(int playerType) {this.lives--;this.direct=Constant.UP;this.isProtected=true;this.protectedTime=500;this.isDestroyed = false;int temp=0;if(playerType==1) {temp=129;}else {temp=256;}this.x = temp + map.offsetX;this.y = 385 + map.offsetY;}}
3.通过子类继承父类实现玩家坦克和敌方坦克的创建,创建完后,接下来就可让坦克动起来,如下:
public void addEnemyTank(Graphics2D ctx2) {if(enemyArr == null || enemyArr.size() >= maxAppearEnemy || maxEnemy == 0){return;}appearEnemy++;Tank objTank=null;int rand=(int) (Math.random()*4);if(rand==0) {objTank=new TankEnemy0(collision, map, this);}else if(rand==1) {objTank=new TankEnemy1(collision, map, this);}else if(rand==2) {objTank=new TankEnemy2(collision, map, this);}else if(rand==3) {objTank=new TankEnemy3(collision, map, this);}enemyArr.add(objTank);this.maxEnemy--;map.clearEnemyNum(maxEnemy, appearEnemy,ctx2);}
4.在移动过程中,涉及到坦克与子弹,坦克与地图之间的碰撞问题,实现如下:
/**
* 坦克与地图间的碰撞
**/
public boolean tankMapCollision(Tank tank,Map map) {//移动检测,记录最后一次的移动方向,根据方向判断+-overlap;int tileNum=0;int rowIndex=0;int colIndex=0;int overlap=3; //允许重叠的大小//根据tank的x、y计算map的row和colif(tank.direct==Constant.UP) {rowIndex=(tank.tempY+overlap-map.offsetY)/map.tileSize;colIndex=(tank.tempX+overlap-map.offsetX)/map.tileSize;}else if(tank.direct==Constant.DOWN) {rowIndex=(tank.tempY-overlap-map.offsetY+tank.size)/map.tileSize;colIndex=(tank.tempX+overlap-map.offsetX)/map.tileSize;}else if(tank.direct==Constant.LEFT) {rowIndex=(tank.tempY+overlap-map.offsetY)/map.tileSize;colIndex=(tank.tempX+overlap-map.offsetX)/map.tileSize;}else if(tank.direct==Constant.RIGHT){rowIndex=(tank.tempY+overlap-map.offsetY)/map.tileSize;colIndex=(tank.tempX-overlap-map.offsetX+tank.size)/map.tileSize;}if(rowIndex>=map.hTileCount || rowIndex<0 || colIndex>=map.wTileCount || colIndex<0) {return true;}if(tank.direct==Constant.UP || tank.direct==Constant.DOWN) {int tempWidth=tank.tempX-map.offsetX-colIndex*map.tileSize+tank.size-overlap;if(tempWidth%map.tileSize==0) {tileNum=tempWidth/map.tileSize;}else {tileNum=tempWidth/map.tileSize+1;}for(int i=0;i<tileNum && colIndex+i<map.wTileCount;i++) {int mapContent=map.mapLevel[rowIndex][colIndex+i];if(mapContent==Constant.WALL || mapContent==Constant.GRID || mapContent==Constant.WATER || mapContent==Constant.HOME || mapContent==Constant.ANOTHER_HOME) {if(tank.direct==Constant.UP) {tank.y=map.offsetY+rowIndex*map.tileSize+map.tileSize-overlap;}else {tank.y=map.offsetY+rowIndex*map.tileSize-tank.size+overlap;}return true;}}}else {int tempHeight=tank.tempY-map.offsetY-rowIndex*map.tileSize+tank.size-overlap;if(tempHeight%map.tileSize==0) {tileNum=tempHeight/map.tileSize;}else {tileNum=tempHeight/map.tileSize+1;}for(int i=0;i<tileNum && rowIndex+i<map.hTileCount;i++) {int mapContent=map.mapLevel[rowIndex+i][colIndex];if(mapContent==Constant.WALL || mapContent==Constant.GRID || mapContent==Constant.WATER || mapContent==Constant.HOME || mapContent==Constant.ANOTHER_HOME) {if(tank.direct==Constant.LEFT) {tank.x=map.offsetX+colIndex*map.tileSize+map.tileSize-overlap;}else {tank.x=map.offsetX+colIndex*map.tileSize-tank.size+overlap;}return true;}}}return false;}
5.绘制界面,通过定时重绘实现,具体代码如下:
public class GameMain extends JPanel{//int enemyNum=12;Map map;Num num;int level=1;Level tankLevel;int gameState=Constant.GAME_STATE_MENU;private boolean isGameOver=false;int maxEnemy = 12;//敌方坦克总数int maxAppearEnemy = 5;//屏幕上一起出现的最大数int appearEnemy = 0; //已出现的敌方坦克int enemyStopTime=0;List<Bullet> bulletArr;List<Tank> enemyArr;List<CrackAnimation> crackArr;List<Integer> keys;Tank player1 = null;//玩家1Tank player2 = null;//玩家2Collision collision;int mainframe = 0;Image offScreenImage;Menu menu;Stage stage;Prop prop;Graphics2D ctx2;int overX = 176;int overY = 384;int propTime = 300; //道具出现频次int homeProtectedTime = -1;int winWaitTime=80;public void initGame(GameMain gameMain) {this.num=new Num(gameMain);this.tankLevel=new Level();this.collision=new Collision(gameMain);}public void initObject() {this.map=new Map(this, num, tankLevel, level);player1=new PlayTank(1,collision, map, this);player1.x = 129 + map.offsetX;player1.y = 385 + map.offsetY;player2 = new PlayTank(2,collision, map, this);player2.x = 256 + map.offsetX;player2.y = 385 + map.offsetY;bulletArr=new ArrayList<>();enemyArr=new ArrayList<>();crackArr=new ArrayList<>();keys=new ArrayList<>();menu=new Menu();stage=new Stage(level, this,this.num);this.isGameOver=false;this.propTime=400;this.homeProtectedTime = -1;this.maxEnemy=12;this.winWaitTime=50;this.appearEnemy=0;this.overY=384;}public void goGameOver() {this.isGameOver=true;}@Overridepublic void paint(Graphics g) {//创建和容器一样大小的Image图片if(offScreenImage==null) {offScreenImage=this.createImage(Constant.SCREEN_WIDTH,Constant.SCREEN_HEIGHT);}//获得该图片的画布Graphics gImage=offScreenImage.getGraphics();//填充整个画布gImage.fillRect(0,0,Constant.SCREEN_WIDTH,Constant.SCREEN_HEIGHT);if(ctx2==null) {ctx2=(Graphics2D)gImage;}if(gameState==Constant.GAME_STATE_MENU) {menu.drawMenu(ctx2);}if(gameState==Constant.GAME_STATE_INIT) {stage.setNum(ctx2);stage.drawStage(ctx2);}if(gameState==Constant.GAME_STATE_START || gameState==Constant.GAME_STATE_OVER) {drawAll(ctx2);}if(gameState==Constant.GAME_STATE_OVER) {gameOver();}if(gameState==Constant.GAME_STATE_WIN) {this.winWaitTime--;drawAll(ctx2);if(this.winWaitTime==0) {nextLevel();}}//将缓冲区绘制好的图形整个绘制到容器的画布中g.drawImage(offScreenImage,0,0,null);}public void initMap(Graphics2D ctx2) {map.setNum(ctx2);map.drawMap(ctx2);}public void drawAll(Graphics2D ctx2) {map.setNum(ctx2);map.drawMap(ctx2);if(player1.lives>0) {player1.drawTank(ctx2);}if(player2.lives>0) {player2.drawTank(ctx2);}if(appearEnemy<maxEnemy){if(mainframe % 100 == 0){addEnemyTank(ctx2);mainframe = 0;}mainframe++;}drawLives(ctx2);drawEnemyTanks(ctx2);map.drawGrassMap(ctx2);drawBullet(ctx2);drawCrack(ctx2);keyEvent();if(propTime<=0){drawProp(ctx2);}else{propTime --;}if(homeProtectedTime > 0){homeProtectedTime --;}else if(homeProtectedTime == 0){homeProtectedTime = -1;homeNoProtected(ctx2);}}public void addEnemyTank(Graphics2D ctx2) {if(enemyArr == null || enemyArr.size() >= maxAppearEnemy || maxEnemy == 0){return;}appearEnemy++;Tank objTank=null;int rand=(int) (Math.random()*4);if(rand==0) {objTank=new TankEnemy0(collision, map, this);}else if(rand==1) {objTank=new TankEnemy1(collision, map, this);}else if(rand==2) {objTank=new TankEnemy2(collision, map, this);}else if(rand==3) {objTank=new TankEnemy3(collision, map, this);}enemyArr.add(objTank);this.maxEnemy--;map.clearEnemyNum(maxEnemy, appearEnemy,ctx2);}public void drawEnemyTanks(Graphics2D ctx2) {if(enemyArr!=null && enemyArr.size()>0) {Iterator<Tank> it=enemyArr.iterator();while(it.hasNext()) {Tank enemyTank=it.next();if(enemyTank.isDestroyed) {it.remove();}else {enemyTank.drawTank(ctx2);}}}if(enemyStopTime > 0){enemyStopTime --;}}/*** 绘制玩家生命数*/public void drawLives(Graphics2D ctx2) {map.drawLives(player1.lives, 1,ctx2);map.drawLives(player2.lives, 2,ctx2);}/*** 绘制子弹* @param ctx2*/public void drawBullet(Graphics2D ctx2) {if(bulletArr != null && bulletArr.size() > 0){Iterator<Bullet> it=bulletArr.iterator();while(it.hasNext()) {Bullet bullet=it.next();if(bullet.isDestroyed) {it.remove();bullet.owner.isShooting=false;}else {//绘制子弹bullet.drawBullet(ctx2);}}}}public void drawCrack(Graphics2D ctx2) {if(crackArr != null && crackArr.size() > 0){Iterator<CrackAnimation> it=crackArr.iterator();while(it.hasNext()) {CrackAnimation crackAnimation=it.next();if(crackAnimation.isOver) {it.remove();if(crackAnimation.crackObj instanceof Tank) {Tank tank=(Tank)crackAnimation.crackObj;if(tank==player1) {PlayTank playerTank1=(PlayTank)player1;playerTank1.renascenc(1);}else if(tank==player2) {PlayTank playerTank2=(PlayTank)player2;playerTank2.renascenc(2);}}}else {//绘制爆炸效果crackAnimation.draw(ctx2);}}}}public void drawProp(Graphics2D ctx2) {double rand=Math.random();if(rand<=0.4 && prop==null) {prop=new Prop(this, map, collision);prop.initProp();}if(prop!=null) {prop.drawProp(ctx2);if(prop.isDestroyed) {prop=null;propTime=600;}}}public void nextLevel() {level++;if(level==17) {level=1;}int oldPlayerNum=menu.playNum;initObject();menu.playNum = oldPlayerNum;//只有一个玩家if(menu.playNum == 1){player2.lives = 0;}map.first=0;stage.init(level);gameState = Constant.GAME_STATE_INIT;}public void preLevel() {level--;if(level == 0){level = 16;}//保存玩家数int oldPlayerNum = menu.playNum;initObject();menu.playNum = oldPlayerNum;//只有一个玩家if(menu.playNum == 1){player2.lives = 0;}stage.init(level);gameState = Constant.GAME_STATE_INIT;}public void gameLoop() {switch (gameState) {case Constant.GAME_STATE_MENU:repaint();break;case Constant.GAME_STATE_INIT://stage.draw();if(stage.isReady == true){gameState = Constant.GAME_STATE_START;}repaint();break;case Constant.GAME_STATE_START://drawAll();if(isGameOver ||(player1.lives <=0 && player2.lives <= 0)){gameState = Constant.GAME_STATE_OVER;map.homeHit(ctx2);Constant.executor.execute(new Runnable() {@Overridepublic void run() {Constant.PLAYER_DESTROY_AUDIO.play();}});}if(appearEnemy == maxEnemy && enemyArr.size() == 0){gameState = Constant.GAME_STATE_WIN;}repaint();break;case Constant.GAME_STATE_WIN:repaint();break;case Constant.GAME_STATE_OVER:repaint();break;}}public void gameOver() {//.clearRect(0, 0, Constant.SCREEN_WIDTH, Constant.SCREEN_HEIGHT);ctx2.drawImage(Constant.RESOURCE_IMAGE, overX+map.offsetX, overY+map.offsetY,overX+map.offsetX+64,overY+map.offsetY+32,Constant.POS.get("over").x, Constant.POS.get("over").y,Constant.POS.get("over").x+64, Constant.POS.get("over").y+32, null);overY-=2;if(overY<=map.mapHeight/2) {initObject();//if(menu.playNum==1) {// player2.lives=0;//}gameState = Constant.GAME_STATE_MENU;}}public void action() {KeyAdapter l=new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) {switch (gameState) {case Constant.GAME_STATE_MENU:if(e.getKeyCode()==KeyEvent.VK_ENTER){gameState = Constant.GAME_STATE_INIT;//只有一个玩家if(menu.playNum==1) {player2.lives=0;}}else {int n=0;if(e.getKeyCode()==KeyEvent.VK_DOWN) {n=1;}else if(e.getKeyCode()==KeyEvent.VK_UP) {n=-1;}menu.next(n);}break;case Constant.GAME_STATE_START:if(!keys.contains(e.getKeyCode())){keys.add(e.getKeyCode());}//射击if(e.getKeyCode()==KeyEvent.VK_SPACE && player1.lives > 0){player1.shoot(Constant.BULLET_TYPE_PLAYER, ctx2);}else if(e.getKeyCode()==KeyEvent.VK_ENTER && player2.lives > 0) {player2.shoot(Constant.BULLET_TYPE_PLAYER, ctx2);}else if(e.getKeyCode()==KeyEvent.VK_N) { //下一关nextLevel();}else if(e.getKeyCode() == KeyEvent.VK_P) {preLevel();}break;}}@Overridepublic void keyReleased(KeyEvent e) {// TODO Auto-generated method stub//super.keyReleased(e);if(keys != null && keys.size() > 0){Iterator<Integer> it=keys.iterator();while(it.hasNext()) {Integer key=it.next();if(key.intValue()==e.getKeyCode()) {it.remove();break;}}}}@Overridepublic void keyTyped(KeyEvent e) {//super.keyTyped(e);}};this.addKeyListener(l);this.setFocusable(true);Timer timer=new Timer();int interval=20;timer.schedule(new TimerTask() {@Overridepublic void run() {gameLoop(); }}, interval, interval);}public void keyEvent() {if(keys.contains(KeyEvent.VK_W)){player1.direct = Constant.UP;player1.hit = false;player1.move();}else if(keys.contains(KeyEvent.VK_S)){player1.direct = Constant.DOWN;player1.hit = false;player1.move();}else if(keys.contains(KeyEvent.VK_A)){player1.direct = Constant.LEFT;player1.hit = false;player1.move();}else if(keys.contains(KeyEvent.VK_D)){player1.direct = Constant.RIGHT;player1.hit = false;player1.move();}if(keys.contains(KeyEvent.VK_UP)){player2.direct = Constant.UP;player2.hit = false;player2.move();}else if(keys.contains(KeyEvent.VK_DOWN)){player2.direct = Constant.DOWN;player2.hit = false;player2.move();}else if(keys.contains(KeyEvent.VK_LEFT)){player2.direct = Constant.LEFT;player2.hit = false;player2.move();}else if(keys.contains(KeyEvent.VK_RIGHT)){player2.direct = Constant.RIGHT;player2.hit = false;player2.move();}}public void homeNoProtected(Graphics2D ctx2) {List<Integer[]> mapChangeIndexList=new ArrayList<Integer[]>();mapChangeIndexList.add(new Integer[] {23,11});mapChangeIndexList.add(new Integer[] {23,12});mapChangeIndexList.add(new Integer[] {23,13});mapChangeIndexList.add(new Integer[] {23,14});mapChangeIndexList.add(new Integer[] {24,11});mapChangeIndexList.add(new Integer[] {24,14});mapChangeIndexList.add(new Integer[] {25,11});mapChangeIndexList.add(new Integer[] {25,14});map.updateMap(mapChangeIndexList,Constant.WALL,ctx2);}public static void main(String[] args) {JFrame jf=new JFrame();jf.setTitle("坦克大战");jf.setSize(Constant.SCREEN_WIDTH, Constant.SCREEN_HEIGHT);GameMain gameMain=new GameMain();jf.add(gameMain);jf.setLocationRelativeTo(null);jf.setResizable(false);jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true);gameMain.initGame(gameMain);gameMain.initObject();gameMain.action();}
}
接下来就可运行了。
其中,切换到下一关,按键盘N,上一个按P,空格键射击。
有兴趣的可以试一试。
下载地址:
坦克大战小游戏完整源码
相关文章:

经典游戏,用java实现的坦克大战小游戏
今天给大家分享一个使用java编写的坦克大战小游戏,整体还是挺好玩的,通过对这款游戏的简单实现,加深对java基础的深刻理解。 一、设计思路 1.坦克大战小游戏通过java实现,其第一步需要先绘制每一关对应的地图,地图包括…...
linux开通端口命令
这块需要开通8088 8083 端口限制 查看已开放端口:sudo firewall-cmd --list-ports 开放8083端口:sudo firewall-cmd --add-port8088/tcp --permanent 开放8088端口:sudo firewall-cmd --add-port8083/tcp --permanent 移除端…...

5、并发锁机制之synchronized
并发锁机制之synchronized i/i--引起的线程安全问题分析原因分析i的JVM字节码指令i--的JVM 字节码指令结论 解决方案 synchronized的使用加锁方式使用synchronized解决之前的共享问题方式一方式二 synchronized底层实现原理分析查看synchronized的字节码指令序列重量级锁实现之…...
职场那些事:应对施暴者的智慧
在职场中,有些人用各种手段让你感到难受,让你屈服,甚至适应他们的变态心理。面对这种人,最重要的就是保持低调。🤐 很多同事选择倾诉,然而这其实是个大错特错。正如鲁迅所说,“同事间的悲欢并不…...

精细化管理和智慧化运营的智慧油站开源了。
AI视频监控平台简介 AI视频监控平台是一款功能强大且简单易用的实时算法视频监控系统。它的愿景是最底层打通各大芯片厂商相互间的壁垒,省去繁琐重复的适配流程,实现芯片、算法、应用的全流程组合,从而大大减少企业级应用约95%的开发成本。用…...

vue项目配置基础路由vue-router
1、运行以下命令安装vue-router yarn add vue-router 2、在src目录下的components中新建两个vue页面 3、在src目录下新建router文件夹,在router文件夹下面新建index.js文件 4、配置main.js文件 //引入Vue import Vue from "vue"; //引入App import App…...

2024年入职/转行网络安全,该如何规划?_网络安全职业规划
前言 前段时间,知名机构麦可思研究院发布了 《2022年中国本科生就业报告》,其中详细列出近五年的本科绿牌专业,其中,信息安全位列第一。 网络安全前景 对于网络安全的发展与就业前景,想必无需我多言,作为…...

【Python系列】执行 Shell 命令的六种方法
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...
2024华为OD机试真题-部门人力分配Python-C卷D卷-200分
【华为OD机试】-(C卷+D卷)-2024最新真题目录 目录 题目描述 输入描述 输出描述 用例1 考点 解题思路 代码 题目描述 部门在进行需求开发时需要进行人力安排。 当前部门需要完成 N 个需求,需求用 requirements 表述,requirements[i] 表示第 i 个需求的工作量大小,单…...
【Leetcode 1436 】旅行终点站—— 哈希表
给你一份旅游线路图,该线路图中的旅行线路用数组 paths 表示,其中 paths[i] [cityAi, cityBi] 表示该线路将会从 cityAi 直接前往 cityBi 。请你找出这次旅行的终点站,即没有任何可以通往其他城市的线路的城市。 题目数据保证线路图会形成一…...
springboot自动配置原理-面试题
网络上看很多文章并没什么用,重点没说到,不知道从那里入手讲,刷到的直接按照下面这个,背出来就行了 1、当启动springboot应用程序的时候,会先创建SpringApplication的对象,在对象的构造方法中会进行某些参数…...

【C++题解】1140 - 亲密数对
欢迎关注本专栏《C从零基础到信奥赛入门级(CSP-J)》 问题:1140 - 亲密数对 类型:自定义函数 题目描述: 键盘输入 N ,N 在 2 至 2000 之间,求 2 至 N 中的亲密数对,就是 A 的因子和…...

学习大数据DAY40 基于 hive 的数据处理
目录 Hive 复合数据定义方法 Hive 复合数据查询方法 hive 内置函数 上机练习 Hive 复合数据定义方法 Hive 复合数据查询方法 hive 内置函数 -- 查看系统自带的函数 show functions; -- 显示自带的函数的用法 desc function upper; -- 详细显示自带的函数的用法 desc …...

[数据集][目标检测]手钳检测数据集VOC+YOLO格式141张1类别
数据集格式:Pascal VOC格式YOLO格式(不包含分割路径的txt文件,仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数):141 标注数量(xml文件个数):141 标注数量(txt文件个数):141 标注类别…...

SQL注入(head、报错、盲注)
目录 【学习目标、重难点知识】 【学习目标】 【重难点知识】 1. 报错注入 1.1 那么什么是报错注入呢? 1.2 报错注入原理 extractvalue函数 updatexml函数 1.3 靶场解析 靶场练习 2. HEAD注入 2.1 相关全局变量 2.2 靶场解析 burp暴力破解 靶场练习 3…...
30. 包含 min 函数的栈
comments: true difficulty: 简单 edit_url: https://github.com/doocs/leetcode/edit/main/lcof/%E9%9D%A2%E8%AF%95%E9%A2%9830.%20%E5%8C%85%E5%90%ABmin%E5%87%BD%E6%95%B0%E7%9A%84%E6%A0%88/README.md 面试题 30. 包含 min 函数的栈 题目描述 定义栈的数据结构ÿ…...
五、OpenTK图形渲染基础
文章目录 一、顶点数据(一)顶点坐标、颜色、纹理坐标的定义(二)顶点数组的组织二、图元绘制(一)点列表、线列表、线带、三角形列表、三角形带的绘制(二)绘制模式(GL_POINTS、GL_LINES、GL_TRIANGLES 等)三、清除屏幕一、顶点数据 (一)顶点坐标、颜色、纹理坐标的定…...

桔子哥/基于云快充协议1.5版本的充电桩系统软件-充电桩系统 -新能源车充电平台源码
基于云快充协议1.5版本的充电桩系统软件 介绍 SpringBoot 框架,充电桩平台充电桩系统充电平台充电桩互联互通协议云快充协议1.5-1.6协议新能源汽车二轮车公交车二轮车充电-四轮车充电充电源代码充电平台源码Java源码 软件功能 小程序端:城市切换、附…...

零基础5分钟上手亚马逊云科技-高可用Web系统设计最佳实践
简介: 欢迎来到小李哥全新亚马逊云科技AWS云计算知识学习系列,适用于任何无云计算或者亚马逊云科技技术背景的开发者,通过这篇文章大家零基础5分钟就能完全学会亚马逊云科技一个经典的服务开发架构方案。 我会每天介绍一个基于亚马逊云科技…...

培训学校课程管理系统-计算机毕设Java|springboot实战项目
🍊作者:计算机毕设匠心工作室 🍊简介:毕业后就一直专业从事计算机软件程序开发,至今也有8年工作经验。擅长Java、Python、微信小程序、安卓、大数据、PHP、.NET|C#、Golang等。 擅长:按照需求定制化开发项目…...
浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)
✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

国防科技大学计算机基础课程笔记02信息编码
1.机内码和国标码 国标码就是我们非常熟悉的这个GB2312,但是因为都是16进制,因此这个了16进制的数据既可以翻译成为这个机器码,也可以翻译成为这个国标码,所以这个时候很容易会出现这个歧义的情况; 因此,我们的这个国…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...

python打卡day49
知识点回顾: 通道注意力模块复习空间注意力模块CBAM的定义 作业:尝试对今天的模型检查参数数目,并用tensorboard查看训练过程 import torch import torch.nn as nn# 定义通道注意力 class ChannelAttention(nn.Module):def __init__(self,…...

中南大学无人机智能体的全面评估!BEDI:用于评估无人机上具身智能体的综合性基准测试
作者:Mingning Guo, Mengwei Wu, Jiarun He, Shaoxian Li, Haifeng Li, Chao Tao单位:中南大学地球科学与信息物理学院论文标题:BEDI: A Comprehensive Benchmark for Evaluating Embodied Agents on UAVs论文链接:https://arxiv.…...

PPT|230页| 制造集团企业供应链端到端的数字化解决方案:从需求到结算的全链路业务闭环构建
制造业采购供应链管理是企业运营的核心环节,供应链协同管理在供应链上下游企业之间建立紧密的合作关系,通过信息共享、资源整合、业务协同等方式,实现供应链的全面管理和优化,提高供应链的效率和透明度,降低供应链的成…...

解决Ubuntu22.04 VMware失败的问题 ubuntu入门之二十八
现象1 打开VMware失败 Ubuntu升级之后打开VMware上报需要安装vmmon和vmnet,点击确认后如下提示 最终上报fail 解决方法 内核升级导致,需要在新内核下重新下载编译安装 查看版本 $ vmware -v VMware Workstation 17.5.1 build-23298084$ lsb_release…...
Java - Mysql数据类型对应
Mysql数据类型java数据类型备注整型INT/INTEGERint / java.lang.Integer–BIGINTlong/java.lang.Long–––浮点型FLOATfloat/java.lang.FloatDOUBLEdouble/java.lang.Double–DECIMAL/NUMERICjava.math.BigDecimal字符串型CHARjava.lang.String固定长度字符串VARCHARjava.lang…...

Psychopy音频的使用
Psychopy音频的使用 本文主要解决以下问题: 指定音频引擎与设备;播放音频文件 本文所使用的环境: Python3.10 numpy2.2.6 psychopy2025.1.1 psychtoolbox3.0.19.14 一、音频配置 Psychopy文档链接为Sound - for audio playback — Psy…...

IT供电系统绝缘监测及故障定位解决方案
随着新能源的快速发展,光伏电站、储能系统及充电设备已广泛应用于现代能源网络。在光伏领域,IT供电系统凭借其持续供电性好、安全性高等优势成为光伏首选,但在长期运行中,例如老化、潮湿、隐裂、机械损伤等问题会影响光伏板绝缘层…...