最近学习了马士兵老师直播的单机版坦克大战,模仿的做了一个,整理一下思路记录下来,项目git地址:https://github.com/zhuchangli/TankWar/tree/master

视频地址https://www.bilibili.com/video/av5949029 

TankClient类:管理其他类,作为主程序的接口,

 package cc.openhome;

 import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List; /**
* @Description: 坦克大战主界面
* @author zili_zl
*/
public class TankClient extends Frame{ /**
* 整个游戏宽度
*/
public static final int GAME_WIDTH = 800;
public static final int GAME_HEIGHT = 600;
public final int bknum = 5; // 解决画面加载卡顿问题
Image offScreenImage = null; Tank mytank = new Tank(500,500,true, Tank.Direction.STOP,this); Wall wall = new Wall(300,300,this); Blood b = new Blood();
// 存储多发炮弹
List<Missile> missiles = new ArrayList<Missile>();
// 存储爆炸
List<Explode> explodes = new ArrayList<Explode>();
// 存储tank
List<Tank> tanks = new ArrayList<Tank>(); /**
* Description
* date: 3:57 PM 1/6/19
* @param g 画笔显示在屏幕上画出一些对象
* @return void
*
**/ public void paint(Graphics g){ // 在屏幕上显示一些文字,有提示的文字
g.drawString("missiles count: "+missiles.size(),10,60);
g.drawString("explodes count: "+explodes.size(),10,80);
g.drawString("tanks count: "+tanks.size(),10,100);
g.drawString("mytank life: "+mytank.getLife(),10,120); // 敌方所有坦克报废后重新生成一批坦克
if(tanks.size()<= 0){
for(int i = 0;i < bknum;i++){
Tank tk = new Tank(50 + (i + 1) * 50,100,false, Tank.Direction.D,this);
tanks.add(tk);
}
} // 拿出所有的子弹
for(int i = 0;i < missiles.size();i++){
Missile m = missiles.get(i);
// 子弹击打敌方
m.hitTanks(tanks);
// 子弹攻击自己
m.hitTank(mytank); // 判断子弹是否撞墙
m.collidesWithWall(wall);
// 第一种解决用bool值解决
/*
if(!m.isLive()){
missiles.remove(m);
}else {
m.draw(g);
}
*/
// 画出子弹
m.draw(g);
} // 产生爆炸逐个画出来
for(int i = 0;i < explodes.size();i++){
Explode ex = explodes.get(i);
ex.draw(g);
}
// 拿出生成的tank
for(int i = 0; i < tanks.size();i++){
Tank t = tanks.get(i);
// 坦克撞墙
t.collidesWithWall(wall);
// 同一个tank相遇
t.collidesWithTanks(tanks);
t.draw(g);
}
// 画出墙来
wall.draw(g);
// tank吃血补充生命值
mytank.eatBlood(b);
mytank.draw(g);
b.draw(g);
} /**
* @Description: 使用update方法 实现双缓冲
* @param: [g]
* @return: void
*/ public void update(Graphics g){
// 保证只生成背景色一次
if(offScreenImage == null){
offScreenImage = this.createImage(GAME_WIDTH,GAME_HEIGHT); }
// 幕后图片,调用paint在画布上作画
Graphics gOffScreen = offScreenImage.getGraphics(); // 背景重刷, 重擦
Color c = gOffScreen.getColor(); // 获取当前颜色
gOffScreen.setColor(Color.GREEN); // 设置颜色为颜色绿色
gOffScreen.fillRect(0,0,GAME_WIDTH,GAME_HEIGHT); // 画一个 800×600的方块,颜色黑色
gOffScreen.setColor(c); // 刷完之后把颜色改回去
paint(gOffScreen);
//一次把图片画的前面去
g.drawImage(offScreenImage,0,0,null); } /**
* @Description: 做一些初始化工作,只调用一次
* @param: []
* @return: void
*/
public void lauchFram(){ // 在未画之前开始生成tank
for(int i = 0;i < 10;i++){
Tank tk = new Tank(50 + (i + 1) * 50,100,false, Tank.Direction.D,this);
tanks.add(tk);
} this.setLocation(400,300); // 打开画面相对屏幕的坐标位置和屏幕的大小
this.setSize(GAME_WIDTH,GAME_HEIGHT); // 设置游戏画面的长度和高度
this.setTitle("TankWar"); // 游戏界面标题值 // 关闭点击叉号起作用的
this.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
}); this.setResizable(false); // 固定画面大小,不可以改变大小
this.setBackground(Color.GREEN); // 设置草地颜色
setVisible(true); // 设置可见性 // 添加键盘监听
this.addKeyListener(new TankClient.KeyMonitor()); // 开启一个线程去画一些对象
new Thread(new TankClient.PaintThread()).start();
} public static void main(String [] args){
TankClient tc = new TankClient();
tc.lauchFram();
} /**
* @Description: 重画方法,让线程工作
* @param:
* @return:
*/
private class PaintThread implements Runnable{ @Override
public void run() {
while (true){
repaint();
try{
Thread.sleep(100);
}catch (InterruptedException e){
e.printStackTrace();
}
}
}
} /**
* @Description: 监听键盘事件
* @param:
* @return:
*/
private class KeyMonitor extends KeyAdapter {
public void keyPressed(KeyEvent e) {
mytank.keyPressed(e);
} public void keyReleased(KeyEvent e) {
mytank.keyReleased(e);
}
}
}

