• 2小时开发《点球射门游戏》,动画演示思路(上),代码已开源


    唠两句

    最近被疫情关在家,时间多运动少,真的很无聊呀!也许是天意为之,居然来世界杯了,虽然这届世界杯很「冷」,但是多少还是为无聊的我们增加了一些无聊的趣事,比如勇哥在等世界杯开幕式的过程中,就无聊手写了一个Java版本的【点球射门游戏】,这几天把球瘾过了,今天有点时间,把这个游戏分享给大家,希望大家喜欢!(游戏也有音乐,gif放不了,有点小可惜)

    1、请各位老铁收藏、点赞鼓励一波!

    2、源码,在评论区扣6,我私服给你!

    游戏有那些值得大家学习【重点】

    • 球的瞄准轨迹线怎么实现【见下图1】?这个在QQ桌球、王者荣耀、愤怒的小鸟等游戏中都用到了!

    • 怎么画三维立体的图片【见下图2】?

    • 怎么实现动画【见下图3】?

      图1
      图1
    图2

    图3

    游戏界面实现思路&代码

    界面术语定义

    界面分为游戏区和计分区,其中游戏区又分为:

    • 观众区

    • 球门区

    • 游戏元素

    • 射门区

    观众区绘制思路&代码

    观众区用swing纯代码是可以绘制的,绘制的思路如下:

    • 1、绘制一个背景矩形框

    • 2、绘制第2排观众

      • 绘制一个圆和椭圆合并成一个观众样式

      • 绘制一个小一点的圆和椭圆合并成一个观众样式

      • 组合并放置到第2排位置,并铺满整排

    • 3、绘制第1排观众【与上一步一致,注意换观众的颜色】

      • 绘制一个圆和椭圆合并成一个观众样式

      • 绘制一个小一点的圆和椭圆合并成一个观众样式

      • 组合并放置到第1排位置,并铺满整排

    • 4、绘制两个不同颜色的矩形框,并摆放最前面遮挡第1排观众的‘脚’

    • 5、绘制几根黑线,遮挡广告边缘

    为方便大家理解,勇哥这次给大家上动画,赞一个吧:

    参考实现代码:

    1. // 观众背景
    2. g2d.setColor(personBgColor);
    3. g2d.fillRect(0,y,getWidth(),100);//画矩形
    4. for (int i = 0; i < getWidth(); i+=46) {
    5. // 观众第二排
    6. g2d.setColor(person2);
    7. g2d.fillOval(i,36,16,16);//画圆
    8. g2d.fillArc(i-7,50,30,50,0,180);// 画扇行
    9. g2d.fillOval(i+24,40,13,13);
    10. g2d.fillArc(i+18,51,24,49,0,180);
    11. }
    12. y+=90;
    13. // 观众第一排
    14. g2d.fillRect(0,y-30,getWidth(),50);
    15. g2d.setColor(person1);
    16. for (int i = 0; i < getWidth(); i+=46) {
    17. g2d.fillOval(i+7,y-41,16,16);
    18. g2d.fillArc(i,y-25,30,50,0,180);
    19. g2d.fillOval(i+31,y-34,13,13);
    20. g2d.fillArc(i+25,y-24,24,49,0,180);
    21. }
    22. // 绘制广告栏和黑线
    23. g2d.setColor(personBgColor1);
    24. g2d.fillRect(0,y,getWidth(),20);
    25. g2d.setColor(personLineColor);
    26. g2d.fillRect(0,y,getWidth(),2);
    27. y+=20;
    28. g2d.setColor(personBgColor2);
    29. g2d.fillRect(0,y,getWidth(),18);
    30. y+=18;
    31. g2d.setColor(personLineColor);
    32. g2d.fillRect(0,y,getWidth(),2);
    33. for (int i = 1; i < 5; i++) {
    34. g2d.fillRect(getWidth()*i/5,y-38,2,38);
    35. }

    草坪绘制思路&代码

    草坪区用swing纯代码是可以绘制的,绘制的思路如下:

    • 1、绘制两种不同颜色的矩形

    • 2、用两种不用颜色的矩形铺满整个屏幕

    • 3、调整矩形的高度是从上下一次递增,呈现立体视觉

    上动画,赞一个吧:

    参考实现代码:

    1. // 足球草地
    2. int count =0;
    3. int h1=60;
    4. for (int i = y; i < getHeight(); i++) {
    5. if(count%2==0){
    6. g2d.setColor(bgColor1);
    7. }else{
    8. g2d.setColor(bgColor2);
    9. }
    10. g2d.fillRect(0,y,getWidth(),h1+count*10);
    11. y+=h1+count*10;
    12. count++;
    13. }

    禁区三维绘制思路&代码

    禁区用swing纯代码是可以绘制的,绘制的思路如下:

    • 1、绘制一个空心的圆角矩形

    • 2、使用变换技术,让圆角矩形具有三维立体效果

    • 3、调整禁区框的位置

    • 4、用一个绿色矩形遮挡多于的禁区部分

    上动画,赞一个吧:

    参考实现代码:

    注意代码实现的时候,需要绘制两个圆角矩形合并,并擦除中间不要的部分,这部分有点难,如果不理解可以留言,我给你弄视频说明。

    1. g2d.setColor(Color.WHITE);
    2. g2d.fillRect(0,175,getWidth(),5);
    3. AffineTransform oldTx = g2d.getTransform();
    4. Stroke stroke = new BasicStroke(5);
    5. g2d.setStroke(stroke);
    6. AffineTransform tx = new AffineTransform();
    7. tx.setToShear(-0.5, 0);
    8. g2d.setTransform(tx);
    9. g2d.drawRoundRect(getWidth()*5/20,175,getWidth()*6/10,120,10,10);
    10. AffineTransform tx2= new AffineTransform();
    11. tx2.setToShear(0.5, 0);
    12. g2d.setTransform(tx2);
    13. g2d.drawRoundRect(getWidth()*3/20,175,getWidth()*6/10,120,10,10);
    14. g2d.setTransform(oldTx);
    15. //清理内部多余的线
    16. g2d.setColor(bgColor1);
    17. g2d.fillRect(0,173,getWidth(),2);
    18. g2d.fillRect(getWidth()*3/20+10,180,getWidth()*7/10-20,20);
    19. g2d.fillRect(getWidth()*3/20+10,270,getWidth()*6/10-20,23);
    20. g2d.setColor(bgColor2);
    21. g2d.fillRect(getWidth()*3/20+10,200,getWidth()*6/10-20,70);

    球门球网三维绘制思路&代码

    球门球网这个是最难的,难在用平面技术画三维效果,当然swing也是可以的,绘制的思路如下:

    • 1、绘制一个圆角矩形,作为球门框

    • 2、绘制两条弯折折线,作为球门内门柱

    • 3、绘制多条水平的三线段折线,作为球门水平球门线

    • 4、绘制多条垂直的二线段折线,作为球门垂直球门线

    这个比较复杂,必须上动画,必须赞一个:

    参考实现代码:

    1. g2d.setColor(Color.WHITE);
    2. int step = 15;
    3. int startX = getWidth()*4/20+20;
    4. int centerX = getWidth()/2;
    5. int startY = 85;
    6. // 球网竖线
    7. for (int i = startX; i < (getWidth()*4/5); i=startX) {
    8. int x[] = {startX,startX+(startX8:-8),startX+(startX12:-12)};
    9. int y[] = {startY,startY+10,155};
    10. if((centerX-startX)!=-10) {
    11. g2d.drawPolyline(x, y, x.length);//画折线
    12. }
    13. startX+=step;
    14. }
    15. // 球迷柱左里
    16. Stroke stroke = new BasicStroke(5);
    17. g2d.setStroke(stroke);
    18. startX = getWidth()*4/20+20;
    19. int tempX[] = {startX-18,startX-2,startX-2};
    20. int tempY[] = {startY+3,startY+10,153};
    21. g2d.drawPolyline(tempX, tempY, tempY.length);
    22. startX = getWidth()*4/5;
    23. int rightX[] = {startX-2,startX-20,startX-24};
    24. int rightY[] = {startY+3,startY+10,153};
    25. g2d.drawPolyline(rightX, rightY, rightY.length);
    26. stroke = new BasicStroke(1);
    27. g2d.setStroke(stroke);
    28. startX = getWidth()*4/20;
    29. // 球网横线
    30. int endX = getWidth()*4/5;
    31. for (int i = startY; i < 156; i=startY) {
    32. int x[] = {startX,startX+(startX18:-18),endX-12,endX};
    33. int y[] = {startY,startY-3,startY-3,startY};
    34. g2d.drawPolyline(x,y,x.length);
    35. startY+=step;
    36. }
    37. int x[] = {startX,startX+(startX18:-18),endX-12,endX};
    38. int y[] = {158,155,155,158};
    39. g2d.drawPolyline(x,y,x.length);
    40. // 绘制门框
    41. g2d.setColor(doorColor);
    42. stroke = new BasicStroke(9);
    43. g2d.setStroke(stroke);
    44. g2d.drawRoundRect(getWidth()*4/20,85,getWidth()*3/5,95,20,20);// 带有圆角的矩形
    45. stroke = new BasicStroke(5);
    46. g2d.setStroke(stroke);
    47. g2d.setColor(Color.WHITE);
    48. g2d.drawRoundRect(getWidth()*4/20,86,getWidth()*3/5,95,20,20);
    49. g2d.fillRect(0,175,getWidth(),5);

    蓄力区绘制思路&代码

    蓄力区用swing纯代码是可以绘制的,绘制的思路如下:

    • 1、绘制两种不同颜色的扇形

    • 2、叠加两个扇形

    • 3、配上高逼格文字

    简单吧,也必上动画,也必须赞一个:

    参考实现代码:

    1. // 蓄力区
    2. g2d.setColor(Color.WHITE);
    3. g2d.fillArc((getWidth()-64)/2-80,460,224,160,0,180);
    4. g2d.setColor(Color.ORANGE);
    5. g2d.fillArc((getWidth()-64)/2-80,460,224,160,0,arc);
    6. // 文字
    7. Font font = new Font("阿里巴巴普惠体 Medium",1,24);
    8. g2d.setFont(font);
    9. g2d.setColor(Color.WHITE);
    10. g2d.drawString("Ctrl + 鼠标: 移动球",30,400);
    11. g2d.drawString("拖动鼠标: 调整角度",50,440);
    12. g2d.drawString("点击鼠标: 射门",50,480);

    计分区绘制思路&代码

    计分区区用swing纯代码是可以绘制的,绘制的思路如下:

    • 1、绘制两种不同颜色的矩形

    • 2、用两种不用颜色的矩形铺满整个屏幕

    • 3、调整矩形的高度是从上下一次递增,呈现立体视觉

    上动画,赞一个吧:

    参考实现代码:

    1. Graphics2D g2d = (Graphics2D)g;
    2. g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    3. g.setColor(bgColor1);
    4. g.fillRect(0,0,getWidth(),getHeight());
    5. g.setColor(bgColor2);
    6. g.fillRect(0,8,getWidth(),getHeight()-8);
    7. Font font = new Font("阿里巴巴普惠体 Medium",1,32);
    8. g.setFont(font);
    9. g2d.setColor(Color.BLACK);
    10. g2d.drawString("分数",30,45);
    11. g2d.drawString("TIME",250,45);
    12. g2d.drawString("次数",540,45);
    13. g2d.setColor(textColor);
    14. g2d.fillRoundRect(100,20,80,30,25,25);
    15. g2d.fillRoundRect(335,20,120,30,25,25);
    16. g2d.fillRoundRect(620,20,80,30,25,25);
    17. g2d.setColor(Color.WHITE);
    18. g2d.drawString(String.format("%02d",score),120,47);
    19. g2d.drawString(String.format("%02d:%02d",time/60,time%60),345,47);
    20. g2d.drawString(String.format("%02d",count),638,47);

    守门员&球绘制思路&代码

    守门员&球绘&石头这里就直接用图片了,绘制的思路如下:

    • 1、加载图片

    • 2、把图片摆放到对应位置

    上动画,赞一个吧:

     

    参考实现代码:

    1. // 球
    2. public class Ball extends JLabel{
    3. int startX = 0 ;
    4. int startY = 0;
    5. public Ball(){
    6. this.setPreferredSize(new Dimension(64,64));
    7. this.setIcon(new ImageIcon(ResourcesUtil.getRootPath()+"\\ball\\football.png"));// 加载图片
    8. }
    9. }
    1. // 守门员
    2. public Goalkeeper(BackgroundPanel backgroundPanel){
    3. this.backgroundPanel = backgroundPanel;
    4. this.setBounds(backgroundPanel.getWidth()/2,100,78,128);
    5. this.setPreferredSize(new Dimension(78,128));
    6. this.setIcon(new ImageIcon(ResourcesUtil.getRootPath()+"\\ball\\smy.png"));
    7. }
    1. // 石头
    2. public class Shitou extends JLabel implements Obstacle {
    3. BackgroundPanel backgroundPanel;
    4. public Shitou(BackgroundPanel backgroundPanel){
    5. this.backgroundPanel = backgroundPanel;
    6. this.setBounds(backgroundPanel.getWidth()/2+50,100,316,100);//设置图片放置的位置
    7. this.setPreferredSize(new Dimension(316,100));
    8. this.setIcon(new ImageIcon(ResourcesUtil.getRootPath()+"\\ball\\st.png"));
    9. }
    10. @Override
    11. public String name() {
    12. return "石头";
    13. }
    14. @Override
    15. public JComponent getComponent() {
    16. return this;
    17. }
    18. public void start(){
    19. }
    20. public void stop(){
    21. }
    22. }
  • 相关阅读:
    一张图读懂人工智能
    四大主流BI工具的对比分析!
    linux 安装R 环境(最新)
    软考——软件工程基础知识
    C++创建型模式-建造者模式
    渗透测试过程中的JS调试(一)
    简单实现,在nodejs中简单使用kafka
    Qt5开发从入门到精通——第十一篇二节(Qt5 事件处理及实例——键盘事件及实例)
    中英双语大模型ChatGLM论文阅读笔记
    BIRCH算法全解析:从原理到实战
  • 原文地址:https://blog.csdn.net/luoxueyong/article/details/128123006