Java Swing 制作一个Pong小游戏

适合新手练习的 java 小项目 不要问我为什么推荐这个,因为我也只是一个新手,这个项目是纯命令行的,不需要数据库和网页编程知识,做起来很简单,可以帮助新手巩固基础知识。 阅读详情

之前呢我们用Python的Pygame做过这个Pong游戏

Python 项目实战 教你用Pygame写一个Pong游戏_Leleprogrammer的博客-优快云博客_pong游戏手把手教你用Pygame写一个Pong游戏https://blog.youkuaiyun.com/leleprogrammer/article/details/124227987?spm=1001.2014.3001.5501

这一次,我们用Java的Swing来实现类似的效果

首先我们列出本次的项目结构

这个程序分为四个部分,一个程序入口,一个模型,一个刷新帧,一个视图,模型里面放入球和挡板的类,视图里面放入主窗口Frame和主面板Panel

接下来是项目目录

src资源下面,我们把东西全部写到com.mr包下,main里的Start是主入口,model里面分别是Ball和Board,service下是刷新帧的服务,view视图下分别为主窗体和主面板 

好啦,现在先来写GameFrame的代码

package com.mr.view;

import javax.swing.*;
import java.awt.*;

public class GameFrame extends JFrame {
    private Container container;
    private GamePanel panel;
    public GameFrame() {
        setTitle("Pong");
        setBounds(300,300,850,1000);
        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        container=getContentPane();
        panel=new GamePanel();
        addKeyListener(panel);
        container.add(panel);
        setVisible(true);
    }
}

首先啊,还是和平常一样声明package,导入一些东西,然后主窗体继承自JFrame,设置以下标题和窗口大小,还有关闭后退出程序的设置(setDefaultCloseOperation)然后实例化GamePanel面板(待会写),然后绑定事件并添加到container容器中,设置窗口可见

然后是GamePanel的代码,也是整个程序的核心,在这里我们要做出对赛点、得分、球体碰撞等检测,并绘制图形

package com.mr.view;

import com.mr.model.Ball;
import com.mr.model.Board;
import com.mr.service.Fresh;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.ArrayList;