TankClient

Tank类:

 package cc.openhome;

 import java.awt.*;
import java.awt.event.KeyEvent;
import java.util.List;
import java.util.Random; /**
*
* @Description 坦克类
* @Author zizl_zq
* @Date 1/6/19 3:51 PM
*/
public class Tank { // tank 生命值
public static final int LIFETIME = 100;
// 移动的速度
public static final int xSpeed = 5;
public static final int ySpeed = 5; // tank 的宽度
public static final int WIDTH = 30;
public static final int HEIGHT = 30; int x ,y;
private boolean bL = false;
private boolean bR = false;
private boolean bU = false;
private boolean bD = false;
enum Direction {L,LU,U,RU,R,RD,D,LD,STOP}; // 有八个移动方向和停止 private Direction dir = Direction.STOP; // tank的方向
private Direction ptdir = Direction.D; // 炮筒的方向 private TankClient tkc; private int oldx,oldy; private boolean good; private BloodBar bb = new BloodBar(); // 显示声明值进度条 /**
* @Description: tank 分敌方和我方tank
* @param: []
* @return: boolean
*/
public boolean isGood() {
return good;
}
// 产生随机数 static 只产生一份,是共享变量
private static Random r = new Random(); public void setLive(boolean live) {
this.live = live;
} /**
* @Description: 当tank撞在墙上是需要停下来的,在撞见墙的上一步开始停下来改变方向
* @param: []
* @return: void
*/
public void stay(){
x = oldx;
y = oldy;
} public boolean isLive() {
return live;
} private boolean live = true;
// 产生移动的步长
private int step = r.nextInt(12) + 3; // 生命值
private int life = 100; public int getLife() {
return life;
} public void setLife(int life) {
this.life = life;
} public Tank(int x,int y,boolean good){
this.x = x;
this.y = y;
this.good = good;
}
public Tank(int x, int y, boolean good, Direction dir, TankClient tkc){
this(x,y,good);
this.dir = dir;
this.tkc = tkc;
} /**
* @Description: 画tank
* @param: [g]
* @return: void
*/
public void draw(Graphics g){
if(!live) {
if(!good){
tkc.tanks.remove(this);
}
return;
}
Color c = g.getColor(); // 保存以前颜色
if(good) g.setColor(Color.red); // 玩家tank画成红色
else g.setColor(Color.blue); // 敌方tank画成蓝色 // 坐标四个参数,确定图案大小
g.fillOval(x,y,WIDTH,HEIGHT);
g.setColor(c); if(good) bb.draw(g);
// 画炮筒
switch (ptdir ){
case L:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x,y + Tank.HEIGHT / 2);
break;
case LU:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x,y );
break;
case U:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x + Tank.WIDTH / 2,y);
break;
case RU:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x + Tank.WIDTH,y);
break;
case R:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x + Tank.WIDTH ,y + Tank.HEIGHT /2);
break;
case RD:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x + Tank.WIDTH,y + Tank.HEIGHT );
break;
case D:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x + Tank.WIDTH /2,y + Tank.HEIGHT);
break;
case LD:
g.drawLine(x+Tank.WIDTH / 2,y + Tank.HEIGHT / 2,x,y + Tank.HEIGHT);
break;
}
// 移动
move();
} /**
* @Description: 根据方向来确定行进方向
* @param: []
* @return: void
*/
void move(){
this.oldx = x;
this.oldy = y;
switch (dir ){
case L:
x -= xSpeed;
break;
case LU:
x -= xSpeed;
y -= ySpeed;
break;
case U:
y -= ySpeed;
break;
case RU:
x += xSpeed;
y -= ySpeed;
break;
case R:
x += xSpeed;
break;
case RD:
x += xSpeed;
y += ySpeed;
break;
case D:
y += ySpeed;
break;
case LD:
x -= xSpeed;
y += ySpeed;
break;
case STOP:
break;
}
// 炮筒方向,解决静止也能发炮
if(dir != Direction.STOP){
ptdir = dir;
} // 限制tank 不能越界
if(x < 0) x = 0;
if(y < 30) y = 30;
if(x + Tank.WIDTH > TankClient.GAME_WIDTH) x = TankClient.GAME_WIDTH - Tank.WIDTH;
if(y + Tank.HEIGHT > TankClient.GAME_HEIGHT) y = TankClient.GAME_HEIGHT - Tank.HEIGHT; // 敌方tank在八个方向里面随机选择方向,找出下一步移动方向
if(!good){
// enum 转换为数组
Direction [] dirs = Direction.values();
if(step == 0){
step = r.nextInt(12) + 3;
int rn = r.nextInt(dirs.length);
dir = dirs[rn];
}
step--;
// 解决子弹发射太快问题 这个条件下发射一枚炮弹
if(r.nextInt(40) > 38) fire(); } } /**
* @Description: 键盘按下事件
* @param: [e]
* @return: void
*/
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch (key){
case KeyEvent.VK_LEFT:
bL = true;
break;
case KeyEvent.VK_RIGHT:
bR = true;
break;
case KeyEvent.VK_UP:
bU = true;
break;
case KeyEvent.VK_DOWN:
bD = true;
break;
}
locateDirection();
} /**
* @Description: 处理松开按键事件
* @param: [e]
* @return: void
*/
public void keyReleased(KeyEvent e){
int key = e.getKeyCode();
switch (key){
case KeyEvent.VK_F2:
if(good){
this.live = true;
this.life = LIFETIME;
}
case KeyEvent.VK_CONTROL: // control键发射炮弹 释放按键时发射炮弹控制 发射频率
fire();
break;
case KeyEvent.VK_LEFT:
bL = false;
break;
case KeyEvent.VK_RIGHT:
bR = false;
break;
case KeyEvent.VK_UP:
bU = false;
break;
case KeyEvent.VK_DOWN:
bD = false;
break;
case KeyEvent.VK_SPACE:
superFire();
break;
}
locateDirection();
} /**
* @Description: 根据按下的键盘确定移动方向
* @param: []
* @return: void
*/
void locateDirection(){
if(bL && !bR && !bU && !bD) dir = Direction.L;
else if(bL && !bR && bU && !bD) dir = Direction.LU;
else if(!bL && !bR && bU && !bD) dir = Direction.U;
else if(!bL && bR && bU && !bD) dir = Direction.RU;
else if(!bL && bR && !bU && !bD) dir = Direction.R;
else if(!bL && bR && !bU && bD) dir = Direction.RD;
else if(!bL && !bR && !bU && bD) dir = Direction.D;
else if(bL && !bR && !bU && bD) dir = Direction.LD;
else if(!bL && !bR && !bU && !bD) dir = Direction.STOP;
} /**
* @Description: 开火打出一发子弹
* @param: []
* @return: cc.openhome.Missile
*/
public Missile fire(){
int x = this.x + (Tank.WIDTH - Missile.WIDTH) / 2;
int y = this.y + (Tank.HEIGHT - Missile.HEIGHT) / 2;
Missile m = new Missile(x,y,good,ptdir,this.tkc);
tkc.missiles.add(m);
return m;
} /**
* @Description: 朝固定方向打出一颗子弹
* @param: [dir]
* @return: cc.openhome.Missile
*/
public Missile fire(Direction dir){
int x = this.x + (Tank.WIDTH - Missile.WIDTH) / 2;
int y = this.y + (Tank.HEIGHT - Missile.HEIGHT) / 2;
Missile m = new Missile(x,y,good,dir,this.tkc);
tkc.missiles.add(m);
return m;
} /**
* @Description: 获取子弹的方块
* @param: []
* @return: java.awt.Rectangle
*/
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
} /**
* @Description: tank 撞见墙了作处理
* @param: [w]
* @return: boolean
*/
public boolean collidesWithWall(Wall w){
// 撞见墙 让坦克掉头,或停下来
if(this.getRect().intersects(w.getRect())){
this.stay();
return true;
}
return false;
} /**
* @Description: 处理tank遇见tank时
* @param: [tanks]
* @return: boolean
*/
public boolean collidesWithTanks(List<Tank> tanks){
for(int i = 0;i < tanks.size();i++){
Tank t = tanks.get(i);
if(this != t){
if(this.live && t.isLive() && this.getRect().intersects(t.getRect())){
this.stay();
t.stay();
return true;
}
} }
return false;
} /**
* @Description: 超级子弹 一次可以朝多个方向打出子弹
* @param: []
* @return: void
*/
public void superFire(){
Direction [] dirs = Direction.values();
for(int i = 0;i < 8;i++){
fire(dirs[i]);
}
} /**
* @Description: 成tank的生命值
* @param:
* @return:
*/
private class BloodBar{
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.red);
g.drawRect(x,y - 15,WIDTH,10);
int w = WIDTH * life / 100;
g.fillRect(x,y - 15,w,10);
g.setColor(c);
}
} /**
* @Description: 给tank补充生命值
* @param: [b]
* @return: boolean
*/
public boolean eatBlood(Blood b){
// 当前tank活着,还有血,子弹和血块相撞
if(this.live && b.isLive() && this.getRect().intersects(b.getRect())){
if(life < LIFETIME){
life += 20;
}
b.setLive(false);
return true;
}
return false;
}
}

