电话号码分析与处理、开发小游戏贪食蛇

Java核心API--电话号码分析与处理

一、熟悉Math类

        Math类包含执行基本数字运算的方法,它没有构造方法,当使用类中的成员时,要查看类中的成员是否是静态,如果是静态的,可以通过类名直接调用。

                                                                  Math类的常用方法

 

 

 二、熟悉String类

1.String类及常用方法使用

        String类代表字符串,Java程序中的所有字符串文字都被实现为此类的实例,也就是说,Java 程序中所有的双引号字符串例如"China",都是String类的对象,String类包含于Java,lang 包中,使用时不需要导包。
a.String类的构造方法
(1)String =new String();
(2)char[] str1= {' a' , ' b', ' c' };
        Strings=new String(str1);
(3)byte[]  str2 = {97,98,99};
        Strings=new String(str2);
(4)String s="China";
b.String类的常用方法

2.String Builder类

        由于String类的内容是不可变的,如果对字符串进行拼接操作,每次拼接,都会构建一个新的String 对象,既耗时,又浪费内存空间,可以通过Java 提供的StringBuilder 类来解决这个问题,StringBuilder 类是一个可变的字符序列,可以把它看成一个容器, 这里的可变指的是StringBuilder可变的,所以它在做拼接时不会生成新的对象。 
a.StringBuilder的构造方法

 

 b.StringBuilder类的常用方法

(1)append(): 在字符串的末尾追加字符串。
(2)insert(): 在字符串的某个位置插入子串。
(3)delete(): 删除字符串中的某段子串。
(4)reverse():反转字符串。
三、System类
        System类提供的设施包括标准输入、 标准输出和错误输出流,访问外部定义的属性和环境变量, 一种加载文件和库的方法,以及用于快速复制阵列的一部分实用方法,它不能被实例化,System类的常用方法如下:
        public static long current Time Millis()返回当前时间(以毫秒为单位)。
        public static viod exit(int status)终止当前运行的Java虚拟机,非零表示异常终止。
四、Object类
        Object类可以视为所有类的父类,如果某个类没有明确的父类,会默认继承Object类,在Object类中只有一个无参数的构造方法,在构造一个子类实例时都会默认优先调用该构造方法。
        只要定义了一个类,就默认继承了Object 类,也就是说,继承了Object 类中的属性和方法。Object 类中常用的方法如下:
(1)toString()
        经常由系统默认调用ꎬ 是活动当前对象的文本描述,Object默认返回值格式是: 全限定
名@hashCode, 建议覆盖为当前对象的文本描述。
(2)equals()
        用来比较两个对象是否相等的方法。
        比较对象有两种方法,分别是引用相等和对象相等,比较引用值是否相等用==符号,比较对象的内容是否相等用对象名.equals()方法。equsls在 Object 类中声明,默认的比较规则是比较引用, 建议覆盖, 实现对象的比较(比较对象的状态, 就是比较对象的数据)。
(3)hashCode()
        hashCode方法要和equals方法一同覆盖(Sun公司规定), 默认的hashCode( )值是当前堆对象地址转换的一个整数,这个整数不是内存地址,一般使用对象的 OID 值作为hashCode的值, OID是对象的唯一编号, 在模块中一般采用数据库生成 OID也就是数据库中的主键。
        覆盖hashCode( )方法要满足如下规则:
        (1)当两个对象 equals 比较为true 时, 应具有相同的hashCode()值。
        (2)当两个对象 equals比较为False时, 应具有不同的hashCode()值。
        (3)hashCode()值要稳定(一致性),一个对象创建以后就不应该再变化.
五、Java中的日期类
(1).Data类的构造方法

 (2).Data类的常用方法

                                                         常用的模式字母

                                               SimpleDateFormat类的构造方法

                                                 SimpleDateFormat类的常用方法

