实践一个乒乓球小游戏 | “朝闻道”知识分享大赛

重生带我走 2023-12-21 22:29:32

这是我参加朝闻道知识分享大赛的第二十四篇文章。

弹出对话框

面向对象:编程进行大规模的社会分工,别的程序员已经写好了一些类,里面有一些方法,我们直接调用就可以了,就比如说,你不需要知道火龙果是怎么种出来的,只需要知道皮一剥开就可以吃了就行。

模板:

public class Test{
    pulic static void main(String[] args){
        JOptionPane.showMessageDialog(null,"哈哈");
    }
}

效果:

img

代码演示(对比):

package GUI;

import javax.swing.*;

public class Test01 {
    public static void main(String[] args) {
        System.out.println("哈哈");//之前写的这行,没有点经验的人都不知道这个输出在控制台了
        //显示一个对话框(对用户比较友好一些)
        JOptionPane.showMessageDialog(null,"哈哈");//这个方法接收两个参数,第一个参数是说这个对话框是属于哪个界面的,如果你不想它属于任何界面,直接写的null就可以了;第二个参数就是消息了
    }
}

文本输入对话框

模板:

public class Test{
    public static void main(String[] args){
        String name = JOptionPane.showInputDialog("你叫什么名字?")
    }
}

img

代码演示:

package GUI;

import javax.swing.*;

public class Test02 {
   public static void main(String[] args) {
        String name = JOptionPane.showInputDialog("请输入您的姓名: ");
        System.out.println("name: " + name);
        JOptionPane.showMessageDialog(null,"您的姓名长度为" + name.length() + "个字符");
    }
}

类似应用:

package GUI;

import javax.swing.*;

public class Test02 {
    public static void main(String[] args) {
        String s = JOptionPane.showInputDialog("请输入年份:");
        int year = Integer.parseInt(s);
        if(year % 4 == 0 && year % 100 != 0 || year % 400 == 0)
        {
            JOptionPane.showMessageDialog(null,"闰年");
        }else{
            JOptionPane.showMessageDialog(null,"平年");
        }
    }
}

过渡

画板

package Bridge;

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

public class MyPanel extends JPanel {
    @Override
    public void paint(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);//对抗锯齿

        for (int i = 0; i < 30; i++) {
            g.drawOval(20 + i * 5, 20 + i * 5, 10 + 10 * i, 10 + 10 * i);
        }
    }
}

对抗锯齿:

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

测试类

package Bridge;

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

public class Test {
    public static void main(String[] args) {
        JFrame frame = new JFrame("圆");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        MyPanel panel = new MyPanel();
        panel.setPreferredSize(new Dimension(600,500));
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
    }
}

设计乒乓球游戏

思考:游戏的关键元素有什么?

  • 捕获键盘事件

  • 游戏业务逻辑(updateLogic)

  • UI更新(renderUI)

游戏是个什么流程?

​ while(true){

​ 游戏业务逻辑;

​ UI更新;

}

介绍坐标系

img

对抗锯齿

        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

魔法数字(便于维护)

package demo14_PingPong;

public class Config {
    public static final int WINDOW_WIDTH = 600;
    public static final int WINDOW_HEIGHT = 400;

    public static final int BALL_WIDTH = 30;
    public static final int PANEL_HEIGHT = 390;
    public static final int PANEL_WIDTH = 50;
}

游戏类(实际是一个画板)

package demo14_PingPong;

import javax.swing.*;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;

public class Game extends JPanel {
    private GameEngine engine;
    private static JFrame frame;

