利用简单游戏项目教你如何用java如何画对象
画对象只需三个步骤:
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如何画对象相关推荐
- 图片太大_图片太大?手把手教你如何用java实现一个高质量图片压缩程序
使用java几十行代码实现一个高质量图片压缩程序,再也不用去自己找网络的压缩程序啦!而且很多网上的工具还有水印或者其他的限制,自己动手写一个简单的应用,是再合适不过了. 一.实现原理 1.声明两个字符 ...
- 时间锁,手把手教你如何用Java设置随时间变化的动态密码
时间锁:顾名思义就是用密码随时间变化而变化. 具体实现步骤如下: 步骤一:我们需要明确我们需要一个什么样的类,我想的是需要一个数据类,如下 步骤二:其次我们需要明确这个类里面需要实现那些功能?以简单的 ...
- 一个简单案例教你如何用Typescript写Vuex
案例源代码: github.com/danielhuoo/- 前言 相信很多人都像我一样,学习使用了vuex后,想把项目改写成Typescript.但是官方教程要么晦涩难懂,要么缺少鲜活的例子.我花了 ...
- java 鼠标绘图,教您如何用JAVA程序实现鼠标绘图
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.awt.Color: import java.awt.Frame: import java.awt.Graphics: impor ...
- java鼠标绘制,教您如何用JAVA程序实现鼠标绘图
该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 import java.awt.Color: import java.awt.Frame: import java.awt.Graphics: impor ...
- 靖哥哥教你如何用java做爬虫抓取网站美女图片(详解步骤)
原文 https://www.jggbk.com/blogs/article/258.html
- 实践操作:六步教你如何用开源框架Tensorflow对象检测API构建一个玩具检测器
TensorFlow对象检测API是一个建立在TensorFlow之上的开源框架,可以轻松构建,训练和部署对象检测模型. 到目前为止,API的性能给我留下了深刻的印象.在这篇文章中,我将API的对象设 ...
- tfr 计算机硬件,实践操作:六步教你如何用开源框架Tensorflow对象检测API构建一个玩具检测器...
TensorFlow对象检测API是一个建立在TensorFlow之上的开源框架,可以轻松构建,训练和部署对象检测模型. 到目前为止,API的性能给我留下了深刻的印象.在这篇文章中,我将API的对象设 ...
- java json设置编码_我们如何用Java编码JSON对象?
甲的JSONObject是的一个子类的java.util.HashMap不设置顺序.我们还可以借助JSONValue.toJSONString(map)方法(即通过实现java.util.Linked ...
最新文章
- opencv算法+人脸检测
- nyoj 1216 整理图书(dp)
- 【Spark Summit EU 2016】摆脱传统ETL,让我们走向Spark吧!
- 俞敏洪最新干货演讲:在动荡的时代做不动荡的自己
- python安装扩展常用的工具是_Python 安装扩展库常用的是 _______ 工具_学小易找答案...
- android开花动画,15款界面最漂亮Android应用程序揭晓
- 2015-2020年各类国际会议与期刊基于图像的三维对象重建论文综述(5)——Leveraging other clues
- 配置csrf_django 入门第一课 配置文件
- 天时、地利、人和,技术成熟推动闪存联盟2.0落地
- 4k电视色彩表现测试软件,选高端4K电视 4K测试图帮你轻松分辨
- mikumikudance 5.X for Android,AR MMD(拡張現実×MikuMikuDance)
- 前端三大主流框架的区别
- 常见的日期计算问题(模板)
- RabbitMQ快速入门(详细)
- Nlite后期处理技术小结(第三次更新...全文完)(by bluewind)
- Sixth season fourth episode,Joey lost his insurance!!!!!
- 自己总结的linux命令
- kdd 2021 多网络挖掘的新前沿:近期发展和未来趋势
- PHP电商运费模板,拼多多运费模板怎么设置?怎么使用运费模板?
- Python打不开、Python 安装时发生严重错误 “A newer version of the Python launcher is already installed“
热门文章
- Tensorflow安装教程详解(图文详解,深度好文)
- 【科技素养题】少儿编程 蓝桥杯青少组科技素养题真题及解析第19套
- mysql 性能分析之 profiling
- Oracle ERP 库存管理(业务流程 核心流程)
- c语言编辑器菜鸟,C语言菜鸟基础教程之Hello World
- Hadoop学习之路(五):Hadoop交互关系型数据库(MySQL)
- websocket系列:基于spring-boot-starter-websocket实现
- Trinity 一条龙策略
- 单向测径仪有何特点来满足现代生产需要
- 1143 联络员(kruskal算法)