不知道对于遇到墙反弹这个任务你的思路是什么,我们还是先分解任务:第一步,做个窗体;第二步,做个小球;第三部,让小球斜着飞;第四步,遇到墙反弹。我们不会的就是第四步而已。
class MyPanel extends Panel implements Runnable{
int x=30;
int y=30;
public void paint(Graphics g){
g.fillOval(x,y,20,20);
}
public void run(){
while(true){
x++;
y++;
if(x>300){
x--;
y++;
}
try{
Thread.sleep(30);
}catch(Exception e){}
repaint();
}
}
}
怎么样,没成吧?小球并没有反弹,而是消失在右边的墙里面了,我们分析一下为什么会这样。我们判断墙的代码是if(x>300){},问题是小球的坐标是左上角的坐标,如果用x和300比较,必须是整个小球都进入了右边的墙里面,才能够符合条件,加上设置窗体大小为300,400,这个值指的是窗体整体的大小,修正为if(x<263),上面这段代码,小球仍然不飞,当小球在墙的边缘时,就是x=263,代码遇到x++和y++以后,x=264,是不是不符合if的条件。 问题:虽然x--了,但是立刻又被++回去,结果x的值一直不变,y以两倍的速度变大,小球贴着墙边滑落下去了,也就是说,我们减x的值,就不要再加了。
改完之后,还是不行,当小球反弹后,便离开墙,一旦离开墙,反弹的条件就不满足了 ,在程序设计过程,我们常常在逻辑遇到困难的时候,想到通过增加变量来解决问题,根据上面的描述,我们增加一个变量来存储当前的飞行状态,并且事先这样来定义。
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Panel;
public class MyBall{
public static void main(String args[]){
Frame w=new Frame();
w.setSize(300,400);
MyPanel mp=new MyPanel();
w.add(mp);
Thread t=new Thread(mp);
t.start();
w.setVisible(true);
}
}
class MyPanel extends Panel implements Runnable{
int x=30;
int y=30;
int att=0;//0就是右下,1就是左下,2就是左上,3就是右上
public void paint(Graphics g){
g.fillOval(x,y,20,20);
}
public void run(){
while(true){
//定义飞行状态
if(x>263){
if(att==0){
att=1;
}else{
att=2;
}
}
if(y>341){
if(att==1){
att=2;
}else att=3;
}
if(x<0){
if(att==2){
att=3;
}else att=0;
}
if(y<0){
if(att==3){
att=0;
}else att=1;
}
//改变飞行状态
if(att==0){
x++;
y++;
}
if(att==1){
x--;
y++;
}
if(att==2){
x--;
y--;
}
if(att==3){
x++;
y--;
}
try{
Thread.sleep(30);
}catch(Exception e){}
repaint();
}
}
}