gpt4 book ai didi

android - 在自定义 View 中为 Drawable 设置动画

转载 作者:行者123 更新时间:2023-11-30 04:31:03 25 4
gpt4 key购买 nike

我正在尝试在自定义 View 中为 ShapeDrawable 设置动画。但我不确定完成这项任务的最佳方法是什么。

我是否应该尝试在路径上绘制棋子并调用 invalidate() 直到它到达目标方 block ?或者是否有使用 AsyncTask 或 Handler 的更好方法?

这是我的代码,为了便于阅读,我省略了很多方法和变量。

public class CheckerBoard extends View {

public enum State implements Parcelable {
EMPTY(0), WHITE(1), BLACK(2);
}

private final State[][] boardStates = new State[SIZE][SIZE];

@Override
protected void onDraw(Canvas canvas) {
canvas.drawColor(bgColor);
for (int y = 0; y < SIZE; y++) {
for (int x = 0; x < SIZE; x++) {
if ((y % 2 == 0 && x % 2 != 0) || (y % 2 != 0 && x % 2 == 0)) {
drawRect(x, y, canvas);
drawPawn(x, y, canvas);
}
}
}
}

private void drawRect(int x, int y, Canvas c) {
}

private void drawPawn(int x, int y, Canvas c) {
}

private void init() {
setupBoard();
pawnLinePaint.setStyle(Paint.Style.STROKE);
wPawnDrawable.getPaint().setColor(wColor);
wPawnDrawable.getPaint().setShadowLayer(tileSize + 2, 4, 4, Color.GRAY);
bPawnDrawable.getPaint().setColor(bColor);
bPawnDrawable.getPaint().setShadowLayer(tileSize + 2, 4, 4, Color.GRAY);
playerState = startState;
}

public boolean onTouchEvent(MotionEvent event) {
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
int x = (int) (event.getX() / tileSize);
int y = (int) (event.getY() / tileSize);
if (selection[0] >= 0) { // A tile is already selected
if (isValidMove(selection[0], selection[1], x, y)) {
makeMove(x, y);
clearSelection();
switchPlayer();
invalidate();
}

} else { // New selection
if (isValidSelection(x, y)) {
selection[0] = x;
selection[1] = y;
invalidate();
}
}

return true;
default:
return super.onTouchEvent(event);
}
}

private void makeMove(int x, int y) {
// Move the pawn to the new square
boardStates[y][x] = boardStates[selection[1]][selection[0]];
// Old square is now empty
boardStates[selection[1]][selection[0]] = State.EMPTY;
}

private void switchPlayer() {
playerState = playerState == State.WHITE ? State.BLACK : State.WHITE;
}

public CheckerBoard(Context context) {
super(context);
init();
}

public CheckerBoard(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}

public CheckerBoard(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
init();
}


private class Pawn extends ShapeDrawable {
public Pawn() {
super(new OvalShape());
}

public void drawWithCircles(Canvas canvas, float x, float y){
super.draw(canvas);
canvas.drawCircle(x * tileSize + pawnDiameter, y * tileSize + pawnDiameter, pawnDiameter - pawnPadding,
pawnLinePaint);
canvas.drawCircle(x * tileSize + pawnDiameter, y * tileSize + pawnDiameter, pawnDiameter - pawnPadding * 6,
pawnLinePaint);
canvas.drawCircle(x * tileSize + pawnDiameter, y * tileSize + pawnDiameter, pawnDiameter - pawnPadding * 8,
pawnLinePaint);
}
}

}

感谢您的帮助。

枯萎病

最佳答案

您应该为您的应用程序创建两个线程。一个线程是 UI 线程,它只在当前状态下绘制面板。另一个线程是移动棋盘上的项目的游戏引擎或动画线程。

第一个线程以您想要的任何帧速率运行,第二个线程应该运行得更快。通过这种方式,您实际上不必自己处理动画,因为 UI 线程只是按当前的样子绘制板。在你的引擎线程中,你更新游戏的状态,棋盘,棋子,线程的每个循环。

以这种方式做事有两个好处。首先,如果引擎线程在某种计算中陷入困境,您的游戏帧率不会下降。其次,它允许您以一种使调试更容易的方式将绘图从游戏中抽象出来。

以进度条为例。假设您尝试创建一个带有进度条的文件 uploader ,但只有一个线程。所以你启动进度条然后开始上传文件。如果上传过程被阻塞,那么你必须等待文件完成上传才能更新进度条,基本上使进度条无用。但是,如果您使用两个线程执行此操作,那么您可以将其设置为一个线程仅根据一些公共(public)变量更新进度条图形。另一个线程负责执行操作并更新进度变量。

查看这些链接以获取更多信息:

http://obviam.net/index.php/the-android-game-loop/

http://www.rbgrn.net/content/54-getting-started-android-game-development

http://www.helloandroid.com/tutorials/using-threads-and-progressdialog

关于android - 在自定义 View 中为 Drawable 设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7697123/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com