精华内容
下载资源
问答
  • 一天入门Java快速入门

    万次阅读 2015-09-23 17:19:36
    在此之前我从未学Java.我会找出Java与C++等语言的区别.以达到快速学习的目的.据了解Java基于C++,但是更简单易学哟,那我们一起走

    前言

    我写此文主要

    参考:

    Java:Java快速入门-幸福框架

    目的是:

    快速入门啦.由于工作的需求-Android安全.

    计划:

    Java一天入门

    我从未学过Java.我会找出Java与C++等语言的区别.以达到快速学习的目的.
    据了解Java基于C++,但是更简单易学哟.

    开始

    类名

    那一群带.的东西是搞毛的?形如:

     package com.happyframework.javastudy.hello;

    package对应目录的相对路径,class对应文件.
    上面对应:
    E:\Workspaces\MyEclipse 10\JavaStudy\src\com\happyframework\javastudy\hello\Hello.java

    关于class有如下几点规则:

    1. 文件的名字必须和class的名字一致(public级别的class名字)。
    2. 文件必须只包含一个public访问基本的class(可以包含多个非public级别的class)。
    3. package名字必须和目录一致。

    入口方法

    Java里面只有方法,没有函数哟.
    入口方法如下:

     public class App {
        public static void main(String[] args) {
             com.happyframework.javastudy.hello.Hello.hello();
         }
     }

    数据类型

    特别之处是小数类型的常量默认是double类型,声明float类型的常量需要使用F作为后缀。

    float fage =21.0F

    运算符

    特别之处是:
    位运算符多了一种:

    >
    “>> 右移,高位补符号位” 这里右移一位.
    “>>> 无符号右移,高位补0”; 与>>类似

    字符串

    Java原生支持字符串类型,而不是像C++一样使用扩展,或者像C一样使用数组.

    String是拥有“值语义”的引用类型,字符串常量实现了“享元模式”,equals会按照内容进行比较,==按照地址比较。

    public class Program {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            String x = "段光伟";
            String y = new String("段光伟");
    
            System.out.println(x.equals(y)); // true
            System.out.println(x == y); // false
        }
    
    }

    为了高效的修改字符串Java引入了StringBuffer:

    {
                StringBuffer sb = 
                        new StringBuffer()
                        .append("段")
                        .append("光")
                        .append("伟");
    
                System.out.println(sb.toString());
            }

    数组

    相较于C++增加了一种声明语法,改成了另外的三种初始化语法:
    声明语法

    DataType[] name 或 DataType name[]。

    初始化语法

    DataType[] name = new DataType[length]。

    DataType[] name = new DataType[] { element1, element2, …elementn }。

    DataType[] name = { element1, element2, …elementn }。

    只有不等长多维数组DataType[][],没有DataType[xxx, xxx]啦。

    控制结构

    1. 条件:没变.
    2. 循环:for-each
    3. Labeled block (多了个lable?)
    public class Program {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            task: {
                int age = 25;
    
                System.out.println("start");
    
                if (age < 30) {
                    break task;
                }
    
                System.out.println("end");
            }
        }
    }

    方法

    终于来到方法了.

    Java中所有的赋值和方法调用都是“按值“处理的,引用类型的值是对象的地址,原始类型的值是其自身。
    Java支持变长方法参数。

    public class Program {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            print("段光伟", "段光宇");
            print(new String[] { "段光伟", "段光宇" });
        }
    
        private static void print(String... args) {
            for (String item : args) {
                System.out.println(item);
            }
        }
    }

    糊涂开始

    调用自身的构造方法是用this(xxx,xxx,…)来完成,且必须位于第一行。

    静态成员

    Java中类似静态构造方法的结构,称之为:静态初始化代码块,与之对应的是实例初始化代码块.

    继承

    继承使用extends,抽象类和抽象方法使用abstract声明,向下转型使用(ChildType)instance.

    重写

    Java中的重写规则比较灵活,具体如下:
    1. 除了private修饰之外的所有实例方法都可以重写,不需要显式的声明.
    2. 重写的方法为了显式的表达重写这一概念,使用@Override进行注解.
    3. 重写的方法可以修改访问修饰符和返回类型,只要和父类的方法兼容(访问级别更高,返回类型更具体).
    4. 可以使用final将某个方法标记为不可重写.
    5. 在构造方法中使用super(xxx,xxx)调用父类构造方法,在常规实例方法中使用super.method(xxx,xxx)调用父类方法.
    6. Java不支持覆盖(new).

    包的名字和项目路径下的目录路径相对应.
    Java支持三种导入语法:
    1. 导入类型:import xxx.xxx.xxxClass
    2. 导入包:import xxx.xxx.xxx.*
    3. 导入静态成员: import static xxx.xxx.*

    import static util.Helper.*;
    
    public class Program {
    
        /**
         * @param args
         */
        public static void main(String[] args) {
            puts("段光伟");
        }
    }

    访问级别

    Java支持四种访问级别:public,private,protected和default(默认),类型和接口只支持public和default.
    - protected 修饰过的成员只能被自己、子类和同一个包里的(不包括子包)其他类型访问。
    - default 修改过的类型或成员只能被自己和同一个包里的(不包括子包)其他类型访问。

    嵌套类

    晕啊

    常量

    有一点需要注意的是:只有一种情况Java的常量是编译时常量(编译器会帮你替换),其它情况都是运行时常量,这种情况是:静态类型常量且常量的值可以编译时确定。

    接口

    Java的接口可以包含方法签名,常量和嵌套类.
    不同什么意思?百度一下.

    枚举

    Java枚举是class.

    异常

    Java中的异常分为checked和unchecked.
    所有继承Exception的异常(除了RuntimeException和它的后代之外)都是checked异常。
    而checked异常必须声明在方法中或被捕获.

    装箱和拆箱

    自动装箱和自动拆箱是Java提供的语法糖。
    语法糖是什么,我怎么会告诉你.

    泛型方法

    类似于C++的模板哈

    类型参数约束

    类型擦除过程

    end.
    入门到此结束.
    统计

    展开全文
  • 一个大数据屌丝的一天

    万次阅读 多人点赞 2018-10-08 17:57:16
    我们以某互联网屌丝小明的一天为蓝本,来看看大数据时代是如何榨取你的数据价值的吧! 小明在一家互联网英语教育公司工作,主要职责是写 bug,一位码农。小明不占有生产资料,也无法从数据变现的大碗里给自己...

    在大数据时代,人最宝贵的已经不再是劳动时间,而是你身上产生的数据。 无数的互联网巨头和大数据专家们,像欣赏鹿茸和牛黄那样,细细品味着你每天都去过哪里、吃的什么、买了几卷卫生纸,并用人工智能技术依次向你推送扎了洞的安全套和无痛人流医院。

    什么,你觉得这些数据还属于你自己?我只能说,too young,too simple!让我们以某互联网屌丝小明的一天为蓝本,快来看看大数据时代是如何榨取你的数据价值的吧!

    小明在一家互联网英语教育公司工作,主要职责是写 bug,一位码农。小明不占有生产资料,也无法从数据变现的大碗里给自己捞一块肉,只能被动地、无可奈何地,像中世纪农奴给领主献上初夜权那样,主动扒光自己隐私的遮羞布,向资本献出自己的数据,还得呲牙咧嘴地摆出被大数据临幸后的满足感。

    一大早 9 点钟,小明刚一下地铁,手机就“叮”的一声送来了短信:“老爷爷家乡鸡望京店,现推出 10 元油条豆浆早餐,绝对不含二手地沟油!”奇怪,这推销来的这么精准,是怎么做到的呢?看来大数据大有可为啊!正好还没吃早点,干脆进去尝尝!

    【画外音:通过 GPS 或者蜂窝信号,可以测得手机移动速度,当用户在早上九点由高速运动变为低速运动时,可以判断是从地铁出来,这时候就可以向他推荐附近的早点了。】

    enter image description here

    吃完了早点,小明满口地沟油的余香,慵懒地坐在了电脑边。这时,电话铃突然响了起来,接通后传来一个女生的声音:“请问先生您有提高英语口语的意愿是么?”咦,这不是同事小娜的声音么?怎么推销业务推销到公司内部来了?“是我啊,同事也不放过么?”小娜扑哧一声乐了,放下电话走到小明身边:“我们运营部昨儿新买了个软件,提交一组关键词上去,就能返回一批电话,打通一个才交几块钱,这比投搜索引擎便宜多了!”小明这才明白,原来自己昨天查过“口语培训”这点儿事,这么快全北京的英语班儿都知道了啊!

    【画外音:通过运营商 DPI 技术,可以截取搜索引擎的搜索行为,并将其与电话号码相关联。】

    enter image description here

    上网转转,平复一下心情吧!可是不论打开新浪搜狐看看八卦,还是看看中国梦,旁边总有一块狗皮膏药一样的广告,上面有个中段的美女,穿着十分简约,还配着一句广告词:“正品硅胶义乳,做女人挺好!”唉,都怪自己昨天为了对付指纹门卡,在某电商上看了几个“硅胶指纹模具”,这谁还有心思看新闻啊,还是关了罢!

    【画外音:根据电商的浏览、购买等行为,可以向用户追身投放广告,这称为重定向;今天,随着广告程序化交易的发展,不论你看哪个网站,只要该网站接入了 ADX,你就都别想跑了!】

    被大数据盯得这么紧,小明有点儿手足无措。好在饭点儿到了,为了尽可能躲开地沟油,小明踱出写字楼,晃进了对面的购物中心。美食城就在购物中心的四层,小明刚迈下扶梯,手机上的“小撮点评”应用就发出了一条提醒:“欢迎您光临吃了吐美食城,前方直行 50 米右转,厕所对面的煎饼摊今日 9.8 折优惠(不接受按揭)!”奇怪了,这应用怎么连我到四层都知道呢?再低头一看自己的安卓手机,似乎又明白了什么。

    【画外音:这是利用 wifi 定位技术实现的精准室内追踪。当你的安卓手机 wifi 处于打开状态时,会与周围的 wifi 热点握手,若干热点可以根据你的信号强度反算出你的位置,并与你的 MAC 地址相关联,精准度可达米级。苹果手机如果打开了蓝牙,也可以实现类似的定位。通过买来的数据将 MAC 与设备号映射起来,手机上的应用就能在你走下扶梯的一刻作出反应了。】

    enter image description here

    饭也没心情吃了,还是回去干活吧!小明翻出一份数据集,这是“朝阳区大数据教会”组织的视频推荐大赛提供的数据集,老板让小明先看看。小明心不在焉地一行行扫着,突然,下面这条数据让他眼前一亮:

    某甲,蓝猫淘气三千问(2016.1.15)、喜羊羊与灰太狼(2016.2.10)、熊出没(2016.2.16)…

    虽然名字隐去了,不过还用问啊,这条记录准是对面 cubic 小刚的啊!这家伙弱智得只看得懂动画片,还每天看了啥都到班上来讲讲。嗯?等会!除了动画片,后面怎么还有一串东洋岛国的爱情动作片儿?小明乐弯了腰,拿着电脑走到小刚面前:“看,这些片是你看的不是?”小刚当时就傻了,心下当然非常不爽,不过人家没有写自己的名字,还真是哑巴吃黄连。

    【画外音:即使没有姓名、电话这些个人可定位信息,对目标用户有一定背景信息了解的熟人,也可通过互联网稀疏行为数据对应到个人从而获取更多隐私。新兴的“差分隐私”技术,也是为了克服这一难题。】

    一波未平,一波又起,小明刚刚坐定,电脑右下角的企鹅嘟嘟嘟叫起来,是小明的同学小宏,现在在某大互联网公司上班。

    “老同学,你上周去东莞干啥了?怎么还搜了发廊这个词?你可别犯错误啊!”
    “少废话,我上东莞是给公司出差去了,理个发还不行么?不对啊,你怎么知道的啊?”
    “嘿嘿,我在这边搜索团队啊,你不是拿手机号注册的我们应用么?”

    小明放下电话,默默地删除了“盯梢搜索”这个应用。

    【画外音:绝非危言耸听,有很多互联网公司、甚至包括一些大公司,内部对数据使用规范性的管理混乱到了令人发指的程度。像上文这样的情形并不是虚构。】

    “小明的快递!”门口又响起了熟悉的快递员喊声,“到付的,一百块钱!”小明一时想不起来是什么,不过经常在网上买东西,到付的也不少,也就没多琢磨。把一百块钱递给快递员,一边往回走一边拆包裹:纸盒子里面拿出个泡沫塑料袋,泡沫塑料袋里面是个牛皮纸包,牛皮纸包里面是个牛皮纸袋,牛皮纸袋里面有个信封儿,信封撕开一开,有一张小纸条,上书两个大字:“挠挠!”小明当时两眼发直,一口血差点喷在纸条上,这么个玩意儿就蒙了我一百块钱啊!(编者注:此处请向已故相声大师马三立经典作品《祖传秘方》致敬!)

    【画外音:不法分子通过各种手段批量买到用户的地址和电话,通过发到付快递的方式可以大规模获利,至于数据从哪儿买到的,前一段某电商数据部门被开除的事儿,您还有印象吧!】

    enter image description here

    天黑了,终于熬到了 9 点的下班点儿,“嘟嘟”打车软件如约发来消息:“您下班时间快到了,要不要再给您预约去保利会所的专车呢?“小明心说:“那是昨天跟老板陪客户去的,天天去哪有那美事儿?我还是骑着单车奔城乡结合部租的 8 平米小复式吧!”

    【画外音:根据个性化数据进行的推荐,应该在没有用户主动意图时尽量保守一些,否则会带来不好的体验,也会让更多人质疑隐私使用的合法性。】

    好容易到了自己租的小屋,可以忘掉这惊悚的一天了吧!小明想蹲会儿马桶,一个人静静。屁股刚往马桶圈上一沾, 胯下的大数据智能马桶就开始发言:“根据您的毛细血管进行光学臀相分析,发现您血色稠暗,可能是二手地沟油摄入过多;另外臀堂发暗,可能是被人窥视私密之事受惊吓所致,建议您珍爱生命,远离地沟油和大数据!” 当时,小明吓得便意全无,不由得抬头望了望窗外的繁星,似一串串 0 和 1 那般闪烁跳跃,顿觉在大数据时代,虽有大地之广,宅院之深,却无半点屌丝立锥之地……

    @北冥乘海生 2018.9

    ——————
    推荐阅读:
    《The Coder》9 月刊聚焦程序员的职场江湖

    展开全文
  • 毕业一年,我想说我过得如何?

    千次阅读 多人点赞 2020-05-17 00:14:34
    毕业一年了,因为个点,搅乱了自己的思绪。这个点是我已经毕业一年了。 原生家庭 08年父亲因癌症晚期去世了。...2019年,我以名程序员的身份毕业,找到了份广州薪资w的工作。当时自己的理想工作城...

        毕业一年了,因为一个点,搅乱了自己的思绪。这个点是我已经毕业快一年了。

    原生家庭

    08年父亲因癌症晚期去世了。我,老妈,小妹三个人组成一个单亲家庭继续走到了现在。家里顶梁柱的缺失在很长的一段时间里,看习惯了很多别人异样的眼光。童年也有许多不快乐的回忆,小时候被许多隔壁小朋友嘲笑过自己是外省人,仅仅是因为老妈是广西嫁这边。我不知道为什么这种会被嘲笑,可能是当时很多拉板车拉货的人很多都是外省过来的吧。

    现状

    2019年,我以一名程序员的身份毕业,找到了一份广州薪资过w的工作。当时自己的理想工作城市是广州,原因第一是广州是自己大学待了四年的城市,有归属感,觉得像深圳其他地方内心有种抵触感;第二 广州曾是自己一个亲人年轻的时候闯荡过的地方,内心想也我能在这找到属于自己的位置吧。

    回忆

    • 大学毕业前,没有选择考研,觉得家庭更需要我。

    • 大学四年很少跟家里要钱,毕业花钱最多的时候也没跟家里要过钱,靠着实习攒的钱,自己找房子,找到了自己毕业后可以落脚的地方。

    • 每个月的工资都会给母亲转些钱,母亲没有按照自己预想的样子让自己过得好一些,还是留着,甚至有时候补贴落魄家庭的亏空。

    • 自己要好的朋友被骗了钱,我给予他一些力所能及的帮助,给了微不足道的1w多。我那时候很深刻的体会到他抑郁的样子甚至轻生的想法,我能感受到抑郁症的恐怖,不希望一个生命就在我眼中消失了。

    • 我以相对同批入公司的人,能力快速的成长,薪资也高了不少,人生第一次这么有成就感。

    • 自己的堂哥,一直以来受过不少照顾。有一天他遇到了困难,100多万的走私罚款,我第一次快掏空了自己工作以来所有的积蓄。

    • 花了钱,借了钱,顺了老妈的心意,跟一个风水先生,给自己心里最亲的人换了墓地,那个人,是我08年已入天堂的父亲。

    总结

    毕业一直到现在,没有攒什么钱,与自己当初攒下10w的点似乎要从头开始了。回想起当初如果我选择了考研,当我面对这些事情的时候我又会怎样呢?不过比起这些,和自己亲的人生能够活在当下,是最幸福的事。总结一年来自己的收获,那就是充实,我也理解了当一个人从一个学生步入事俗的不易,也明白了一个人应该有的担当。我在某书上看过一句话:一个人的成功,不是看他站在顶峰有多高,是看他跌落谷底后到达山峰的反弹力。我觉得这个句话说的是一个人的韧性,对梦想的韧性,只要不放弃,不久之后你可以获得你想要的东西。期待自己从现在起一年后又会是怎样子,现在就记录这些东西吧,一年后再看看~

    展开全文
  • 老Java程序员花一天时间写了个飞机大战,很舒服!

    万次阅读 多人点赞 2021-05-25 21:42:07
    前两我发现CSDN上有两篇飞机大战的文章异常火爆,各种指标都很高(阅读、点赞、评论、收藏等),但都是python写的,竟然不是我大Java,说实话作为老java选手,我心里是有那么一些失落的,难道我大java打飞机不行?...

    老Java程序员花1天时间做了个飞机大战

    系列目录

    1. Java俄罗斯方块
    2. 老Java程序员花2天写了个连连看
    3. 老Java程序员花一天时间写了个飞机大战
    4. Java五子棋人机版
    5. Java植物大战僵尸
    6. Java消消乐(天天爱消除)
    7. Java贪吃蛇小游戏
    8. Java扫雷小游戏
    9. Java坦克大战

    引言:

    前两天我发现CSDN上有两篇飞机大战的文章异常火爆,各种指标都很高(阅读、点赞、评论、收藏等),但都是python写的,竟然不是我大Java,说实话作为老java选手,我心里是有那么一些失落的,难道我大java打飞机不行?就算大java打飞机不行,那我用单身30年的打飞机手速,我肯定行(反正我的代码我做主,就是玩!),于是我决定一展伸手,用java写了一个飞机大战。我就问你们我打飞机行不行,我媳妇都说行,你们呢?欢迎我亲爱的大Java选手们 点赞+评论+收藏!给我冲、冲、冲。。。

    代码实现

    创建窗口

    首先创建一个游戏窗体类GameFrame,继承至JFrame,用来显示在屏幕上(window的对象),每个游戏都有一个窗口,设置好窗口标题、尺寸、布局等就可以。

    /*
     * 游戏窗体类
     */
    public class GameFrame extends JFrame {
    	
    	public GameFrame() {
    		setTitle("飞机大战");//设置标题
    		setSize(526, 685);//设定尺寸
    		setLayout(new BorderLayout());
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭按钮是关闭程序
            setLocationRelativeTo(null);   //设置居中
        	setResizable(false); //不允许修改界面大小
    	}
    }
    

    创建面板容器GamePanel继承至JPanel

    package main;
    
    import java.awt.Graphics;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    /*
     * 画布类
     */
    public class GamePanel extends JPanel{
    	GamePanel gamePanel=this;
    	private JFrame mainFrame=null;
    	//构造里面初始化相关参数
    	public GamePanel(JFrame frame){
    		this.setLayout(null);
    		mainFrame = frame;
    		
    		mainFrame.setVisible(true);
    	}
    	
    	@Override
    	public void paint(Graphics g) {
    		
    	}
    }
    

    再创建一个Main类,来启动这个窗口,用来启动。

    package main;
    public class Main {
    	//主类
    	public static void main(String[] args) {
    		GameFrame frame = new GameFrame();
    		GamePanel panel = new GamePanel(frame);
    		frame.add(panel);
    		frame.setVisible(true);//设定显示
    	}
    }
    

    右键执行这个Main类,窗口建出来了
    ​​窗口

    创建菜单及菜单选项

    创建菜单

    private void  initMenu(){
    	// 创建菜单及菜单选项
    	jmb = new JMenuBar();
    	JMenu jm1 = new JMenu("游戏");
    	jm1.setFont(new Font("微软雅黑", Font.BOLD, 15));// 设置菜单显示的字体
    	JMenu jm2 = new JMenu("帮助");
    	jm2.setFont(new Font("微软雅黑", Font.BOLD, 15));// 设置菜单显示的字体
    	
    	JMenuItem jmi1 = new JMenuItem("开始新游戏");
    	JMenuItem jmi2 = new JMenuItem("退出");
    	jmi1.setFont(new Font("微软雅黑", Font.BOLD, 15));
    	jmi2.setFont(new Font("微软雅黑", Font.BOLD, 15));
    	
    	JMenuItem jmi3 = new JMenuItem("操作说明");
    	jmi3.setFont(new Font("微软雅黑", Font.BOLD, 15));
    	JMenuItem jmi4 = new JMenuItem("胜利条件");
    	jmi4.setFont(new Font("微软雅黑", Font.BOLD, 15));
    	
    	jm1.add(jmi1);
    	jm1.add(jmi2);
    	
    	jm2.add(jmi3);
    	jm2.add(jmi4);
    	
    	jmb.add(jm1);
    	jmb.add(jm2);
    	mainFrame.setJMenuBar(jmb);// 菜单Bar放到JFrame上
    	jmi1.addActionListener(this);
    	jmi1.setActionCommand("Restart");
    	jmi2.addActionListener(this);
    	jmi2.setActionCommand("Exit");
    	
    	jmi3.addActionListener(this);
    	jmi3.setActionCommand("help");
    	jmi4.addActionListener(this);
    	jmi4.setActionCommand("win");
    }
    

    实现ActionListener并重写方法actionPerformed
    在这里插入图片描述
    actionPerformed方法的实现

    @Override
    public void actionPerformed(ActionEvent e) {
    
    	String command = e.getActionCommand();
    	UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("宋体", Font.ITALIC, 18)));
    	UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("宋体", Font.ITALIC, 18)));
    	if ("Exit".equals(command)) {
    		Object[] options = { "确定", "取消" };
    		int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
    				JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
    				options, options[0]);
    		if (response == 0) {
    			System.exit(0);
    		} 
    	}else if("Restart".equals(command)){
    		if(startFlag){
    			Object[] options = { "确定", "取消" };
    			int response = JOptionPane.showOptionDialog(this, "游戏中,您确认要重新开始吗", "",
    					JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
    					options, options[0]);
    			if (response == 0) {
    				//需要先结束游戏
    				realGameEnd(1);
    				restart();
    			} 
    		}else{
    			restart();
    		}
    	}else if("help".equals(command)){
    		JOptionPane.showMessageDialog(null, "游戏开始后,要先动鼠标到飞机处,触发移动效果,然后飞机就会跟随鼠标移动!",
    				"提示!", JOptionPane.INFORMATION_MESSAGE);
    	}else if("win".equals(command)){
    		JOptionPane.showMessageDialog(null, "得分1000,获得胜利!",
    				"提示!", JOptionPane.INFORMATION_MESSAGE);
    	}
    }
    

    在这里插入图片描述

    创建背景

    在GamePanel类中重写paint方法,绘制背景图即可

    //绘图方法
    @Override
    public void paint(Graphics g) {
    	gameHeight = this.getHeight();
    	gameWidth = this.getWidth();
    	//绘制背景
    	g.drawImage((BufferedImage)imageMap.get("bg"), 0, -150, null);
    }
    

    在这里插入图片描述

    开启主线程

    主线程,用来重绘页面,重绘全部交给主线程,主线程调用 repaint方法就行,要产生动画就要靠这个repaint。

    //刷新线程,用来重新绘制页面
    private class RefreshThread implements Runnable {
    	@Override
    	public void run() {
    		while (startFlag) {
    			repaint();
    			try {
    				Thread.sleep(50);
    			} catch (InterruptedException e) {
    				e.printStackTrace();
    			}
    		}
    	}
    }
    

    在GamePanel的构造里面启动这个主线程
    在这里插入图片描述
    有了这个主线程刷新,待会我们更新飞机的位置,飞机就会移动,不需要另外的代码去调用repaint方法了(这是我的做法,仅供参考)。

    创建我方飞机

    创建MyPlane类,属性有坐标x、y,宽高、图片、是否存活、是否可以移动等;方法主要有绘制、移动、射击等。

    public class MyPlane {
    
    	private int x = 0;
    	private int y = 0;
    	private int width = 0;
    	private int height = 0;
    	private BufferedImage image = null;
    	private GamePanel panel=null;
    	private HashMap imageMap=null;
    	private boolean alive=true;
    	private boolean canMove=false;
    	private int key=1;
    	private HashMap boomImageMap=null;
    	private boolean hitFlag=false;//正在碰撞
    	
    	public MyPlane(int x,int y,int width,int height,GamePanel panel) {
    		this.x=x;
    		this.y=y;
    		this.width=width;
    		this.height=height;
    		this.panel=panel;
    		this.imageMap=panel.imageMap;
    		this.image=(BufferedImage)imageMap.get("myplane1");
    		this.boomImageMap=panel.mypalneBoomImageMap;
    		
    	}
    	//绘制
    	public void draw(Graphics g) {
    		g.drawImage(image, x, y, width,height, null);
    	}
    }
    

    创建(这里只是创建好了飞机对象,需要绘制)

    //创建自己飞机
    private void initMyPlane() {
    	myPlane = new MyPlane(200, 530, 132, 86, this);
    }
    

    在paint方法中绘制

    //绘图方法
    @Override
    public void paint(Graphics g) {
    	gameHeight = this.getHeight();
    	gameWidth = this.getWidth();
    	//绘制背景
    	g.drawImage((BufferedImage)imageMap.get("bg"), 0, -150, null);
    	
    	//绘制飞机
    	if(myPlane!=null){
    		myPlane.draw(g);
    	}
    }
    

    在这里插入图片描述

    鼠标事件监听

    加入监听是为了让飞机跟随鼠标移动,我这里定的规则是第一次鼠标必须移动到飞机上,然后飞机才会跟随。

    代码里面用一个属性canMove来控制,默认是false,只有鼠标第一次移入到飞机上时,这个属性设置为true,然后就可以跟随鼠标移动了。

    //鼠标事件的创建
    private void createMouseListener() {
    	MouseAdapter mouseAdapter = new MouseAdapter() {
    		@Override
    		public void mouseMoved(MouseEvent e) {
    			int x = e.getX();
    			int y = e.getY();
    			if(myPlane==null) return ;
    			//飞机第一次是不允许移动的,只有飞机的canMove为true才去跟随
    			if(myPlane.isCanMove()){
    				myPlane.move(x,y);
    				return;
    			}
    			//判断鼠标的移入,如果移动到飞机上则canMove设置为true
    			if(myPlane.isPoint(x,y)){
    				myPlane.setCanMove(true);
    			}
    		}
    	};
    	addMouseMotionListener(mouseAdapter);
    	addMouseListener(mouseAdapter);
    }
    

    来实现一下MyPlane的move方法,这里处理了边界,保证飞机不出界,同时保证鼠标在飞机的中间位置

    //飞机跟随鼠标移动
    public void move(int x,int y) {
    	//判断范围,当横向移动在窗口范围内
    	if(x-width/2>=0 && x<=panel.getWidth()-width/2){
    		this.x=x-width/2;
    	}
    	//判断范围,当纵向移动在窗口范围内
    	if(y-height/2>=0 && y<=panel.getHeight()-height/2){
    		this.y=y-height/2;
    	}
    }
    

    在这里插入图片描述

    创建子弹类

    属性也就是坐标、宽高这些,给子弹加入移动方法

    //移动
    void move(){
    	new Thread(new Runnable() {
    		@Override
    		public void run() {
    			while(alive){
    				y-=speed;
    				if(y<=0){
    					clear();
    				}
    				
    				try {
    					Thread.sleep(50);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    	}).start();
    }
    

    飞机类加入射击方法,200毫秒创建一发子弹

    //射击
    void shoot() {
    	new Thread(new Runnable() {
    		@Override
    		public void run() {
    			while(alive){
    				//创建子弹
    				createBullet();
    				try {
    					Thread.sleep(200);
    				} catch (InterruptedException e) {
    					e.printStackTrace();
    				}
    			}
    		}
    
    		private void createBullet() {
    			Bullet bullet = new Bullet(x+width/2-10, y, 20, 30, panel);
    			panel.bulletList.add(bullet);
    			new MusicPlayer("/music/shoot.wav").play();
    		}
    	}).start();
    }
    

    别忘记在paint方法里面绘制子弹出来

    //绘制子弹
    Bullet bullet=null;
    for (int i = 0; i < bulletList.size(); i++) {
    	bullet = (Bullet)bulletList.get(i);
    	bullet.draw(g);
    }
    

    在这里插入图片描述

    创建敌机

    创建抽象类Plane

    package main;
    
    import java.awt.Graphics;
    
    public abstract class Plane {
    	public abstract void move();
    	public abstract void draw(Graphics g);
    	public abstract void boom();
    	public abstract void clear();
    	
    	abstract int getX();
    	abstract int getY();
    	abstract int getWidth();
    	abstract int getHeight();
    }
    

    创建敌机子类

    有个特殊一点的地方: 因为有4种敌机,这里随机1、2、3、4这4个数字作为属性index,然后根据这个index来展现不同的飞机图片,当然也可以通过这个index来设置敌机不同的移动速度,但是我为了偷懒,就全部一样的移动速度,嘿嘿。
    移动就是开启线程让y坐标增加,没什么好讲的,这里加一个飞机碰撞,就是当敌机跟我方飞机如何判断碰撞的问题。

    撞机分析(敌机与我机的撞机)
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    从上面几个图可看出什么?因为图片是方形的,他们的4个顶点一定至少有一个在对方的范围内。再看一下从左边撞击的图:
    在这里插入图片描述
    在这里插入图片描述
    在这里插入图片描述
    从上图看到也是这样,其他两个方向的也是一样的道理,为了稳点我还加了一种情况:

    1.判断敌机的4个点是否在飞机范围内,如果有则表示碰撞了。
    2.如果1不成立,则反过来,判断我机的4个点是否在敌机的范围内,如果是表示碰撞了。

    //判断飞机与子弹是否碰撞
    private boolean isPoint(MyPlane plane) {
    	/*
    	 * 
    	 * 两种情况
    	 * 1.需要判断敌机的4个点是否在飞机范围内,如果有则表示碰撞了
    	 * 2.如果步骤1不成立,则反过来,判断我机的4个点是否在敌机的范围内,如果是标志碰撞了
    	*/
    	
    	//方式1
    	
    	//左上角
    	int x1 = x;
    	int y1 = y;
    	//右上角
    	int x2 = x+width;
    	int y2 = y;
    	//右下角
    	int x3 = x+width;
    	int y3 = y+height;
    	//左下角
    	int x4 = x;
    	int y4 = y+height;
    	//只要有一个点在范围内,则判断为碰撞
    	if(comparePointMyPlane(x1,y1,plane)|| comparePointMyPlane(x2,y2,plane)||comparePointMyPlane(x3,y3,plane)||comparePointMyPlane(x4,y4,plane) ){
    		return true;
    	}
    	
    	//方式1没成立则用方式2判断
    	
    	//方式2
    	x1 = plane.getX();
    	y1 = plane.getY();
    	//右上角
    	x2 = plane.getX()+plane.getWidth();
    	y2 = plane.getY();
    	//右下角
    	x3 = plane.getX()+plane.getWidth();
    	y3 =plane.getY()+plane.getHeight();
    	//左下角
    	x4 = plane.getX();
    	y4 = plane.getY()+plane.getHeight();
    	if(comparePoint(x1,y1)|| comparePoint(x2,y2)||comparePoint(x3,y3)||comparePoint(x4,y4) ){
    		return true;
    	}
    	return false;
    }
    //用敌机的坐标来判断
    private boolean comparePointMyPlane(int x,int y,MyPlane plane){
    	//大于左上角,小于右下角的坐标则肯定在范围内
    	if(x>plane.getX() && y >plane.getY()
    		&& x<plane.getX()+plane.getWidth() && y <plane.getY()+plane.getHeight()	){
    		return  true;
    	}
    	return false;
    }
    //用我机的坐标来判断
    private boolean comparePoint(int x,int y){
    	//大于左上角,小于右下角的坐标则肯定在范围内
    	if(x>this.x && y >this.y
    		&& x<this.x+this.width && y <this.y+this.height){
    		return  true;
    	}
    	return false;
    }
    

    测试一下效果
    在这里插入图片描述

    忘记说击中敌机的了(原理跟刚才差不多,代码直接放了)

    //判断击中敌机
    protected void hitEnemy() {
    	EnemyPlane enemyPlane=null;
    	List enemys = panel.enemyList;
    	for (int i = 0; i < enemys.size(); i++) {
    		try {
    			enemyPlane = (EnemyPlane)enemys.get(i);
    		} catch (Exception e) {
    		}
    		if(enemyPlane==null) continue;
    		if(this.isPoint(enemyPlane)){
    			
    			panel.curCount+=enemyPlane.getCount();
    			//删除当前子弹
    			clear();
    			
    			//飞机爆炸
    			enemyPlane.boom();
    			
    			if(panel.curCount>=panel.totalCount){
    				panel.myPlane.setCanMove(false);
    				panel.gameWin();
    			}
    		}
    	}
    }
    
    //判断飞机与子弹是否碰撞
    private boolean isPoint(EnemyPlane plane) {
    	//因为子弹比飞机小,所以只需要判断子弹的4个点是否在飞机范围内,如果有则表示碰撞了
    	//左上角
    	int x1 = x;
    	int y1 = y;
    	//右上角
    	int x2 = x+width;
    	int y2 = y;
    	//右下角
    	int x3 = x+width;
    	int y3 = y+height;
    	//左下角
    	int x4 = x;
    	int y4 = y+height;
    	//只要有一个点在范围内,则判断为碰撞
    	if(comparePoint(x1,y1,plane)|| comparePoint(x2,y2,plane)||comparePoint(x3,y3,plane)||comparePoint(x4,y4,plane) ){
    		return true;
    	}
    	return false;
    }
    
    private boolean comparePoint(int x,int y,EnemyPlane plane){
    	//大于左上角,小于右下角的坐标则肯定在范围内
    	if(x>plane.getX() && y >plane.getY()
    		&& x<plane.getX()+plane.getWidth() && y <plane.getY()+plane.getHeight()	){
    		return  true;
    	}
    	return false;
    }
    

    最后加上计分的、胜利、失败等提示就完成了!

    看到这里的大佬,动动发财的小手 点赞 + 回复 + 收藏,能【 关注 】一波就更好了。

    想要代码的 加微信私聊 我!

    为了帮助更多小白从零进阶 Java 工程师,从CSDN官方那边搞来了一套 《Java 工程师学习成长知识图谱》,尺寸 870mm x 560mm,展开后有一张办公桌大小,也可以折叠成一本书的尺寸,有兴趣的小伙伴可以了解一下。
    在这里插入图片描述

    ★ 更多精彩

    ♥ Java植物大战僵尸 ♥

    ♥ Java坦克大战,回忆童年!♥

    ♥ Java扫雷小游戏,以前上学经常玩 ♥

    ♥ Java学生宿舍管理系统 ♥

    展开全文
  • 最近就有一位阿里员工在某职场论坛晒出了自己被辞退的经历,这位阿里员工今年35岁,有10年开发经验,完年第一天上班,就被公司劝退,建议他这个月提离职,而被辞退的理由也是他没想到,公司给的理由是他年纪较大...
  • 四个程序员的一天

    万次阅读 多人点赞 2012-11-26 08:40:48
    你,个DotNet程序员,刚刚加入个新项目组。除了你之外,其他的成员包括:Ceer,一直从事C项目的程序员,他刚刚转入C#不到个月; Jally,整天抱着本Design Pattern(没错,就是GoF的那本)在啃的前Java程序员;...
  • 本文转载自腾讯网,昨晚(2月10日),“地球自转加快一天已不足...2021年会过得吗? 据新华视点报道,科学地来讲,2021年确实会比以往年份稍短。 作为浩瀚宇宙中的一员,地球无论是公转还是自转,都会受到星际间
  • 6月最后一天

    千次阅读 2019-06-30 21:59:28
    时间的真。 学习速度很慢, 但是学的东西。 很快就忘记了。 哎
  • 判断是否为同一天 日期格式化 给日期加上指定时长 得到指定时间节点的Date 1、时间戳转Date 注:以下的方法中很多常量和方法我都没有提取出来,正式项目中还是建议大家封装在时间处理类中,规范化操作 public...
  • 每当有人问起我的工作:嗯…CDN…内容分发网络,做站长的说就懂,普通人哪里知道CDN是个什么鬼。
  • 入职第一天

    千次阅读 2016-04-20 18:17:47
    这是我写的第五篇文章,是关于我入职的第一天,分享我的故事经历,和大家一起聊聊职场。
  • 研究生浑浑噩噩的一天

    千次阅读 2020-10-31 21:52:20
    祝大家国庆中秋都能开开心心,快快乐乐。...写写我在学校的一天把。在以后的写作当中我也多写一点自己的一些生活,经历,感想等方面的文章。每篇都是干货也有些许枯燥。 时光如梭,转眼都已经研二...
  • 小公司项目经理的一天,记录我普通的一天

    万次阅读 多人点赞 2011-08-30 23:19:20
    团队5人,电子商务Web项目,前段时间离职2人,尚未补充,手下现有个开发组长、个程序员、个美术设计、个运营专员,还算个完整的战斗单位。直接汇报对象,几乎是老总(还有个元老总工程师,几乎不管我这块...
  • 今天大概写了4个函数,昨天写了5个函数,每个函数大概20行左右吧,都累死了~~~也不知道和优秀的程序员差多少。 不知道大家每天都写多少~~~~
  • 生活中有很多事情我们不顺心,有的人不停抱怨,有的人把这种烦恼发泄在别的地方,有的人则看很开,该干什么还干什么,就当这种事从来没有发生。...难道你想自己现在的生活状态像条狗一样,一天一天...
  • 大厂程序员的一天是如何度过的?

    千次阅读 多人点赞 2019-08-06 01:03:51
    阅读本回答大概需要 5 分钟。 ...小李是一位大公司里的程序员,虽然已经在公司上班一年了...这一天早上,小李照常准时起床,因为家里离公司有半小时的车程,所以他不得不在七点多就匆忙地从床上爬起来,很熟练...
  • 作为程序员上班的第一天

    千次阅读 2014-07-01 22:19:58
    2014年07月01日,今天是去四创公司报到的日子,打心底里面对于自己的第一天程序员之路感到兴奋。首先是到人事部报到,了解了一下公司的工作环境,一些入职的手续等等。接下来就是跟我们两个老大见面啦,从交流上感觉...
  • Java判断两个Date是不是同一天

    万次阅读 2018-09-17 11:36:34
    Java判断两个Date是不是同一天 1. 利用Calendar Calendar cal1 = Calendar.getInstance(); Calendar cal2 = Calendar.getInstance(); cal1.setTime(date1); cal2.setTime(date2); boolean sameDay = cal1.get...
  • public class test3 { public static void main(String[] args) { System.out.println(monkey(1,10)); } public static int monkey( int sum,int day){ if(day==1){ return sum; }else { ...
  • 程序员写在猝死的前一天

    千次阅读 多人点赞 2017-11-01 12:39:48
    怕我有什么心愿未了,他就提前托梦给我,我在这一天把自己想做的做完,然后他就带我走了。 我心想真是可笑,一个要带我去死的人,还把自己的行为说的天经地义。真想骂他,我年纪轻轻的说什么阳寿已尽。但想到他也...
  • 当年第一天到最后一天 select trunc(sysdate,'YYYY'),add_months(trunc(sysdate,'YYYY'),12)-1, from dual t 去年第一天到今年最后一天 BETWEEN (select trunc(add_months(trunc(sysdate, 'YYYY'), -12)) FROM...
  • 处理归档日志增加过快一

    千次阅读 2012-07-06 14:51:38
    本文介绍了不久前作者是如何彻底解决一家医院数据库由于归档日志增长过快,导致磁盘剩余空间占满,引起宕机全过程。通过本案例的描述,我们可以了解到当遇到数据库宕机问题时,应该如何分析现象、找到问题关键、最终...
  • 作为一名技术人员,新到一个公司都要先熟悉一下公司所在的平台,然后才能开展后续的工作,毕竟每个公司使用的技术框架不太一样,开发的规范,各项操作流程都有一定...据这名程序员网友说,他是刚上班第一天,就被安...
  • 件事,做得快,还是好?

    千次阅读 2019-09-27 13:49:52
    做任何事,一定要,不要上来就要求自己做多么的完美,因为不可能嘴吃个大胖子的。但从长远的角度来看,一定要本着把这件事做好的初心,要投入巨大的精力,不要试错后就轻易地放弃,而是要试错后进行快速地...
  • 舅舅带外甥的一天

    千次阅读 2019-02-28 16:23:06
      寒暑假是多少个学生日日夜夜所期盼着的,不知不觉间我大学的寒假就这样悄悄的向我走来了,突然感觉这时间真的的有点,仿佛暑假才刚刚从我身边走过,就这样我如期而至的回到了家里,之前跟我姐约好了放假回来...
  • Javaweb开发入职第一天

    千次阅读 2017-05-03 21:57:16
    甚至于在入职前的一周内,一直在纠结和反纠结,因为距离毕业还有一个月,论文啥的都还没搞,加之之前比较忙,长期在外地,想着可以回学校休整休整,虽然各种纠结加想法,最终还是如期入了职,五一劳动节后的第一天,...
  • 学习 node.js 第一天:引言

    万次阅读 热门讨论 2010-08-25 10:39:00
    Node.js是资深 C 程序员 Ryan Dahl 的作品,依据 Google ...V8 本身是非常的 JavaScript 引擎,处理 JS 执行运行的速度非常高。相关测试表明,FireFox、Opera 和 IE 的 JS 引擎速度都不及 V8 来得快。而且还可以说...
  •  工作3年+技术人员、测试人员在入职第一天,除了寻常的熟悉公司文化、团队人员、安装工具等等外,还需要了解什么,才能尽快上手新的工作呢?由于有丰富的工作经验,也接触了不同的团队、公司,那么除了所有公司共同...
  • 新浪微博爬虫分享(一天可抓取 1300 万条数据)

    万次阅读 多人点赞 2016-03-16 12:11:22
    代码请移步GitHub:SinaSpider爬虫功能: 此项目和QQ空间爬虫类似,主要爬取...项目爬的是新浪微博wap站,结构简单,速度应该会比较,而且反扒没那么强,缺点是信息量会稍微缺少一些(可见爬虫福利:如何爬wap站)。
  • 上班第一天(1)--一个程序员的成长史(10)

    万次阅读 热门讨论 2016-07-30 17:42:29
    个程序员的成长史》系列第十篇。

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 812,223
精华内容 324,889
关键字:

如何让一天过得很快