最近被疫情关在家,时间多运动少,真的很无聊呀!也许是天意为之,居然来世界杯了,虽然这届世界杯很「冷」,但是多少还是为无聊的我们增加了一些无聊的趣事,比如勇哥在等世界杯开幕式的过程中,就无聊手写了一个Java版本的【点球射门游戏】,这几天把球瘾过了,今天有点时间,把这个游戏分享给大家,希望大家喜欢!(游戏也有音乐,gif放不了,有点小可惜)
球的瞄准轨迹线怎么实现【见下图1】?这个在QQ桌球、王者荣耀、愤怒的小鸟等游戏中都用到了!
怎么画三维立体的图片【见下图2】?
怎么实现动画【见下图3】?
图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
蓄力区用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(){
}
}