这次作业是设计一个很有意思的小游戏。

  • problem1:
    这题还是比较简单的,只要看一下课本第10章即可。
/*
 * File: MouseReporter.java
 * -----------------------------
 * Output the location of the mouse to a label on the
 * screen. Change the color of the label to red when
 * the mouse touches it.
 */

import java.awt.Color;
import java.awt.event.MouseEvent;

import acm.graphics.*;
import acm.program.*;

public class MouseReporter extends GraphicsProgram {

	// A constant for the x value of the label
	private static final int INDENT = 20;
	
	// This variable is visible to the entire program
	// It is called an "instance" variable
	private GLabel label = new GLabel("");
	
	public void run() {	
		// this code already adds the label to the screen!
		// run it to see what it does.
		label.setFont("Courier-24");
		label.setColor(Color.BLUE);
		
		// this setLabel method takes in a "String" 
		// you can concatenate integers and commas as such:
		label.setLabel(0 + "," + 0);
		
		// add the label to the screen!
		add(label, INDENT, getHeight()/2);
		
		addMouseListeners();
		//GObject getElementAt(double x,double y);
	}
	
	public void mouseMoved(MouseEvent e) {
		last = new GPoint(e.getPoint());
		gobj = getElementAt(last);
		label.setLabel(e.getX()+","+e.getY());
		if(gobj!=null) {
			label.setColor(Color.RED);
		}
	}
	
	private GObject gobj;
	private GPoint last;

}
  • problem2:


这题刚看的时候确实比较复杂,但是只要根据作业的讲义一步步来就可以了,这里添加了一些补充功能,如声音,计分等等。

/*
 * File: Breakout.java
 * -------------------
 * Name:
 * Section Leader:
 * 
 * This file will eventually implement the game of Breakout.
 */

import acm.graphics.*;
import acm.program.*;
import acm.util.*;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.*;

public class Breakout extends GraphicsProgram {

	// Dimensions of the canvas, in pixels
	// These should be used when setting up the initial size of the game,
	// but in later calculations you should use getWidth() and getHeight()
	// rather than these constants for accurate size information.
	public static final double CANVAS_WIDTH = 420;
	public static final double CANVAS_HEIGHT = 600;

	// Number of bricks in each row
	public static final int NBRICK_COLUMNS = 10;

	// Number of rows of bricks
	public static final int NBRICK_ROWS = 10;

	// Separation between neighboring bricks, in pixels
	public static final double BRICK_SEP = 4;

	// Width of each brick, in pixels
	public static final double BRICK_WIDTH = Math.floor(
			(CANVAS_WIDTH - (NBRICK_COLUMNS + 1.0) * BRICK_SEP) / NBRICK_COLUMNS);

	// Height of each brick, in pixels
	public static final double BRICK_HEIGHT = 8;

	// Offset of the top brick row from the top, in pixels
	public static final double BRICK_Y_OFFSET = 70;

	// Dimensions of the paddle
	public static final double PADDLE_WIDTH = 60;
	public static final double PADDLE_HEIGHT = 10;

	// Offset of the paddle up from the bottom 
	public static final double PADDLE_Y_OFFSET = 30;

	// Radius of the ball in pixels
	public static final double BALL_RADIUS = 10;

	// The ball's vertical velocity.
	public static final double VELOCITY_Y = 3.0;

	// The ball's minimum and maximum horizontal velocity; the bounds of the
	// initial random velocity that you should choose (randomly +/-).
	public static final double VELOCITY_X_MIN = 1.0;
	public static final double VELOCITY_X_MAX = 3.0;

	// Animation delay or pause time between ball moves (ms)
	public static final double DELAY = 1000.0 / 60.0;

	// Number of turns 
	public static final int NTURNS = 3;
	
	public void run() {
		// Set the window's title bar text
		setTitle("CS 106A Breakout");

		// Set the canvas size.  In your code, remember to ALWAYS use getWidth()
		// and getHeight() to get the screen dimensions, not these constants!
		setCanvasSize(CANVAS_WIDTH, CANVAS_HEIGHT);
		
		//增加声音
		Setupbricks();
		Setuppaddle();
		Setupball();
		}
	