2.Calendar类的使用

        Calendar是个抽象类,是系统时间的抽象表示。它为特定瞬间与一组诸如YEAR、MONTH、DAY_OF_MONTH、HOUR 等日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法瞬间用毫秒值来表示,它是距历元(即格林威治标准时间 1970 日的 00: 00: 00􀆰 000)的偏移量。
        Calendar 提供了一个类方法getInstance用以获得此类型的一个通用的对象,alendar 的 getInstance方法 返 回 一 个 Calendar对 象,其 日 历 字 段 已 使 用 当 前 日 期 和 时 间 初 始 化:Calendar rightNow=Calendar.getInstance().
        Calendar的实例是系统时间的抽象表示,从Calendar的实例可以知道年星期时间区等信息,Calendar类中有一个静态方法 get(int X), 通过这个方法可以获取到相关实例的一些值(星期等) 信息,参数 是一个产量值.在Calendar中有定义.
        calendar有一个实现的子类是GregorianCalendar, 提供了世界上大多数国家使用的标准日历系统.
        Calendar 是个抽象类,只有创建Calendar对应的子类实例才能使用其中的方法.
六、包装类
         在实际开发中,经常需要对Java中的基本数据类型进行处理,比如需要把int类型的数据转换为字符串,但是int是基本数据类型,它没有方法可供调用,怎么办?
        在Java中,将Java 的基本数据类型与其提供的一些常用的操作方法进行封装,封装成引用类型———包装类。
        包装类是不可改变的,在构造了包装类对象后,不允许改变包装在其中的值,下表是Java的8 种基本数据类型对应的包装类。
                                                   基本数据类型对应的包装类 

1.Integer类的使用

        Integer类提供了多个方法,能在int类型和String类型之间相互转换,还提供一些常数,比如:
        (1)static int MAX_VALUE值是int类型表示的最大值。
        (2)static int MIN_VALUE值是int类型表示的最小值。
2.Double类的使用
        Double类的对象是double的包装类, 其提供的构造方法如下:
        (1)Double(double value): 包装一个double 类型的Double 实例。
        (2)Double(Strings): 包装一个类型为String 的Double 实例, 这里要注意 s必须是整型的字符串。
        Double类中提供的方法如下:
        double doubleValue( )返回此Double对象的double 值。
        Static double parse Double(Strings) 返回一个新的double 值, 该值被初始化为用指定的String 表示的值。 
3.什么是自动装箱和拆箱。
自动装箱和拆箱是JDK5 以后提供的编译器在编译期预处理的工作,装箱是指将基本类型转换为包装类型的过程,拆箱是指将包装类型转换为对应的基本数据类型的过程。
七、电话号码分析与处理
1.任务描述
        设计一个方法统计给定的电话号码中每个数字出现的频率ꎬ 然后根据该方法返回的结果,把出现频率最高的数字与 8 互换。 
2.任务目标
        熟悉一维数组的创建和使用ꎬ 掌握字符串操作的常用方法ꎮ。
3.实现思路
        首先,定义一个整型数组(默认数组的每个元素为 0),其次, 遍历用户输入的电话号码, 将电话号码数字出现的频率写入数字对应数组下标的元素,最后,将数组的最大值元素的下标对应的电话号码数字替换为 8。 
4. 实现代码
package NumberHandle;
import java. util. * ;
//电话号码处理
public class NumberHandle{
    public static void main ( String []sra){
        Scanner sc = new Scanner( System. in);
        System. out. println("输入电话号码:");
        String number = sc. nextLine();
        int[] a=new int[10];     //未初始化的整型数组默认每个元素为0
        char[] old = number. toCharArray();
        for (int i= 0; i<old. length; i++){
            //统计数字的出现频率
            switch(old[i]){
                //因为任何数都由10个基本数字组成,所以a的每一个下标对应一个基本数字
                case 'O' : a[0] ++; break;
                case ' 1' : a[1] ++; break;
                case '2' : a[2] ++; break;
                case '3' : a[3] ++; break;
                case '4' : a[4] ++; break;
                case ' 5' : a[5] ++; break;
                case '6' : a[6] ++; break;
                case '7' : a[7] ++; break;
                case '8' : a[8] ++; break;
                case '9' : a[9] ++; break;
                //非法字符统一替换成特定字符,循环结束后通过replace方法过滤
                default: old[i] ='#' ;
                break;
            }
        }     
        //char数组转String,删除特定字符,替换出现率最高的数字为8
        String newstr = new String (old). replace(" #" , ""). replace ("" +Max(a), "8");
        System. out. println("新号:" +newstr);
        //通过下标确定出现次数最多的数字
        public static int Max( int[] n) int max =n[0] , index=0;
            for( int i=0; i<n. length;i++)
            if(n[i]>max) |max=n[i]; index=i;{
        }
        return index;
    }
}