public class GamePanel extends JPanel implements KeyListener {
    private BufferedImage img;
    private Graphics2D g2;
    public ArrayList<Object> select;
    private Fresh fresh;
    private Board b1;
    private Board b2;
    private Ball ball;
    private int score1;
    private int score2;
    private int winPoint;
    private int matchPoint; // 0表示没有赛点,1表示玩家1的赛点,2表示玩家2的赛点
    private int winner;
    public GamePanel() {
        img=new BufferedImage(850,1000,BufferedImage.TYPE_INT_BGR);
        g2=img.createGraphics();
        select=new ArrayList<>();
        b1=new Board(0);
        b2=new Board(1);
        ball=new Ball();
        score1=0;
        score2=0;
        matchPoint=0;
        winPoint=11;
        winner=0;
        fresh=new Fresh(this);
        fresh.start();
    }
    private void paintImage() {
        g2.setColor(Color.WHITE);
        if (winner==0) {
            int width=10;
            g2.fillRect(425-width/2,0,width,1000);
            g2.fillRect(b1.x,b1.y,b1.width,b1.height);
            g2.fillRect(b2.x,b2.y,b2.width,b2.height);
            g2.fillOval(ball.x-ball.r,ball.y-ball.r,ball.r*2,ball.r*2);
        }
        g2.setFont(new Font("黑体",Font.BOLD,56));
        g2.drawString(String.valueOf(score1),295,150);
        g2.drawString(String.valueOf(score2),525,150);
        g2.setFont(new Font("黑体",Font.PLAIN,22));
        if (winner==0) {
            switch (matchPoint) {
                case 1:
                    g2.drawString("赛点",295,200);
                    break;
                case 2:
                    g2.drawString("赛点",525,200);
                    break;
                default:
                    break;
            }
        } else {
            g2.drawString("玩家"+String.valueOf(winner)+"获胜",winner==1?295:525,200);
        }
    }
    public void paint(Graphics g) {
        if (winner==0) {
            move();
            ball.move(b1.getBound(),b2.getBound());
            checkPoint();
            checkMatchPoint();
            b1.checkBound();
            b2.checkBound();
        }
        g2.setColor(Color.BLACK);
        g2.fillRect(0,0,850,1000);
        paintImage();
        g.drawImage(img,0,0,this);
    }
    private void checkPoint() {
        if (ball.x<=0) {
            score2+=1;
        } else if (ball.x+ball.r*2>=850) {
            score1+=1;
        } else {
            return;
        }
        ball=new Ball();
    }
    private void checkMatchPoint() {
        if (score1==winPoint) {
            winner=1;
            return;
        } else if (score2==winPoint) {
            winner=2;
            return;
        }
        if (score1+1==winPoint&&score2+1!=winPoint) {
            matchPoint=1;
        } else if (score1+1!=winPoint&&score2+1==winPoint) {
            matchPoint=2;
        } else if (score1+1==winPoint&&score2+1==winPoint) {
            matchPoint=0;
            winPoint++;
        } else if (score1+1!=winPoint&&score2+1!=winPoint) {
            matchPoint=0;
        }
    }
    private void move() {
        for (Object code:select) {
            if (code==(Object)KeyEvent.VK_W) {
                b1.y-=b1.speed;
            } else if (code==(Object)KeyEvent.VK_S) {
                b1.y+=b1.speed;
            } else if (code==(Object)KeyEvent.VK_UP) {
                b2.y-=b2.speed;
            } else if (code==(Object)KeyEvent.VK_DOWN) {
                b2.y+=b2.speed;
            }
        }
    }
    @Override
    public void keyPressed(KeyEvent event) {
        if (select.indexOf(event.getKeyCode())==-1) {
            select.add(event.getKeyCode());
        }
    }
    @Override
    public void keyReleased(KeyEvent event) {
        select.remove((Object)event.getKeyCode());
    }
    @Override
    public void keyTyped(KeyEvent event) {
        ;
    }
}

声明com.mr.view包下,导入一些东西,然后创建主类GamePanel,继承自JPanel并实现KeyListener事件,接下来就是声明变量,一个主图片img以及对应的g2,select用于储存按下的按键,这个待会讲,接下来是fresh刷新帧线程,两块板,一个球,两个玩家的分数,胜利所需要的分数,赛点归属于谁,是否出现了赢家等。接下来来到构造函数,先创建img主图片850x1000还有g2,初始化一些东西,这里Board的0和1表示归属于哪个玩家,0则为左手边的,1则为右手边的。接下来创建球(ps.这些类待会就来写),然后分数初始化,赛点为0,表示没有人获得赛点,获胜分数为11分,和乒乓球一样,然后winner为0表示没有赢家,创建线程,这里传入了自己,是为了待会可以通过repaint方式不断重绘,然后启动线程。paint中,没有获胜,则移动板(move),移动球,检查得分,检查赛点,保持两块板处于场内(窗口内),然后设置颜色为黑色,填充背景为黑色,绘制,并把主图片画在g中。paintImage中对板、球、得分、中线进行绘制,不难理解。好,GamePanel的最后,我们来讲讲刚刚的那个select,因为我们要同时检测做个键盘按钮,但是这个KeyListener只支持一次性按下一个,按下多个也只会获取到一个,所以我们用一种方法来解决,我们创建一个select数组,按下按键且按键不在select中则添加到select中,松开则删除,这样同时按下多个按钮,这些按钮(就像排着队伍一样)相继添加到select中,这样也便于了我们移动板的if判断。

接下来我们来看看一个同样非常重要的Fresh刷新帧线程

package com.mr.service;

import com.mr.view.GamePanel;

