目录
前戏
最近有些日子没更新了,一方面是公司需求压身,属实脱不开身;在着就是开始搞一些休闲的娱乐; 最近压力大哇,没法向有钱人那样,一晚就能放松整个身心;为了保持对coding的热爱,更持久,咱来搞搞游戏舒缓下,闲谈少叙,看图说话
太无聊了,真的是太无聊了,所以开始研究了下游戏的切图原理,其实对于游戏的的理解,各位也在各个大佬云集的场所道听途说可能或许应该是这样: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;
}
注:想要全部源码,点关注留言给我哦,童叟无欺【虽然我知道有些坏童鞋立刻取关了,咱认为```
它```
不懂事】
收尾
知道游戏怎么回事了,下一篇搞一个较完整的游戏显摆下,敬请期待哦 : 闲来无事 - 如何让爱更持久【其二】