5.运行结果

 

 

集合——开发小游戏贪食蛇

 一、Collection集合

        Collection集合是单列集合的顶层接口,它表示一组对象ꎬ 这些对象也称为Collection的元素,JDK不提供此接口的任何直接实现,它提供更具体的子接口(Set和List)实现。
                                                         Collection集合中的常用方法

 

 二、Iterator

       Iterator接口也是Java集合框架的成员,Iterator 主要用于遍历(即迭代访)Iterator集合中的元素,Iterator对象也被称为迭代器。

        Iterator接口隐藏了各种 Collection 实现类的底层细节, 向应用程序提供了遍历Collection 集合元素的统一编程接口,Iterator接口里定义了如下 3 个方法:

        (1)booleanhasNext(), 如果被迭代的集合元素还没有被遍历,则返回 true。
        (2)Object next(), 返回集合里下一个元素。
        (3)void remove()。删除集合里上一次next方法返回的元素。
三、List集合
1.List集合
         List 是有序的集合(也称为序列),使用此接口能够精确地控制每个元素插入的位置,用户能够使用索引(元素在 List中的位置,类似于数组下标)来访问 List 中的元素,这类似于Java 的数组, 与下面提到的set不同,List 允许有相同的元素。
        除了从Collection 继承过来的操作之外,List 接口还包括以下操作。
        (1)按位置访问,根据元素在序列中的位置来引访问元素。
        (2)查找,在序列中查找指定的对象,并返回其位置索引。
        (3)迭代,扩展了Iterator 接口,以利用序列的顺序特性。
        (4)List子集合,在序列上执行任意范围的操作。
        List 作为Collection 接口的子接口,可以使用Collection接口里的全部方法,而且由于List 是有序集合,因此 List 集合里增加了一些根据索引来操作集合元素的方法。
                                                                    List常用方法
        所有的List实现类可以调用这些方法来操作集合元素,与set 集合相比,List 增加了根
据索引来插入、 替换和删除集合元素的方法。
2.List Iterator的使用
        ListIterator称为列表迭代器,它是通过List 集合的Iterator( )方法得到,所以说它是List 集合特有的迭代器,它用于允许程序员沿着任意方向遍历列表的列表迭代器,在迭代期间修改列表,并获取列表中迭代器的当前位置。

 

 3.增强for循环的使用

        增强 for循环的作用就是用来简化数组和Collection集合的遍历,它实现Iterator 接口的类允许其对象成为增强型for语句的目标,它是JDK5之后出现的,其内部原理是一个Iterator 迭代器。
        增强 for的语法格式如下:
for(元素数据类型 变量名:数组或者 Collection 集合){ 
    // 在此处使用变量即可ꎬ该变量就是元素 
}

4.ArrayList类和Linked List类的使用

        实现 List集合的子类有LinkedList、ArrayList、Vector 和Stack 等,它的常用子类有两个:Array List、Linked List,LinkedList和Array List的用法基本相同,但两者的性能不同,Array List的底层数据结构是数组,LinkedList的底层数据结构是链表,ArrayList 在添加和删除元素时比LinkedList慢,ArrayList  集合在查询元素时比LinkedList 集合要快,ArrayList 实现了可变大小的数组,它允许所有元素,包括 null。

                                               ArrayList的构造方法和常用方法 

 

 四、Set集合

                                                         set常用方法

 五、泛型

 

        泛型是JDK5中引入的特性,它提供了编译时类型安全检测机制,该机制允许在编译时检测到非法的类型,它的本质是参数化类型,也就是说操作的数据类型被指定为一个参数,一提到参数,人们最熟悉的就是定义方法时有形式参数,然后调用该方式时传递实际参数,那么参数化类型就是将类型由原来的具体的类型参数化,然后在使用/ 调用时传入具体的类型, 这种参数类型可以用在类、 方法和接口中, 分别称为泛型类、 泛型方法、 泛型接口, 具体格式如下:
