[Java] 个人台球 →→→→→进入此内容的聊天室

来自 , 2020-06-26, 写在 Java, 查看 115 次.
URL http://www.code666.cn/view/6b8eba43
  1. package taiqiu;
  2.  
  3. import java.awt.Color;
  4. import java.awt.Frame;
  5. import java.awt.Graphics;
  6. import java.awt.Image;
  7. import java.awt.Panel;
  8. import java.awt.event.MouseEvent;
  9. import java.awt.event.MouseListener;
  10. import java.awt.event.MouseMotionListener;
  11. import java.awt.event.WindowAdapter;
  12. import java.awt.event.WindowEvent;
  13. import java.awt.image.BufferedImage;
  14.  
  15. /** */
  16. /**
  17.  * <p>
  18.  * Title: LoonFramework
  19.  * </p>
  20.  * <p>
  21.  * Description:Java桌球演示
  22.  * </p>
  23.  * <p>
  24.  * Copyright: Copyright (c) 2007
  25.  * </p>
  26.  * <p>
  27.  * Company: LoonFramework
  28.  * </p>
  29.  * http://cping1982.blog.51cto.com/601635/130098
  30.  * @author chenpeng
  31.  * @email:ceponline@yahoo.com.cn
  32.  * @version 0.1
  33.  */
  34.  
  35. public class JavaBilliards extends Panel implements Runnable, MouseListener,
  36.         MouseMotionListener {
  37.  
  38.     /** */
  39.     /**
  40.      *
  41.      */
  42.     private static final long serialVersionUID = -5019885590391523441L;
  43.  
  44.     // 球
  45.     private double _ball;
  46.  
  47.     // 缓存用背景
  48.     private Image _screen;
  49.  
  50.     // 画布
  51.     private Graphics _graphics;
  52.  
  53.     // 台桌
  54.     private Image _table;
  55.  
  56.     private double c[];
  57.  
  58.     private double d[];
  59.  
  60.     private double e[];
  61.  
  62.     private double f[];
  63.  
  64.     private int countBall;
  65.  
  66.     private int h;
  67.  
  68.     private double i[];
  69.  
  70.     private double j[];
  71.  
  72.     private double k[];
  73.  
  74.     private double l[];
  75.  
  76.     private double m[];
  77.  
  78.     private double n[];
  79.  
  80.     private double o[];
  81.  
  82.     private double p[];
  83.  
  84.     private boolean q[];
  85.  
  86.     private double r;
  87.  
  88.     private int a;
  89.  
  90.     private int u;
  91.  
  92.     private int v;
  93.  
  94.     private int w;
  95.  
  96.     private int x;
  97.  
  98.     private boolean y;
  99.  
  100.     private int z;
  101.  
  102.     private int A;
  103.  
  104.     /** */
  105.     /**
  106.      * 初始化
  107.      *
  108.      */
  109.     public JavaBilliards() {
  110.         a = 0;
  111.         r = 10D;
  112.         z = 300;
  113.         A = 0;
  114.         setBounds(50, 50, 700, 350);
  115.         Frame frame = new Frame("Java桌球演示");
  116.         frame.add(this);
  117.         frame.setBounds(0, 0, 700, 380);
  118.         frame.setResizable(false);
  119.         frame.setVisible(true);
  120.         frame.addWindowListener(new WindowAdapter() {
  121.             public void windowClosing(WindowEvent e) {
  122.                 System.exit(0);
  123.             }
  124.         });
  125.         requestFocus();
  126.         initialize();
  127.     }
  128.  
  129.     public void initialize() {
  130.         // 基础数据
  131.         base();
  132.         // 注入实例
  133.         immit();
  134.         // 缓存背景
  135.         _screen = new BufferedImage(this.getWidth(), this.getHeight(), 1);
  136.         // 背景图形
  137.         _graphics = _screen.getGraphics();
  138.         // 绘制台桌
  139.         makeTable();
  140.         // 设置监听
  141.         addMouseListener(this);
  142.         addMouseMotionListener(this);
  143.         // 启动
  144.         new Thread(this).start();
  145.     }
  146.  
  147.     /** */
  148.     /**
  149.      * 初始化数据
  150.      *
  151.      */
  152.     public void base() {
  153.  
  154.         // 球体
  155.         _ball = 16D;
  156.         c = (new double[] { 40D, (double) (getWidth() - 40) });
  157.         d = (new double[] { c[0], (double) getHeight() - c[0] });
  158.         e = (new double[] { c[0] + 20D, (double) (getWidth() / 2), c[1] - 20D });
  159.         f = (new double[] { d[0] + 20D, d[1] - 20D });
  160.     }
  161.  
  162.     /** */
  163.     /**
  164.      * 注入实例
  165.      *
  166.      */
  167.     public void immit() {
  168.         countBall = 16;
  169.         i = new double[countBall];
  170.         j = new double[countBall];
  171.         k = new double[countBall];
  172.         l = new double[countBall];
  173.         m = new double[countBall];
  174.         n = new double[countBall];
  175.         o = new double[countBall];
  176.         p = new double[countBall];
  177.         q = new boolean[countBall];
  178.         // 打击对象
  179.         hitObject();
  180.         // 打击用球
  181.         hitBall();
  182.     }
  183.  
  184.     /** */
  185.     /**
  186.      * 打击用球数值
  187.      *
  188.      */
  189.     public void hitBall() {
  190.         i[0] = (1.0D * (e[2] - e[0])) / 3D;
  191.         j[0] = this.getHeight() / 2;
  192.         k[0] = 0.0D;
  193.         l[0] = 0.0D;
  194.         q[0] = true;
  195.     }
  196.  
  197.     /** */
  198.     /**
  199.      * 打击对象
  200.      *
  201.      */
  202.     public void hitObject() {
  203.         int il = 1;
  204.         h = countBall - 1;
  205.         // 求平方根
  206.         double dl = Math.sqrt(3.5D);
  207.         for (int j1 = 0; j1 < 5; j1++) {
  208.             double d2 = ((double) getWidth() * 2D) / 3D + (double) j1 * dl * r;
  209.             double d3 = (double) (getHeight() / 2) - (double) j1 * r;
  210.             for (int k1 = 0; k1 <= j1; k1++) {
  211.                 i[il] = d2;
  212.                 j[il] = d3;
  213.                 k[il] = 0.0D;
  214.                 l[il] = 0.0D;
  215.                 q[il] = true;
  216.                 d3 += 2D * r;
  217.                 il++;
  218.             }
  219.  
  220.         }
  221.  
  222.     }
  223.  
  224.     /** */
  225.     /**
  226.      * 绘制台球桌
  227.      *
  228.      */
  229.     public void makeTable() {
  230.         _table = new BufferedImage(this.getWidth(), this.getHeight(), 1);
  231.         Graphics g = _table.getGraphics();
  232.         g.setColor(Color.GRAY);
  233.         g.fillRect(0, 0, getWidth(), getHeight());
  234.         g.setColor((new Color(200, 100, 50)).darker());
  235.         g.fill3DRect((int) c[0], (int) d[0], (int) (c[1] - c[0]),
  236.                 (int) (d[1] - d[0]), true);
  237.         g.setColor(Color.BLACK);
  238.         g.fill3DRect((int) e[0], (int) f[0], (int) (e[2] - e[0]),
  239.                 (int) (f[1] - f[0]), false);
  240.         g.setColor(Color.GREEN.darker());
  241.         g.drawLine((int) ((1.0D * (e[2] - e[0])) / 3D), (int) f[0],
  242.                 (int) ((1.0D * (e[2] - e[0])) / 3D), (int) f[1]);
  243.         g.fillOval((int) ((1.0D * (e[2] - e[0])) / 3D) - 2,
  244.                 (int) ((f[1] + f[0]) / 2D) - 2, 4, 4);
  245.         g.drawArc((int) ((1.0D * (e[2] - e[0])) / 3D) - 20,
  246.                 (int) ((f[1] + f[0]) / 2D) - 20, 40, 40, 90, 180);
  247.         g.setColor(Color.BLACK);
  248.         double d1 = _ball - 2D;
  249.         for (int i1 = 0; i1 < 3; i1++) {
  250.             for (int j1 = 0; j1 < 2; j1++) {
  251.                 g.fillOval((int) (e[i1] - d1), (int) (f[j1] - d1),
  252.                         (int) (2D * d1), (int) (2D * d1));
  253.             }
  254.         }
  255.     }
  256.  
  257.     /** */
  258.     /**
  259.      * 线程处理
  260.      */
  261.     public void run() {
  262.         long timeStart;
  263.         timeStart = System.currentTimeMillis();
  264.         // 死循环反复处理
  265.         for (;;) {
  266.             long timeEnd = System.currentTimeMillis();
  267.             switch (a) {
  268.             default:
  269.                 break;
  270.  
  271.             case 1:
  272.                 // 根据时间换算运动轨迹
  273.                 conversion(timeEnd - timeStart);
  274.                 // 过程处理
  275.                 course();
  276.                 break;
  277.  
  278.             case 2:
  279.                 conversion(timeEnd - timeStart);
  280.                 // 过程处理
  281.                 course();
  282.                 boolean flag = true;
  283.                 for (int i1 = 0; flag && i1 < countBall; i1++)
  284.                     flag = k[i1] == 0.0D && l[i1] == 0.0D;
  285.  
  286.                 if (flag) {
  287.                     a = 1;
  288.                     // 击球
  289.                     if (!q[0]) {
  290.                         hitBall();
  291.                     }
  292.                 }
  293.                 if (h == 0)
  294.                     a = 3;
  295.                 break;
  296.  
  297.             case 3:
  298.                 hitObject();
  299.                 hitBall();
  300.                 a = 0;
  301.                 break;
  302.             }
  303.  
  304.             repaint();
  305.             timeStart = timeEnd;
  306.             try {
  307.                 Thread.sleep(10L);
  308.             } catch (InterruptedException e1) {
  309.                 e1.printStackTrace();
  310.             }
  311.         }
  312.  
  313.     }
  314.  
  315.     public void course() {
  316.         // 限制区域
  317.         limit();
  318.         // 入袋处理
  319.         pocket();
  320.         // 运动演算
  321.         play();
  322.         for (int i1 = 0; i1 < countBall; i1++)
  323.             if (q[i1]) {
  324.                 i[i1] = m[i1];
  325.                 j[i1] = n[i1];
  326.             }
  327.     }
  328.  
  329.     /** */
  330.     /**
  331.      * 变换时间为动作数据
  332.      *
  333.      * @param value
  334.      */
  335.     public void conversion(long value) {
  336.         double d1 = (double) value / 1000D;
  337.         for (int i1 = 0; i1 < countBall; i1++)
  338.             if (q[i1]) {
  339.                 m[i1] = i[i1] + k[i1] * d1;
  340.                 n[i1] = j[i1] + l[i1] * d1;
  341.                 k[i1] *= 0.98999999999999999D;
  342.                 l[i1] *= 0.98999999999999999D;
  343.                 if (Math.abs(Math.hypot(k[i1], l[i1])) < 2D) {
  344.                     k[i1] = 0.0D;
  345.                     l[i1] = 0.0D;
  346.                 }
  347.             }
  348.  
  349.     }
  350.  
  351.     public void pocket() {
  352.         for (int i1 = 0; i1 < countBall; i1++)
  353.             if (q[i1]) {
  354.                 for (int j1 = 0; j1 < 3; j1++) {
  355.                     for (int k1 = 0; k1 < 2; k1++)
  356.                         if (Math.hypot(e[j1] - i[i1], f[k1] - j[i1]) < _ball) {
  357.                             q[i1] = false;
  358.                             if (i1 != 0) {
  359.                                 h--;
  360.                             }
  361.                             k[i1] = 0.0D;
  362.                             l[i1] = 0.0D;
  363.                         }
  364.  
  365.                 }
  366.  
  367.             }
  368.  
  369.     }
  370.  
  371.     public void play() {
  372.         for (int i1 = 0; i1 < countBall; i1++)
  373.             if (q[i1]) {
  374.                 for (int j1 = i1 + 1; j1 < countBall; j1++) {
  375.                     boolean flag;
  376.                     if (q[j1] && (flag = randball(i1, j1))) {
  377.                         for (int k1 = 0; k1 < 10 && flag; k1++) {
  378.                             m[i1] = (m[i1] + i[i1]) / 2D;
  379.                             n[i1] = (n[i1] + j[i1]) / 2D;
  380.                             m[j1] = (m[j1] + i[j1]) / 2D;
  381.                             n[j1] = (n[j1] + j[j1]) / 2D;
  382.                             flag = randball(i1, j1);
  383.                         }
  384.  
  385.                         if (flag) {
  386.                             m[i1] = i[i1];
  387.                             n[i1] = j[i1];
  388.                             m[j1] = i[j1];
  389.                             n[j1] = j[j1];
  390.                         }
  391.                         double d1 = m[j1] - m[i1];
  392.                         double d2 = n[j1] - n[i1];
  393.                         double d3 = Math.hypot(m[i1] - m[j1], n[i1] - n[j1]);
  394.                         double d4 = d1 / d3;
  395.                         double d5 = d2 / d3;
  396.                         o[j1] = k[j1] - k[j1] * d4 * d4;
  397.                         o[j1] -= l[j1] * d4 * d5;
  398.                         o[j1] += k[i1] * d4 * d4;
  399.                         o[j1] += l[i1] * d4 * d5;
  400.                         p[j1] = l[j1] - l[j1] * d5 * d5;
  401.                         p[j1] -= k[j1] * d4 * d5;
  402.                         p[j1] += k[i1] * d4 * d5;
  403.                         p[j1] += l[i1] * d5 * d5;
  404.                         o[i1] = k[i1] - k[i1] * d4 * d4;
  405.                         o[i1] -= l[i1] * d4 * d5;
  406.                         o[i1] += k[j1] * d4 * d4;
  407.                         o[i1] += l[j1] * d4 * d5;
  408.                         p[i1] = l[i1] - l[i1] * d5 * d5;
  409.                         p[i1] -= k[i1] * d4 * d5;
  410.                         p[i1] += k[j1] * d4 * d5;
  411.                         p[i1] += l[j1] * d5 * d5;
  412.                         k[i1] = o[i1];
  413.                         l[i1] = p[i1];
  414.                         k[j1] = o[j1];
  415.                         l[j1] = p[j1];
  416.                     }
  417.                 }
  418.  
  419.             }
  420.  
  421.     }
  422.  
  423.     public boolean randball(int i1, int j1) {
  424.         // hypot随机决定两值之一
  425.         return Math.hypot(m[i1] - m[j1], n[i1] - n[j1]) < 2D * r;
  426.     }
  427.  
  428.     /** */
  429.     /**
  430.      * 限制区域
  431.      *
  432.      */
  433.     public void limit() {
  434.         for (int i = 0; i < countBall; i++)
  435.             if (q[i]) {
  436.                 if (m[i] - r < e[0]) {
  437.                     m[i] = e[0] + r;
  438.                     k[i] *= -1D;
  439.                 } else if (m[i] + r > e[2]) {
  440.                     m[i] = e[2] - r;
  441.                     k[i] *= -1D;
  442.                 }
  443.                 if (n[i] - r < f[0]) {
  444.                     n[i] = f[0] + r;
  445.                     l[i] *= -1D;
  446.                 } else if (n[i] + r > f[1]) {
  447.                     n[i] = f[1] - r;
  448.                     l[i] *= -1D;
  449.                 }
  450.             }
  451.  
  452.     }
  453.  
  454.     public void makeScreen(Graphics screenGraphics) {
  455.  
  456.         screenGraphics.drawImage(_table, 0, 0, null);
  457.         if (q[0]) {
  458.             _graphics.setColor(Color.WHITE);
  459.             _graphics.fillOval((int) (i[0] - r), (int) (j[0] - r),
  460.                     (int) (r * 2D), (int) (r * 2D));
  461.         }
  462.         screenGraphics.setColor(Color.RED);
  463.         for (int i1 = 1; i1 < countBall; i1++)
  464.             if (q[i1])
  465.                 screenGraphics.fillOval((int) (i[i1] - r), (int) (j[i1] - r),
  466.                         (int) (r * 2D), (int) (r * 2D));
  467.  
  468.         screenGraphics.setColor(Color.BLACK);
  469.         for (int j1 = 0; j1 < countBall; j1++)
  470.             if (q[j1]) {
  471.                 screenGraphics.drawOval((int) (i[j1] - r), (int) (j[j1] - r),
  472.                         (int) (r * 2D), (int) (r * 2D));
  473.             }
  474.  
  475.         if (a == 1) {
  476.             makeHelper(screenGraphics);
  477.         }
  478.         if (a == 0) {
  479.             int k1 = getWidth() / 2 - 85;
  480.             int l1 = getHeight() / 2;
  481.             screenGraphics.setColor(Color.BLACK);
  482.             screenGraphics.drawString("点击画面开始", k1 + 2, l1 + 2);
  483.             if ((System.currentTimeMillis() / 1000L & 1L) == 0L) {
  484.                 screenGraphics.setColor(Color.YELLOW);
  485.             } else {
  486.                 screenGraphics.setColor(Color.CYAN);
  487.             }
  488.             screenGraphics.drawString("点击画面开始", k1, l1);
  489.         }
  490.     }
  491.  
  492.     /** */
  493.     /**
  494.      * 绘制球杆及辅助线
  495.      *
  496.      * @param screenGraphics
  497.      */
  498.     public void makeHelper(Graphics screenGraphics) {
  499.         double d1 = Math.hypot(i[0] - (double) u, j[0] - (double) v);
  500.         double d2 = ((double) u - i[0]) / d1;
  501.         double d3 = ((double) v - j[0]) / d1;
  502.         double d4 = y ? n() / 10D : 1.0D;
  503.         double d5 = i[0] + d2 * (r + d4);
  504.         double d6 = i[0] + d2 * (r + (double) z + d4);
  505.         double d7 = j[0] + d3 * (r + d4);
  506.         double d8 = j[0] + d3 * (r + (double) z + d4);
  507.         screenGraphics.setColor(Color.ORANGE);
  508.         screenGraphics.drawLine((int) d5, (int) d7, (int) d6, (int) d8);
  509.         int i1 = 0;
  510.         int j1 = y ? (int) (150D * (d4 / 1000D)) : 15;
  511.         double d9;
  512.         double d10 = (d9 = 30D) * d2;
  513.         double d11 = d9 * d3;
  514.         double d12 = i[0] + (double) A * d2;
  515.         double d13 = j[0] + (double) A * d3;
  516.         A--;
  517.         A %= d9;
  518.         screenGraphics.setColor(Color.WHITE);
  519.         for (; i1 < j1; i1++) {
  520.             if (d12 < e[0]) {
  521.                 d12 = e[0] - d12;
  522.                 d12 = e[0] + d12;
  523.                 d10 *= -1D;
  524.             } else if (d12 > e[2]) {
  525.                 d12 -= e[2];
  526.                 d12 = e[2] - d12;
  527.                 d10 *= -1D;
  528.             }
  529.             if (d13 < f[0]) {
  530.                 d13 = f[0] - d13;
  531.                 d13 = f[0] + d13;
  532.                 d11 *= -1D;
  533.             } else if (d13 > f[1]) {
  534.                 d13 -= f[1];
  535.                 d13 = f[1] - d13;
  536.                 d11 *= -1D;
  537.             }
  538.             screenGraphics.fillOval((int) d12 - 2, (int) d13 - 2, 4, 4);
  539.             d12 -= d10;
  540.             d13 -= d11;
  541.         }
  542.  
  543.     }
  544.  
  545.     public double n() {
  546.         if (y) {
  547.             return Math.min(1000D,
  548.                     10D * Math.hypot(i[0] - (double) w, j[0] - (double) x));
  549.         } else {
  550.             return Math.min(1000D, 10D * Math.hypot(u - w, v - x));
  551.         }
  552.     }
  553.  
  554.     public void update(Graphics g) {
  555.         paint(g);
  556.     }
  557.  
  558.     public void paint(Graphics g) {
  559.         makeScreen(_graphics);
  560.         g.drawImage(_screen, 0, 0, null);
  561.     }
  562.  
  563.     public void mousePressed(MouseEvent mouseevent) {
  564.         y = true;
  565.     }
  566.  
  567.     public void mouseReleased(MouseEvent mouseevent) {
  568.         if (a == 1) {
  569.             double d1 = Math.hypot(i[0] - (double) u, j[0] - (double) v);
  570.             double d2 = (i[0] - (double) u) / d1;
  571.             double d3 = (j[0] - (double) v) / d1;
  572.             double d4;
  573.             if ((d4 = n()) > 0.0D) {
  574.                 a = 2;
  575.                 k[0] = d4 * d2;
  576.                 l[0] = d4 * d3;
  577.             }
  578.         }
  579.         y = false;
  580.     }
  581.  
  582.     public void mouseClicked(MouseEvent mouseevent) {
  583.         if (a == 0)
  584.             a = 1;
  585.     }
  586.  
  587.     public void mouseEntered(MouseEvent mouseevent) {
  588.     }
  589.  
  590.     public void mouseExited(MouseEvent mouseevent) {
  591.     }
  592.  
  593.     public void mouseMoved(MouseEvent mouseevent) {
  594.         w = mouseevent.getX();
  595.         x = mouseevent.getY();
  596.         u = w;
  597.         v = x;
  598.     }
  599.  
  600.     public void mouseDragged(MouseEvent mouseevent) {
  601.         w = mouseevent.getX();
  602.         x = mouseevent.getY();
  603.     }
  604.  
  605.     public static void main(String args[]) {
  606.         new JavaBilliards();
  607.     }
  608.  
  609. }
  610.  

回复 "个人台球"

这儿你可以回复上面这条便签

captcha