Tank

Missile类:

 package cc.openhome;

 import cc.openhome.Explode;
import cc.openhome.Wall; import java.awt.*;
import java.util.List;
/**
* @descpition 子弹类
* @author zizl_zq
* @date 1/6/19 3:51 PM
*/
public class Missile { // 子弹的移动速度
public static final int xSpeed = 10;
public static final int ySpeed = 10; // 子弹的宽度,高度
public static final int WIDTH = 10;
public static final int HEIGHT = 10;
private int x,y;
private Tank.Direction dir; private boolean good;
private TankClient tc; private boolean live = true; public Missile(int x, int y, Tank.Direction dir) {
this.x = x;
this.y = y;
this.dir = dir;
} public Missile(int x, int y, Boolean good, Tank.Direction dir, TankClient tc){
this(x,y,dir);
this.good = good;
this.tc = tc;
} public boolean isLive() {
return live;
}
public void setLive(boolean live) {
this.live = live;
} public void draw(Graphics g){
if(!live)
{
tc.missiles.remove(this);
return;
}
Color c = g.getColor();
if(!good){
g.setColor(Color.blue);
}
if(good){
g.setColor(Color.black);
}
// 坐标四个参数,确定图案大小
g.fillOval(x,y,WIDTH,HEIGHT);
g.setColor(c); // 移动
move();
} /**
* @Description 子弹移动方法
* @Param []
* @return void
*/
void move(){
switch (dir ){
case L:
x -= xSpeed;
break;
case LU:
x -= xSpeed;
y -= ySpeed;
break;
case U:
y -= ySpeed;
break;
case RU:
x += xSpeed;
y -= ySpeed;
break;
case R:
x += xSpeed;
break;
case RD:
x += xSpeed;
y += ySpeed;
break;
case D:
y += ySpeed;
break;
case LD:
x -= xSpeed;
y += ySpeed;
break;
}
// 判断炮弹出界
if(x < 0 || y < 0 || x > TankClient.GAME_WIDTH || y > TankClient.GAME_HEIGHT){
live = false;
}
} // 获取子弹的方块
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT); }
/**
* @Description 子弹打击tank
* @Param [tk]
* @return boolean
*/
public boolean hitTank(Tank tk){
// 1,判断子弹是否活着 2,判断是否击中,3,判断坦克是否活着,4,判断是否是一伙的
if(this.live && this.getRect().intersects(tk.getRect()) && tk.isLive() && this.good != tk.isGood()){
if(tk.isGood()){
tk.setLife(tk.getLife() - 20);
if(tk.getLife() <= 0){
tk.setLive(false);
} }else {
tk.setLive(false);
}
this.setLive(false);
Explode e = new Explode(x,y,tc);
tc.explodes.add(e);
return true;
}
return false;
} /**
* @Description 击打所有的tank
* @Param [tanks]
* @return boolean
*/
public boolean hitTanks(List<Tank> tanks){
for(int i = 0;i < tanks.size();i++){
if(hitTank(tanks.get(i))){
return true;
}
}
return false;
} /**
* @Description 子弹撞在墙上
* @Param [w]
* @return boolean
*/
public boolean collidesWithWall(Wall w){
// 子弹撞到墙上,让它消失
if(this.getRect().intersects(w.getRect())){
setLive(false);
return true;
}
return false;
}
}