ArrayList<参数化类型> list =new ArrayList<参数化类型>( );

六、设计贪食蛇游戏

1.任务描述
贪食蛇是经典手机游戏,既简单又耐玩,通过控制蛇头方向吃蛋, 使蛇变长,从而获得积分,本案例实现了贪食蛇上、 下、 左、 右来回游动的效果,以此锻炼学生对LinkedList 集合的应用,以及对贪食蛇模块流程的理解,为以后开发功能完整的贪食蛇模块打下良好的基础。
2.任务目标
(1)学会分析“贪食蛇”任务实现的逻辑思路。
(2)能够独立完成“贪食蛇”程序的源代码编写、 编译及运行。
(3)理解LinkedList集合的应用,特别是 LinkedList 集合中的add( )、clear( )、addAll()、getFlrst()、addFirs()、removeList()、contains()、toString()这些方法的应用。
3.实现思路
本程序可分为四个类: 蛇身类、 蛇类、 食物类、 游戏窗体类。
(1)蛇身类具有四个属性ꎬ 分别是: 蛇身宽度、 蛇身高度、 蛇身 x 轴位置、 蛇身 y 轴位置。
(2)蛇类具有四个属性ꎬ 分别是: 蛇身节点、 吃食物的数量、 蛇身初始化节数、 蛇是否存活, 以及六个方法ꎬ,分别是: 移动、 掉头、 控制方向、 咬身体、 撞墙检测、 吃食物。
(3)食物类具有四个属性,分别是: 食物宽度、 食物高度、 食物 x 轴位置、 食物 y 轴位置。
(4)实游现戏代窗码体类具有绘制窗体、 键盘监听和线程调度等功能。
4.实现代码
(1)定义一个蛇身类
package SnakeGame;
import java. util. * ;
class SnakeBody{
    final static int WIDTH = 20;    //蛇身的宽
    final static int HEIGHT = 20;    //蛇身的高
    int x = 0;    //此节蛇身x轴位置
    int y = 0;    //此节蛇身y轴位置

    public SnakeBody ( int a, int b){
        this. x=a;
        this. y=b;
    }
    public SnakeBody (){}
}

(2)定义一个蛇类

 

