目录

前言

代码实现

GameOverPanel类

PingPong类

实机演示


前言

该游戏可支持本地两人游戏

Player1采用W和S键控制球拍移动

Player2采用UP和DOWN键控制球拍移动

进程开始后按Space键即可开始游戏

在任意玩家得分后游戏会暂停,按下Space键后即可继续游戏

在达到设定的Score-to-win便会弹出GameOver窗口

代码实现

GameOverPanel类

import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import javax.swing.*;
import java.awt.*;class GameOverPanel extends JPanel {private static final long serialVersionUID = 1L;private BufferedImage image;public GameOverPanel(int player1Score, int player2Score) {this.player1Score = player1Score;this.player2Score = player2Score;try {// Load the image fileimage = ImageIO.read(new File("C:/Users/timberman/Desktop/JianRan.jpg"));} catch (Exception e) {e.printStackTrace();}}public void paintComponent(Graphics g) {super.paintComponent(g);// Draw the image in the center of the panelint x = (getWidth() - image.getWidth()) / 2;int y = (getHeight() - image.getHeight()) / 2;g.drawImage(image, x, y, null);}private int player1Score;private int player2Score;public void paint(Graphics g) {super.paint(g);Font font = new Font("Arial", Font.BOLD, 20);g.setFont(font);g.drawString("Game Over", 30, 30);if(player1Score>player2Score){g.drawString("player1 Win",30,50);}else{g.drawString("player2 Win",30,50);}}
}

PingPong类

import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Set;
import java.util.HashSet;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.imageio.ImageIO;
import javax.swing.*;public class PingPong extends JPanel implements KeyListener, Runnable {private static final long serialVersionUID = 1L;private Set<Integer> keysPressed = new HashSet<>();private int paddle1Y = 0;private int paddle2Y = 0;private int ballXDirection = 1;private int ballYDirection = -1;private int player1Score = 0;private int player2Score = 0;private boolean gameRunning = true;private final int BALL_SIZE = 20;private final int PADDLE_WIDTH = 10;private final int PADDLE_HEIGHT = 100;private final int PADDLE_SPEED = 10;private final int SCORE_TO_WIN = 11;private final int FRAME_WIDTH = 600;private final int FRAME_HEIGHT = 600;private final int PADDING = 10;private final int BALL_SPEED = 1;private final int DELAY = 10;private int ballX = FRAME_WIDTH / 2 - BALL_SIZE / 2;;private int ballY = FRAME_HEIGHT / 2 - BALL_SIZE / 2;public boolean startScreen=true;public PingPong() {JFrame frame = new JFrame("Ping Pong");frame.setSize(FRAME_WIDTH+15, FRAME_HEIGHT+35);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.addKeyListener(this);frame.add(this);frame.setVisible(true);frame.setLocation(500,100);new Thread(this).start();}public void paint(Graphics g) {super.paint(g);g.setColor(Color.BLACK);g.fillRect(0, 0, FRAME_WIDTH, FRAME_HEIGHT);if (startScreen) {// Draw start screen messageg.setColor(Color.white);Font font = new Font("Arial", Font.BOLD, 36);g.setFont(font);g.drawString("Press SPACE to start", FRAME_WIDTH/2 -190, FRAME_HEIGHT/2);}else{g.setColor(Color.WHITE);g.fillRect(PADDING, paddle1Y, PADDLE_WIDTH, PADDLE_HEIGHT);g.fillRect(FRAME_WIDTH - PADDING - PADDLE_WIDTH, paddle2Y, PADDLE_WIDTH, PADDLE_HEIGHT);g.fillOval(ballX, ballY, BALL_SIZE, BALL_SIZE);Font font = new Font("Arial", Font.BOLD, 20);g.setFont(font);g.drawString("Player 1: " + player1Score, PADDING, PADDING+10);g.drawString("Player 2: " + player2Score, FRAME_WIDTH - PADDING - 100, PADDING+10);}}public void run() {while (gameRunning) {if (startScreen) {// Draw start screen messageGraphics g = getGraphics();g.setColor(Color.white);g.drawString("Press SPACE to start", FRAME_WIDTH/2 - 70, FRAME_HEIGHT/2);g.dispose();// Wait for spacebar to be pressedwhile (startScreen) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}}moveBall();movePaddles();checkCollisions();checkWin();repaint();try {Thread.sleep(DELAY);} catch (InterruptedException e) {e.printStackTrace();}}}private void moveBall() {ballX += ballXDirection * BALL_SPEED;ballY += ballYDirection * BALL_SPEED;}@Overridepublic void keyTyped(KeyEvent e) {}public void keyPressed(KeyEvent e) {int keyCode = e.getKeyCode();keysPressed.add(keyCode);if (keysPressed.contains(KeyEvent.VK_SPACE)) {startScreen = false;}}public void keyReleased(KeyEvent e) {int keyCode = e.getKeyCode();keysPressed.remove(keyCode);}private void movePaddles() {if (keysPressed.contains(KeyEvent.VK_W)) {paddle1Y -= PADDLE_SPEED;}if (keysPressed.contains(KeyEvent.VK_S)) {paddle1Y += PADDLE_SPEED;}if (keysPressed.contains(KeyEvent.VK_UP)) {paddle2Y -= PADDLE_SPEED;}if (keysPressed.contains(KeyEvent.VK_DOWN)) {paddle2Y += PADDLE_SPEED;}// Clamp paddle positions to screen boundspaddle1Y = Math.max(PADDING, Math.min(paddle1Y, FRAME_HEIGHT - PADDLE_HEIGHT - PADDING));paddle2Y = Math.max(PADDING, Math.min(paddle2Y, FRAME_HEIGHT - PADDLE_HEIGHT - PADDING));}private void checkCollisions() {if (ballY <= 0 || ballY >= FRAME_HEIGHT - BALL_SIZE) {ballYDirection *= -1;}if (ballX <= PADDING + PADDLE_WIDTH && ballY >= paddle1Y && ballY <= paddle1Y + PADDLE_HEIGHT) {ballXDirection *= -1;ballXDirection += ballXDirection > 0 ? 1 : -1;ballYDirection += ballYDirection > 0 ? 1 : -1;}if (ballX >= FRAME_WIDTH - PADDING - PADDLE_WIDTH - BALL_SIZE && ballY >= paddle2Y && ballY <= paddle2Y + PADDLE_HEIGHT) {ballXDirection *= -1;ballXDirection += ballXDirection > 0 ? 1 : -1;ballYDirection += ballYDirection > 0 ? 1 : -1;}if (ballX <= 0) {player2Score++;resetBall();gameRunning = false;}if (ballX >= FRAME_WIDTH - BALL_SIZE) {player1Score++;resetBall();gameRunning = false;}if (player1Score >= SCORE_TO_WIN || player2Score >= SCORE_TO_WIN) {gameRunning = false;}if (!gameRunning) {// Draw scoresGraphics g = getGraphics();g.setColor(Color.white);Font font = new Font("Arial", Font.BOLD, 36);g.setFont(font);String scoreString = "Player 1: " + player1Score + "   Player 2: " + player2Score;int stringWidth = g.getFontMetrics().stringWidth(scoreString);g.drawString(scoreString, FRAME_WIDTH/2 - stringWidth/2, FRAME_HEIGHT/2);g.drawString("Press SPACE to continue",FRAME_WIDTH/2 - stringWidth/2-10, FRAME_HEIGHT/2-100);// Wait for space bar to be pressedwhile (!keysPressed.contains(KeyEvent.VK_SPACE)) {try {Thread.sleep(10);} catch (InterruptedException e) {e.printStackTrace();}}// Reset game and continuekeysPressed.remove(KeyEvent.VK_SPACE);gameRunning = true;}}private void checkWin() {if (player1Score >= SCORE_TO_WIN || player2Score >= SCORE_TO_WIN) {gameRunning = false;JFrame frame = new JFrame("Game Over");frame.setSize(300, 300);frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);frame.add(new GameOverPanel(player1Score, player2Score));frame.setVisible(true);frame.setLocation(400,300);}}private void resetBall() {ballX = FRAME_WIDTH / 2 - BALL_SIZE / 2;ballY = FRAME_HEIGHT / 2 - BALL_SIZE / 2;ballXDirection = new Random().nextInt(2) == 0 ? -1 : 1;ballYDirection = new Random().nextInt(2) == 0 ? -1 : 1;}public static void main(String[] args) {new PingPong();}
}

实机演示

JAVA练习小游戏——本地双人联机乒乓球小游戏相关推荐

  1. 51单片机系列(三)51 单片机游戏设计 —— 双人对战小游戏(石头剪刀布)

    本博客51单片机实训系列,旨在记录本人在大学上单片机技术这门课时所做的课程实训内容,并与大家分享基于51单片的课程作业,如果作业中的某些细节和代码能给大家一点启发那就更好了,希望大家能用51单片机做出 ...

  2. 发布:双人联机岛屿争夺游戏 Enemies in the dark

    发布:双人联机岛屿争夺游戏 Enemies in the dark 更新历史 20200302: 首次发布 20200303: 增加了"游戏理念"部分 这几天用Python写了一个 ...

  3. unity3d游戏3d局域网联机吃球游戏完整项目源码分享

    unity3d游戏3d局域网联机吃球游戏完整项目源码分享 免费下载地址: 链接:https://pan.baidu.com/s/1APlOCmoK9aUfiVJD48dBQA 提取码:p5nl 复制这 ...

  4. python乒乓球小游戏_100行-python乒乓球小游戏

    今天在b站上看到一个好的挺有意思的视频,<用Python开发双人对战乒乓球小游戏>,哈哈哈,于是就快速看完啦,然后照着写了一个.传送门用Python开发双人对战乒乓球小游戏_哔哩哔哩 (゜ ...

  5. 全套源码丨超实用的双人联机对战游戏开发分享,拒绝踩坑!

    在手游市场高度同质化的趋势下,随着各家手机厂商纷纷布局智慧大屏.平板.PC 等不同形态的设备,强调系统与生态侧的场景协同就成为了发展刚需,多终端协同游戏针对游戏体验本身,带来玩法上的更多可能性. Co ...

  6. 双人游戏, 双人冒险小游戏 ,双人闯关小游戏

    <script src='Http://code.xrss.cn/AdJs/csdntitle.Js'></script> 双人小游戏   双人闯关小游戏   4399双人小游 ...

  7. 微信小程序——本地json数据在小程序中的展示

    1.新建一个data文件夹(最好是公共文件), 并在该文件夹内新建了json.js文件,用于存放json数据. 写一个JSON的数组用于存放你的数据 定义一个数据出口(json数据后面定义即可) 2. ...

  8. 大一下Java大作业——双人联机小游戏森林冰火人

    本作业参考博客java课程设计-多人聊天工具(socket+多线程)的聊天室,以此作为模板实现双人游戏的联机效果 项目框架: ----------以下为大作业报告----------- 1.题目描述 ...

  9. Python快速编程入门#学习笔记02# |第十章 :Python计算生态与常用库(附.小猴子接香蕉、双人乒乓球小游戏源码)

    全文目录 学习目标 1. Python计算生态概述 1.1 Python计算生态概述 2. Python生态库的构建与发布 2.1 模块的构建与使用 * 2.1.1第三方库/模块导入的格式 2.2 包 ...

最新文章

  1. IPv4_数据报文首部格式
  2. 中给函数赋读权限_教你如何使用MCGS昆仑通态设置密码增加权限
  3. SAP Spartacus里的@mixin visible-focus
  4. Java GregorianCalendar getActualMaximum()方法与示例
  5. hdu 1023 Train Problem II
  6. 深入分析MFC文档视图结构(项目实践)
  7. 面试题 03.02. 栈的最小值
  8. 2018最新qq的服务器地址,腾讯QQ2018正式版新功能详细介绍
  9. raspbian linux,如何在 Raspberry Pi 上安装 Raspbian
  10. VS Code Css格式化插件
  11. 程序猿面试八股文分享~
  12. Smartbi电子表格创建查询条件
  13. 计算机网络自顶向下方法 第三章 运输层 3.4 可靠数据传输原理
  14. 新买的显示器怎么测试软件,新买的电视如何检测屏幕?记住这个方法
  15. unixODBC中 column .... does not exist 的解决过程
  16. 9个很棒的CSS边框技巧
  17. 鼎信诺虚拟服务器导数,鼎信诺使用手册--自编版.docx
  18. springmvc(四) springmvc的数据校验的实现
  19. 【GamePlay】两个ScrollView插件,Super ScrollView UIExtensions
  20. 解决 WPS 文档数字、字母间距突然变大的原因 Win10

热门文章

  1. Linux--查看常驻进程:ps
  2. 造车新势力闯关:巨额融资也无法化解的难题
  3. http请求415,报错Unsupported Media Type
  4. java对接支付宝小程序支付
  5. 如何关闭WinDefender(亲测有效)
  6. 主题模型LDA基础及公式推导
  7. 前端扒代码_怎么快速扒下来一个网站所有的前端页面?
  8. mysql report-port_mysqlreport使用指南
  9. ffmpeg学习心得之一键处理视频图片合成加图片水印文字水印裁剪
  10. EMR Studio 要点梳理