public class Fresh extends Thread {
    public final int INTERVAL=20;
    private GamePanel panel;
    public Fresh(GamePanel panel) {
        this.panel=panel;
    }
    public void run() {
        while (true) {
            panel.repaint();
            try {
                Thread.sleep(INTERVAL);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

这个就while循环实现啦~~~

然后是Ball

package com.mr.model;

import java.awt.*;
import java.util.Random;

public class Ball {
    public int x;
    public int y;
    public int r;
    private int xspeed;
    private int yspeed;
    private int max_speed;
    private int min_speed;
    private int max_speed2;
    private int min_speed2;
    public Ball() {
        x=425;
        y=500;
        r=15;
        Random rd=new Random();
        xspeed=rd.nextInt(1,3)==1?rd.nextInt(4,7):rd.nextInt(-6,-3);
        yspeed=rd.nextInt(1,3)==1?rd.nextInt(4,7):rd.nextInt(-6,-3);
        max_speed=12;
        min_speed=3;
        max_speed2=-3;
        min_speed2=-12;
    }
    public void move(Rectangle b1,Rectangle b2) {
        x+=xspeed;
        y+=yspeed;
        Random rd=new Random();
        if (getBound().intersects(b1)||getBound().intersects(b2)) {
            xspeed=-xspeed;
            yspeed+=rd.nextInt(-2,3);
        }
        else if (y-r<=0||y+r>=965) {
            yspeed=-yspeed;
            xspeed+=rd.nextInt(-2,3);
        }
        if (xspeed>max_speed&&xspeed>0) {
            xspeed=max_speed;
        }
        if (yspeed>max_speed&&yspeed>0) {
            yspeed=max_speed;
        }
        if (xspeed<min_speed&&xspeed>0) {
            xspeed=min_speed;
        }
        if (yspeed<min_speed&&yspeed>0) {
            yspeed=min_speed;
        }
        if (xspeed>max_speed2&&xspeed<0) {
            xspeed=max_speed2;
        }
        if (yspeed>max_speed&&yspeed<0) {
            yspeed=max_speed2;
        }
        if (xspeed<min_speed&&xspeed<0) {
            xspeed=min_speed2;
        }
        if (yspeed<min_speed&&yspeed<0) {
            yspeed=min_speed2;
        }
    }
    private Rectangle getBound() {
        return new Rectangle(x-r,y-r,r*2,r*2);
    }
}

这个模型嘛,一般情况下都有x和y还有大小,因为这个是个圆,所以我们用半径r,然后xspeed和yspeed表示各个方向的速度从而实现斜着移动,还有max_speed和min_speed用于把动态变换的速度限制于这个范围内,待会每碰到一次墙壁或板,就会适当增加或减少速度,所以要把速度限制在特定范围内,max_speed2和min_speed2也一样,前2者是用于正数速度的,后2者是用于负数速度的,然后移动的时候就对一些碰撞等情况进行检测就好了,getBound用于返回对象的Rect长方形对象,用于检测碰撞。

最后是Board

package com.mr.model;

import java.awt.*;

public class Board {
    public int x;
    public int y;
    public int width;
    public int height;
    public int speed;
    public Board(int type) {
        width=8;
        height=120;
        speed=15;
        y=500-height/2;
        if (type==0) {
            x=0;
        } else {
            x=850-15-width;
        }
    }
    public void checkBound() {
        if (y+height>=985) {
            y=985-height;
        }
        if (y<=0) {
            y=0;
        }
    }
    public Rectangle getBound() {
        return new Rectangle(x,y,width,height);
    }
}

Board和Ball也有着差不多的一些参数和类成员和方法

现在全部就都写完了,最后画上点睛之笔,写上最后的程序入口就大功告成啦!!!

Start.java:

package com.mr.main;

import com.mr.view.GameFrame;

public class Start {
    public static void main(String[] args) {
        GameFrame gameFrame=new GameFrame();
    }
}

好啦,这样就实现了Pong游戏的效果,喜欢的话就点赞收藏关注吧!!!

Python之游戏Pong的简单实现 Python之游戏Pong的简单实现最近闲的无聊在MOOC上注册了Python的学习课程,课程链接为: http://mooc.guokr.com/course/395/An-Introduction-to-Interactive-Programming-in-Python%EF%BC%88part-1%EF%BC%89/ 课程Part 1 部分已经结束,按要求做了一个Pong的小游戏。Pong 阅读详情

相关推荐

python:实现pongpong乒乓球游戏(附完整源码)

python:实现pongpong乒乓球游戏(附完整源码)

希望我的博客,能帮上你解决学习中工作中所遇到的问题 483

Java实现贪吃蛇大作战小游戏(完整版)

用swing技术实现编写一个贪吃蛇大作战小游戏,项目供大家参考学习交流。

陈橘又青的博客 7万+

信捷CODESYS平台伺服电机转矩控制模式应用与切换

信捷CODESYS二次开发软件:XS Studio 在运动控制中的转矩控制案例

weixin_64614866的博客 1万+

还在为毕业设计发愁吗?免费送2023年java毕业设计项目300个选题开题【源码+论文】分享

提示:2023年java毕业设计项目源码论文分享

qq_25674251的博客 642

自动驾驶中的多传感器融合实战:用卡尔曼滤波搞定毫米波雷达与摄像头航迹对齐

本文深入探讨了自动驾驶中多传感器融合的实战技术,重点介绍了如何使用卡尔曼滤波实现毫米波雷达与摄像头的航迹对齐。通过分析传感器特性差异、时空同步挑战及工程化实现步骤,提供了包括状态向量定义、观测矩阵设计和故障检测机制在内的完整解决方案,最终实现0.15米以内的高精度航迹对齐。

weixin_28728495的博客 410

uniapp 使用摄像头 live-pusher (APP)

uniapp 中开发 app 时使用live-pusher踩过的坑

随身笔记 1万+

Godot学习笔记8——PONG游戏制作

PONG是1972年由雅达利公司推出的游戏,主要玩法为玩家控制两个可以上下移动的板子击打屏幕中不断运动的球。

fengtian65的博客 2476

立创EDA手动拼板实战:当自带功能不够用,如何用‘复制粘贴’搞定异形拼版与特殊布局

本文详细介绍了立创EDA手动拼板技术在异形拼版与特殊布局中的应用实战。通过CTRL+SHIFT+V等核心操作技巧,解决混合尺寸拼板、特殊间距需求等复杂场景,提升PCB设计效率与灵活性,特别适合需要高精度控制的射频电路和医疗设备项目。

weixin_31967485的博客 385

java小项目-继承-接口-Swing窗口(一共5个demo)

java小项目-继承-接口-Swing窗口(一共5个demo)

m0_48851832的博客 1273

从永恒之蓝看内网安全:企业如何用Nmap+MSF快速检测445端口风险

本文探讨了企业如何利用Nmap和Metasploit快速检测445端口风险,防范永恒之蓝(MS17-010)漏洞攻击。通过分阶段检测流程和自动化工具组合,企业可高效识别内网风险主机,并实施紧急隔离与长效防护策略,提升整体网络安全防护能力。

weixin_30772105的博客 598

智能车竞赛必备:STC32G144K开源库实战指南(含总钻风摄像头配置)

本文为智能车竞赛参赛者提供了一份基于STC32G144K微控制器与逐飞开源库的实战开发指南。文章详细介绍了从开发环境搭建、总钻风摄像头驱动配置与图像采集优化,到核心控制算法实现与多任务调度等关键步骤,旨在帮助队伍快速构建稳定高效的视觉处理系统,提升竞赛竞争力。

weixin_29191081的博客 706

java乒乓球小游戏

乒乓球小游戏 import javax.swing.*; import java.awt.*; import java.awt.event.*; public class PinBall { private Frame frame = new Frame("弹球游戏"); // 桌面宽高 private final int TABLE_WIDTH = 300; private final int TABLE_HEIGHT = 400; // 球拍的宽高 p

qq_51706881的博客 473

超酷炫,Python实现交通数据可视化!

此时输出的栅格化参数params的内容存储了栅格坐标系的原点坐标(slon、slat)、单个栅格的经纬度长宽 (deltalon、deltalat)、栅格的旋转角度(theta)、栅格的形状(method参数,其值可以是方形rect、三角形tri和六边形hexa)以及栅格的大小(gridsize参数,单位为米)。Python所有方向的技术点做的整理,形成各个领域的知识点汇总,它的用处就在于,你可以按照上面的知识点去找对应的学习资源,保证自己学得较为全面。今天分享一次Python交通数据分析与可视化的实战!

m0_59236127的博客 1696

Java实现经典 Pong 游戏——从零开始开发双人乒乓小游戏

Java Swing 图形开发游戏循环设计键盘事件处理面向对象编程碰撞检测动画刷新机制Pong 虽然简单,但它包含了绝大多数二维游戏开发的核心思想,非常适合 Java 初学者练手。如果继续扩展,还可以逐渐发展成完整的小游戏项目。Pong 是电子游戏发展史上的经典之作。使用 Java 实现 Pong,不仅能够帮助我们理解 GUI 编程,还能够掌握游戏开发的核心机制。对于 Java 学习者来说,这是一个非常适合作为课程设计或者个人练习的小项目。

2403_88444298的博客 328

03. 线性规划与混合整数规划 (LP/MIP)

本文介绍了OR-Tools中的线性规划(LP)和混合整数规划(MIP)求解器。主要内容包括:1) LP/MIP的基本概念和数学形式,对比了LP、MIP、ILP和BIP的区别;2) OR-Tools支持的求解器类型,如GLOP、SCIP等,以及它们各自的特点和适用场景;3) 详细展示了如何使用GLOP求解器进行线性规划求解,包括变量定义、约束添加和目标函数设置;4) 介绍了SCIP求解器的配置和使用方法;5) 讨论了变量类型、约束类型、多目标优化等进阶功能。文章通过Java代码示例演示了如何实现一个完整的优化