package SnakeGame;
import java. awt. Color;
import java. awt. Graphics;
import java. awt. Rectangle;
import java. awt. event. KeyEvent;
import java. util. LinkedList;
import java. util. Random;
class Snake{
    //这里不能用父类List做引用,否则使用不了其子类的addFrist和addLast方法
    static LinkedList<SnakeBody> It =new LinkedList<SnakeBody>();//
    SnakeBody sb;     //蛇身节点
    int eatEggs = 0;    //蛇吃掉的蛋的数量
    int number = 5;    //蛇身初始化节数
    boolean isLive;    //蛇是否存活 
    enum Direction{
    Left, Up, Right, Down ;    //方向枚举
    Random rd =new Random();    //随机数
    Direction snakeDirection: SnakeClient se;    //初始化
    public Snake(SnakeClient sn){
        //设蛇存活
        this.isLive = true;
        //初始化蛇身节点,头元素到尾元素在坐标系上呈从左向右分布的一条直线
        for( int i=0, bi = 300; i<= number; i++, bi+= 20){
            It. add( new SnakeBody(bi, 300));
        }
        //初始化蛇身的前进方向,因为蛇头是集合尾,最后打印,所以初始方向不能向左
        //否则就咬到自己的身体,可以向右、上或下
        this. snakeDirection = Direction. Right;
        this. se = sn;
    }
    //蛇移动
    //最后更新头部坐标,若先更新头,身体的坐标会跟头相同,结果只有一个头在运动
    public void movel ()
        //如果蛇死了,就把尸体停留在那儿
        if(this. isLive = =false)
            for( int i=0; iclt. size();i++) {
            It. get(i). x= It. get(i).x;
            It. get(i). y=It. get(i).y;
        }
    }
    //否则就判断移动方向并移动
    else{
        if( this. snakeDirection == Direction. Down){
            for(int i=0;iclt. size() ;i++) {
                if(i==It. size()-1)         //如果是尾元素,即头部 
                {         
                    It. get(i). y+=It. get(i). HEIGHT;     //-个身位 固定20 
                else{    //非头元素
                    It. get(i). x= It. get(i+1). x;
                    It. get(i). y=It. get(i+1).y;
                }
            }
        } 
        else if(this, snakeDirection= = Direction. Up){
            for(int i=0;iclt. size();i++){
            if(i==It. size()-1)         //如果是尾元素,即头部
            {    
                It. get(i). y-= It. get(i). HEIGHT;
            }
            else{    //非头元素
                It. get (i). x=It. get(i+1).x;
                It. get(i). y=It. get(i+1).y; 
            }
        }
    }
    else if ( this, snakeDirection == Direction. Right){ 
        for(int i=0;iclt. size() ;i++) {
            if(i==It. size()-1)    //如果是尾元素,即头部
            {
                It. get(i). x+=It. get(i). HEIGHT;
            }
            else{    //非头元素
                It. get (i). x=It. get(i+1).x;
                It. get (i), y=It. get(i+1). y;
            }    
        }
    }
    else{
        for(int i=0;iclt. size();i++)
            if(i==It. size()-1) //如果是尾元素,即头部
            {
                It. get (i). x-= It. get(i). HEIGHT;
            }
            else{    //非头元素
                 It. get(i). x=It. get(i+1).x;
                 It. get(i). y=It. get(i+1).y;
            }
        }
    }
}
int ti=0;     //这个值指示是否掉头。0:否,1:是
//执行掉头的中间操作
public void huitou(){
    if(ti ==1){
        switch ( this. snakeDirection){
            //掉头操作第二步
            case Up: this. snakeDirection = Direction. Right; ti=0; break;
            case Down: this. snakeDirection=Direction. Left; ti =0; break;
            case Left; this. snakeDirection = Direction. Up; ti=0; break;
            case Right: this, snakeDirection = Direction. Down; ti=0; break;
        }
    }
}
int press=0;     //蛇方向代表的整数
//方向键对蛇的控制
public void keyPress( Key Event e){
    /*注意!这个程序在用户很快速地连续输入两个方向的时候, 
    *比如正在向右前进,快速连续地输入个一或者+时,
    *会原地掉头,如果开启了咬自己的检测,蛇会直接死亡。
    */
    //输入的方向不是蛇运动方向的反方向时,正常接收行动
    //是反方向时,第一步:向当前方向的右手转向;第二步:再执行回头,完成掉头
        switch ( this, snakeDirection) {
            case Left: if(e. getKeyCode()! = KeyEvent. VK_RIGHT) press = e. getKeyCode();
           else{ press= KeyEvent. VK_UP ; ti=1;
            break;
            case Right: if(e. getKeyCode()! = KeyEvent. VK_LEFT) press = e. getKeyCode();
            else {press = KeyEvent. VK_DOWN ; ti =1;
            break;
            case Up: if(e. getKeyCode()! = KeyEvent. VK_DOWN) press = e. getKeyCode();
            else{ press = KeyEvent. VK_RIGHT ;ti=1;
            break;
            case Down: if(e. getKeyCode()! = KeyEvent. VK_UP) press = e. getKeyCode();
            else{ press = KeyEvent. VK_LEFT; ti=1;) break;
        }    
        //等于T1+→四个按键所代表的整数值时,更新蛇的前进方向 
        //如果输入的非方向,无效
        switch ( press){
            case KeyEvent. VK_LEFT:
                this, snakeDirection = Direction. Left;
                break;
            case KeyEvent. VK_UP:
                this. snakeDirection = Direction. Up;
                break;
            case KeyEvent. VK_RIGHT:
                this, snakeDirection = Direction. Right;
                break;
            case KeyEvent. VK_DOWN:
                this. snakeDirection = Direction. Down;
                break;
        }
    }
    //与蛇相关的一切行为在这里发生
    public void paint ( Graphics g)!
        for (SnakeBody sbt: lt)
            //如果是尾元素,渲染成黄色,集合尾是蛇头
            if(It. peekLast(). equals (sbt))|
                g. setColor( Color. yellow);
                g. fillRect (sbt. x, sbt. y,20,20);
            }
            else{
                g. setColor( Color. blue);
                g. fillRect(sbt. x, sbt. y, 20, 20);
            }   
        }   
        movel();     //蛇移动
        huitou();     //检查是否在掉头 
        //eatBody();     //是否咬到身体 
        zhuangqiang();     //是否撞到墙 
        eatFood (this. sc. food);     //是否吃到食物
    }
    //咬身体
    public void eatBody(){
        //遍历蛇身除了头的每一个节点
        //如果蛇头的区域和其他部位的区域重叠,蛇就死亡
        for(int i=0; iclt. size()-1;i++){
            if( getRecHead(). intersects( new Rectangle (It. get (i). x, It.get (i). y,20,20))) 
            this, isLive = false;
        }
    }
    //撞墙检测
    //蛇一个节点20*20 地图900 *800 边界大概宽度4 标题栏大概高度23
    public void zhuangqiang() {
        //当头部节点碰到边界时蛇死亡
        //要额外给一个身位的原因在于,这样才能让蛇贴着边界跑
        //否则用户看见的效果就是蛇头在即将碰到边界之前还来不及操作就死掉了
        if (It. peekLast (). x<4-201 I It. peekLast (). y<23 -20 + 40||It. peekLast ().x>877 + 20||It. peekLast(). y>777+20)
        }
            //蛇死亡,计分板提示并变色
            this. isLive = false;
            sc. Ib1. setText("提示:游戏结束!! (你一共吃到了"+eatEggs+" 个蛋)");
            sc. Ib1. setBackground (Color. red);
        }
    }
    //蛇吃食物
    public void eatFood ( Food fd){
        //头部和食物重叠后
        if ( this. getRec(). intersects(fd. getRec())) eatEggs++;sc. Ibl. setText("你已经吃了" +eatEggs+" 个蛋了");
        //获取旧的头元素
        SnakeBody bodyold = It. peekFirst();
        //集合头部插入新节点
        It. addFirst (new SnakeBody());
        //获取新的头元素
        SnakeBody bodynew = It. peekFirst();
        //判断当前方向
        switch ( this, snakeDirection){
                //头部节点坐标更新,尾巴长度增加 
                //往上走,x轴不变,y轴加长一格+20
                case Up: bodynew. x= bodyold. x; bodynew. y= bodyold. y+20; break;
                //往下走,x轴不变,y轴加长一格-20
case Down: bodynew. x = bodyold. x; bodynew. y= bodyold. y-20; break;
                //往左走,y轴不变,x轴加长一格+20
                case Left: bodynew. x = bodyold. x+20; bodynew. y= bodyold. y; break;
                //往右走,y轴不变,x轴加长一格-20
                case Right: bodynew. x= bodyold. x-20; bodynew. y = bodyold. y; break;
            }        
            //重置食物的坐标 
            sc. food. reFood();
        }
    }
    //返回蛇头上一节的区域,用来检测是否吃到食物
    public Rectangle getRec()
        //之所以不用蛇头的区域检测是否吃到食物,是因为那样看起来蛇头还没碰到食物,食物就消失了
        return new Rectangle ( It. get( It. size() -2). x, It. get ( It. size()-2). y, It. peekFirst (). WIDTH.It. peekFirst (). HEIGHT);
        } 
    //返回蛇头区域
    public Rectangle getRecHead()
        return new Rectangle ( It. peekLast(). x, It. peekLast(). y, 20,20);
     }
}

 