Missile

Blood类:

 package cc.openhome;

 import java.awt.*;

 /**
*@ClassName cc.openhome.Blood
*@Description 血块类
*@Author zizl_zq
*@Date 1/6/19 3:51 PM
*/
public class Blood { int x,y,w,h; // 血块出现的位置,长和宽
private int step = 0;
TankClient tc;
// 血块按照指定的这几个点移动
int [][] positions = {
{430,440},{430,450},{440,460},{460,470},{470,450},{450,440},{440,430}
}; /**
* @Description 判断血块是否活着,如果被坦克吃掉了就消失
* @Param []
* @return boolean
*/
public boolean isLive() {
return live;
} /**
* @Description 设置血块的生命
* @Param [live]
* @return void
*/
public void setLive(boolean live) {
this.live = live;
} private boolean live = true; public Blood(){
x = positions[0][0];
y = positions[0][1];
w = 10;
h = 10;
} /**
* @Description 按着这个步子在移动的
* @Param []
* @return void
*/
public void move(){ if(step == positions.length){
step = 0;
}
x = positions[step][0];
y = positions[step][1];
step++;
} /**
* @Description 画出血块
* @Param [g]
* @return void
*/
public void draw(Graphics g){
if(!live){
return;
}
Color c = g.getColor();
g.setColor(Color.magenta);
g.fillRect(x,y,w,h);
g.setColor(c);
move();
} /**
* @Description 获取自身位置,为碰撞做准备
* @Param []
* @return java.awt.Rectangle
*/
public Rectangle getRect(){
return new Rectangle(x,y,w,h);
}
}

