20170817 - 今日技能封装 - Q

Posted 清及

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了20170817 - 今日技能封装 - Q相关的知识,希望对你有一定的参考价值。

重点 整体流程体会。
①子类构造调用静态块加载的东西
②敌机与蜜蜂用一个父类共同讨论

1 敌人进场
2 飞行物走一步
3 子弹入场
4 英雄机随鼠标移动
5 删除越界的飞行物

2 如何理解定时发生?

3 如何引入定时类?

4 如何让程序定时发生?

5 静态方法中可以调用类内方法吗?

思路梳理
飞行物走步用定时方法,每隔10ms运行一次,
因此定义各类的走步方法,先抽象到父类中,再在子类中重写。
子类写完后,只要在定时方法中调用即可。

这个先后顺序还是比较关键的,

一开始加载是没有敌人的,所以初始化赋值为空,后面开始运行了,就往数组里面装东西,
再(在主流程中)调用repaint()

自然化编程,无需考虑太多,直接按照对象需求编程,

6 如何进行定时控制?

7 0.1%2=?
1%2=?
2%2=?

8 任何数取余2的结果是?
0或1.

 


//思维薄弱点

image = images[index++/10%images.length];
/*

index++;
int a = index/10;
int b = a%2;
image = images[b];
*/


② 对变量的作用域及来龙去脉一定要非常清晰。
定义在类体内,定义在函数内,定义在其上函数。

public void run(){
enterAction();
//10点35分调用重画,自动调用paint方法,将数组中数据重新画出。
stepAction();//飞行物走一步 
hero.shoot();
repaint();
};
定义在了定时run里面,结果每次都重新加载,导致y坐标一直都是377;

bullets = hero.shoot();
public void stepAction(){
hero.step();
//遍历数组
for(int i = 0;i < flyings.length;i++){
flyings[i].step();
}
for(int i = 0;i < bullets.length;i++){
bullets[i].step();
}
for(int i = 0;i < bullets.length;i++){
bullets[i].step();
}


}
定义在了stepAction外,根本没传进去,y坐标还是获取y的private Bullet[] bullets = {}; 中的坐标,即无;


public void enterAction(){
//敌人进场--敌机加小蜜蜂
flyIndex++;
if(flyIndex%40 == 0){
FlyingObject obj = nextOne();
bullets = hero.shoot();
flyings = Arrays.copyOf(flyings,flyings.length+1);
flyings[flyings.length-1] = obj;

}
}

public void enterAction(){
flyIndex++;
if(flyIndex%40 == 0){
FlyingObject obj = nextOne();
flyings = Arrays.copyOf(flyings,flyings.length+1);
flyings[flyings.length-1] = obj;

}
}
最终定义了在其(stepAction)上的函数enterAction()内,成功赋值.
public void run(){
enterAction();
stepAction();//飞行物走一步 
repaint();

③ public void shootAction(){
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);
//数组的追加

子弹是怎么动起来的?

④ public boolean outOfBounds(){
if(y >= ShootGame.HEIGHT){
return true;
}else{
return false;
}
}

public boolean outOfBounds(){
return this.y <= ShootGame.HEIGHT;
}

3 swing事件触发分为什么?
侦听器,事件,处理,

4 一个抽象类可否不重写?
可以,只要这个抽象类内无抽象方法.(Adapter)

 

 

创建敌人写在了主类上,因为敌人就是在窗口上随机产生的

子弹是英雄机发射的(英雄机的行为),所以写在英雄机里

先写行为,页面再调

目标是,在框内显示所有对象并让他们动起来

分为敌机进场,子弹开始动,英雄机随鼠标移动,删除越界敌机

--------------------
过程思维漏洞记录
①abstract方法后,类需要立刻抽象化

public abstract class FlyObject

 

思路必须极其清晰,清晰到什么程度?

最少要知道前面三步,后面两步是要做什么

如飞机大战项目

整体框架是——在主类窗口类中将各个对象画上去

细节框架则分别是各个对象的创建,以及大小对象间的调用(非父子类,而是主次的调用关系,如英雄机中的发射子弹方法调用子弹对象,主类中的窗口类调用各对象)

具体到实践:

在确定是调用timer来定时循环执行代码块实现飞机大战的效果后,不确定将repaint放在哪, 结合定时循环思考(脑中必须有一个清晰的流程,哦前一步是这个,那我这一步就应该这样) 后明白repaint必须不断反复加载,并且是在重复代码块的前方,实现整体的动态加载效果,再来分别将敌机,小蜜蜂,英雄机,子弹步进的效果实现

 

拓展:

一些可以作为指导思想的面向对象编程原则

如何判断方法写在哪个类中?

如果是对象自身的行为,则写在对象内。(英雄机发射子弹,于是发射子弹方法便写在英雄机内——但并不是直接便将包括画子弹的函数也写在内部,该原则亦需要根据实际情况做调整,上课过程中老师强调过很多次的一句话,在类内部写行为,在主类中调方法,这里需要结合大框架思考来确定方法的编写——由于是在主类(继承了JPanel)中将对象画出来,因此不是直接在函数中将子弹画出来,而是返回一个子弹类型的值交由主类去画)

 

以上是关于20170817 - 今日技能封装 - Q的主要内容,如果未能解决你的问题,请参考以下文章

20170804 - 今日技能封装 - Q

20170811 - 今日技能封装 - Q

20170803 - 今日技能封装 - Q

20170810 - 今日技能封装 - Q

20170802 - 今日技能封装 - Q

20170731 - 今日技能封装 - Q