(3)定义一个食物类

 

package SnakeGame;
import java. awt. Color;
import java. awt. Graphics;
import java. awt. Rectangle;
import java. util. Random;
class Food{
    public static int WIDTH = 20;
    public static int HEIGHT = 20;
    int x,y;    //食物出现的地点
    SnakeClient ms;
    Random rd =new Random();
    public Food(SnakeClient ms){
        reFood();
        this. ms = ms;
    }
    //重新设置食物坐标 
    public void reFood()
        //标题栏高度23,边界宽度4,计分板高度约为2倍的标题栏高度
        //经测试,地图为900*800 时,x=877、y=777是食物在地图的右下角位置
        //而x=4、y=67是在左上角的位置
        int num2=rd. nextlnt( 877); //食物x坐标的最大值 877
        if(num2<4) num2= num2+(4-num2); //避免食物有一部分处在边界里,x坐标要大于4 x=num2;
        int num=rd. nextlnt(777); //食物y坐标的最大值 777 
        if(num<67) num=num+(67-num); //避免刷新在标题栏或者计分板里,y坐标要大于67 
        y=num;
    }
    public int getX(){
        return x;
    }
    public void setX(int x){
        this. x = x;
    }
    public int getY(){ 
        return y;
    }
    public void setY (int y) {
        this. y = y;
    }
    //绘制食物
    public void paint( Graphics g){
        g. setColor( Color. red);
        g. fillRect(x, y, WIDTH, HEIGHT);
    }
    public Rectangle getRee()
        //返回食物的区域
        return new Rectangle(x, y, WIDTH, HEIGHT);
    }
}

 

