GUI:简易弹球小游戏

本文详细介绍了使用Java Swing实现的弹球游戏,包括Canvas自定义绘制、键盘控制球拍、小球碰撞检测和游戏结束逻辑。核心步骤涉及事件监听、坐标计算与重绘,展示了如何利用Timer和KeyListener来控制游戏元素的运动。
摘要由CSDN通过智能技术生成

目录

一.实现原理

二.关键步骤解读

三.代码实现


一.实现原理

小球游戏的主要实现原理是通过自定义的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();
    }
}

 

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值