安卓精灵图 今天找到了一个很好的安卓上播放精灵图的控件 https://www.wanandroid.com/blog/show/2551
然后我把它改写了一下 加入了一个pause方法,这样一开始也可以显示出来了,虽然一开始就调用一个叫做pause的方法让他初始化,感觉有点语义不明,反正能跑就算成功。。。
public void pause() {
mIsPause=true;
mRunning = true;
mRenderThread = new Thread(this);
mRenderThread.start();
}
于是他整个代码是这样的,并不是我写的 我只是加了一句 pause
package com.example.whatrubbish.util;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.PixelFormat;
import android.graphics.PorterDuff;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
import com.example.whatrubbish.R;
public class SpriteAnimationView extends SurfaceView implements Runnable {
private static final String TAG = "AnimationView";
private static final String LEFT_TO_RIGHT = "left-to-right";
private static final String RIGHT_TO_LEFT = "right-to-left";
private Thread mRenderThread;
private SurfaceHolder mSurfaceHolder;
private volatile boolean mRunning;
private boolean mIsPlaying;
private boolean mIsPause;
private Canvas mCanvas;
private Paint mPaint;
private Bitmap mBitmap;
private long mLastFrameChangeTime;
private long mFps;
private Rect mSrcFrameRect;
private RectF mDstFrameRect;
private int mSpriteSheet;
private int mFrameWidth = 300;
private int mFrameHeight = 150;
private int mFrameCount = 3;
private int mRowCount = 1;
private int mRowIndex = 0;
private int mCurrentFrame = 0;
private int mFrameDuration = 100;
private float mOffset = 0;
private float mOffsetPerSecond = 250;
private boolean mInPlace = true;
private boolean mTouchToMove = false;
private boolean mPlayOnce = false;
private String mDirection = LEFT_TO_RIGHT;
public SpriteAnimationView(Context context) {
this(context, null);
}
public SpriteAnimationView(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public SpriteAnimationView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
parseAttributes(context, attrs, defStyleAttr);
mPaint = new Paint();
mSurfaceHolder = getHolder();
mSurfaceHolder.setFormat(PixelFormat.TRANSLUCENT);
setZOrderOnTop(true);
mBitmap = BitmapFactory.decodeResource(this.getResources(), mSpriteSheet);
mBitmap = Bitmap.createScaledBitmap(mBitmap,
mFrameWidth * mFrameCount,
mFrameHeight * mRowCount,
false);
mSrcFrameRect = new Rect(
0,
mFrameHeight * mRowIndex,
mFrameWidth,
mFrameHeight * (mRowIndex + 1));
mDstFrameRect = new RectF();
}
private void parseAttributes(Context context, AttributeSet attrs, int defStyleAttr) {
TypedArray a = context.getTheme().obtainStyledAttributes(attrs,
R.styleable.SpriteAnimationView, defStyleAttr, 0);
for (int i = 0; i < a.getIndexCount(); i++) {
int attr = a.getIndex(i);
switch (attr) {
case R.styleable.SpriteAnimationView_sprite_sheet:
mSpriteSheet = a.getResourceId(attr, mSpriteSheet);
break;
case R.styleable.SpriteAnimationView_frame_width:
mFrameWidth = a.getDimensionPixelSize(attr, mFrameWidth);
break;
case R.styleable.SpriteAnimationView_frame_height:
mFrameHeight = a.getDimensionPixelSize(attr, mFrameHeight);
break;
case R.styleable.SpriteAnimationView_frame_count:
mFrameCount = a.getInteger(attr, mFrameCount);
break;
case R.styleable.SpriteAnimationView_row_count:
mRowCount = a.getInteger(attr, mRowCount);
break;
case R.styleable.SpriteAnimationView_row_index:
mRowIndex = a.getInteger(attr, mRowIndex);
break;
case R.styleable.SpriteAnimationView_start_frame:
mCurrentFrame = a.getInteger(attr, mCurrentFrame);
break;
case R.styleable.SpriteAnimationView_frame_duration:
mFrameDuration = a.getInteger(attr, mFrameDuration);
break;
case R.styleable.SpriteAnimationView_offset_per_second:
mOffsetPerSecond = a.getDimensionPixelSize(attr, (int) mOffsetPerSecond);
break;
case R.styleable.SpriteAnimationView_position:
mOffset = a.getDimensionPixelSize(attr, (int) mOffset);
break;
case R.styleable.SpriteAnimationView_in_place:
mInPlace = a.getBoolean(attr, mInPlace);
break;
case R.styleable.SpriteAnimationView_touch_to_move:
mTouchToMove = a.getBoolean(attr, mTouchToMove);
break;
case R.styleable.SpriteAnimationView_play_once:
mPlayOnce = a.getBoolean(attr, mPlayOnce);
break;
case R.styleable.SpriteAnimationView_direction:
mDirection = (a.getString(attr) != null ? a.getString(attr) : mDirection);
break;
}
}
a.recycle();
}
@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
mOffset = (mDirection.equals(LEFT_TO_RIGHT) ? 0 : getMeasuredWidth() - mFrameWidth);
}
@Override
public void run() {
while (mRunning) {
long frameStartTime = System.currentTimeMillis();
updateFrame();
drawFrame();
long frameDrawingTime = System.currentTimeMillis() - frameStartTime;
if (frameDrawingTime >= 1) {
mFps = 1000 / frameDrawingTime;
if (!mTouchToMove && !mIsPlaying) {
mIsPlaying = true;
}
}
}
}
public void getCurrentFrame(){
long time = System.currentTimeMillis();
if (mIsPlaying) {
if (time > mLastFrameChangeTime + mFrameDuration) {
mLastFrameChangeTime = time;
mCurrentFrame = (mCurrentFrame + 1) % mFrameCount;
}
}
if(!mIsPause){
mSrcFrameRect.left = mCurrentFrame * mFrameWidth;
mSrcFrameRect.right = mSrcFrameRect.left + mFrameWidth;
}
}
public void updateFrame() {
if (mIsPlaying && !mInPlace) {
if (getMeasuredWidth() > 0) {
switch (mDirection) {
case LEFT_TO_RIGHT:
mOffset += (mOffsetPerSecond / mFps);
if (!mPlayOnce) {
mOffset %= getMeasuredWidth();
}
break;
case RIGHT_TO_LEFT:
mOffset -= (mOffsetPerSecond / mFps);
if (!mPlayOnce) {
mOffset = mOffset > -mFrameWidth ? mOffset : mOffset + getMeasuredWidth();
}
break;
}
}
}
}
public void doDraw(){
mCanvas = mSurfaceHolder.lockCanvas();
mCanvas.drawColor(Color.TRANSPARENT, PorterDuff.Mode.CLEAR);
getCurrentFrame();
mDstFrameRect.set(mOffset,
0,
mOffset + mFrameWidth,
mFrameHeight);
mCanvas.drawBitmap(mBitmap,
mSrcFrameRect,
mDstFrameRect, mPaint);
mSurfaceHolder.unlockCanvasAndPost(mCanvas);
}
public void drawFrame() {
if (mSurfaceHolder.getSurface().isValid()) {
doDraw();
}
}
public void stop() {
mIsPlaying = false;
mRunning = false;
try {
mRenderThread.join();
} catch (InterruptedException e) {
Log.e(TAG, "joining thread");
}
}
public void pause() {
mIsPause=true;
mRunning = true;
mRenderThread = new Thread(this);
mRenderThread.start();
}
public void start() {
mIsPause=false;
mRunning = true;
mRenderThread = new Thread(this);
mRenderThread.start();
}
@Override
public boolean onTouchEvent(MotionEvent motionEvent) {
if (mTouchToMove) {
switch (motionEvent.getAction() & MotionEvent.ACTION_MASK) {
case MotionEvent.ACTION_DOWN:
mIsPlaying = true;
break;
case MotionEvent.ACTION_UP:
mIsPlaying = false;
break;
}
return true;
} else {
return super.onTouchEvent(motionEvent);
}
}
}
<com.example.whatrubbish.util.SpriteAnimationView
android:id="@+id/personWalk"
app:frame_count="4"
app:offset_per_second="@dimen/dp_32"
app:frame_height="@dimen/dp_48"
app:frame_width="@dimen/dp_32"
android:layout_width="match_parent"
android:layout_height="@dimen/dp_48"
app:sprite_sheet="@mipmap/miku_walk_left_to_right_whole_nb" />
因为我现在只要从左往右走的 第三行,所以ps了一下 然而其实不用ps 主要是我之前没有把他的文档看全,其实他是有 这种东西的,所以也就是说,我只要指定他是第三行就行了。。 不过这个我还没试过。。有机会试一试吧
app:row_count="2"
app:row_index="1"
<com.xinxin.spritesheetanimation.SpriteAnimationView
android:id="@+id/animation_view"
android:layout_width="match_parent"
android:layout_height="80dp"
app:sprite_sheet="@drawable/antelope"
app:frame_count="4"
app:frame_width="80dp"
app:frame_height="80dp"
app:frame_duration="100"
app:start_frame="0"
app:row_count="2"
app:row_index="1"
app:offset_per_second="250"
app:position="0"
app:in_place="false"
app:touch_to_move="false"
app:direction="right-to-left"
/>
以下是ps ctrl j 新建图层 拖入素材 双击图片 取消自由变换,先在右边ctrl j 复制一个图层,防止错误操作导致事情变得可怕,然后选中我们要的第三行 再次ctrl j,然后下面两个图层不可见,发现只剩下这个图层,而这个图层是我们刚才选择的那部分。现在这个图层留作备用素材
再次新建一个文件
要根据这张图去计算他的参数 这里有四行 那么一个人的宽度是 128/4==32 高度是 192/4=48 宽度是四个人 128 高度 一个人的高度 48
alt 鼠标滚轮,放大一下 ctrl j 新建图层 把刚才剪辑好的图片拉进来 背景不可见 这样png 背景就是透明的 储存为 png 才会有背景透明效果 复制图片到 mipmap
|