智慧是做事用的 156

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

java swing实训项目(图书管理系统)

2.登录注册页面 登录页面 注册页面 3. 管理员页面 以子窗口的形式,实现用户,图书的增删改查(删改图书查询没有用到like的模糊查询,有需要的可以增做修改) 管理员登录界面 用户管理子界面 图书管理子界面 图书添加 普通用户界面 实体类 数据的增删改查 需要导入mysql的驱动架包(不懂的可以去网上找,也可以私信我) mysql数据库...

weixin_64490645的博客 8454

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Java项目(swing项目)【超市系统管理】【进销存】

小伙伴们,大家好哇! 上次分享给大家的swing项目还没有分享完,这次继续分享给大家!争取 这一次分享完,主要是给大家分享项目时的一些思路,如果对代码感兴趣,欢迎大家私聊我,我们一起讨论!【项目是很久之前写的,如有不足,请大家批评指正!】 现在大家看到的是进货管理模块 : 分为 采购进货,退货,和单据查询 供货商管理 采购进货: 首先是选择供货商:选择供货商之后,老商品添加,则会出现该供货商对应的商品,比如化妆品 对应化妆品,水果对应水果! 以及右上角出现的单号,方便单据生成之...

a__wjsjs的博客 2654

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

计算机控制技术及应用

