画对象只需三个步骤:

1.对象的图片
2.绘制到窗口的x坐标
3.绘制到窗口的y坐标

 @Overridepublic void paint(Graphics g) { //Jpanle提供的绘制图片的方法//1.对象图片  2.需要绘制的 x  和y坐标ImageIcon img = Images.battleship;//获取战舰图片//1.填null  2. g   3.x坐标  4.y坐标img.paintIcon(null,g,270,124);}

贴切到项目中画对象

需要5个步骤
第一个步骤定义获取对象图片的抽象方法:
每个对象都需要有自己的图片,意味着每个类都需要写一个获取图片的方法.如果都要写一个获取图片的方法,那么代码冗余,那么就需要将当前getImage方法提取到SeaObject父类中.因为子类的具体返回的图片不一样,所以父类需要做一个抽象方法,约束子类必须返回自己的图片.

public abstract ImageIcon getImage();

第二个步骤

获取图片的具体逻辑,每个对象都有状态, 例如 活着的状态和死亡的状态,我们认为对象都有状态,且状态的固定的.所以需要在SeaObject父类去定义两个常量的死亡和活着状态 , 还应该有一个表示当前状态的变量.

 public static final int LIVE = 0;//活着的状态public static final int DEAD = 1;//死亡的状态public int currentState = LIVE; //当前状态默认为活着的

在SeaObject类中添加两个方法,一个是用来判断当前对象是否是活着的方法,一个是用来判断当前对象是否是死亡的方法

  /** 判断当前调用这个方法的对象状态 是否是死亡状态 */public boolean isDead(){return currentState == DEAD;}/** 判断当前调用这个方法的对象状态 是否是活着状态 */public boolean isLive(){return currentState ==LIVE;}

第三个步骤

子类重写实现父类的getImage方法

战舰类@Override //战舰比较特殊,并不是一打就死亡,所以可以直接返回图片.public ImageIcon getImage() {return Images.battleship;  //返回战舰图片}
--------------------
深水炸弹类@Overridepublic ImageIcon getImage() {if(this.isLive()){//如果当前对象是活着的状态return Images.bomb;//返回深水炸弹图片}return null;//如果能走到这里 说明当前对象死亡 则不再返回图片}
--------------------
水雷类@Overridepublic ImageIcon getImage() {if(this.isLive()){ //如果是活着的状态return Images.mine;//返回图片}return null;//返回null 代表不是活着的意思}
--------------------
水雷潜艇类@Overridepublic ImageIcon getImage() {if(this.isLive()){ //如果是活着的状态return Images.minesubm;//返回图片}return null;//返回null 代表不是活着的意思}
--------------------
侦察潜艇类@Overridepublic ImageIcon getImage() {if(this.isLive()){ //如果是活着的状态return Images.obsersubm;//返回图片}return null;//返回null 代表不是活着的意思}
---------------------
鱼雷类@Overridepublic ImageIcon getImage() {if(this.isLive()){ //如果是活着的状态return Images.torpedo;//返回图片}return null;//返回null 代表不是活着的意思}
----------------------
鱼雷潜艇类@Overridepublic ImageIcon getImage() {if(this.isLive()){ //如果是活着的状态return Images.torpesubm;//返回图片}return null;//返回null 代表不是活着的意思}
​

第四个步骤

获取对象图片功能有了,因为每个对象都需要绘制,那么可以设计一个绘制的方法,设计SeaObject中,因为每个对象绘制的行为具体逻辑是一样的,所以设计一个普通方法.

/*** 因为每个子类都需要绘制图片 那么就将逻辑写到父类中,子类可以复用* 需要外部传递一个画笔 所以做成一个形式参数* */public void paintImage(Graphics g){if(this.getImage()!=null){//如果当前对象图片不为空ImageIcon icon = this.getImage();//获取当前对象图片//1.填null  2. g   3.x坐标  4.y坐标icon.paintIcon(null,g,this.x+100,this.y);}}

第五个步骤

在GameWorld的paint方法中测试

@Overridepublic void paint(Graphics g) { //Jpanle提供的绘制图片的方法ship.paintImage(g);for (int i = 0; i <submarines.length ; i++) {submarines[i].paintImage(g);}}

问题:运行游戏以后,潜艇能够生成并绘制出来的,但是并不能够移动,而移动是动态自动移动的。
对象的动态移动要先学习 成员内部类匿名内部类

成员内部类(应用率不高)

类中套个类!外层的类称之为外部类 ,内层称之为内部类
1.内部类对外不具备可见性,除了外部类的其它类不可直接访问!
2.内部类对象 可以在外部类中创建。
3.内部类可以共享外部类的属性和行为(包括私有)。
4.内部类访问外部类的成员会有一个隐式写法:外部类名.this.xx;

package oo.day05;
/***  用于测试内部类和外部类的语法规则:* */
public class TestDemo {public static void main(String[] args) {//        Baby a = new Baby(); 编译错误: 内部类 无法直接被外部其它直接使用Mama  m = new Mama();
​}
}
class Mama{ //外部类------ 妈妈类int  a;private int b;void action(){Baby b = new Baby();//外部类可以创建内部类对象}class Baby{//内部类 ------ 宝宝类int c;void test(){this.c = 10;//使用本类的内容会有隐式的thisMama.this.a = 10;//内部类可以共享外部类的属性和行为  隐式写法:外部类名.this.ab = 20;//可以访问外部类私有的内容}}
}
​

匿名内部类(应用率高)

没有名字的内部类叫做匿名内部类。
适用性:如果一个子类,仅仅只是想重写父类的某个功能(方法),其它类根本不需要用到这个子类,那么可以直接用匿名内部类 来便捷的快速实现。
1.匿名内部类只会存在于子类要重写父类的(抽象或普通)方法时 才会使用!!
2.匿名内部类无法修改外部类的值! 因为规定在匿名内部类使用外部类的属性时,会自动修饰为final。

package oo.day05;
/*** 匿名内部类的测试:* */
public class NstInnerClassDemo { //外部类public static void main(String[] args) {//常规的子类实现重写的方法//1.创建Boo对象//2.把Boo对象地址 赋值 给bBoo b = new Boo();b.show();int d = 10;//局部变量//使用匿名内部类来创建子类并重写父类的功能实现://1.创建了Aoo的子类  只不过没有名字//2.将当前这个子类的地址  赋值给 a//3.花括号就是子类的类体Aoo a = new Aoo(){ //匿名的Aoo子类 是  NstInnerClassDemo 的内部类@Overridepublic void show() {//                d= 10; 编译错误 内部类 无法修改外部类的内容 默认在内部类中会将外部类内容修饰为finalSystem.out.println(d);//内部类可以访问外部类的成员System.out.println("匿名Aoo的子类重写父类的show方法");}};a.show();}
}
​
class Aoo{//父类public void show(){System.out.println("父类Aoo中的show方法....");}
}
class Boo extends Aoo{  //常规的子类实现重写的方法@Overridepublic void show() {System.out.println("Boo子类中重写父类的show方法");}
}

面试题:

问:内部类是否有独立的.class 字节码文件吗?
有!!

成员内部类

外部类的名字 字节码文件 内部类 成员内部类字节码文件
Mama.java Mama.class Baby Mama$Baby.class

匿名内部类

外部类的名字 字节码文件 内部类 成员内部类字节码文件
NstInnerClassDemo NstInnerClassDemo.class 1 NstInnerClassDemo$1.class

动态入场

潜艇动态入场 ----------------------------- 自动发生的
水雷和鱼雷动态入场---------------------自动发生的

如何自动发生:

1.定时器
2.线程(后面会讲)

定闹钟:

1.给闹钟制定一个任务 2.开始延时多久执行这个任务的时间 3.闹钟任务执行一次后据下次执行的间隔时间

定时器:

1.具体什么任务 2.延时多久开始执行 3.执行后下一次的间隔时间
Java提供的两个类 任务类 和 定时器类
TimerTask 任务类 定时类 Timer
在GameWorld类上方导入这两个功能。

import java.util.Timer;//定时器类
import java.util.TimerTask;//任务模板类


在action方法中写上:

 Timer t = new Timer();//创建定时器对象TimerTask task = new TimerTask() { //创建 TimerTask匿名子类  实现重写父类的run方法@Overridepublic void run() { //自定义的任务逻辑System.out.println("叮叮叮~~~");}};//1.要执行的具体任务对象   2. 延时时间(毫秒)  3.间隔时间(毫秒)t.schedule(task, 5000,1000);

潜艇动态生成对象后需要 将对象存给潜艇数组,所以需要将数组先扩容。

数组扩容:

package oo.day05;
​
import java.util.Arrays;
​
/*** 数组的拷贝的方式:* 1.  Arrays.copyof  ---------------更多是基于源数组 扩容 或者 缩容 的使用方式。** 2. System.arraycopy --------------更多是基于存在 两个数组的拷贝方式。(把A 数组元素拷贝 给B数组)*/
public class ArrayCopyDemo {public static void main(String[] args) {//        int[] array = {};
//        System.out.println("扩容之前数组的空间" + array.length);//0
//        int a = 10;
//
//        //1.要操作的数组  2.扩容 (基于要扩容的数组长度上加1)
//        array = Arrays.copyOf(array, array.length + 1);
//        System.out.println("扩容之后数组的空间" + array.length);//1
//            //代表数组空间下最后一个索引 的写法 array.length-1
//        array[array.length-1] = a;
//        for (int i = 0; i < array.length; i++) {//            System.out.println(array[i]);
//        }
​
​//2.System.arraycopy
​int[] arrA = {10,50,5,6,1};int[] arrB = {1 ,1 ,1,1,1};/**  1.要拷贝的数组*  2.从要拷贝的数组的哪个索引开始拷贝*  3.要拷贝到的目标数组*  4.从目标数组的哪个索引开始装*  5.拷贝过来的数量是多少* */System.arraycopy(arrA,0,arrB,0,arrA.length);for (int i = 0; i < arrB.length; i++) {System.out.println(arrB[i]);}
​}
}

在GameWorld类中再去写一个方法,代表潜艇入场的方法,方法名submarineEnterAction

/*** 生成潜艇对象的方法  返回值可以写具体的潜艇类型吗?不可以,如果写了具体的子潜艇类型* 该方法还通用吗?不能!* 返回值应该写 父类型*/public SeaObject nextSubmarine() {int type = (int) (Math.random() * 20);//随机数  0 ~ 20if (type < 10) { //生成的随机数在 0~9区间return new ObserverSubmarine();//返回侦查潜艇} else if (type < 15) {//生成的随机数在 10~14区间return new TorpedoSubmarine();//返回鱼雷潜艇} else {  //生成的随机数在 15~19区间return new MineSubmarine();//返回水雷潜艇}}
private int subEnterIndex = 0;//用来控制潜艇产生的速度
​
/*** 潜艇入场的具体实现方法 放到run中调用*/
public void submarineEnterAction() { //10毫秒调用一次 (0.01s)subEnterIndex++;//每10毫秒自增一次if (subEnterIndex % 40 == 0) {//每400毫秒走一次 (0.4s)//潜艇生成sSeaObject obj = nextSubmarine();//调用创建潜艇对象的方法 接收返回的潜艇对象submarines = Arrays.copyOf(submarines, submarines.length + 1);//扩容//将obj 装到数组中的最后一个元素submarines[submarines.length - 1] = obj;}
}

在run中调用:

//做创建对象的事情private void action() {Timer timers = new Timer();//创建具体的定时器//schedule方法 参数  1.具体任务  2.延时多久开始执行  3.开始执行后的间隔时间
​TimerTask task = new TimerTask() {//创建匿名内部类@Overridepublic void run() {//在run中去写 你要执行的任务submarineEnterAction();//调用潜艇入场的方法repaint();//每隔0.01s做一次绘制刷新}};//延时5秒后执行任务,执行任务以后下次执行任务时看间隔时间//              任务      延时5秒   //间隔执行任务时间timers.schedule(task, 5000, 10);//间隔0.01s
​}

水雷 和鱼雷分别由水雷潜艇和鱼雷潜艇发射,因为发射的逻辑基本一样。所以在父类中写一个shootThunder方法来进行复用。

   /** 生成雷的方法* 因为这个方法要被鱼雷潜艇或水雷潜艇对象所调用。* 所以返回值 不能写具体的子类型,否则方法不通用,可以填父类来代表。* */public  SeaObject shootThunder(){int x = this.x + this.width;//雷的x坐标int y = this.y - 5;//雷的y坐标// instanceof 是java提供的判断类型的语法//判断当前调用方法的对象 是不是 鱼雷潜艇if(this instanceof TorpedoSubmarine){return new Torpedo(x,y);//返回鱼雷对象}else if( this instanceof MineSubmarine){//判断当前调用方法的对象 是不是 水雷潜艇return new Mine(x,y);//返回水雷对象}return null;//如果方法能执行到这一行 说明是侦察潜艇对象使用了方法,则返回null}

水雷和鱼雷的入场也是自动发生,那么也需要GameWorld类中去做一个雷入场的方法,thunderEnterAction,也要在run中去调用。

private int thunderEnterIndex = 0;//用来控制雷的生成速度/*** 当前方法是雷入场的方法 ,需要放到run中去调用。*/
public void thunderEnterAction() {//每10毫秒调用一次(0.01s)thunderEnterIndex++;//每次方法被调用自增1if (thunderEnterIndex % 100 == 0) {//每1000毫秒执行一次(1s)// 1.循环遍历当前潜艇数组,并依次调用数组潜艇对象的shootThunder方法 会返回一个对象(雷,null) 接收。for (int i = 0; i < submarines.length; i++) {SeaObject obj = submarines[i].shootThunder();if (obj != null) { //2.判断接收的对象 是否不等于null//3.如果条件成立,给雷数组扩容thunders = Arrays.copyOf(thunders, thunders.length + 1);//4.将对象装到雷数组的最后一个位置thunders[thunders.length-1] = obj;}}}
}

所有的潜艇、水雷和鱼雷 的移动行为。

所有潜艇都是向右运动,所以所有潜艇类的step方法内写上 x+=speed;
水雷和鱼雷都是向上运动,所以水雷和鱼雷类的step方法内写上 y-=speed;
深水炸弹向下运动,所以深水炸弹类的step方法内写上 y+=speed;
当前水雷、鱼雷,深水炸弹,所有潜艇 运动都自动发生的,所以在GameWorld写一个方法,stepAction方法主要就是用来遍历潜艇数组和雷数组,深水炸弹数组 并依次调用他们的移动的方法。然后将stepAction 放到run中进行调用。

 /*** 所有潜艇、水雷、鱼雷 深水炸弹 调用移动方法的 方法。* */public void stepAction(){for (int i = 0; i < submarines.length; i++) {submarines[i].step();//依次调用潜艇数组里每个对象的移动方法}for (int i = 0; i < thunders.length; i++) {thunders[i].step();//依次调用雷数组里每个对象的移动方法}for (int i = 0; i < bombs.length; i++) {bombs[i].step();//依次调用深水炸弹数组里每个对象的移动方法}}

深水炸弹入场是当按下空格键来进行入场的。
因为发射深水炸弹的行为是战舰的,所以应该在战舰类里面写一个shootBomb的方法。

  /***发射深水炸弹的方法  返回值就是深水炸弹对象* 由战舰对象进行调用。*  */public Bomb shootBomb(){return new Bomb(this.x,this.y);}

深水炸弹发射是基于一个事件—当玩家按下了键盘的空格键 再进行发射。
事件:发生了一件事 (在餐厅点了一份餐)
事件处理:发生事件以后要做的事情 (点完餐让服务员出餐了通知我取餐)
**侦听:**用来检测要做的事情有没有完成 (服务员在侦听 有没有出餐)
深水炸弹发射也是由事件产生的,所以需要用到事件和侦听的功能,Java中已经提供了键盘相关的事件和侦听的功能。
在GameWorld类上方导入这两个包

import java.awt.event.KeyAdapter;//键盘侦听器
import java.awt.event.KeyEvent;//键盘事件

在GameWorld类加上深水炸弹入场的方法:

 /*** 深水炸弹入场的方法 ,放到按下键盘空格键以后进行调用*/public void bombEnterAction() {//      1.战舰对象打点调用shootBombs方法,返回一个深水炸弹对象并接收Bomb obj = ship.shootBomb();
//      2.给深水炸弹数组扩容bombs = Arrays.copyOf(bombs, bombs.length + 1);
//      3.将产生的深水炸弹对象 装到深水炸弹数组的最后一个位置bombs[bombs.length-1] = obj;}

在Action方法里面加上相关需要侦听的逻辑代码并调用深水炸弹入场的方法:

 void action() {//创建了键盘侦听匿名子类  具体实现按下的时 所需要执行的代码逻辑KeyAdapter key = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) { //重写父类键盘按下的方法if (e.getKeyCode() == KeyEvent.VK_SPACE) {//判断用户按下的是否是空格的意思//调用深水炸弹入场的方法bombEnterAction();}}};this.addKeyListener(key);//将创建好的具体侦听逻辑的子类对象 添加到检测当中
​Timer t = new Timer();//创建定时器对象TimerTask task = new TimerTask() { //创建 TimerTask匿名子类  实现重写父类的run方法@Overridepublic void run() { //自定义的任务逻辑submarinesEnterAction();//调用潜艇入场的方法...thunderEnterAction();//调用雷入场的方法stepAction();//调用移动的方法repaint();//重新绘制一次 0.01s}};//1.要执行的具体任务对象   2. 延时时间(毫秒)  3.间隔时间(毫秒)t.schedule(task, 5000, 10);//间隔0.01s
​}

实现战舰的左右移动,在战舰类中添加左右移动的方法:

public void moveLeft() {//左移动的方法this.x -= speed;}public void moveRight() {//右移动的方法this.x += speed;}

在GameWorld类的Action方法中进行调用

void action() {//创建了键盘侦听匿名子类  具体实现按下的时 所需要执行的代码逻辑KeyAdapter key = new KeyAdapter() {@Overridepublic void keyPressed(KeyEvent e) { //重写父类键盘按下的方法if (e.getKeyCode() == KeyEvent.VK_SPACE) {//判断用户按下的是否是空格的意思//调用深水炸弹入场的方法bombEnterAction();}if(e.getKeyCode() == KeyEvent.VK_LEFT){//判断用户按下的是否是左←键的意思ship.moveLeft();//调用左移的方法System.out.println(123);}if(e.getKeyCode() == KeyEvent.VK_RIGHT){//判断用户按下的是否是右→键的意思ship.moveRight();//调用右移的方法System.out.println(456);}}};this.addKeyListener(key);//将创建好的具体侦听逻辑的子类对象 添加到检测当中
​Timer t = new Timer();//创建定时器对象TimerTask task = new TimerTask() { //创建 TimerTask匿名子类  实现重写父类的run方法@Overridepublic void run() { //自定义的任务逻辑submarinesEnterAction();//调用潜艇入场的方法...thunderEnterAction();//调用雷入场的方法stepAction();//调用移动的方法repaint();//重新绘制一次 0.01s}};//1.要执行的具体任务对象   2. 延时时间(毫秒)  3.间隔时间(毫秒)t.schedule(task, 5000, 10);//间隔0.01s
​}

分析:有一些潜艇、鱼雷水雷、深水炸弹当已经移出了屏幕外,还需要进行移动和绘制吗??具体点来说,还需要将这些已经除出了屏幕外的对象留在对应的数组里面吗?

优化内存:

400毫秒 1个潜艇 1秒----- 2个潜艇 + 2个雷 --------------共4个对象 1分钟
---------240个对象 10分钟 --------2400个对象 ​ 每10毫秒-------移动的方法里循环遍历 2400个对象 绘制的方法里面循环遍历 2400个对象 -----4800个对象 1秒 -------处理…4800000个对象。

内存泄漏:指的是一直在创建对象。
内存溢出:指的是内部没有地方可以用于创建对象了。

优化海洋对象出界的问题,在父类中写一个判断是否越界的方法,isOutBounds 。

  /** 是否是越界的方法*  为什么不做抽象方法而做普通方法:*              当前3个潜艇类判断是否越界的行为是一样的,可以进行复用。*              其它3个类鱼雷类、水雷类、深水炸弹 自行进行重写实现既可。* */public boolean isOutBounds(){return this.x >= GameWorld.WIDTH;//判断潜艇对象是否越界的标准}

其它3个类鱼雷类、水雷类、深水炸弹 自行进行重写实现既可。

鱼雷类:
@Overridepublic boolean isOutBounds() {return this.y <= -height;//y如果小于或等于 -一个图片的高度,说明超过了上方窗口了}
水雷类: @Overridepublic boolean isOutBounds() {return this.y <= 150 -height;//判断是否在水平面上}
深水炸弹:@Overridepublic boolean isOutBounds() {//重写父类判断是否越界的标准return this.y >= GameWorld.HEIGHT;//是否超过屏幕的高}

删除越界对象的行为是自动发生的,在GameWorld类里面定义一个方法,outOfBounds。

/*** 删除越界对象的行为逻辑: 放到run中 移动的方法后面调用。*/public void outOfBounds() {//循环遍历潜艇数组的每个对象 并依次调用每个对象判断是否越界的标准方法for (int i = 0; i < submarines.length; i++) {if (submarines[i].isOutBounds()) { //2.判断如果当前对象越界//3.将最后一个元素的对象 覆盖给当前越界对象的位置submarines[i] = submarines[submarines.length - 1];//4.将数组最后一个元素删除掉(缩容)submarines = Arrays.copyOf(submarines, submarines.length - 1);}}//2.循环遍历thunders数组的每个对象 并依次调用每个对象判断是否越界的标准方法for (int i = 0; i < thunders.length; i++) {if (thunders[i].isOutBounds()) { //2.判断如果当前对象越界//3.将最后一个元素的对象 覆盖给当前越界对象的位置thunders[i] = thunders[thunders.length - 1];//4.将数组最后一个元素删除掉(缩容)thunders = Arrays.copyOf(thunders, thunders.length - 1);}}//3.循环遍历bombs数组的每个对象 并依次调用每个对象判断是否越界的标准方法for (int i = 0; i < bombs.length; i++) {if (bombs[i].isOutBounds()) { //2.判断如果当前对象越界//3.将最后一个元素的对象 覆盖给当前越界对象的位置bombs[i] = bombs[bombs.length - 1];//4.将数组最后一个元素删除掉(缩容)bombs = Arrays.copyOf(bombs, bombs.length - 1);}}}

放到run中进行调用判断是否越界的方法

 public void run() { //自定义的任务逻辑submarinesEnterAction();//调用潜艇入场的方法...thunderEnterAction();//调用雷入场的方法stepAction();//调用移动的方法outOfBounds();//判断对象是否需要越界删除的方法System.out.println("潜艇数组里的对象" + submarines.length + " 雷的数组里的对象" + thunders.length);repaint();//重新绘制一次 0.01s}

利用简单游戏项目教你如何用java如何画对象相关推荐

  1. 图片太大_图片太大?手把手教你如何用java实现一个高质量图片压缩程序

    使用java几十行代码实现一个高质量图片压缩程序,再也不用去自己找网络的压缩程序啦!而且很多网上的工具还有水印或者其他的限制,自己动手写一个简单的应用,是再合适不过了. 一.实现原理 1.声明两个字符 ...

  2. 时间锁,手把手教你如何用Java设置随时间变化的动态密码

    时间锁:顾名思义就是用密码随时间变化而变化. 具体实现步骤如下: 步骤一:我们需要明确我们需要一个什么样的类,我想的是需要一个数据类,如下 步骤二:其次我们需要明确这个类里面需要实现那些功能?以简单的 ...

  3. 一个简单案例教你如何用Typescript写Vuex

    案例源代码: github.com/danielhuoo/- 前言 相信很多人都像我一样,学习使用了vuex后,想把项目改写成Typescript.但是官方教程要么晦涩难懂,要么缺少鲜活的例子.我花了 ...

  4. java 鼠标绘图,教您如何用JAVA程序实现鼠标绘图

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.awt.Color: import java.awt.Frame: import java.awt.Graphics: impor ...

  5. java鼠标绘制,教您如何用JAVA程序实现鼠标绘图

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.awt.Color: import java.awt.Frame: import java.awt.Graphics: impor ...

  6. 靖哥哥教你如何用java做爬虫抓取网站美女图片(详解步骤)

    原文 https://www.jggbk.com/blogs/article/258.html

  7. 实践操作:六步教你如何用开源框架Tensorflow对象检测API构建一个玩具检测器

    TensorFlow对象检测API是一个建立在TensorFlow之上的开源框架,可以轻松构建,训练和部署对象检测模型. 到目前为止,API的性能给我留下了深刻的印象.在这篇文章中,我将API的对象设 ...

  8. tfr 计算机硬件,实践操作:六步教你如何用开源框架Tensorflow对象检测API构建一个玩具检测器...

    TensorFlow对象检测API是一个建立在TensorFlow之上的开源框架,可以轻松构建,训练和部署对象检测模型. 到目前为止,API的性能给我留下了深刻的印象.在这篇文章中,我将API的对象设 ...

  9. java json设置编码_我们如何用Java编码JSON对象?

    甲的JSONObject是的一个子类的java.util.HashMap不设置顺序.我们还可以借助JSONValue.toJSONString(map)方法(即通过实现java.util.Linked ...

最新文章

  1. opencv算法+人脸检测
  2. nyoj 1216 整理图书(dp)
  3. 【Spark Summit EU 2016】摆脱传统ETL,让我们走向Spark吧!
  4. 俞敏洪最新干货演讲:在动荡的时代做不动荡的自己
  5. python安装扩展常用的工具是_Python 安装扩展库常用的是 _______ 工具_学小易找答案...
  6. android开花动画,15款界面最漂亮Android应用程序揭晓
  7. 2015-2020年各类国际会议与期刊基于图像的三维对象重建论文综述(5)——Leveraging other clues
  8. 配置csrf_django 入门第一课 配置文件
  9. 天时、地利、人和,技术成熟推动闪存联盟2.0落地
  10. 4k电视色彩表现测试软件,选高端4K电视 4K测试图帮你轻松分辨
  11. mikumikudance 5.X for Android,AR MMD(拡張現実×MikuMikuDance)
  12. 前端三大主流框架的区别
  13. 常见的日期计算问题(模板)
  14. RabbitMQ快速入门(详细)
  15. Nlite后期处理技术小结(第三次更新...全文完)(by bluewind)
  16. Sixth season fourth episode,Joey lost his insurance!!!!!
  17. 自己总结的linux命令
  18. kdd 2021 多网络挖掘的新前沿:近期发展和未来趋势
  19. PHP电商运费模板,拼多多运费模板怎么设置?怎么使用运费模板?
  20. Python打不开、Python 安装时发生严重错误 “A newer version of the Python launcher is already installed“

热门文章

  1. Tensorflow安装教程详解(图文详解,深度好文)
  2. 【科技素养题】少儿编程 蓝桥杯青少组科技素养题真题及解析第19套
  3. mysql 性能分析之 profiling
  4. Oracle ERP 库存管理(业务流程 核心流程)
  5. c语言编辑器菜鸟,C语言菜鸟基础教程之Hello World
  6. Hadoop学习之路(五):Hadoop交互关系型数据库(MySQL)
  7. websocket系列:基于spring-boot-starter-websocket实现
  8. Trinity 一条龙策略
  9. 单向测径仪有何特点来满足现代生产需要
  10. 1143 联络员(kruskal算法)