(4)定义一个游戏窗体类

 

package SnakeGame;
import java. awt. * ;
import java. awt. event. * ;
class SnakeClient extends Frame {
    Snake mySnake = new Snake (this);
    Food food = new Food( this);
    //新建label控件作为计分板
    Label lbl =new Label("E经吃了" +mySnake. eatEggs+"了");
    //新建容器
    Panel p=new Panel();
    public SnakeClient(){
        //绘制地图窗体
        this. setBounds (0,0, 900, 800);     //窗体坐标和大小 
        this. setTitle("贪食蛇");     //窗体标题
        this. setBackground (Color. BLACK);     //窗体背景颜色 
        //实现点击“x”图标关闭窗体的功能,
        this. addWindowListener(new WindowAdapter() {
            public void windowClosing( WindowEvent e){
                System. exit(-1);
            }
        });
        setResizable(false);     //设置地图窗体大小不可调整
        //加入得分信息
        Ib1. setAlignment(1); //设置label控件的文本居中显示
        p. add(lbl);     //容器p加入一个label控件
        p. setBackground (Color. GREEN);     //容器p设为黄色背景色
        this. setLayout ( new GridLayout (7,1,50,80));     //地图设置成7行1列,水平50,垂直80
        p. setLayout ( new GridLayout(1,1));    //容器p设置成1行1列 
        this. add(p);     //地图中加入容器p
        this. setVisible(true);     //图窗体设为显示
    }
    //开启线程和打开键盘监视
    public void lanch(){
        this. addKeyListener( new KeyMointer());     //调用键盘,不启用这个无法开启键盘控制 
        new Thread (new PaintThread() ). start();     //开启线程
    }
    //线程执行的方法,repaint方法会执行该方法
    public void paint( Graphics g) {
        mySnake. paint(g);
        food. paint (g);
    }
    //线程控制
    class PaintThread implements Runnable {
        public void run(){
            //保持蛇能一直运行 
            while(true){
                repaint();
                try{
                    //物体运行太快,减慢速度,使肉眼能跟上刷新速度
                    Tread. sleep(90) ;
                }catch (InterruptedException e){
                    e. printStackTrace();
                }
            }
        }
    }
        //键盘监听
    class KeyMointer extends KeyAdapter{
        public void keyPressed ( KeyEvent e){
            mySnake. keyPress(e);
        }
    }
    public static void main ( String[] args){
        SnakeClient snakeClient = new SnakeClient();
        snakeClient. lanch () ;
    }
}

 

5.运行结果

 

 

posted @ 2022-09-27 21:54  史华月  阅读(160)  评论(0)    收藏  举报