《计算机控制技术及应用》通过总结作者的科研成果和吸收国内外的先进理论、方法和技术,以计算机控制系统的网络化、开放化、智能化和集成化发展趋势为主线索,主要介绍计算机控制系统的基本概念和计算机控制系统的典型形式,计算机控制系统的数学描述与基本分析方法,以及数字PID控制器、最少拍控制系统、达林算法、状态变量设计法等设计方法及其各种改进算法。重点突出计算机控制系统输入输出通道接口的设计方法和典型控制系统的设计案例与实现方法等。

JAVA基于Swing和Netty,仿QQ界面聊天小项目,非常建议玩玩!

先说一下这个小项目也算是我在大学做得第一个应该算的上是的项目的项目,前前后后用了20天左右吧。先是用swing写好了仿QQ界面(界面很丑)最后逻辑实现都是后面断断续续加进去的。写这个项目之前没有很好的规划在逻辑实现方面与数据库逻辑交互过于频繁。走了很多的弯路。...

m0_57042151的博客 493

Swing应用程序美化--FlatLaf (IDEA风格)

前言: Swing默认主题已经无法适应现在的软件界面设计风格,第三方发行者推出的FlatLaf主题拥有很漂亮的设计风格,使用也很简单。 依赖: 进入如下地址: https://search.maven.org/artifact/com.formdev/flatlaf/1.6.5/jar 然后选择最右侧的Download选择下载到本地为jar包。添加依赖方式与普通jar包一致。 嫌手动导入麻烦的直接配置pom即可: <dependencies> <dependency&gt

