4.5打砖块游戏
package view;
import java.awt.Color;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Panel;
import java.awt.Point;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
public class GameFrame {
public GameFrame(){
Frame f=new Frame("Block Game");
GamePanel gp=new GamePanel();
Thread t=new Thread(gp);
t.start();
f.setLocation(100,100);
f.setSize(500,500);
f.add(gp);
f.setVisible(true);
}
public static void main(String args[]){
new GameFrame();
}
}
class GamePanel extends Panel implements KeyListener,Runnable{
private Pad p;
private Block bl;
private Ball bal;
int width=500;
int height=500;
public boolean padMoveRight;
public boolean padMoveLeft;
public boolean ballMove;
public GamePanel(){
p=new Pad(this);
bl=new Block(this);
bal=new Ball(this,p,bl);
addKeyListener(this);
}
public void gameUpdate(){
p.update();
bl.update();
bal.update();
}
public void paint(Graphics g){
p.draw(g);
bl.draw(g);
bal.draw(g);
}
@Override
public void keyTyped(KeyEvent e) {
// TODO 自动生成的方法存根
}
@Override
public void keyPressed(KeyEvent e) {
// TODO 自动生成的方法存根
int keycode=e.getKeyCode();
if(keycode==KeyEvent.VK_LEFT){
padMoveLeft=true;
}
if(keycode==KeyEvent.VK_RIGHT){
padMoveRight=true;
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO 自动生成的方法存根
int keycode=e.getKeyCode();
if(keycode==KeyEvent.VK_RIGHT){
padMoveRight=false;
}
if(keycode==KeyEvent.VK_LEFT){
padMoveLeft=false;
}
}
@Override
public void run() {
// TODO 自动生成的方法存根
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO 自动生成的 catch 块
e.printStackTrace();
}
gameUpdate();//游戏刷新
repaint();//重绘
}
}
}
class Pad{
public Point location;//挡板坐标
public Point size;//挡板尺寸
private GamePanel gameP;
public Pad(GamePanel gp){
gameP=gp;
size=new Point(100,20);
location =new Point((gp.width-size.x)/2,gp.height-size.y);
//初始位置位于屏幕正下方
}
public void update(){
if(gameP.padMoveRight){ //如果玩家按下右键
if(location.x+size.x<gameP.width){ //如果右边沿没有出界
location.x+=10; //挡板向右移动
}//if
}//if
if(gameP.padMoveLeft){
if(location.x>0){
location.x-=10;
}
}
}//update
public void draw(Graphics g){
g.setColor(Color.BLACK);
g.fillRoundRect(location.x,location.y,size.x,size.y,10,10);
}
}
class Block{
private GamePanel gameP;
private Point allocation; //存放砖块的分布,行数*列数
public Point location[]; //存放每个砖块的坐标
public Point size; //存放砖块的尺寸,长*宽
public int num; //存放砖块的数量
public boolean exist[]; //标识砖块是否被敲击
public Block(GamePanel gp){
gameP=gp;
num=20;
allocation=new Point(4,5);//砖块分布为4行*5列
size=new Point(50,20);
location=new Point[num];
for(int i=0;i<allocation.y;i++){
for(int j=0;j<allocation.x;j++){
//初始化各砖块的坐标值,让每个砖块均匀的分布在屏幕上部区域
location[i*allocation.x+j]=new Point((gp.width/allocation.x
-size.x)/2+j*(gp.width/allocation.x),(i*2+1)*size.y);
}
}
exist=new boolean[num];//初始化exsit数组
for(int i=0;i<num;i++){
exist[i]=true;
}
}
public void update(){
for(int i=0;i<num;i++){
if(exist[i]==false){
//如果砖块被敲击,将其坐标设置在程序窗口范围之外
location[i].setLocation(gameP.width+1,gameP.height+1);
}
}
}
public void draw(Graphics g){
g.setColor(Color.gray);
for(int i=0;i<num;i++){
if(exist[i]==true){
g.fillRect(location[i].x,location[i].y,size.x,size.y);
}
}
}
}
class Ball{
private GamePanel gameP;
private Block blk;
private Pad pd;
private Point location;//小球的坐标
private int diameter;
private int dx;
private int dy;
public Ball(GamePanel gp,Pad p,Block bk){
gameP=gp;
blk=bk;
pd=p;
location=new Point(pd.location.x+(pd.size.x-diameter)/2,
pd.location.y-pd.size.y);//小球初始值位于挡板正中央
dx=10;
dy=-5;
diameter=20;
}
public void update(){
if(gameP.ballMove){//若小球处于运动状态
location.x+=dx;
location.y+=dy;
wallBounced();//小球与墙壁碰撞检测
blockBounced();//小球与砖块碰撞检测
padBounced();//小球与挡板碰撞检测
}else{ //若小球停止运动,回到挡板正中央
location.setLocation(pd.location.x+(pd.size.x-diameter)/2,
pd.location.y-pd.size.y);
}
}
public void draw(Graphics g){
g.setColor(Color.blue);
g.fillOval(location.x, location.y, diameter, diameter);
}
private boolean Bounce(Point bk_location,Point bk_size){
if((location.x>bk_location.x-diameter) &&
(location.x<bk_location.x+bk_size.x) &&
(location.y>bk_location.y-diameter) &&
(location.y<bk_location.y+bk_size.y)){
return true;
}else{
return false;
}
}
private void padBounced() {
// TODO 自动生成的方法存根
Point local1,local2,local3,size1,size2,size3;
//水平方向按1:5:1的比例分割挡板,垂直方向只取挡板高度的1/4
local1=pd.location;
size1=new Point(pd.size.x*1/7,pd.size.y/4);
local2=new Point(pd.location.x+pd.size.x*1/7,pd.location.y);
size2=new Point(pd.size.x*5/7,pd.size.y/4);
local3=new Point(pd.location.x+pd.size.x*6/7,pd.location.y);
size3=new Point(pd.size.x*1/7,pd.size.y/4);
if(Bounce(local2,size2)){
dy=-dy;
}else if(Bounce(local1,size1)){
if(dx>0){
dx=-dx;
}
dy=-dy;
}else if(Bounce(local3,size3)){
if(dx<0){
dx=-dx;
}
dy=-dy;
}
}
private void blockBounced() {
// TODO 自动生成的方法存根
Point local1,local2,local3,size1,size2,size3;
for(int i=0;i<blk.num;i++){
//按照1:8:1的比例将每个砖块划分为三个区域R1、R2、R3
local1=blk.location[i];
size1=new Point(blk.size.x*1/10,blk.size.y);
local2=new Point(blk.location[i].x+blk.size.x*1/10,blk.location[i].y);
size2=new Point(blk.size.x*8/10,blk.size.y);
local3=new Point(blk.location[i].x+blk.size.x*9/10,blk.location[i].y);
size3=new Point(blk.size.x*1/10,blk.size.y);
//分别对三个区域进行碰撞检测
if(Bounce(local2,size2)){//若碰撞发生在R2区
dy=-dy;
blk.exist[i]=false;
}else if(Bounce(local1,size1)){
if(dx>0){
dx=-dx;
}else {
dy=-dy;
}
blk.exist[i]=false;
}else if(Bounce(local3,size3)){
if(dx<0){
dx=-dx;
}else{
dy=-dy;
}
blk.exist[i]=false;
}
}
}
private void wallBounced() {
// TODO 自动生成的方法存根
if((location.x>gameP.width-diameter)||(location.x<0)){
//小球碰撞到左边或右边墙壁,改变水平运动方向
dx=-dx;
}
if(location.y<0){//小球碰到上方墙壁,改变垂直运动方向
dy=-dy;
}
if(location.y>gameP.height){//小球落出窗口下边界,让小球停止运动
gameP.ballMove=false;
}
}
}