    /**
     * 初始化的方法,把游戏界面给展现出来
     *
     * @param title  游戏窗体的名称
     * @param width  窗体的宽度
     * @param height 窗体的高度
     * @param engine 游戏引擎
     */
    public static void init(String title, int width, int height, GameEngine engine) {
        frame = new JFrame(title);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        Game panel = new Game();
        panel.addKeyListener(engine.listener);
        panel.setFocusable(true);
        panel.engine = engine;
        panel.setPreferredSize(new Dimension(width, height));
        frame.add(panel);
        frame.pack();
        frame.setVisible(true);
        while (true) {
            engine.updateLogic();
            panel.repaint();//让画板自动重绘
            try {
                Thread.sleep(30);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 游戏引擎退出游戏的界面
     *
     * @param message
     */
    public static void gameOver(String message,String title) {
        JOptionPane.showMessageDialog(frame, message,title,JOptionPane.YES_NO_OPTION);
        System.exit(ABORT);
    }

    @Override
    public void paint(Graphics g) {
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);
        engine.rendUI(g2d);
    }
}

游戏引擎(抽象类)

package demo14_PingPong;

import java.awt.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public abstract class GameEngine {
    KeyListener listener;
    private int currentPressedKeyCode;

    public GameEngine(){
        this.listener = new KeyListener() {
            @Override
            public void keyTyped(KeyEvent e) {

            }

            @Override
            public void keyPressed(KeyEvent e) {
                currentPressedKeyCode = e.getKeyCode();
            }

            @Override
            public void keyReleased(KeyEvent e) {
                currentPressedKeyCode = -1;
            }
        };
    }
    public int getCurrentPressedKeyCode(){return currentPressedKeyCode;}
    /**
     * 引擎设计者不关心游戏的逻辑怎么写
     */

    public abstract void updateLogic();

    /**
     * 引擎设计者不关心UI如何渲染,显示什么内容
     */
    public abstract void rendUI(Graphics2D g2d);//需要将Graphics传过来,不然没有它怎么画东西
}

"核心"的类

package demo14_PingPong;

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

public class MyGameEngine extends GameEngine{
    Random r = new Random();
    int x = 100;
    int y = 100;
    int x_speed = 3;
    int y_speed = 3;
    int panel_x = 300;
    @Override
    public void updateLogic() {
        x = x + x_speed;
        y = y + y_speed;
        if(x >= Config.WINDOW_WIDTH - Config.BALL_WIDTH){x_speed = -3;}
        if(y >= Config.WINDOW_HEIGHT - Config.BALL_WIDTH)
        {
            if(x >= panel_x && x <= panel_x + Config.PANEL_WIDTH)   y_speed = -3;
            else{
                Game.gameOver("游戏失败,再接再厉","很遗憾");
            }
        }
        if(x <= 0){x_speed = 3;}
        if(y <= 0){y_speed = 3;}
        int keyCode = getCurrentPressedKeyCode();
        if(keyCode == KeyEvent.VK_LEFT){
            panel_x-=5;
        }
        if(keyCode == KeyEvent.VK_RIGHT){
            panel_x+=5;
        }
    }

    @Override
    public void rendUI(Graphics2D g2d) {
        g2d.setColor(Color.black);
        g2d.fillOval(x,y,Config.BALL_WIDTH,Config.BALL_WIDTH);
        g2d.setColor(Color.black);
        g2d.fillRect(panel_x,Config.WINDOW_HEIGHT - 10,70,10);
    }
}

测试类(main)

package demo14_PingPong;

public class Test {
    public static void main(String[] args) {
        Game.init("乒乓球游戏", Config.WINDOW_WIDTH, Config.WINDOW_HEIGHT, new MyGameEngine());

    }
}
...全文
42 回复 打赏 收藏 转发到动态 举报
写回复
用AI写文章
回复
切换为时间正序
请发表友善的回复…
发表回复

1,040

社区成员

发帖
与我相关
我的任务
社区描述
中南民族大学CSDN高校俱乐部聚焦校内IT技术爱好者,通过构建系统化的内容和运营体系,旨在将中南民族大学CSDN社区变成校内最大的技术交流沟通平台。
经验分享 高校 湖北省·武汉市
社区管理员
  • c_university_1575
  • WhiteGlint666
  • wzh_scuec
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

欢迎各位加入中南民族大学&&CSDN高校俱乐部社区(官方QQ群:908527260),成为CSDN高校俱乐部的成员具体步骤(必填),填写如下表单,表单链接如下:
人才储备数据库及线上礼品发放表单邀请人吴钟昊:https://ddz.red/CSDN
CSDN高校俱乐部是给大家提供技术分享交流的平台,会不定期的给大家分享CSDN方面的相关比赛以及活动或实习报名链接,希望大家一起努力加油!共同建设中南民族大学良好的技术知识分享社区。

注意:

1.社区成员不得在社区发布违反社会主义核心价值观的言论。

2.社区成员不得在社区内谈及政治敏感话题。

3.该社区为知识分享的平台,可以相互探讨、交流学习经验,尽量不在社区谈论其他无关话题。

试试用AI创作助手写篇文章吧