Blood

Wall 类:

 package cc.openhome;

 import java.awt.*;
/**
*@Description 增加游戏好玩度,增加一堵墙
*@Author zizl_zq
*@Date 1/6/19 3:51 PM
*/
public class Wall {
public static final int WIDTH = 200;
public static final int HEIGHT = 10; int x,y;
private TankClient tc;
public Wall(int x, int y, TankClient tc) {
this.x = x;
this.y = y;
this.tc = tc;
} /**
* @Description 画出一个tank
* @Param [g]
* @return void
**/
public void draw(Graphics g){
Color c = g.getColor();
g.setColor(Color.black);
g.fillRect(x,y,WIDTH,HEIGHT);
g.setColor(c);
} /**
* @Description 获取墙的位置
* @Param []
* @return java.awt.Rectangle
**/
public Rectangle getRect(){
return new Rectangle(x,y,WIDTH,HEIGHT);
} }

Wall

Explode类:

 package cc.openhome;

 import java.awt.*;

 /**
*@ClassName cc.openhome.Explode
*@Description 爆炸类
*@Author zizl_zq
*@Date 1/6/19 3:51 PM
*/
public class Explode {
int x,y;
private boolean live = true;
private TankClient tc; int [] diameter = {4,7,12,18,26,32,49,60,30,14,6};
int step = 0; public Explode(int x, int y, TankClient tc){
this.x = x;
this.y = y;
this.tc = tc;
} public void draw(Graphics g){ if(!live) {
tc.explodes.remove(this);
return;
} if(step == diameter.length){
live = false;
step = 0;
return;
}
Color c = g.getColor();
g.setColor(Color.yellow);
g.fillOval(x,y,diameter[step],diameter[step]);
g.setColor(c); step++;
}
}

Explode

运行结果:

总结 :

进一步理解了面向对象的思想,处理问题是,首要考虑解决这个问题需要什么对象,这些对象需要有那些属性,用这些属性来解决什么问题。

使用IDEA生成api文档。生成jar包。

新学到的知识点:继承Fram类,paint,lauchFram,uptate方法,里面用于图像处理的几个方法。键盘监听事件,继承KeyAdapter类,keyPressed,KeyReleased方法。键盘可以控制画面上的图像运动。

不足之处:页面很简陋,没运用多态方法,功能还很单一,可以使用一个标志值来控制重画线程的结束,线程的使用不够熟练。