kicinio的博客 1万+

java swing有趣编程_java界面编程Swing入门案例介绍

1 什么是javaswingSwing 是一个为Java设计的GUI工具包。Swing是JAVA基础类的一部分。Swing包括了图形用户界面(GUI)器件如:文本框,按钮,分隔窗格和表。Swing提供许多比AWT更好的屏幕显示元素。它们用纯Java写成,所以同Java本身一样可以跨平台运行,这一点不像AWT。它们是JFC的一部分。它们支持可更换的面板和主题(各种操作系统默认的特有主题),然而不是...

weixin_36304806的博客 308

【pgzero】手把手教你制作游戏——Pong

今天要做的游戏叫Pong,它是世界上第一款街机游戏。(关键它好做)制作游戏的引擎有很多,比如Unity、Construct............而今天我们用的既不是Unity,也不是Construct,而是Python。制作游戏的模块是pgzero,它是在Python比较有名的库Pygame上又加了一层封装,对初学者制作游戏非常友好。

WhereIsHero的博客 3492

【c++游戏编程】第一站!Game模板和《Pong》

我们在本次中制作了《Pong》,并制作了Game类

一个平庸的人 636

Python+PyGame实战:从零实现Pong弹球游戏,掌握游戏循环与碰撞检测

游戏开发中,游戏循环、事件处理和碰撞检测是构建交互式应用的基石。在2D游戏领域,帧率控制与坐标系统决定了运动的流畅性与物理准确性。通过面向对象设计,可将游戏实体封装为独立类,提升代码可维护性。以经典Pong弹球游戏为例,利用Python的PyGame库,仅需两百余行代码即可实现完整游戏逻辑,涵盖窗口初始化、键盘事件响应、矩形碰撞检测与动态反弹角度计算。这一过程不仅强化了对游戏编程基础架构的理解,也为后续复杂项目如三消或塔防游戏打下坚实基础。文章深入拆解了从环境配置到代码实现的每个环节,并提供了手感调优与AI

weixin_42697475的博客 77

Pygame游戏 : PONG

最近刚学Pygame 做个小游戏玩玩~~以上就是我分享的内容 , 希望大家喜欢~~有bug还是留言 , 博主会争取改进^v^

W987654321123456的博客 696

Pong 游戏控制台版

Pong 游戏控制台版 我就直接上代码了欢迎来讨论 #include <iostream> #include <conio.h> #include <Windows.h> #include <ctime> #include <cstdlib> using namespace std; #define WIDTH 120 #define ...

qq_44698445的博客 989

Python Pong游戏教程:使用pygame库创建基础弹球游戏代码示例

弹球游戏(Pong)是一个经典的电子游戏,玩家控制一个挡板,防止一个球进入对方的领土。以下是一个使用Python和。库创建基础弹球游戏的示例代码。这段代码将创建一个简单的游戏界面,两个挡板和一颗球,球会在挡板之间弹跳。

程序熊的博客 513
上一篇: Java Swing 飞机大战游戏
下一篇: 解决Visual Studio中C++创建类时报错“未能返回新代码元素,可能是语法错误,新元素名:xxx”的问题
Leleprogrammer
博客等级 码龄5年 1万+粉丝 103原创
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值