闲来无事之 - 如何让编程兴趣更浓厚?【其一】

目录

 

前戏

高潮

收尾


前戏

最近有些日子没更新了,一方面是公司需求压身,属实脱不开身;在着就是开始搞一些休闲的娱乐; 最近压力大哇,没法向有钱人那样,一晚就能放松整个身心;为了保持对coding的热爱,更持久,咱来搞搞游戏舒缓下,闲谈少叙,看图说话

  1.  游戏视频被和谐了 【详情可以看腾讯视频

  2. 游戏视频被和谐了 【详情可以看腾讯视频

太无聊了,真的是太无聊了,所以开始研究了下游戏的切图原理,其实对于游戏的的理解,各位也在各个大佬云集的场所道听途说可能或许应该是这样:2D游戏叠罗汉,3D游戏自旋转, 不管怎么说吧,今天来探究下罗汉【图片】到底是怎么叠的?


高潮

其实啊,游戏在我看来就是三部分:素材 + 切图 + coding; 素材很重要,就好比一张床【咳咳你懂的】切图自然就是怎么摆出优雅姿势,让你的游戏运行起来更流程,coding 就不用说了吧,那么来看下开局展示的两个效果的切图是如何实现的,以下是核心源码

 

 动图

public class DynamicImage extends JPanel implements ActionListener{

	private Direction dir;
	private String path;
	/**
	 * 横坐标
	 */
	private int x;
	/**
	 * 纵坐标
	 */
	private int y;
	
	/**
	 * 宽
	 */
	private int width;
	/**
	 * 高
	 */
	private int height;
	
	/**
	 * 速度
	 */
	private int speed;
	
	/**
	 * 时间帧
	 */
	private Timer timer;		
	
	/**
	 * 显示图片的载体,可以自由选择
	 */
	private JLabel imagePanel;
	
	/**
	 * 现实的图片
	 */
	private ImageIcon icon;	
	
	/**
	 * 每帧的开始位置
	 */
	private int index = 0;
	
	/**
	 * 每个方向所在的视觉位置
	 */
	private int indexUp;
	private int indexRight;
	private int indexDown;
	private int indexLeft;
	
	/**
	 * 切图数量
	 */
	private int cutNumX;
	private int cutNumY;
	
	/**
	 * 
	 * @param path 图片路径
	 * @param cutXNum 切图数量
	 * @param indexUp 向上帧位置
	 * @param indexRight 向右帧位置
	 * @param indexDown 向下帧位置
	 * @param indexLeft 向左帧位置
	 * @param x 绘制的开始横坐标
	 * @param y 绘制的开始纵坐标
	 * @param speed 速度
	 */
	public DynamicImage(String path, int cutNum,
			int indexUp, int indexRight, int indexDown, int indexLeft, 
			int x, int y, int speed) {
		this(path, cutNum, cutNum, indexUp, indexRight, indexDown, indexLeft, x, y, speed);
	}
	
	public DynamicImage(String path, int cutNum,
			int indexUp, int indexRight, int indexDown, int indexLeft, 
			int x, int y) {
		this(path, cutNum, cutNum, indexUp, indexRight, indexDown, indexLeft, x, y, 10);
	}

	public DynamicImage(String path, int cutNumX, int cutNumY,
			int indexUp, int indexRight, int indexDown, int indexLeft, 
			int x, int y, int speed) {
		
		this.x = x;
		this.y = y;
		this.speed = speed;
		this.path = path;
		this.indexUp = indexUp;
		this.indexRight = indexRight;
		this.indexDown = indexDown;
		this.indexLeft = indexLeft;
		// 不管如何切,横向切片总是对的
		this.cutNumX = cutNumX;
		this.cutNumY = cutNumY;
		
		setLocation(this.x, this.y);
		
		imagePanel = new JLabel();
		
		// 核心切图工具
		java.awt.Image img = SwingCutImageUtil.cut(path, 0, 0, cutNumX, cutNumY);
		this.icon = SwingCutImageUtil.convertImgToIcon(img);
		this.width = icon.getIconWidth() ;
		this.height = icon.getIconHeight();
		imagePanel.setIcon(icon);
	
		this.add(imagePanel);
		// 时间轴  100毫秒延迟
		timer = new Timer(100, this);
	}


