[JAVA]从零开始的“桌面宠物”之路(一):动画效果

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Shenpibaipao/article/details/78704714

>我将要做一个什么?

    也算是突发奇想,以前一直用C#写的桌面应用,但最近有点沉迷JAVA,加上最近不小心打开了阔别十来年的QQ宠物(现在QQ宠物Client已经变得都是广告了),想起了瑞星小狮子,有点怀旧,就想找找有没有简单、干净一些的桌面宠物养成游戏软件,写代码的时候趴在窗口上卖卖萌也是甚好的。

    找了找,还真有。在Github上找到了一个日本人写的开源桌面宠物项目:https://github.com/nonowarn/shimeji4mac。然而不幸的是,作者似乎也很久不开发了,且这个东西是明确标明需要JRE6-32bit才能运行。在JRE9都出来了的今天,为了这么个宠物专门去寻找、并安装一个JRE6,不合适吧;况且这玩意现在也不算很好找了,哪怕是在oracle官网找JRE6的下载地址都要找不少时间。于是就手痒,想自己写一个。

    我会尽量不使用除了JDK自带的jar以外的东西,并随缘更新这个系列。由于我不是很喜欢写xml,因此主要将用Swing来进行开发。


>JAVA的运行问题

     刚刚提到了Shimoji桌面宠物需要JRE6才能运行的问题,那我现在用JRE,换个没有JRE环境的电脑不就不能运行了?

     啊,确实是这样的,不过我们有办法规避这个问题,让你的jar伪装成一个exe,像c#写的桌面应用一样到处跑:http://blog.csdn.net/shenpibaipao/article/details/78701034


>今天的目标

    今天的目标是,既然是桌面宠物,那么它一定是能动的。所以我们先从如何解决桌面宠物的动画问题解决起。

扫描二维码关注公众号,回复: 3867943 查看本文章

    下面是完成后的效果演示:(素材取自Undertale贴吧)



>核心问题

   核心问题主要有两个:

  • 如何加载图片?
  • 如何让图片动起来?
   先说第一个问题:如何加载图片。

   在Swing中,我习惯用一个JLabel去加载图片:

	public JLabel loadPicture(int x,int y,String url){
		JLabel jLabel = new JLabel();
		ImageIcon icon = new ImageIcon(url);
		int picWidth = icon.getIconWidth(),pinHeight = icon.getIconHeight();
		icon.setImage(icon.getImage().getScaledInstance(picWidth,pinHeight,Image.SCALE_DEFAULT));
		jLabel.setBounds(x,y,picWidth,pinHeight);
		jLabel.setIcon(icon);
		return jLabel;
	}
    上面这段代码会返回一个加载了图片的JLabel,其左上角位置相对于父容器为(x,y)。

    要让它动起来,我们需要准备一条连续的图片素材:(图片素材和项目Demo代码我会放到最后供下载使用)


    其次,我们专门运行一个新的线程,通过sleep的方法去更换帧。这样效率虽然不高,但我们并不是在写什么大工程,作为一个桌面宠物,足矣。

    现在,我们修改刚刚加载图片的方法,把它变成一个给指定JLabel更换新图片的方法:

	private void cgJLabelImg(JLabel jLabel,String imgUrl){
		ImageIcon icon = new ImageIcon(imgUrl);
		int picWidth = icon.getIconWidth(),pinHeight = icon.getIconHeight();
		icon.setImage(icon.getImage().getScaledInstance(picWidth,pinHeight, Image.SCALE_DEFAULT));
		jLabel.setBounds(0,0,picWidth,pinHeight);
		jLabel.setIcon(icon);
	}
    假设上面三张素材图片的名字分别为:"a1.png"、"a2.png"、"a3.png",那么专门处理动画帧的线程就可以这么写了:

	// 动画线程 这里用到了JDK8的lambda表达式
	new Thread(() -> {
		int i=1;
		try{
			while (true){
				Thread.sleep(250);
					cgJLabelImg(jLabel,"a"+ i++ +".png");
				if(i>3)i=1;
			}
		} catch (Exception e){
			e.printStackTrace();
		}
	}).start();
    我在这里写了个JDK8的Lambda表达式,如果你对这种写法有兴趣,可以看看这里: http://blog.csdn.net/shenpibaipao/article/details/78622456。不过就算不想了解Lambda表达式也没关系,其相当于:

	new Thread(new Runnable() {
		@Override
		public void run() {
			int i=1;
			try{
				while (true){
					Thread.sleep(250);
					cgJLabelImg(jLabel,"a"+ i++ +".png");
					if(i>3)i=1;
				}
			}catch (Exception e){
				e.printStackTrace();
			}
		}
	}).start();
    现在就可以去运行程序了。然后你会注意到一个问题,由于我们的素材是背景透明的png图片,但承载JLabel的JFrame的背景却是灰色的实体背景,看着就很丑。而且我们其实也不需要标题栏,那么我们可以给JFrame加上两个属性:

	// 框体透明
	this.setUndecorated(true); // 取消窗口标题栏
	this.setBackground(new Color(0,0,0,0));// 背景透明

    完活,今天的任务就到这里结束了。可以到下面的链接去下载具体的素材和代码自己试试。


>素材及Demo代码下载

   CSDN下载:http://download.csdn.net/download/shenpibaipao/10143462




猜你喜欢

转载自blog.csdn.net/Shenpibaipao/article/details/78704714