目录
一.实现原理
小球游戏的主要实现原理是通过自定义的Canvas类,通过改变小球在Canvas类中的坐标位置,不断进行重绘,以此来实现小球的运动。小球在触碰到界面边缘或者下方球拍时,改变自身运动方向,以此来实现游戏,通过此原理,实现的到了下述游戏效果图:
二.关键步骤解读
1.通过键盘控制下方球拍的运动。该过程的实现主要依靠自定义事件监听器实现KeyListener接口,通过读取键盘输入的按键信息对球拍实现左右移动。
KeyListener keyListener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_LEFT)//左箭头
{
if(RacketX > 0)
{
RacketX -= 10;
}
}
else if(keyCode == KeyEvent.VK_RIGHT)//右箭头
{
if(RacketX < (BackGround_Width - Racket_Width))
{
RacketX += 10;
}
}
}
};
//给frame与myCanvas注册事件监听器
//frame为自定义的Frame类,myCanva为自定义的Canvas类
frame.addKeyListener(keyListener);
myCanvas.addKeyListener(keyListener);
2.实现小球的方向改变与移动。本过程主要依靠Swing包中的Timer类来实现每100毫秒进行一次重绘,对小球的坐标进行改变,针对小球碰壁方向改变的问题,我们对小球的坐标进行判断,若其坐标贴近左右两侧边界,我们即改变其在X轴方向上的速度,触碰到上下边界,我们即改变Y轴上的方向。
//完成小球坐标的变化
ActionListener task = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//根据界面边界修正速度
if(BallX <= 0 || BallX >= (BackGround_Width - Ball_Size))
{
speedX = -speedX;
}
if(BallY <= 0 ||(BallY > (RacketY - Ball_Size) && (BallX > RacketX) && (BallX < RacketX + Racket_Width)))
{
speedY = -speedY;
}
if(BallY > (RacketY - Ball_Size) && (BallX < RacketX || BallX > RacketX + Racket_Width))
{
timer.stop();
isover = true;
myCanvas.repaint();
}
//更新小球坐标
BallX += speedX;
BallY += speedY;
//重绘
myCanvas.repaint();
}
};
timer = new Timer(100,task);
timer.start();
3.对游戏结束条件的判断。引入boolean变量isover(默认为false),若小球的坐标超越球拍的坐标,则修改isover为ture,进行游戏结束。
public class MyCanvas extends Canvas
{
@Override
public void paint(Graphics g) {
if(isover)
{
//游戏结束
g.setColor(Color.red);
g.setFont(new Font("Times",Font.BOLD,30));
g.drawString("游戏结束",75,200);
}
else
{
//绘制小球
g.setColor(Color.red);
g.fillOval(BallX,BallY,Ball_Size,Ball_Size);
//绘制球拍
g.setColor(Color.pink);
g.fillRect(RacketX,RacketY,Racket_Width,Racket_Height);
}
}
}
三.代码实现
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class PlayBall {
//创建Window对象
Frame frame = new Frame("弹球游戏");
//定义界面的长度与宽度
private final int BackGround_Width = 300;
private final int BackGround_Height = 400;
//定义球拍的长度与宽度
private final int Racket_Width = 60;
private final int Racket_Height = 20;
//定义球的大小
private final int Ball_Size = 16;
//定义变量,记录小球坐标
private int BallX = 150;
private int BallY = 20;
//定义变量,定义小球在两个方向上的运动速度
private int speedX = 5;
private int speedY = 10;
//定义变量记录球拍的位置
private int RacketX = 150;
private final int RacketY = 340;
//定义变量用于判断当前游戏是否结束
private boolean isover = false;
//定义一个定时器
private Timer timer;
//自定义一个类继承自Canvas,用于充当此游戏的画布
public class MyCanvas extends Canvas
{
@Override
public void paint(Graphics g) {
if(isover)
{
//游戏结束
g.setColor(Color.red);
g.setFont(new Font("Times",Font.BOLD,30));
g.drawString("游戏结束",75,200);
}
else
{
//绘制小球
g.setColor(Color.red);
g.fillOval(BallX,BallY,Ball_Size,Ball_Size);
//绘制球拍
g.setColor(Color.pink);
g.fillRect(RacketX,RacketY,Racket_Width,Racket_Height);
}
}
}
//创建绘图区域
MyCanvas myCanvas = new MyCanvas();
//组装界面
public void Init()
{
//组装视图,以及完成游戏逻辑控制
//完成球拍坐标变化
KeyListener keyListener = new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
int keyCode = e.getKeyCode();
if(keyCode == KeyEvent.VK_LEFT)//左箭头
{
if(RacketX > 0)
{
RacketX -= 10;
}
}
else if(keyCode == KeyEvent.VK_RIGHT)//右箭头
{
if(RacketX < (BackGround_Width - Racket_Width))
{
RacketX += 10;
}
}
}
};
//给frame与myCanvas注册事件监听器
frame.addKeyListener(keyListener);
myCanvas.addKeyListener(keyListener);
//完成小球坐标的变化
ActionListener task = new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//根据界面边界修正速度
if(BallX <= 0 || BallX >= (BackGround_Width - Ball_Size))
{
speedX = -speedX;
}
if(BallY <= 0 ||(BallY > (RacketY - Ball_Size) && (BallX > RacketX) && (BallX < RacketX + Racket_Width)))
{
speedY = -speedY;
}
if(BallY > (RacketY - Ball_Size) && (BallX < RacketX || BallX > RacketX + Racket_Width))
{
timer.stop();
isover = true;
myCanvas.repaint();
}
//更新小球坐标
BallX += speedX;
BallY += speedY;
//重绘
myCanvas.repaint();
}
};
timer = new Timer(100,task);
timer.start();
myCanvas.setPreferredSize(new Dimension(BackGround_Width,BackGround_Height));
frame.add(myCanvas);
frame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
System.exit(0);
}
});
frame.setVisible(true);
frame.pack();
}
public static void main(String[] args) {
new PlayBall().Init();
}
}