</pre><pre name="code" class="java">Java
花了一点时间写的Java弹球, 木有别的目的, 只是希望让自己对OOP思想的理解更上一层, 同时也希望给Java初学的亲们一个例子。 包括封装,继承,等Java特性~~~PS: 大神么可选择无视此项目或者发现又任何错误和改进的地方, 多多指教,谢谢。(转载请说明作者和出处)
开始啦!
功能较简单,就是让红球不要掉, 一直接, 掉了就挂了。。。。 按2和3可以生成更多颜色的球(最多3个)
我们先建一个Ball类:
Ball类包含了所有相关的特性, 都封装在里面勒~~
public class Ball {
//球的颜色
private Color color;
//球的大小
static int size;
int x;//球自己的X坐标
int y;//球自己的Y坐标
int direction=2;
public Ball() {
// TODO Auto-generated constructor stub
super();
}
public Color getColor() {
return color;
}
public void setColor(Color color) {
this.color = color;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public Ball(Color color, int size) {
//super();
this.color = color;
this.size = size;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public int getDirection() {
return direction;
}
public void setDirection(int direction) {
this.direction = direction;
}
然后我们需要一块木板, 所以来一个Plank类啦:
public class Plank{
private int width;
private int height;
private Color Plankcolor;
public int getWidth() {
return width;
}
public void setWidth(int width) {
this.width = width;
}
public int getHeight() {
return height;
}
public void setHeight(int height) {
this.height = height;
}
public Color getPlankcolor() {
return Plankcolor;
}
public void setPlankcolor(Color plankcolor) {
Plankcolor = plankcolor;
}
public Plank() {
// TODO Auto-generated constructor stub
}
public Plank(int width, int height, Color plankcolor) {
//super();
this.width = width;
this.height = height;
Plankcolor = plankcolor;
}
}
同样也封装了所有要用的。。
想必大家都应该对AWT和SWING基本知识有所了解吧, 没错, 我用了SWING,在我们使用jframe前, 先来个Jpanel, 相当于画板勒, 然后把画板“订到” jframe上是不是很好呢?
先来个BallFrame.java
//这里我用了Timer作为任务启动器
//基本用法 timer.schedule(new TimerTask(
//public void run()
//{
//你要执行的任务code。。。
//} ), 开始时间, 持续时间);
public class BallFrame extends JPanel{
Timer timer;
Ball ball;//球对象
int direction=2;
public void setBall(Ball ball) {
this.ball = ball;
}
public BallFrame(Ball ball) {
// TODO Auto-generated constructor stub
setBackground(Color.black);
//setSize(800,800);
this.ball=ball;
timer=new Timer();
timer.schedule(new TimerTask() {
@Override
public void run() {
// TODO Auto-generated method stub
ActiveMove();
}
}, 0,15);
}
@SuppressWarnings("static-access")
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
if(!Isdead(ball)){
int level=BallFactory.difficulty;
//int level=BallFactory.difficulty;
if(level==1){
/*****draw some words******/
g.setColor(Words.level1_color);
g.drawString(Words.WELCOME,20,30);
g.drawString(Words.DIFFICULTY1,400,30);
g.drawString(Words.SCORE+BallFactory.score,600,30);
/*****draw some words******/
}
if(level==2){
g.setColor(Words.level2_color);
g.drawString(Words.WELCOME,20,30);
g.drawString(Words.DIFFICULTY2,400,30);
g.drawString(Words.SCORE+BallFactory.score,600,30);
}
if(level==3){
g.setColor(Words.level3_color);
g.drawString(Words.WELCOME,20,30);
g.drawString(Words.DIFFICULTY3,400,30);
g.drawString(Words.SCORE+BallFactory.score,600,30);
}
/*****draw very first ball******/
g.setColor(ball.getColor());
g.fillOval(ball.x, ball.y,ball.size, ball.size);
g.drawOval(ball.x, ball.y,ball.size, ball.size);
/*****draw very first ball******/
}else {
ball=null;
timer.cancel();
timer=null;
g.setColor(Color.red);
g.setFont(new Font(getName(),Font.ITALIC,50));
g.drawString("You dead!",400,400);
}
}
public void Leftup() {
//Ball balll=target;
ball.y-=3;
ball.x-=3;
ball.direction=1;
repaint();
}
public void Rightdown() {
//Ball balll=target;
ball.y+=3;
ball.x+=3;
ball.direction=2;
repaint();
}
public void Rightup() {
ball.x+=3;
ball.y-=3;
ball.direction=3;
repaint();
}
public void Leftdown() {
ball.x-=3;
ball.y+=3;
ball.direction=4;
repaint();
}
//碰撞测试
@SuppressWarnings("static-access")
public boolean hitRight(){
//加上ball.getsize()的原因是及时作出变化
//需要把X,Y封装起来试下
//getwidth?
if(ball.x+ball.getSize()>=800)//碰到左,上,右的时候
{
return true;
}
return false;
}
//note1
public boolean hitLeft(){
if (ball.x-1<=0) {
return true;
}
return false;
}
//note2
public boolean hitTop(){
if (ball.y-1<=0) {
return true;
}
return false;
}
//要让里面的X变量更新
public boolean hitPlank(){
if((ball.y+48)==699){
if((ball.x<(BallFactory.xPlank+300)) && (ball.x>BallFactory.xPlank)){
//System.out.println("Ball's X is: " + ball.x + " and Y is: " + ball.y);
//System.out.println("Plank's x is: " + BallFactory.xPlank + " and Y is: " + BallFactory.yPlank);
return true;
}
//x=getxBall();
//y=getyBall();
//i=BallFactory.xPlank;
}
// }
return false;
}
public boolean Isdead(Ball ball){
if (ball.getY()>800)
return true;
return false;
}
public int getxBall() {
return ball.x;
}
public void setxBall(Ball ball,int xBall) {
ball.x=xBall;
}
public int getyBall() {
return ball.y;
}
public void setyBall(Ball ball,int yBall) {
ball.y=yBall;
}
public void ActiveMove() {
//System.out.println("Ball's X is: " + getxBall() + " and Y is: " + getyBall());
if(hitLeft()){
if(ball.direction==4){
Rightdown();
}else if(ball.direction==1){
Rightup();
}
}else if (hitRight()) {
if (ball.direction==2) {
Leftdown();
}else if(ball.direction==3){
Leftup();
}
}else if (hitTop()) {
if(ball.direction==3){
Rightdown();
}else if(ball.direction==1){
Leftdown();
}
}else if (hitPlank()) {
if(BallFactory.difficulty==1)
BallFactory.score+=1;
if(BallFactory.difficulty==2)
BallFactory.score+=2;
if(BallFactory.difficulty==3)
BallFactory.score+=3;
if(ball.direction==4){
Leftup();
}else if(ball.direction==2){
Rightup();
}
}
if(ball.direction==1)
Leftup();
if(ball.direction==2)
Rightdown();
if(ball.direction==3)
Rightup();
if(ball.direction==4)
Leftdown();
repaint();
}
}
}
还有一点需要注意, 就是我们的游戏得分,难度这些STRING要不断的画, 为了节省空间, 提高程序的效率, 我也同样把信息封装到一个类里了
public class Words {
static final String WELCOME="welcome to my game";
static final String SCORE="My Score: ";
static final String DIFFICULTY1="Level: 1";
static final String DIFFICULTY2="Level: 2";
static final String DIFFICULTY3="Level: 3";
/***My colors setting****/
static final Color level1_color=Color.red;
static final Color level2_color=Color.yellow;
static final Color level3_color=Color.blue;
/***My colors setting****/
}
最后就是我们的大BOSS jframe的出现了:
先建一个BallFactory.java
直接上代码。。。
public class BallFactory extends JFrame implements KeyListener{
/**
*
*/
private static final long serialVersionUID = 1L;
static int score=0;
Plank plank;
static int xPlank=100;//小球的横坐标
static int yPlank=699;//小球的纵坐标小球的纵坐标,如果是用getHeight-100呢?
Ball ball=null;
Ball ball2=null;
Ball ball3=null;
Panel panelWords;
JTextArea scorePanel;
static int[] difficulties={1,2,3};//代表球的个数
// static Vector<Ball> balls=new Vector<Ball>();//装球的容器
static int difficulty=1;
BallFrame ballFrame;
BallFrame ballFrame2;
BallFrame ballFrame3;
//BallFrame frame=new BallFrame();
Timer timer;
public BallFactory() {
// TODO Auto-generated constructor stub
setTitle("MyBallgame");
setSize(800,800);
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
addKeyListener(this);
ball=new Ball(Color.red, 24);
ball.setX(400);
ball.setY(0);
ballFrame=new BallFrame(ball);
plank=new Plank(300,10, Color.yellow);
add(ballFrame);
//add(ballFrame);
//repaint();
setVisible(true);
}
@Override
public void paint(Graphics g) {
// TODO Auto-generated method stub
super.paint(g);
int level=BallFactory.difficulty;
if(level==2){
// g.setColor(ball2.getColor());
// g.fillOval(ball2.x, ball2.y,ball2.size, ball2.size);
// g.drawOval(ball2.x, ball2.y,ball2.size, ball2.size);
if(ball3!=null){
g.setColor(ball3.getColor());
g.fillOval(ball3.x, ball3.y,ball3.getSize(), ball3.getSize());
g.drawOval(ball3.x, ball3.y,ball3.getSize(), ball3.getSize());
}
g.setColor(ball2.getColor());
g.fillOval(ball2.x, ball2.y,ball2.getSize(), ball2.getSize());
g.drawOval(ball2.x, ball2.y,ball2.getSize(), ball2.getSize());
}
if(level==3){
g.setColor(ball2.getColor());
g.fillOval(ball2.x, ball2.y,ball2.getSize(), ball2.getSize());
g.drawOval(ball2.x, ball2.y,ball2.getSize(), ball2.getSize());
g.setColor(ball3.getColor());
g.fillOval(ball3.x, ball3.y,ball3.getSize(), ball3.getSize());
g.drawOval(ball3.x, ball3.y,ball3.getSize(), ball3.getSize());
}
//scorePanel.setText(score+"");
//doSth(g);
g.setColor(plank.getPlankcolor());
g.fillRect(xPlank,yPlank, plank.getWidth(), plank.getHeight());
g.drawRect(xPlank,yPlank, plank.getWidth(), plank.getHeight());
repaint();
}
public static void main(String[] args) {
//Timer timer=new Timer();
// BallFactory jFrame=new BallFactory();
//thread.start();
new BallFactory();
}
@Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
@Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
int keyCode=e.getKeyCode();
switch (keyCode) {
case KeyEvent.VK_LEFT:
xPlank-=5;
//repaint();
break;
case KeyEvent.VK_RIGHT:
xPlank+=5;
//repaint();
break;
case KeyEvent.VK_1:
setDifficulty(0);
//repaint();
break;
case KeyEvent.VK_2:
setDifficulty(1);
if(ball2==null){
ball2=new Ball(Color.blue, 24);
ball2.x=200;
ball2.y=0;
// valiBalls.add(ball2);
ballFrame2=new BallFrame(ball2);
add(ballFrame2);
}
//valiBalls.remove(ball2);
//repaint();
break;
case KeyEvent.VK_3:
setDifficulty(2);
if(ball3==null){
ball3=new Ball(Color.green, 24);
ball3.x=500;
ball3.y=0;
//valiBalls.add(ball3);
ballFrame3=new BallFrame(ball3);
add(ballFrame3);
}
//valiBalls.remove(ball3);
//repaint();
break;
}
}
@Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
public static void setDifficulty(int index) {
difficulty = difficulties[index];
}
public int getDifficulty() {
return difficulty;
}
//之前要对球2初始化
public void BallhitsBall(){
if(ball.x+100>=ball2.x){
if(ball.direction==2 && ball2.direction==1){
ball.x-=3;
ball.y-=3;
ball2.x+=3;
ball2.x+=3;
}
}
}
// public boolean Isdead(){
// if (ball.getY()>800)
// return true;
// }
// return false;
// }
}
关于这段代码,想说的就一点, 因为界面上最多会画3个球, 每个球的行为(是否撞墙壁了,是否挂了。。是否撞到板子上了,etc)都应该是一样的, 所以我把上面的那些行为封装到了“Ballframe”类里, 但是。。Ballframe里只能一次判断一个球, 如何让3个球(如果有)同时进行呢? 3个线程? 太繁琐, 而且你还得锁, 一旦锁就会出现一个先于另一个的问题。。。 所以我的策略是, 创建3个Ballfactory的实例, 这样就不会受影响了。。 关于画游戏信息, 我还是放到了Ballframe类里, 因为作为“画板”, 是第一个作为Jpanel加到Jframe上的, 如果放到Ballfactory里, 应该画不出, 因为被挡着了。 好, 代码就是这些, 有问题,建议指点, 请留在下面讨论啦。。