	@Override
	public void actionPerformed(ActionEvent e) {
		if (indexUp == 0 && indexRight == 0 && indexLeft == 0 && indexRight == 0) {
			return;
		}
		switch (dir) {
		// 具体的方向依赖于素材的方向
		// 向上的所有帧的区间,一定确保时连续的
		case UP:
			index = getTagetIndex(indexUp);
			setLocation(getLocation().x, getLocation().y - speed);
		break;
		case RIGHT:
			index = getTagetIndex(indexRight);
			setLocation(getLocation().x + speed, getLocation().y);
			break;
		case DOWN:
			index = getTagetIndex(indexDown);
			setLocation(getLocation().x, getLocation().y + speed);
			break;
		case LEFT:
			index = getTagetIndex(indexLeft);
			setLocation(getLocation().x - speed, getLocation().y);
			break;	
		default:
			break;
		}
		//切图算法
		java.awt.Image img = SwingCutImageUtil.cut(path, (index % this.cutNumX) * width, (index / this.cutNumY) * height, cutNumX, cutNumY);
		this.icon = SwingCutImageUtil.convertImgToIcon(img);
		imagePanel.setIcon(icon);
		index++;
		repaint();
	}

	private int getTagetIndex(int indexDir) {
		int cutNum = cutNumX;
		int start = cutNum * (indexDir - 1);
		int end = (start + cutNum) - 1; 
		if (index < start || index >  end) {
			index = start;
		}
		return index;
	}
	
	public void start() {
		timer.start();
	}
	
	public void stop() {
		timer.stop();
	}

	public Direction getDir() {
		return dir;
	}

	public void setDir(Direction dir) {
		this.dir = dir;
	}

	
	
}
切图工具

public class SwingCutImageUtil {
	
	
	
	/**
	 * 
	 * @param srcImageFile
	 * @param x 裁剪的开始位置
	 * @param y 裁剪的结束位置
	 * @param cutNumX 横轴切片数量
	 * @param cuntNumY 纵轴切片数量
	 * @return
	 */
	public static Image cut(String srcImageFile, int x, int y, int cutNumX, int cuntNumY) {	
		try {
				BufferedImage bi = getImage(srcImageFile);
				
				int srcWidth = bi.getWidth(); 
				int srcHeight = bi.getHeight(); 
				// 1:1 裁剪
				Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
				Image img;
				// 裁剪过滤
				ImageFilter cropFilter;
				int destWidth = srcWidth / cutNumX;
				int destHeight = srcHeight / cuntNumY;
				cropFilter = new CropImageFilter(x,y,
                         destWidth, destHeight);
				// jwt工具箱操作
				img = Toolkit.getDefaultToolkit().createImage(
                                 new FilteredImageSource(image.getSource(), cropFilter));
               
                BufferedImage tag = new BufferedImage(destWidth, destHeight,
                         BufferedImage.TYPE_4BYTE_ABGR);
                 Graphics g = tag.getGraphics();
                 // 将工具箱的创建裁剪图片绘制到内存中
                 g.drawImage(img, 0, 0, null);
                 // 释放画笔
                 g.dispose();
				return tag;
		} catch (Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	
	public static ImageIcon convertImgToIcon(Image image) {
		if (image == null) {
			return new ImageIcon();
		}
		return new ImageIcon(image );
		
	}
	
	public static BufferedImage getImage(String srcImgFile) {
		BufferedImage bi = null;
		try {
				bi = ImageIO.read(SwingCutImageUtil.class.getClassLoader().getResourceAsStream(srcImgFile));
		} catch (Exception e) {
			e.printStackTrace();
		}
		return bi;
	}

注:想要全部源码,点关注留言给我哦,童叟无欺【虽然我知道有些坏童鞋立刻取关了,咱认为```它```不懂事】


收尾

知道游戏怎么回事了,下一篇搞一个较完整的游戏显摆下,敬请期待哦 : 闲来无事 - 如何让爱更持久【其二】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值