求解答以下的java源代码,详细点,说明这个程序的设计思路,还有比如运用了多线程的话运用了多线程的啥
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了求解答以下的java源代码,详细点,说明这个程序的设计思路,还有比如运用了多线程的话运用了多线程的啥相关的知识,希望对你有一定的参考价值。
回答满意追加到200分
import java.awt.*;import java.awt.event.*;
import java.util.Random;
import javax.swing.Timer;
public class PinBall
private final int TABLE_WIDTH = 300;//桌面宽度
private final int TABLE_HEIGHT = 400;//桌面高度
private final int RACKET_Y = 340;//球拍的垂直位置
private final int RACKET_HEIGHT = 20;//球拍高度
private final int RACKET_WIDTH = 60;//球拍宽度
private final int BALL_SIZE = 16;//球的大小
private Frame f = new Frame("弹球游戏");//实例化一个窗口
Random rand = new Random();//实例化一个随机数生成器
private int ySpeed = 10;//小球的纵向运动数度、
private double xyRate = rand.nextDouble() - 0.5;//返回一个-0.5到0.5之间的比率用控制小球运动方向
private int xSpeed = (int)(ySpeed*xyRate*2);//这个横向速度在-10到10之间,产生左右摆动运动效果
private int ballX = rand.nextInt(200)+20;//小球开始的横坐标位置,200表示产生0到100之间的随机数
private int ballY = rand.nextInt(10)+20;//小球开始的纵坐标位置
private int racketX = rand.nextInt(200);//球拍开始时的横坐标位置
private MyCanvas tableArea = new MyCanvas();//实力化一个画布工具,集成Canvas类
private String shape = "";//保存需要绘制图形的字符串属性
Timer timer;//声明一个时间变量
private boolean isLose = false;//表示游戏是否结束
public void init()
tableArea.setPreferredSize(new Dimension(TABLE_WIDTH,TABLE_HEIGHT));//定义画布大小
f.add(tableArea);//添加画布到窗口
KeyAdapter keyProcessor = new KeyAdapter()//实例化一个键盘监听事件适配器
public void keyPressed(KeyEvent ke)//重写适配器里面的按下某键盘方法
if(ke.getKeyCode()==KeyEvent.VK_LEFT)//按下键盘左键时
if(racketX > 0)//球拍左边框不能出画布的左边框
racketX -=10;//按一左键次向左移动10个像素
if(ke.getKeyCode()==KeyEvent.VK_RIGHT)//按下键盘右键时
if(racketX < TABLE_WIDTH - RACKET_WIDTH)//球拍右边框不能出画布的右边框
racketX +=10;//按一次右键移动向右移动10个像素
;
f.addKeyListener(keyProcessor);//给窗口添加键盘监听器
tableArea.addKeyListener(keyProcessor);//给画布添加键盘监听器
ActionListener taskPerformer = new ActionListener()//这里是实例化了一个监听接口,这个接口里面只有一个方法
public void actionPerformed(ActionEvent evt)//重写这个接口里面的方法,判断小球的位置
if(ballX<=0 || ballX>=TABLE_WIDTH-BALL_SIZE)//保证小球横向上在画布之内运动
xSpeed = -xSpeed;//触发反方向运动
if(ballY>=RACKET_Y-BALL_SIZE&&(ballX<racketX||ballX>racketX+RACKET_WIDTH))//出了球拍的可击打范围
timer.stop();//停止对监听器的触发
isLose=true;//将标志isLose变量置为true
tableArea.repaint();//调用画布的重绘方法
else if(ballY<=0||(ballY>=RACKET_Y-BALL_SIZE&&ballY>racketX&&ballX<=racketX+RACKET_WIDTH))//小球在球拍之内,而其到达球拍的高度
ySpeed=-ySpeed;//上下方向改变,小球反弹
ballY+=ySpeed;//小球的坐标在纵向上增加
ballX+=xSpeed;//小球的坐标在横向上的增加
tableArea.repaint();//调用画布的重绘方法3
;
timer = new Timer(100,taskPerformer);//每隔0.1秒运行一次监听器
timer.start();//计时器开始运行
f.addWindowListener(new MyListener());//关闭窗口事件
f.pack();//设置窗口最佳大小
f.setVisible(true);//显示窗口
class MyListener extends WindowAdapter//关闭窗口的类
public void windowClosing(WindowEvent e)
System.exit(0);
public static void main(String[] args)//程序入口
new PinBall().init();//调用PinBall类里面的init()方法
class MyCanvas extends Canvas//建一个集成Canvas类的类
public void paint(Graphics g)//重写父类的绘图方法
if(isLose)//如果isLose为真,则在画布里打印“游戏已结束”
g.setColor(new Color(255,0,0));//当前颜色
g.setFont(new Font("黑体",Font.BOLD,30));//字体名称,样式,大小
g.drawString("游戏已结束!",50,200);//按坐标绘制文字图形
else//负责
g.setColor(new Color(240,240,80));//当前颜色
g.fillOval(ballX,ballY,BALL_SIZE,BALL_SIZE);//填充颜色,根据坐标和长宽填充圆形
g.setColor(new Color(80,80,200));//当前颜色
g.fillRect(racketX,RACKET_Y,RACKET_WIDTH,RACKET_HEIGHT);//填充颜色,根据坐标和长宽填充矩形
追问
就是这个源码,求解
参考技术A 很简单的一个碰撞事件监听程序一堆private静态属性定义了桌面的宽高,球拍Y坐标,球拍的高宽以及球的大小,加final表示静态数值不可变
Frame f = new Frame("弹球游戏");实例化窗口,即运行程序时所见到的窗口
随机数的生成应该算是本程序的精华了,这个你得注意
Random rand = new Random();//实例化一个随机数生成器
private int ySpeed = 10;//小球的纵向运动数度、
这两行没什么
private double xyRate = rand.nextDouble() - 0.5;
rand.nextDouble()只是从0到1之间的小数,xyRate的取值范围在-0.5到0.5之间,通过正负判断移动方向
private int xSpeed = (int)(ySpeed*xyRate*2);X方向上的移动方向和速度,同样方向通过正负判断
private int ballX = rand.nextInt(200)+20;//小球开始的横坐标位置,200表示产生0到100之间的随机数
private int ballY = rand.nextInt(10)+20;//小球开始的纵坐标位置
通过(ballX,ballY)坐标显示小球的初始位置
private int racketX = rand.nextInt(200);球拍初始位置,Y坐标固定X随机取值
Timer timer;//声明一个时间变量 这是一个记时器,后面会用到
init()方法初始化
有注释就不一一说明了,加了个键盘事件监听器,ke.getKeyCode()==KeyEvent.VK_RIGHT通过ke值判断按下的左或右键控制球拍的左右移动
ActionListener taskPerformer = new ActionListener()//这里是实例化了一个监听接口并重写了接口里的actionPerformed(ActionEvent evt)方法
actionPerformed(ActionEvent evt)判断小球的位置
if(ballX<=0 || ballX>=TABLE_WIDTH-BALL_SIZE) if语句控制xSpeed的正负,保证小球在水平方向上不跑出画布
if(ballY<=0||(ballY>=RACKET_Y-BALL_SIZE&&ballY>racketX&&ballX<=racketX+RACKET_WIDTH))判断小球与画布上边界或球拍碰撞ySpeed改变正负,小球反方向运动
timer = new Timer(100,taskPerformer);记时器在这里起作用了,每100毫秒触发taskPerformer里的actionPerformed(ActionEvent evt)方法执行一次,产生小球的移动效果 参考技术B 解答的java源码在哪儿呢?
字符编码Java字符编码详细解答及问题探讨
一、前言
继上一篇写完字节编码内容后,现在分析在Java中各字符编码的问题,并且由这个问题,也引出了一个更有意思的问题,笔者也还没有找到这个问题的答案。也希望各位园友指点指点。
二、Java字符编码
直接上代码进行分析似乎更有感觉。
运行结果:
说明:通过结果我们知道如下信息。
1. 在Java中,中文在用ASCII码表示为3F,实际对应符号\'?\',用ISO-8859-1表示为3F,实际对应符号也是为\'?\',这意味着中文已经超出了ASCII和ISO-8859-1的表示范围。
2. UTF-16采用大端存储,即在字节数组前添加了FE FF,并且FE FF也算在了字符数组长度中。
3. 指定UTF-16的大端(UTF-16BE)或者小端(UTF-16LE)模式后,则不会有FE FF 或 FF FE控制符,相应的字节数组大小也不会包含控制符所占的大小。
4. Unicode表示与UTF-16相同。
5. getBytes()方法默认是采用UTF-8。
三、char表示问题
我们知道,在Java中char类型为两个字节长度,我们来看下一个示例。
public class Test { public static void main(String[] args) throws Exception { char ch1 = \'a\'; // 1 char ch2 = \'李\'; // 2 char ch3 = \'\\uFFFF\'; // 3 char ch4 = \'\\u10000\'; // 4 } }
问题:读者觉得这样的代码能够编译通过吗?如不能编码通过是为什么,又具体是那一行代码出现了错误?
分析:把这个示例拷贝到Eclipse中,定位到错误,发现是第四行代码出现了错误,有这样的提示,Invalid character constant。
解答:问题的关键就在于char类型为两个字节长度,Java字符采用UTF-16编码。而\'\\u10000\'显然已经超过了两个字节所能表示的范围了,一个char无法表示。说得更具体点,就是char表示的范围为Unicode表中第零平面(BMP),从0000 - FFFF(十六进制),而在辅助平面上的码位,即010000 - 10FFFF(十六进制),必须使用四个字节进行表示。
有了这个理解后,我们看下面的代码
public class Test { public static void main(String[] args) throws Exception { char ch1 = \'a\'; char ch2 = \'李\'; char ch3 = \'\\uFFFF\'; String str = "\\u10000"; System.out.println(String.valueOf(ch1).length()); System.out.println(String.valueOf(ch2).length()); System.out.println(String.valueOf(ch3).length()); System.out.println(str.length()); } }
运行结果:
1 1 1 2
说明:从结果我们可以知道,所有在BMP上的码点(包括\'a\'、\'李\'、\'\\uFFFF\')的长度都是1,所有在辅助平面上的码点的长度都是2。注意区分字符串的length函数与字节数组的length字段的差别。
四、问题的发现
在写Java小程序时,笔者一般不会打开Eclispe,而是直接在NodePad++中编写,然后通过javac、java命令运行程序,查看结果。也正是由于这个习惯,发现了如下的问题,请听笔者慢慢道来,来请园友们指点指点。
有如下简单程序,请忽略字符串的含义。
public class Test { public static void main(String[] args) throws Exception { String str = "我我我我我我我\\uD843\\uDC30"; System.out.println(str.length()); } }
说明:程序功能很简单,就是打印字符串长度。
4.1 两种编译方法
1. 笔者通过javac Test.java进行编译,编译通过。然后通过java Test运行程序,运行结果如下:
说明:根据结果我们可以推测,字符\'我\'为长度1,\\uD843\\uDC30为长度10,其中\\u为长度1。
2. 笔者通过javac -encoding utf-8 Test.java进行编译,编译通过。然后通过java Test运行程序,运行结果如下:
说明:这个结果很好理解,字符\'我\'、\\uD843、\\uDC30都在BMP,都为长度1,故总共为9。
通过两种编译方法,得到的结果不相同,经过查阅资料知道javac Test.java默认的是采用GBK编码,就像指定javac -encoding gbk Test.java进行编译。
4.2. 查看class文件
1. 查看java Test.java的class文件,使用winhex打开,结果如下:
说明:图中红色标记给出了字符串"我我我我我我我\\uD843\\uDC30"大致所在位置。因为前面我们分析过,class文件的存储使用UTF-8编码,于是,先算E9 8E B4,得到Unicode码点为94B4(十六进制),查阅Unicode表,发现表示字符为\'鎴\',这完全和\'我\'没有关系。并且E9 8E B4 后面的E6 88 9E,和E9 8E B4也不相等,照理说,相同的字符编码应该相同。后来发现,红色标记地方好像有点规则,就是E9 8E B4 E6 88 9E E5 9E 9C(九个字节)表示\'我我\',重复循环了3次,表示字符\'我我我我我我\',之后的E9 8E B4 E6 85(五个字节)表示\'我\',总共7个\'我\',很明显又出现疑问了。
猜测是因为使用javac Test.java进行编译,采用的是GBK编码,而class文件存储的格式为UTF-8编码。这两种操作中肯定含有某种转化关系,并且最后的class文件中也加入相应的信息。
2. 查看java -encoding -utf-8 Test.java的class文件,使用winhex打开,结果如下:
说明:红色标记给出了字符串的大体位置,E6 88 91,经过计算,确实对应字符\'我\'。这是没有疑问的。
4.3 针对疑问的探索
1. 又改变了字符串的值,使用如下代码:
public class Test { public static void main(String[] args) throws Exception { String str = "我我coder"; System.out.println(str.length()); } }
同样,使用javac Test.java、java Test命令。得到结果为:
这就更加疑惑了。为什么会得到8。
2. 查阅资料结果
在Javac时,若没有指定-encoding参数指定Java源程序的编码格式,则javac.exe首先获得我们操作系统默认采用的编码格式,也即在编译java程序时,若我们不指定源程序文件的编码格式,JDK首先获得操作系统的file.encoding参数(它保存的就是操作系统默认的编码格式,如WIN2k,它的值为GBK),然后JDK就把我们的java源程序从file.encoding编码格式转化为Java内部默认的UTF-16格式放入内存中。之后会输出class文件,我们知道class是以UTF-8方式编码的,它内部包含我们源程序中的中文字符串,只不过此时它己经由file.encoding格式转化为UTF-8格式了。
五、问题提出
1. 使用javac Test.java编译后,为何会得到上述class文件的格式(即GBK -> UTF16 -> UTF8具体是如何实现的)。
2. 使用javac Test.java编译后,为何得到的结果一个是17,而另外一个是8。
六、总结
探索的过程有很意思,这个问题暂时还没有解决,以后遇到该问题的答案会贴出来,也欢迎有想法的读者进行交流探讨。谢谢各位园友的观看~
参考链接:
http://blog.csdn.net/xiunai78/article/details/8349129
以上是关于求解答以下的java源代码,详细点,说明这个程序的设计思路,还有比如运用了多线程的话运用了多线程的啥的主要内容,如果未能解决你的问题,请参考以下文章
Ubuntu 虚拟机上遇到以下提示,不知道是什意思,求解答,谢谢!