java大概整体的框架
import acm.graphics.*;
//一般程序的开头,导入包(一组类),然后在程序中可以使用包里的类。
public class Arkanoid extends GraphicsProgram {
//public,访问修饰符/class,类声明/类名/extends,继承的意思/extends GraphicsProgram,继承GraphicsProgram这个父类
/* 动画每一帧间隔10ms*/
private static final double DELAY = 100 / 6;
//final赋值一个常量时前面需要加上保留字final
/* 初始水平速度:每一帧水平方向的移动距离 */
private static final double VELOCITY_Y = 10;
/* 初始竖直速度:每一帧竖直方向的移动距离 */
private static final double VELOCITY_X = 10;
/* 小球的半径 */
private static final int BALL_RADIUS = 15;
/* 小球的颜色 */
private static final Color BALL_COLOR = Color.black;
//Color BALL_COLOR,BALL—COLOR是一个color类的变量,带有类Color的属性。
//color.black;原点运算,调用color中的black方法
/* 小球 */
GOval ball;
//定义一个GOval类型的变量ball。
/* 小球此刻的水平速度 */
double vx;
/* 小球此刻的竖直速度 */
double vy;
声明一个类以及父类或者interface(接口),接着对成员变量赋值。
public void init() {
//对成员变量赋值后,下面都是希望执行的函数,或者说方法,行为,动作。/init()来自父类,父类在main()的方法中定义程序先从init运行。
//认识一个函数,函数的组成:
makeBricks();
//调用函数makeBricks()
makeBall(); // 往屏幕上添加小球
//...
vx = randomGenerator.nextInt(-20, 20); // 水平速度
//randomGenerator.nextInt(-20,20),调用randomGenerator中的nextInt(-20,20)方法
vy = VELOCITY_Y; // 竖直速度
}
函数的组成:修饰符+返回类型+函数名(提供给函数的参数);public void init(),void表示不需要返回
public void run() {
// 等待用户点击
waitForClick();
//调用的函数可以来自父类
//noinspection InfiniteLoopStatement
while (true) {
checkCollision();
//调用函数,这个函数是检测小球碰撞的。如果小球碰到墙,在这个函数中改变了小球的方向
// 移动小球的位置
ball.move(vx, vy);
//调用ball的move()函数,ball是程序开头类GOval定义的。
breakBricks();
//调用这个函数
// 延迟
pause(DELAY);
}//循环,程序都是逻辑分明的,所有东西都是一步步来的
}//run()函数来自父类,定义init()后接着运行润run()
void checkCollision() {
//函数
// 小球碰到上下两侧的墙,竖直反弹
if (hitBottomWall()) {
//if 调用函数,这个函数的返回类型是boolean,等于truer时运行{}中的程序
vy = -VELOCITY_Y;
} else if (hitTopWall()) {
vy = VELOCITY_Y;
}
// 小球碰到左右两侧的墙,水平反弹
if (hitLeftWall()) {
//if (true)也可以执行。
vx = VELOCITY_X;
} else if (hitRightWall()) {
vx = -VELOCITY_X;
}
}
boolean hitBottomWall() {
//函数的返回值是boolean类型
return ball.getY() > getHeight() - ball.getWidth();
}
前部程序调用到的三个函数
public void makeBall() {
double size = BALL_RADIUS * 2;
ball = new GOval(size, size);
//new新建一个对象
// 设置小球为实心
ball.setFilled(true);
// 填充颜色是黑色
ball.setColor(BALL_COLOR);
// 添加到画布上(20,20)的位置
add(ball, A, B);
}
public void makeBricks() {
// 一堆黑色的砖块
for (int i = 0; i < 6; i++) {
///for循环语句/赋值0给int类型的变量i;i<6的时候运行{},并i++,也就是自增1
for (int j = 0; j < 7; j++) {
brick = new GRect(BRICK_WIDTH, BRICK_HEIGHT);
brick.setFilled(true);
brick.setColor(BRICK_COLOR);
int x = j * (BRICK_MARGIN * 2 + BRICK_WIDTH) + BRICK_MARGIN;
int y = i * (BRICK_MARGIN * 2 + BRICK_HEIGHT) + BRICK_MARGIN;
add(brick, x, y);
//添加砖块的位置
}
}
}
GObject getCollidingObject() {
//getCollidingObject()函数,返回的类型是GObject
GObject obj1 = getElementAt(ball.getX(), ball.getY());
//getElementAt(x,y),获取位置x,y上的要素,图形
GObject obj2 = getElementAt(ball.getRightX(), ball.getY());
GObject obj3 = getElementAt(ball.getX(), ball.getBottomY());
GObject obj4 = getElementAt(ball.getRightX(), ball.getBottomY());
if (obj1 != null) {
//!=等价于不等于
return obj1;
} else if (obj2 != null) {
return obj2;
} else if (obj3 != null) {
return obj3;
} else if (obj4 != null) {
return obj4;
} else {
return null;
}
}
public void breakBricks() {
if (getCollidingObject() != null) {
//getCollidingObject()在上文中返回的是 GObject类型的数据
remove(getCollidingObject());
vy = -vy;
}
}
}
成员变量或者也可以说全局变量,写在类中函数外面,一般写在程序开头。局部变量写在函数中,随着函数进栈出栈生成和销毁。
另一个线程
添加addMouseListeners();/鼠标监听后,倒像是添加了一个线程,在函数中不随着函数的进栈出栈而丢失。
通过addMouseListeners启用鼠标后,每当检测到鼠标移动时,都会自动调用这个函数
public void mouseMoved(MouseEvent e) {
///函数名不可改变,像是特定的
paddle.setLocation(e.getX(), e.getY());
}
null和remove
ball = null;和remove(ball)。两者不一样的,把变量等于null的时候,屏幕上的ball并没有消失。remove(ball),删除了屏幕上的小球,但ball这个变量还存在??
两块砖不能一起跟随鼠标的问题
paddle = new GRect(100, 15);
每生成一个新的GRect对象,内存就放弃跟踪前一个GRect对象,只跟踪新的对象。