坦克大战学习笔记-TankWar的更多相关文章

  1. HTML坦克大战学习02---坦克动起来

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  2. HTML坦克大战学习01

    <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <t ...

  3. C# 坦克大战学习总结

    1.学会用Resource管理资源 添加资源 在properties下的Resource.resx添加资源 使用资源 工程名.Properties.Resource.资源名 实际本质,是一个流. 2. ...

  4. 阶段学习总结-坦克大战(2D)案例

    这是前几天学习的案例,这两天学习了NGUI和UGUI,被UI搞得很烦躁,但是今天还是将前几天学习的坦克大战总结以下.这个游戏是小时候的经典红白机游戏的复刻,见截图: 一.游戏物体 游戏中包含地图元素( ...

  5. unity3D学习—坦克大战(一)

    背景介绍 本人一名C#程序员,从事C#开发已经有四年有余了,目前在一家大型公司上班.鉴于公司的业务需要,现在需要学习unity3D游戏开发,好在unity支持C#脚本开发,无形中省下了许多重新学习新语 ...

  6. <老友记>学习笔记

    这是六个人的故事,从不服输而又有强烈控制欲的monica,未经世事的千金大小姐rachel,正直又专情的ross,幽默风趣的chandle,古怪迷人的phoebe,花心天真的joey——六个好友之间的 ...

  7. SQLite介绍、学习笔记、性能测试

    SQLite介绍.学习笔记.性能测试 哪些人,哪些公司或软件在用SQLite: Nokia's Symbian,Mozilla,Abobe,Google,阿里旺旺,飞信,Chrome,FireFox可 ...

  8. javascript 面向对象制作坦克大战 (一)

    PS:这个坦克大战是在网上下的一段源码之后,自己进行的重写.   写这个的目的是为了巩固自己这段时间对js的学习.整理到博客上,算是对自己近端时间学习js的一个整理. 同时也希望可以帮助到学习js的园 ...

  9. java制作简单的坦克大战

    坦克大战是我们小时候玩红白机时代的经典游戏,看到有不少小伙伴都使用各种语言实现了一下,手痒痒,也使用java做的一个比较简单的坦克大战,主要面向于学过Java的人群,与学了一段时间的人,有利于面向对象 ...

随机推荐

  1. Git_GitHub-使用过程遇到的问题——坑(持续添加)

    push错误——>master git push -u origin master 最后找到解决办法如下: 1.先删除远程 Git 仓库 $ git remote rm origin 2.再添加 ...

  2. Elasticsearch-搭建自己的搜索系统

    参考链接: https://blog.csdn.net/weixin_42730079/article/details/81113806 https://www.cnblogs.com/dreamro ...

  3. 基于OpenCV做“三维重建”(2)--封装标定过程

    既然已经能够找到了标定点,那么下边的工作就是使用标定结果了.[这本书在这里的内容组织让人莫名其妙]但是通过阅读代码能够很方便地串起来. /*------------------------------ ...

  4. JSP页面静态包含和动态包含的区别与联系

    ---恢复内容开始--- JSP页面静态包含和动态包含的区别与联系: 1.<%@ include file=" " %> 是指令元素,<jsp:include p ...

  5. ASP.NET Core开发总结

    1.关于浏览器缓存,修改CSS文件和Javascript文件后调试,浏览器不更新问题,解决办法是在link标签和script标签引用的文件名后面添加版本信息如下: <link rel=" ...

  6. Android文件各种存储路径的比较

    1.File cacheDir = context.getCacheDir(); 应用内部存储空间(数据文件私有)文件存储到这个路径下,不需要申请权限,当应用被卸载的时候,目录下的文件会被删除. 需要 ...

  7. TCP 传输控制协议

    开头先说几个协议: IP:网际协议 TCP:传输控制协议 Http:超文本传输协议 AMQP:高级消息队列协议 一:TCP是什么? TCP(Transmission Control Protocol ...

  8. Conclusions about Deep Learning with Python

     Conclusions about Deep Learning with Python  Last night, I start to learn the python for deep learn ...

  9. [luaj]在安卓用使用luaj

    luaj与安卓 什么是luaj luaj是一个Java的一个lua语言引擎,他可以让你在java上运行Lua代码. 在安卓中使用lua干嘛 lua代码可以用来书写布局,或者一些业务逻辑. 为什么要在安 ...

  10. Multiple markers at this line - Missing semicolon时的解决方法

    Myeclipse的web项目中的js文件报Multiple markers at this line - Missing semicolon时的解决方法 MyEclipse的web项目中的js文件报 ...