写点什么

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

作者:非喵鱼
  • 2022-12-08
    重庆
  • 本文字数:4327 字

    阅读完需:约 14 分钟

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

勇哥来 INFOQ 了、关注一下

  • 学习小游戏开发

  • 学习大型数据库管理软件开发

  • 学习 IDEA 插件开发

  • 学习微服务技术开发

  • 还有更多内容,请期待~

~~~ 记得点赞、关注哦 ~~~

唠两句

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


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

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

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

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




游戏界面实现思路 &代码

界面术语定义

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

  • 观众区

  • 球门区

  • 游戏元素

  • 射门区



观众区绘制思路 &代码

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

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

  • 2、绘制第 2 排观众

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

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

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

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

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

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

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

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

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

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


参考实现代码:


// 观众背景g2d.setColor(personBgColor);g2d.fillRect(0,y,getWidth(),100);//画矩形for (int i = 0; i < getWidth(); i+=46) {    // 观众第二排    g2d.setColor(person2);    g2d.fillOval(i,36,16,16);//画圆    g2d.fillArc(i-7,50,30,50,0,180);// 画扇行    g2d.fillOval(i+24,40,13,13);    g2d.fillArc(i+18,51,24,49,0,180);}y+=90;// 观众第一排g2d.fillRect(0,y-30,getWidth(),50);g2d.setColor(person1);for (int i = 0; i < getWidth(); i+=46) {    g2d.fillOval(i+7,y-41,16,16);    g2d.fillArc(i,y-25,30,50,0,180);    g2d.fillOval(i+31,y-34,13,13);    g2d.fillArc(i+25,y-24,24,49,0,180);}// 绘制广告栏和黑线g2d.setColor(personBgColor1);g2d.fillRect(0,y,getWidth(),20);g2d.setColor(personLineColor);g2d.fillRect(0,y,getWidth(),2);y+=20;g2d.setColor(personBgColor2);g2d.fillRect(0,y,getWidth(),18);y+=18;g2d.setColor(personLineColor);g2d.fillRect(0,y,getWidth(),2);for (int i = 1; i < 5; i++) {    g2d.fillRect(getWidth()*i/5,y-38,2,38);}
复制代码

草坪绘制思路 &代码

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

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

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

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

上动画,赞一个吧:



参考实现代码:


// 足球草地int count =0;int h1=60;for (int i = y; i < getHeight(); i++) {    if(count%2==0){        g2d.setColor(bgColor1);    }else{        g2d.setColor(bgColor2);    }    g2d.fillRect(0,y,getWidth(),h1+count*10);    y+=h1+count*10;    count++;}
复制代码

禁区三维绘制思路 &代码

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

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

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

  • 3、调整禁区框的位置

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

上动画,赞一个吧:



参考实现代码:

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


g2d.setColor(Color.WHITE);g2d.fillRect(0,175,getWidth(),5);AffineTransform oldTx = g2d.getTransform();Stroke stroke = new BasicStroke(5);g2d.setStroke(stroke);AffineTransform tx = new AffineTransform();tx.setToShear(-0.5, 0);g2d.setTransform(tx);g2d.drawRoundRect(getWidth()*5/20,175,getWidth()*6/10,120,10,10);AffineTransform tx2= new AffineTransform();tx2.setToShear(0.5, 0);g2d.setTransform(tx2);g2d.drawRoundRect(getWidth()*3/20,175,getWidth()*6/10,120,10,10);g2d.setTransform(oldTx);//清理内部多余的线g2d.setColor(bgColor1);g2d.fillRect(0,173,getWidth(),2);g2d.fillRect(getWidth()*3/20+10,180,getWidth()*7/10-20,20);g2d.fillRect(getWidth()*3/20+10,270,getWidth()*6/10-20,23);g2d.setColor(bgColor2);g2d.fillRect(getWidth()*3/20+10,200,getWidth()*6/10-20,70);
复制代码

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

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

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

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

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

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

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



参考实现代码:


