【APP GAME KIT】能碰到障碍物的移动小人
来源:互联网 发布:淘宝裸根月季苗 编辑:程序博客网 时间:2024/05/01 03:18
网上下载的例子运行以后会出现以下情况:
① 小人移动速度较慢。
② 小人移动动画不准确,即移动时候小人的双脚并不会运动。反而是站着的时候双脚会走。
③ 小人向下或向下移动的时候同时按左键或右键,小人方向不会发生改变,但是会向左或向右移动;小人向左或向右移动的时候按上下键,小人方向会发生改变。这是因为 if 和 else if 导致的按键事故。
原版代码:
// Includes, namespace and prototypes#include "template.h"using namespace AGK;app App;// Function prototypesvoid loadTiles();void displayTiles();void updateAlecX(float);void updateAlecY(float);// Constants for the screen resolutionconst int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;// Constants for the image numbersconst int GRASS = 1;const int PATH = 2;const int PATHNE = 3;const int PATHNW = 4;const int PATHSE = 5;const int PATHSW = 6;const int TREENW = 7;const int TREENE = 8;const int TREESW = 9;const int TREESE = 10;const int ROCK = 11;// Constants for the tile image sizesconst int TILE_WIDTH = 64;const int TILE_HEIGHT = 48;// Constants for the tile map size declaratorsconst int TILE_ROWS = 10;const int TILE_COLS = 10;// Constants for the Alec sprite sheetconst int ALEC_IMAGE = 12; // Texture atlas image indexconst int ALEC_SPRITE = 100; // Alec's sprite indexconst int ALEC_FRAME_WIDTH = 40; // Alec's frame widthconst int ALEC_FRAME_HEIGHT = 75; // Alec's frame heightconst int ALEC_FRAME_COUNT = 16; // Alec's frame countconst int EAST_START = 1; // First frame for going eastconst int EAST_END = 4; // Last frame for going eastconst int NORTH_START = 5; // First frame for going northconst int NORTH_END = 8; // Last frame for going northconst int SOUTH_START = 9; // First frame for going southconst int SOUTH_END = 12; // Last frame for going southconst int WEST_START = 13; // First frame for going westconst int WEST_END = 16; // Last frame for going westconst int ALEC_FPS = 5; // Alec's frames per secondconst int ANIMATION_LOOP = 1; // To make Alec loopconst float ALEC_STARTING_X = 0; // Alec's starting X coordinateconst float ALEC_STARTING_Y = 150; // Alec's starting Y coordinate// Constants for Alec's directionconst int NORTH = 1;const int SOUTH = 2;const int EAST = 3;const int WEST = 4;// The tile mapint g_tileMap[TILE_ROWS][TILE_COLS] ={ {GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS}, {GRASS, GRASS, GRASS, ROCK, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS}, {GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, PATHNW, PATH, PATH }, {GRASS, GRASS, GRASS, GRASS, GRASS, TREENW, TREENE, PATH, GRASS, GRASS}, {PATH, PATH, PATH, PATH, PATHNE, TREESW, TREESE, PATH, ROCK, GRASS}, {GRASS, GRASS, GRASS, GRASS, PATH, GRASS, GRASS, PATH, GRASS, GRASS}, {GRASS, GRASS, GRASS, GRASS, PATHSW, PATH, PATH, PATHSE, GRASS, GRASS}, {GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS}, {GRASS, ROCK, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS}, {GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS, GRASS}};// Variable for Alec's directionint g_alecDirection = EAST;// Begin app, called once at the startvoid app::Begin( void ){ // Set the window title. agk::SetWindowTitle("Walking Alec"); // Set the virtual resolution. agk::SetVirtualResolution(SCREEN_WIDTH, SCREEN_HEIGHT); // Load the texture atlas. agk::LoadImage(ALEC_IMAGE, "Alec/Alec.png"); // Create the sprite using the texture atlas as the image. agk::CreateSprite(ALEC_SPRITE, ALEC_IMAGE); // Make sure Alec is displayed on top of the tile sprites. agk::SetSpriteDepth(ALEC_SPRITE, 0); // Set Alec's starting position. agk::SetSpritePosition(ALEC_SPRITE, ALEC_STARTING_X, ALEC_STARTING_Y); // Set the sprite animation. agk::SetSpriteAnimation(ALEC_SPRITE, ALEC_FRAME_WIDTH, ALEC_FRAME_HEIGHT, ALEC_FRAME_COUNT); // Load the tile images. loadTiles(); // Create the tile sprites and display them. displayTiles();}// Main loop, called every framevoid app::Loop ( void ){ // Get the state of the direction keys. float directionX = agk::GetDirectionX(); float directionY = agk::GetDirectionY(); // If the right or left arrow keys are pressed, // update Alec's X coordinate. if (directionX != 0) { updateAlecX(directionX); } // If the up or down arrow keys are pressed, // update Alec's Y coordinate. if (directionY != 0) { updateAlecY(directionY); } // Refresh the screen. agk::Sync();}// Called when the app endsvoid app::End ( void ){}// The loadTiles function loads the images that will be// used for tiles.void loadTiles(){ agk::LoadImage(GRASS, "Alec/Grass.png"); agk::LoadImage(PATH, "Alec/Path.png"); agk::LoadImage(PATHNE, "Alec/PathNE.png"); agk::LoadImage(PATHNW, "Alec/PathNW.png"); agk::LoadImage(PATHSE, "Alec/PathSE.png"); agk::LoadImage(PATHSW, "Alec/PathSW.png"); agk::LoadImage(TREENE, "Alec/TreeNE.png"); agk::LoadImage(TREENW, "Alec/TreeNW.png"); agk::LoadImage(TREESE, "Alec/TreeSE.png"); agk::LoadImage(TREESW, "Alec/TreeSW.png"); agk::LoadImage(ROCK, "Alec/Rock.png");}// The displayTiles function displays the tiles, as// specified by the tile map.void displayTiles(){ // Variables for the tile coordinates float x = 0, y = 0; // Variable to temporarily hold a sprite index int spriteIndex; // Display all the tiles specified in the map. for (int r = 0; r < TILE_ROWS; r++) { // Set x to 0. x = 0; // Display all the tiles in this row. for (int c = 0; c < TILE_COLS; c++) { // Create a sprite for this tile. spriteIndex = agk::CreateSprite(g_tileMap[r][c]); // Set the tile's position. agk::SetSpritePosition(spriteIndex, x, y); // Update the X coordinate for the next tile. x += TILE_WIDTH; } // Increase y for the next row. y += TILE_HEIGHT; }}// The updateAlecX function turns Alec either east or west,// depending on which arrow key is being pressed, and moves// him to his new X coordinate.void updateAlecX(float directionX){ float alecX, // Alec's current X position newX; // Alec's new X coordinate // Get Alec's X coordinate alecX = agk::GetSpriteX(ALEC_SPRITE); // Which key was pressed? Right or left? if (directionX > 0) { // Turn Alec east agk::PlaySprite(ALEC_SPRITE, ALEC_FPS, ANIMATION_LOOP, EAST_START, EAST_END); // Save Alec's current direction. g_alecDirection = EAST; // Calculate Alec's new X coordinate. newX = alecX + 1; } else if (directionX < 0) { // Turn Alec west agk::PlaySprite(ALEC_SPRITE, ALEC_FPS, ANIMATION_LOOP, WEST_START, WEST_END); // Save Alec's current direction. g_alecDirection = WEST; // Calculate Alec's new X coordinate newX = alecX - 1; } // Move Alec agk::SetSpriteX(ALEC_SPRITE, newX);}// The updateAlecY function turns Alec either north or south,// depending on which arrow key is being pressed, and moves// him to his new Y coordinate.void updateAlecY(float directionY){ float alecY, // Alec's current Y position newY; // Alec's new Y coordinate // Get Alec's Y coordinate alecY = agk::GetSpriteY(ALEC_SPRITE); // Which key was pressed? Up or down? if (directionY < 0) { // Turn Alec north agk::PlaySprite(ALEC_SPRITE, ALEC_FPS, ANIMATION_LOOP, NORTH_START, NORTH_END); // Save Alec's current direction. g_alecDirection = NORTH; // Calculate Alec's new Y coordinate. newY = alecY - 1; } else if (directionY > 0) { // Turn Alec south agk::PlaySprite(ALEC_SPRITE, ALEC_FPS, ANIMATION_LOOP, SOUTH_START, SOUTH_END); // Save Alec's current direction. g_alecDirection = SOUTH; // Calculate Alec's new Y coordinate. newY = alecY + 1; } // Move Alec agk::SetSpriteY(ALEC_SPRITE, newY);}
自己尝试独立打了一次代码:
#include "template.h"using namespace AGK;app App;//tile图片编号const int GRASS = 1;//草坪图片const int PATH = 2;//石径满const int PATHNE = 3;//石径左拐下const int PATHNW = 4;//石径右拐下const int PATHSE = 5;//石径左拐上const int PATHSW = 6;//石径上拐右const int TREENW = 7;//树左上部分const int TREENE = 8;//树右上部分const int TREESW = 9;//树坐下部分const int TREESE = 10;//树右下部分const int ROCK = 11;//石头//每张矩图的大小const int TILE_WIDTH = 64;const int TILE_HEIGHT = 48;//地图矩阵n x nconst int TILE_ROWS = 10;const int TILE_COLS = 10;//屏幕大小const int SCREEN_WIDTH = 640;const int SCREEN_HEIGHT = 480;int g_tileMap[TILE_ROWS][TILE_COLS] = {GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,PATHNW,PATH,PATH,GRASS,GRASS,GRASS,GRASS,GRASS,TREENW,TREENE,PATH,GRASS,GRASS,PATH ,PATH ,PATH ,PATH ,PATHNE,TREESW,TREESE,PATH,ROCK,GRASS,GRASS,GRASS,GRASS,GRASS,PATH,GRASS,GRASS,PATH,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,PATHSW,PATH,PATH,PATHSE,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,ROCK,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,GRASS,};//四个方向const int NORTH = 1;const int SOUTH = 2;const int EAST = 3;const int WEST = 4;//人物参数const int ALEC_IMAGE = 12;//ALEC图片const int ALEC_SPRITE = 100;//ALEC精灵const int ALEC_FRAME_WIDTH = 40;//alec人物图片宽度const int ALEC_FRAME_HEIGHT = 75;//alec人物图片高度const int ALEC_FRAME_COUNT = 16;//总共16幅图片const int EAST_START = 1;//向东开始const int EAST_END = 4;//向东结束const int NORTH_START = 5;//向北开始const int NORTH_END = 8;//向北结束const int SOUTH_START = 9;//向南开始const int SOUTH_END = 12;//向南结束const int WEST_START = 13;//向西开始const int WEST_END = 16;//向西结束const int ALEC_FPS = 5;//帧率const int ANIMATION_LOOP = 1;//循环const int WALK_DISTANCE = 4;const int STANDING = 0;//站立const int WALKING = 1;//行走const float ALEC_STARTING_X = 0;//X坐标const float ALEC_STARTING_Y = 150;//Y坐标int g_alecDirection = EAST;//人物朝向int g_state = STANDING;//人物当前状态//测试数据const int X = 1;const int Y = 2;//Functionvoid loadTiles();//加载tile图片void displayTiles();//输出地图void updateAlecX(float);void updateAlecY(float);int direction(float,float);bool checkCollision(float x,float y);void app::Begin(void){agk::SetVirtualResolution (SCREEN_WIDTH, SCREEN_HEIGHT);agk::SetWindowTitle("Walking Alec");agk::LoadImage(ALEC_IMAGE,"Alec/Alec.png");agk::CreateSprite(ALEC_SPRITE,ALEC_IMAGE);agk::SetSpriteDepth(ALEC_SPRITE,0);agk::SetSpritePosition(ALEC_SPRITE,ALEC_STARTING_X,ALEC_STARTING_Y);agk::SetSpriteAnimation(ALEC_SPRITE,ALEC_FRAME_WIDTH,ALEC_FRAME_HEIGHT,ALEC_FRAME_COUNT);agk::CreateText(X,agk::Str(ALEC_STARTING_X));agk::SetTextSize(X,24);agk::SetTextPosition(X,SCREEN_WIDTH - agk::GetTextTotalWidth(X),0);agk::CreateText(Y,agk::Str(ALEC_STARTING_Y));agk::SetTextSize(Y,24);agk::SetTextPosition(Y,SCREEN_WIDTH - agk::GetTextTotalWidth(Y),agk::GetTextTotalHeight(X)+5);agk::CreateText(200,"10");agk::SetTextSize(200,24);agk::SetTextPosition(200,SCREEN_WIDTH - agk::GetTextTotalWidth(200),agk::GetTextTotalHeight(X)+5+agk::GetTextTotalHeight(Y)+5);agk::CreateText(201,"10");agk::SetTextSize(201,24);agk::SetTextPosition(201,SCREEN_WIDTH - agk::GetTextTotalWidth(201),agk::GetTextTotalHeight(X)+5+agk::GetTextTotalHeight(Y)+5+agk::GetTextTotalHeight(200)+5);agk::CreateText(202,"1");agk::SetTextSize(202,24);agk::SetTextPosition(202,0,400);loadTiles();displayTiles();}void app::Loop (void){float directionX = agk::GetDirectionX();float directionY = agk::GetDirectionY();agk::SetTextString(X,agk::Str(agk::GetSpriteX(ALEC_SPRITE)));agk::SetTextString(Y,agk::Str(agk::GetSpriteY(ALEC_SPRITE)));int isLEFTRIGHT = direction(directionX,directionY);switch(isLEFTRIGHT){case 0:if(g_state==WALKING){g_state = STANDING;switch(g_alecDirection){case NORTH:agk::PlaySprite(ALEC_SPRITE,1,ANIMATION_LOOP,6,6);break;case SOUTH:agk::PlaySprite(ALEC_SPRITE,1,ANIMATION_LOOP,10,10);break;case WEST:agk::PlaySprite(ALEC_SPRITE,1,ANIMATION_LOOP,14,14);break;case EAST:agk::PlaySprite(ALEC_SPRITE,1,ANIMATION_LOOP,2,2);break;}}break;case 1:updateAlecX(directionX);break;case 2:updateAlecY(directionY);break;}agk::Sync();}void app::End (void){}void loadTiles(){//加载tile图片agk::LoadImage(GRASS,"Alec/Grass.png");agk::LoadImage(PATH,"Alec/Path.png");agk::LoadImage(PATHNE,"Alec/PathNE.png");agk::LoadImage(PATHNW,"Alec/PathNW.png");agk::LoadImage(PATHSE,"Alec/PathSE.png");agk::LoadImage(PATHSW,"Alec/PathSW.png");agk::LoadImage(TREENW,"Alec/TreeNW.png");agk::LoadImage(TREENE,"Alec/TreeNE.png");agk::LoadImage(TREESW,"Alec/TreeSW.png");agk::LoadImage(TREESE,"Alec/TreeSE.png");agk::LoadImage(ROCK,"Alec/Rock.png");}void displayTiles(){float x = 0, y = 0;int spriteIndex;for(int r = 0;r<TILE_ROWS;r++){x = 0;for(int c = 0 ; c < TILE_COLS; c++){spriteIndex = agk::CreateSprite(g_tileMap[r][c]);agk::SetSpritePosition(spriteIndex,x,y);x+=TILE_WIDTH;}y+=TILE_HEIGHT;}}void updateAlecX(float directionX){float alecX,newX;alecX = agk::GetSpriteX(ALEC_SPRITE);if(directionX>0){if(g_alecDirection !=EAST || g_state==STANDING){agk::PlaySprite(ALEC_SPRITE,ALEC_FPS,ANIMATION_LOOP,EAST_START,EAST_END);g_alecDirection = EAST;g_state = WALKING;}if(alecX+ALEC_FRAME_WIDTH <= SCREEN_WIDTH-WALK_DISTANCE && checkCollision(alecX+WALK_DISTANCE,agk::GetSpriteY(ALEC_SPRITE))){newX = alecX + WALK_DISTANCE;agk::SetSpriteX(ALEC_SPRITE,newX);}}else if(directionX < 0){if(g_alecDirection !=WEST || g_state==STANDING){agk::PlaySprite(ALEC_SPRITE,ALEC_FPS,ANIMATION_LOOP,WEST_START,WEST_END);g_alecDirection = WEST;g_state = WALKING;}if(alecX>=WALK_DISTANCE && checkCollision(alecX-WALK_DISTANCE,agk::GetSpriteY(ALEC_SPRITE))){newX = alecX - WALK_DISTANCE;agk::SetSpriteX(ALEC_SPRITE,newX);}}}void updateAlecY(float directionY){float alecY,newY;alecY = agk::GetSpriteY(ALEC_SPRITE);if(directionY > 0){if(g_alecDirection != SOUTH || g_state==STANDING){agk::PlaySprite(ALEC_SPRITE,ALEC_FPS,ANIMATION_LOOP,SOUTH_START,SOUTH_END);g_alecDirection = SOUTH;g_state = WALKING;}if(alecY+ALEC_FRAME_HEIGHT <= SCREEN_HEIGHT-WALK_DISTANCE && checkCollision(agk::GetSpriteX(ALEC_SPRITE),alecY+WALK_DISTANCE)){newY = alecY + WALK_DISTANCE;agk::SetSpriteY(ALEC_SPRITE,newY);}}else if(directionY < 0){if(g_alecDirection != NORTH || g_state==STANDING){agk::PlaySprite(ALEC_SPRITE,ALEC_FPS,ANIMATION_LOOP,NORTH_START,NORTH_END);g_alecDirection = NORTH;g_state = WALKING;}if(alecY>=WALK_DISTANCE && checkCollision(agk::GetSpriteX(ALEC_SPRITE),alecY-WALK_DISTANCE)){newY = alecY - WALK_DISTANCE;agk::SetSpriteY(ALEC_SPRITE,newY);}}}int direction(float x,float y){int c=0,isx = -1;if(x!=0){c++;isx = 1;}if(y!=0){c++;isx = 0;}switch(c){case 0:return 0;break;case 1:if(isx == 1){return 1;}else if(isx == 0){return 2;}break;case 2:switch(g_alecDirection){case NORTH:case SOUTH:return 1;break;case WEST:case EAST:return 2;break;}break;}return 0;}bool checkCollision(float a,float b){int y = (int)((a + ALEC_FRAME_WIDTH/2)/TILE_WIDTH);int x = (int)((b + ALEC_FRAME_HEIGHT)/TILE_HEIGHT);agk::SetTextString(200,agk::Str(x));agk::SetTextString(201,agk::Str(y));agk::SetTextString(202,agk::Str(g_tileMap[x][y]));if(g_tileMap[x][y]>=7){return false;}return true;}
做出的修改如下:
① 小人速度加快。
② 增加了阻碍移动的物体。
③ 按下左右键时候按下上下键的时候互相切换,反之亦然。这样虽然避免了if和else if导致有一个键先行判断而另一个键后判断的情况。但是人物移动的时候两个方向快速切换也是影响视觉效果。最好还是绘制四个斜方向的移动小人动画。
④ 小人移动的时候双脚摆动,站立时停止摆动。
实际上的速度要比gif图片要快的多。中间的图上右上右动的极快。
agk有一点致命的地方是并不支持中文文本。中文文本输出会出现乱码。所以想要中文只能用图片的形式输出了。
0 0
- 【APP GAME KIT】能碰到障碍物的移动小人
- 输出移动小人的程序
- C乐趣之移动的小人
- 关于Microsoft Visual Studio 2010 使用 APP GAME KIT中遇到的问题
- 【APP GAME KIT】无法使用agk::PlayMusic(MUSICE_INDEX)播放的问题
- 美团app动画奔跑的小人
- Unity移动障碍物设置
- web app是否能主宰未来的移动互联网?
- 把小人移动到鼠标点击的位置
- Unity3D-移动障碍物之吊桥
- Google App Engine 碰到的
- 读书笔记---蓝牙 (Game Kit)
- 整理下能碰到的技术资料
- 移动APP数据分析能做什么
- Unity20--动态的障碍物
- 游戏中常用的寻路算法的分享(4)处理移动中的障碍物
- 关于寻路算法的一些思考(5):处理移动中的障碍物
- 关于寻路算法的一些思考(5):处理移动中的障碍物
- Android 第三方开源SwipeToDismiss:左滑/右滑删除ListView条目Item
- 模板_KMP算法
- swift析构方法和扩展
- 《启示录》阅读笔记(7)——产品评审团
- Android 第三方开源SwipeMenuListView(QQ侧滑置顶,删除)
- 【APP GAME KIT】能碰到障碍物的移动小人
- 浅谈粒子群算法的学习方法-Particle Swarm Optimisation
- 根据一点坐标和距离计算另一点坐标(PHP),以及计算两点间距离(PHP)
- Android 开发中使用Fragment跳转到下一个Fragment(使用add方法),并实现返回键和自定义返回键。
- 【codechef】Save Spaceman Spiff(人能否安全从起点走到终点)
- 限制root用户登录ssh
- Android 第三方开源PullToRefresh加入Item(系列2)
- Android工程引用其他项目
- ios 9.1以后 添加libz.dylib 方法