当前位置: 首页 > 工具软件 > O2OO > 使用案例 >

oo.day07

邵骁
2023-12-01

Shoot射击游戏第一天:
1.创建了6个对象类,并创建World类测试

Shoot射击游戏第二天:
1.给6个对象类添加构造方法,并测试

Shoot射击游戏第三天:
1.设计小敌机、大敌机、小蜜蜂、子弹数组,并测试
2.设计FlyingObject超类,6个对象类分别继承
3.给FlyingObject超类设计两个构造方法,对象类分别调用

Shoot射击游戏第四天:
1.将小敌机数组、大敌机数组、小蜜蜂数组合为FlyingObject数组,并测试
2.在6个对象类中重写超类的step()移动
3.画窗口

Shoot射击游戏第五天:
1.给类中的成员添加访问控制修饰符
2.给6个对象类添加图片属性

Shoot射击游戏第六天:
1.设计窗口的宽和高为常量,适当地方做修改
2.画对象:
  1)想画对象需要获取对象的图片,每个对象都能获取图片,
    意味着获取图片行为为共有的行为,所以设计在超类中,
    每个对象获取图片的行为都是不一样的,所以设计为抽象方法
    ----在FlyingObject中设计抽象方法getImage()用于获取图片
  2)在获取图片时,因为不同的状态下需要获取不同的图片,
    所以需要去考虑对象的状态,每个对象都有状态,为共有的,
    所以将状态设计在超类中,状态一般都是常量
    ----在FlyingObject中设计三个常量,state变量表示当前状态
    在获取图片时,需要去判断对象的状态,
    每个对象都得判断,为共有的,所以设计在超类中,
    每个对象判断状态的行为都是一样的,所以设计为普通方法
    ----在FlyingObject中设计isLife()、isDead()、isRemove()
  3)重写FlyingObject的getImage():
    3.1)天空Sky,直接返回image即可
    3.2)子弹Bullet:
        3.2.1)若活着呢,直接返回image即可
    3.2.2)若死了的,直接删除
    3.3)英雄机Hero:
        3.3.1)若活着呢,返回images[0]和images[1]切换
    3.4)小敌机Airplane:
        3.4.1)若活着呢,直接返回images[0]即可
    3.4.2)若死了的,返回images[1]到images[4]轮换,4之后则删除
    3.5)大敌机Airplane:
        3.4.1)若活着呢,直接返回images[0]即可
    3.4.2)若死了的,返回images[1]到images[4]轮换,4之后则删除
    3.6)小蜜蜂Airplane:
        3.4.1)若活着呢,直接返回images[0]即可
    3.4.2)若死了的,返回images[1]到images[4]轮换,4之后则删除
  4)前面3步准备好图片之后,可以开画了,
    每个对象都能画,所以将画对象的行为设计在超类中,
    每个对象画的方式都是一样的,所以设计为普通方法
    ----在FlyingObject中设计普通方法paintObject()实现画对象
  5)天空每次需要画2张图,所以重写超类的paintObject()
    ----在Sky中重写paintObject()画对象
  6)在World类中重写paint()----调用paintObject()即可

Shoot射击游戏第七天:
1.敌人入场:
  1)敌人是由窗口创建的,所以在World类中设计nextOne()生成敌人对象
  2)敌人入场为定时发生的,在run()中调用enterAction()实现敌人入场
    在enterAction()中:
      每400毫秒,获取敌人,enemies扩容,装到最后元素上
2.子弹入场:
  1)子弹是由英雄机发射出来的,所以在Hero类中设计shoot()生成子弹对象
  2)子弹入场为定时发生的,在run()中调用shootAction()实现子弹入场
    在shootAction()中:
      每300毫秒,获取子弹,bullets扩容,数组的追加
3.飞行物移动:
  1)飞行物移动为所有派生类所共有的行为,设计在超类中
    因所有派生类行为不同,所以设计为抽象step()实现飞行物移动
    所有派生类中重写抽象step()方法
  2)飞行物移动为定时发生的,在run()中调用stepAction()实现飞行物移动
    在stepAction()中:
      天空动,遍历敌人敌人动,遍历子弹子弹动

回顾:
1.static final常量:
    必须声明同时初始化、类名点来访问,不能被改变、大写
    编译器在编译时自动转换为具体的值,效率高
    何时用:数据永远不变,并且经常使用
2.抽象方法:
    abstract,只能方法的定义,没有具体的实现
3.抽象类:
    abstract,包含抽象方法的类必须是抽象类
    抽象类是不能被实例化的,需要被继承的,派生类:
      1)重写所有抽象方法
      2)也声明为抽象类
    抽象类的意义:
      封装共有的属性和行为----------代码复用
      为所有派生类提供统一的类型----向上造型
      可以包含抽象方法,为所有派生类提供统一的入口
        派生类的具体行为不同,但入口是一致的

设计规则:
1)将派生类所共有的属性和行为,抽到超类中----抽共性
2)所有派生类的行为都一样,设计为普通方法
  所有派生类的行为都不一样,设计为抽象方法
3)


