Amazed游戏学习二 坐标的分析

本文详细介绍了迷宫游戏中坐标计算的方法,包括从文件加载迷宫数据到内存,并根据这些数据在屏幕上绘制迷宫。此外,还讲解了如何利用加速度传感器更新游戏中小球的位置,并进行边界检查。

对于这种和贪吃蛇类似的游戏,坐标的计算在程序中占了很大的比重,只有坐标算对了,才能在正确的时间、正确的地点画出来正确的东西。

下面是Maze迷宫的坐标计算

// maze level data private static int[] mMazeData;这个一维数组存放所有的tile的类型

// maze tile size and dimension private final static int TILE_SIZE = 16; private final static int MAZE_COLS = 20; private final static int MAZE_ROWS = 26;

// tile types public final static int PATH_TILE = 0; public final static int VOID_TILE = 1;//death area public final static int EXIT_TILE = 2;//the target而这个坐标的读取是通过从文件读取的,当然也可以通过写几个数组的形式,但是以文件的形式的话就不需要修改代码就可以实现软件的修改是一种比在代码中写几个大的数组要好的形式。

/** * Load specified maze level. * * @param activity * Activity controlled the maze, we use this load the level data * @param newLevel * Maze level to be loaded. */ void load(Activity activity, int newLevel) { // maze data is stored in the assets folder as level1.txt, level2.txt // etc.... String mLevel = "level" + newLevel + ".txt"; InputStream is = null; try { // construct our maze data array. mMazeData = new int[MAZE_ROWS * MAZE_COLS]; // attempt to load maze data. is = activity.getAssets().open(mLevel); // we need to loop through the input stream and load each tile for // the current maze. for (int i = 0; i < mMazeData.length; i++) { // data is stored in unicode so we need to convert it. mMazeData[i] = Character.getNumericValue(is.read()); // skip the "," and white space in our human readable file. is.read(); is.read(); } } catch (Exception e) { Log.i("Maze", "load exception: " + e); } finally { closeStream(is); } }mMazeData数组存放了每个tile是什么类型的,MAZE_ROWS一共有多少行,MAZE_COLS一共多少列,TILE_SIZE每个tile的宽度,这样就可以在界面上画出来整个界面的布局

/** * Draw the maze. * * @param canvas * Canvas object to draw too. * @param paint * Paint object used to draw with. */ public void draw(Canvas canvas, Paint paint) { // loop through our maze and draw each tile individually. for (int i = 0; i < mMazeData.length; i++) { // calculate the row and column of the current tile. mRow = i / MAZE_COLS; mCol = i % MAZE_COLS; // convert the row and column into actual x,y co-ordinates so we can // draw it on screen. mX = mCol * TILE_SIZE; mY = mRow * TILE_SIZE; // draw the actual tile based on type. if (mMazeData[i] == PATH_TILE){ canvas.drawBitmap(mImgPath, mX, mY, paint); } else if (mMazeData[i] == EXIT_TILE){ canvas.drawBitmap(mImgExit, mX, mY, paint); } else if (mMazeData[i] == VOID_TILE) { // since our "void" tile is purely black lets draw a rectangle // instead of using an image. // tile attributes we are going to paint. mRect.left = mX; mRect.top = mY; mRect.right = mX + TILE_SIZE; mRect.bottom = mY + TILE_SIZE; paint.setColor(VOID_COLOR); canvas.drawRect(mRect, paint); } } }// calculate the row and column of the current tile. mRow = i / MAZE_COLS; mCol = i % MAZE_COLS;获得第i个点所在的行号和列号

// convert the row and column into actual x,y co-ordinates so we can // draw it on screen. mX = mCol * TILE_SIZE; mY = mRow * TILE_SIZE;已知行号和列号,知道在屏幕上的位置,但是并不是实际屏幕上的位置,通过乘以每个tile的宽度,获得在屏幕上实际的位置,这个位置是可以画在屏幕上的位置。

上面onDraw的过程是根据mMazeData[i]的第i个点计算在屏幕上的实际位置,而下面的getCellType则是根据在屏幕上的实际的x/y坐标点,计算出在mMazeData中的位置,也就是上面过程的逆过程,函数getCellType(int x, int y)的作用也就是计算出现在Marble所在的屏幕的位置所在的tile是什么类型的。

/** * Determine which cell the marble currently occupies. * * @param x * Current x co-ordinate of marble on the screen. * @param y * Current y co-ordinate of marble on the screen. * @return The actual cell occupied by the marble. */ public int getCellType(int x, int y) { // convert the x,y co-ordinate into row and col values. int mCellCol = x / TILE_SIZE; int mCellRow = y / TILE_SIZE; // location is the row,col coordinate converted so we know where in the // maze array to look. int mLocation = 0; // if we are beyond the 1st row need to multiple by the number of // columns. if (mCellRow > 0) mLocation = mCellRow * MAZE_COLS; // add the column location. mLocation += mCellCol; return mMazeData[mLocation]; }下面是Marble小球的坐标计算

// marble attributes // x,y are private because we need boundary checking on any new values to // make sure they are valid. private int mX = 0; private int mY = 0; private int mRadius = 8; private int mColor = Color.WHITE; private int mLives = 5;在AmazedView中的onDraw()调用gameTick()的时候会更新小球Marble的坐标:

/** * Called from gameTick(), update marble x,y based on latest values obtained * from the Accelerometer sensor. AccelX and accelY are values received from * the accelerometer, higher values represent the device tilted at a more * acute angle. */ public void updateMarble() { // we CAN give ourselves a buffer to stop the marble from rolling even // though we think the device is "flat". if (mAccelX > mSensorBuffer || mAccelX < -mSensorBuffer) mMarble.updateX(mAccelX); if (mAccelY > mSensorBuffer || mAccelY < -mSensorBuffer) mMarble.updateY(mAccelY); // check which cell the marble is currently occupying. if (mMaze.getCellType(mMarble.getX(), mMarble.getY()) == mMaze.VOID_TILE) { // user entered the "void". if (mMarble.getLives() > 0) { // user still has some lives remaining, restart the level. mMarble.death(); mMarble.init(); mWarning = true; } else { // user has no more lives left, end of game. mEndTime = System.currentTimeMillis(); mTotalTime += mEndTime - mStartTime; switchGameState(GAME_OVER); } } else if (mMaze.getCellType(mMarble.getX(), mMarble.getY()) == mMaze.EXIT_TILE) { // user has reached the exit tiles, prepare the next level. mEndTime = System.currentTimeMillis(); mTotalTime += mEndTime - mStartTime; initLevel(); } }在Marble中更新小球坐标:

/** * Attempt to update the marble with a new x value, boundary checking * enabled to make sure the new co-ordinate is valid. * * @param newX * Incremental value to add onto current x co-ordinate. */ public void updateX(float newX) { mX += newX; // boundary checking, don't want the marble rolling off-screen. if (mX + mRadius >= mView.getWidth()) mX = mView.getWidth() - mRadius; else if (mX - mRadius < 0) mX = mRadius; }if-else中是对左右边界的处理,同样的是对上下边界的处理。

内容概要:本文围绕六自由度机械臂的人工神经网络(ANN)设计展开,重点研究了正向与逆向运动学求解、正向动力学控制以及基于拉格朗日-欧拉法推导逆向动力学方程,并通过Matlab代码实现相关算法。文章结合理论推导与仿真实践,利用人工神经网络对复杂的非线性关系进行建模与逼近,提升机械臂运动控制的精度与效率。同时涵盖了路径规划中的RRT算法与B样条优化方法,形成从运动学到动力学再到轨迹优化的完整技术链条。; 适合人群:具备一定机器人学、自动控制理论基础,熟悉Matlab编程,从事智能控制、机器人控制、运动学六自由度机械臂ANN人工神经网络设计:正向逆向运动学求解、正向动力学控制、拉格朗日-欧拉法推导逆向动力学方程(Matlab代码实现)建模等相关方向的研究生、科研人员及工程技术人员。; 使用场景及目标:①掌握机械臂正/逆运动学的数学建模与ANN求解方法;②理解拉格朗日-欧拉法在动力学建模中的应用;③实现基于神经网络的动力学补偿与高精度轨迹跟踪控制;④结合RRT与B样条完成平滑路径规划与优化。; 阅读建议:建议读者结合Matlab代码动手实践,先从运动学建模入手,逐步深入动力学分析与神经网络训练,注重理论推导与仿真实验的结合,以充分理解机械臂控制系统的设计流程与优化策略。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值