	private void Setupbricks() {
		for(int i=0;i<NBRICK_ROWS;i++) {
			for(int j=0;j<NBRICK_COLUMNS;j++) {
				GRect a=new GRect(BRICK_SEP+j*(BRICK_SEP+BRICK_WIDTH),BRICK_Y_OFFSET+i*(BRICK_SEP+BRICK_HEIGHT),
						BRICK_WIDTH,BRICK_HEIGHT);
				a.setFilled(true);
				switch(i/2) {
				case 0:
					a.setColor(Color.RED);
					break;
				case 1:
					a.setColor(Color.ORANGE);
					break;
				case 2:
					a.setColor(Color.YELLOW);
					break;
				case 3:
					a.setColor(Color.GREEN);
					break;
				case 5:
					a.setColor(Color.CYAN);
					break;
				}
				add(a);	
			}
		}
	}
	
	private void Setuppaddle() {
		paddle=new GRect((getWidth()-PADDLE_WIDTH)/2,getHeight()-PADDLE_Y_OFFSET-PADDLE_HEIGHT,
				PADDLE_WIDTH,PADDLE_HEIGHT);
		paddle.setFilled(true);
		add(paddle);
		addMouseListeners();
	}
	
	public void mouseMoved(MouseEvent e) {
		double x=e.getX();
		double y=e.getY();
		paddle.move(x-paddle.getX(), 0);
		//paddle.move(x-paddle.getX(), y-paddle.getY());
	}
	
	private void Setupball() {
		//初始化球
		ball =new GOval(getWidth()/2-BALL_RADIUS,getHeight()/2-BALL_RADIUS,BALL_RADIUS*2,BALL_RADIUS*2);
		ball.setFilled(true);
		add(ball);
		//初始化速度
		vx=rgen.nextDouble(VELOCITY_X_MIN , VELOCITY_X_MAX);
		if (rgen.nextBoolean(0.5)) vx = -vx;
		vy=VELOCITY_Y;
		
		//增加声音
		AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");
		
		//增加分数
		score=new GLabel("Your score is:"+0);
		add(score,(getWidth()-score.getWidth())/2,20);
		
		while(true) {			
			//移动球
			moveball();
			//判断是否碰壁
			checkForCollision();
			//碰到底部结束
			if(ball.getY()>getHeight()-2*BALL_RADIUS) {
				GLabel label=new GLabel("You Lose!");
				add(label,(getWidth()-label.getWidth())/2,(getHeight()-label.getHeight())/2);
				break;
			}
			//判断是否碰到物体
			GObject collider=getCollidingObject();
			if(collider==paddle) {
				bounceClip.play();
				vy=-vy;
			}else if(collider!=null) {
				bounceClip.play();
				remove(collider);
				vy=-vy;
				count++;
				remove(score);
				score=new GLabel("Your score is:"+count);
				add(score,(getWidth()-score.getWidth())/2,20);
				//每7次增加速度
				if(count>0 && count%7==0) {
					vx=2*vx;
					vy=2*vy;
				}
				//全部完成
				if(count==NBRICK_COLUMNS*NBRICK_ROWS) {
					GLabel label=new GLabel("You Win!");
					add(label,(getWidth()-label.getWidth())/2,(getHeight()-label.getHeight())/2);
					break;
				}
			}
		}
	}
	
	//移动球
	private void moveball() {
		ball.move(vx, vy);
		pause(speed);
	}
	
	//判断是否碰壁
	private void checkForCollision() {
		AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");
		if(ball.getX()>getWidth()-2*BALL_RADIUS || ball.getX()<0){
			vx=-vx;
			bounceClip.play();
		}
		
		if(ball.getY()>getHeight()-2*BALL_RADIUS || ball.getY()<0) {
			vy=-vy;
			bounceClip.play();
		}
	}
	
	//判断是否碰到物体
	private GObject getCollidingObject() {
		double x=ball.getX();
		double y=ball.getY();
		if(getElementAt(x,y)!=null) {
			return getElementAt(x,y);
		}else if(getElementAt(x+2*BALL_RADIUS,y)!=null) {
			return getElementAt(x+2*BALL_RADIUS,y);
		}else if(getElementAt(x+2*BALL_RADIUS,y+2*BALL_RADIUS)!=null) {
			return getElementAt(x+2*BALL_RADIUS,y+2*BALL_RADIUS);
		}else {
			return getElementAt(x,y+2*BALL_RADIUS);
		}
	}
	
	//底部物块
	private GRect paddle;
	//速度
	private double vx, vy;
	//随机数生成器
	private RandomGenerator rgen = RandomGenerator.getInstance();
	//球
	private GOval ball;
	//记录得分
	private int count=0;
	//得分标签
	private GLabel score;
	//速度
	private int speed=10;
}