笔记:
1.成员内部类:应用率低,了解
  1)类中套类,外面的称为Outer外部类,里面的称为Inner内部类
  2)内部类通常只服务于外部类,对外不具备可见性
  3)内部类对象通常只在外部类中创建
  4)内部类中可以直接访问外部类的成员(包括私有的)
    内部类中有隐式的引用指向了创建它的外部类对象
      eg: 外部类名.this.
2.匿名内部类:
  1)若想创建一个类(派生类)的对象,并且对象只被创建一次,
    此时该类不必命名,称为匿名内部类
  2)匿名内部类中若想访问外面的变量,该变量必须是final的(JDK1.7(含)以前)

面试题:
问:内部类有独立的.class吗?
答:有

功能实现的步骤:
1)先写行为:
  1.1)为对象所特有的行为,将其设计在特定的类中
  1.2)为所有对象所共有的行为,将其设计在超类中
2)页面调用:
  2.1)定时触发的,在定时器中调用
  2.2)事件触发的,在侦听器中调用

当程序的运行结果与你所预期的结果不同时:
1)打桩: System.out.println(数据);
2)Debug调试工具


定时,多线程


5+1-----------加1
5+(-1)--------减1


int shootIndex = 0;
public void shootAction() { //10毫秒
  shootIndex++;
  if(shootIndex%30==0){ //300毫秒
    Bullet[] bs = hero.shoot();
    bullets = Arrays.copyOf(bullets,bullets.length+bs.length);
    System.arraycopy(bs,0,bullets,bullets.length-bs.length,bs.length); //数组的追加
  }
}

class Hero{
  public Bullet[] shoot(){ //生成子弹对象(英雄机发射子弹)
    int xStep = this.width/4; //1/4英雄机的宽
    int yStep = 20;
    if(doubleFire>0){ //双
      Bullet[] bs = new Bullet[2];
      bs[0] = new Bullet(this.x+1*xStep,this.y-yStep); 
      bs[1] = new Bullet(this.x+3*xStep,this.y-yStep); 
      doubleFire-=2;
      return bs;
    }else{ //单
      Bullet[] bs = new Bullet[1];
      bs[0] = new Bullet(this.x+2*xStep,this.y-yStep); 
      return bs;
    }
  }
}

int enterIndex = 0; //计数器
public void enterAction() { //10毫秒走一次
  enterIndex++; //每10毫秒增1
  if(enterIndex%40==0){ //400(40*10)毫秒走一次
    FlyingObject obj = nextOne();
    enemies = Arrays.copyOf(enemies,enemies.length+1);
    enemies[enemies.length-1] = obj;
  }
}


paint()方法的调用方式:
1)frame.setVisible(true);
2)repaint();


假设有5个敌人了,又来了一个敌人


敌人入场:
子弹入场:
飞行物移动:


  //生成敌人(小敌机、大敌机、小蜜蜂)对象
  public FlyingObject nextOne(){
    Random rand = new Random();
    int type = rand.nextInt(20); //0到19
    if(type<4){ //0到3
      return new Bee();
    }else if(type<12){ //4到11
      return new Airplane();
    }else{ //12到19
      return new BigAirplane();
    }
  }

    Random rand = new Random();
    int type = rand.nextInt(3); //0到2
    if(type==0){
      return new Bee();
    }else if(type==1){
      return new Airplane();
    }else{
      return new BigAirplane();
    }

?处设计为什么类型:
  既能接收小敌机对象,
  也能接收大敌机对象,
  也能接收小蜜蜂对象


敌人入场:
  敌人是由窗口产生的,所以行为设计在窗口类中

子弹入场:
  子弹是由英雄机产生的,所以行为设计在英雄机类中

飞行物移动:
  飞行物移动为共有的行为,所以行为设计在超类中

1)敌人入场
2)子弹入场
3)飞行物移动


              TimerTask,            long,long
timer.schedule(new TimerTask(){
  public void run(){ //定时干的那个事--每10毫秒走一次
    //敌人入场,子弹入场,飞行物移动
    //...
    //...
  }
},10,10);


class Aoo extends ?{
  
}

第1个10:从程序启动到第一次触发的时间间隔
第2个10:从第一次触发到第二次触发的时间间隔
        从第二次触发到第三次触发的时间间隔
    从第三次触发到第四次触发的时间间隔
    ...

字母、数字、_和$符

Mama$Baby.class
NstInnerClassDemo$1.class
NstInnerClassDemo$2.class
NstInnerClassDemo$3.class


jdk1.0/1.1/1.2/1.3/1.4/1.5/1.6/1.7-----内存几乎没变
jdk1.8---------------------------------几存做了改变


Aoo o1 = new Aoo();
Boo o2 = new Boo(); //编译错误

class Aoo{
  private int a;
  void create(){
    Boo o = new Boo();
  }
  class Boo{
    void test(){
      System.out.println(a);
      System.out.println(Aoo.this.a);
      System.out.println(this.a); //编译错误
    }
  }
}

项目功能:
1)敌人入场
2)子弹入场
3)飞行物移动

 类似资料:

相关阅读

相关文章

相关问答