g2d.setColor(Color.WHITE);int step = 15;int startX = getWidth()*4/20+20;int centerX = getWidth()/2;int startY = 85;// 球网竖线for (int i = startX; i < (getWidth()*4/5); i=startX) {    int x[] = {startX,startX+(startX<centerX?+8:-8),startX+(startX<centerX?+12:-12)};    int y[] = {startY,startY+10,155};    if((centerX-startX)!=-10) {        g2d.drawPolyline(x, y, x.length);//画折线    }    startX+=step;}// 球迷柱左里Stroke stroke = new BasicStroke(5);g2d.setStroke(stroke);startX = getWidth()*4/20+20;int tempX[] = {startX-18,startX-2,startX-2};int tempY[] = {startY+3,startY+10,153};g2d.drawPolyline(tempX, tempY, tempY.length);startX = getWidth()*4/5;int rightX[] = {startX-2,startX-20,startX-24};int rightY[] = {startY+3,startY+10,153};g2d.drawPolyline(rightX, rightY, rightY.length);stroke = new BasicStroke(1);g2d.setStroke(stroke);startX = getWidth()*4/20;// 球网横线int endX = getWidth()*4/5;for (int i = startY; i < 156; i=startY) {    int x[] = {startX,startX+(startX<centerX?+18:-18),endX-12,endX};    int y[] = {startY,startY-3,startY-3,startY};    g2d.drawPolyline(x,y,x.length);    startY+=step;}int x[] = {startX,startX+(startX<centerX?+18:-18),endX-12,endX};int y[] = {158,155,155,158};g2d.drawPolyline(x,y,x.length);// 绘制门框g2d.setColor(doorColor);stroke = new BasicStroke(9);g2d.setStroke(stroke);g2d.drawRoundRect(getWidth()*4/20,85,getWidth()*3/5,95,20,20);// 带有圆角的矩形stroke = new BasicStroke(5);g2d.setStroke(stroke);g2d.setColor(Color.WHITE);g2d.drawRoundRect(getWidth()*4/20,86,getWidth()*3/5,95,20,20);g2d.fillRect(0,175,getWidth(),5);
复制代码

射门区绘制思路 &代码

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

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

  • 2、叠加两个扇形

  • 3、配上高逼格文字

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



参考实现代码:


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

计分区绘制思路 &代码

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

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

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

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

上动画,赞一个吧:



参考实现代码:


Graphics2D g2d = (Graphics2D)g;g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);g.setColor(bgColor1);g.fillRect(0,0,getWidth(),getHeight());g.setColor(bgColor2);g.fillRect(0,8,getWidth(),getHeight()-8);Font font = new Font("阿里巴巴普惠体 Medium",1,32);g.setFont(font);g2d.setColor(Color.BLACK);g2d.drawString("分数",30,45);g2d.drawString("TIME",250,45);g2d.drawString("次数",540,45);g2d.setColor(textColor);g2d.fillRoundRect(100,20,80,30,25,25);g2d.fillRoundRect(335,20,120,30,25,25);g2d.fillRoundRect(620,20,80,30,25,25);g2d.setColor(Color.WHITE);g2d.drawString(String.format("%02d",score),120,47);g2d.drawString(String.format("%02d:%02d",time/60,time%60),345,47);g2d.drawString(String.format("%02d",count),638,47);
复制代码

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

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

  • 1、加载图片

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

上动画,赞一个吧:



参考实现代码:


// 球public class Ball extends JLabel{
int startX = 0 ; int startY = 0; public Ball(){ this.setPreferredSize(new Dimension(64,64)); this.setIcon(new ImageIcon(ResourcesUtil.getRootPath()+"\\ball\\football.png"));// 加载图片 }
}
复制代码


// 守门员public Goalkeeper(BackgroundPanel backgroundPanel){    this.backgroundPanel = backgroundPanel;    this.setBounds(backgroundPanel.getWidth()/2,100,78,128);    this.setPreferredSize(new Dimension(78,128));    this.setIcon(new ImageIcon(ResourcesUtil.getRootPath()+"\\ball\\smy.png"));}
复制代码


// 石头public class Shitou extends JLabel implements Obstacle {    BackgroundPanel backgroundPanel;    public Shitou(BackgroundPanel backgroundPanel){        this.backgroundPanel = backgroundPanel;        this.setBounds(backgroundPanel.getWidth()/2+50,100,316,100);//设置图片放置的位置        this.setPreferredSize(new Dimension(316,100));        this.setIcon(new ImageIcon(ResourcesUtil.getRootPath()+"\\ball\\st.png"));    }
@Override public String name() { return "石头"; }
@Override public JComponent getComponent() { return this; }
public void start(){ }
public void stop(){ }
}
复制代码


发布于: 刚刚阅读数: 5
用户头像

非喵鱼

关注

技术专业一点,才能多一点时间陪家人! 2018-11-28 加入

Java生态开发高效工具 Tinkle、Boom的作者,欢迎大家持续关注!

评论

发布
暂无评论
2小时开发《点球射门游戏》,动画演示思路(上),代码已开源_游戏_非喵鱼_InfoQ写作社区