欢迎光临散文网 会员登陆 & 注册

手机C4droid打飞机

2023-07-23 19:06 作者:乐的不要不要的  | 我要投稿

使用手机C4droid编译器的SDL2库写的打飞机 (水平很有限,仅仅是基本实现能玩) 希望可以和大家一起学习进步

敌机

本机

子弹 这段代码复制下来就能用,图片素材都在上面,字体顺便网上下载 #include #include #include #include #include #include #define WIDTH 1000 #define HEIGHT 2000 #define ERROR_FONT_SIZOF 80 //字体大小 #define FRAMERATE 60 //帧率 #define BULLET_SPEED 5 //子弹速度 #define ENEMY_SPEED 3 //敌机速度 #define FONT_NANE "/storage/emulated/0/1/resource//ttf/15.ttf" #define PLANE_FILE "/storage/emulated/0/1/resource/aircraft.png" #define BULLET_FILE "/storage/emulated/0/1/resource/bullet.png" #define ENEMY_FILE "/storage/emulated/0/1/resource/enemy.png" //上面的路径自己修改自己手机图片的路径就好 using namespace std; SDL_Window *window; SDL_Renderer *renderer; TTF_Font *font = NULL; SDL_bool move_no = SDL_FALSE; bool init(); void showvalue(string a, int g, int x, int y); void close(); class plane //飞机类 {  public: plane(); SDL_Texture *img; SDL_Surface *simg; int planew; int planeh; SDL_Rect imgr; SDL_Rect srcr; int mouseplane(SDL_Event *event); SDL_Rect &draw(); ~plane(); }; class bullet //子弹类 {  public: bullet(); SDL_Texture *img; SDL_Surface *simg; SDL_Rect imgr; SDL_Rect srcr; bullet *last; bullet *next; bool show; void move(SDL_Rect rect); int bulletw; int bulleth; SDL_Rect *returect(); void draw(int y); ~bullet(); }; class enemy //敌机类 {  public: enemy(); SDL_Texture *img; SDL_Surface *simg; SDL_Rect imgr; SDL_Rect srcr; enemy *last; enemy *next; bool show; SDL_Rect *returect(); int enemyw; int enemyh; SDL_Rect &draw(int y); ~enemy(); }; int main(int argc, char *argv[]) { init();  //初始化函数 plane plane1; //飞机对象 //这里用指针圆形链表创建子弹和敌机 bullet *butemp = new bullet; bullet *butip2, *butip; butip = butemp; butemp->srcr.y = HEIGHT - 50; butemp->next = butemp; butemp->last = butemp; // enemy *entemp = new enemy; enemy *entip2 = new enemy; entip2->srcr.y = 50; enemy *entip = entemp; entip2->next = entemp; entip2->last = entemp; entemp->next = entip2; entemp->last = entip2; // int i = 0;   //帧数 int grade = 0; //分数 int tt = 0; while (1) { long begin = SDL_GetTicks(); //测时间开点 SDL_SetRenderDrawColor(renderer, 55, 55, 55, 255); SDL_RenderClear(renderer); //以上面的颜色清屏,分别是R.G.B.α透明 SDL_Rect bullet_rect; bullet_rect = plane1.draw(); //创建子弹链 if (i % 40 == 1) //每到这里往链表里面塞一个对象 { butemp = butip; butip = new bullet; butip->next = butemp->next; butip->last = butemp; butemp->next->last = butip; butemp->next = butip; butip->move(bullet_rect); //子弹的初始位置等于当前本机的位置 } butip2 = butip; do { butip->draw(5); if (butip->srcr.y < -400) //判断是否到达边界,这里设置的比较远是因为不能让同时只能存在一个子弹 { butemp = butip; butip->last->next = butip->next; butip->next->last = butip->last; butip = butip->last; butemp->~bullet(); free(butemp); butemp = NULL; } butip = butip->next; } while (butip != butip2); // //创建敌机链 if (i % (60 - (i / 100)) == 1)//敌机的创建速度跟随帧率 { entip = entip2->next; entemp = new enemy; entip2->next = entemp; entip->last = entemp; entemp->next = entip; entemp->last = entip2; entip = entemp; } entip2 = entip; do { entip->draw(ENEMY_SPEED + i / 800);//帧数每增加800个,速度加1 if (entip->srcr.y > HEIGHT) //判断是否到达边界 { entemp = entip; entip->last->next = entip->next; entip->next->last = entip->last; entip = entip->last; entemp->~enemy(); free(entemp); entemp = NULL; } entip = entip->next; } while (entip != entip2); ///////* butip2 = butip; entip2 = entip; do { do { //判断是否接触 if (SDL_HasIntersection(entip->returect(), butip->returect())) { //showvalue("jz", entip->srcr.y, 0, 300); butip->show = false; //这里不删除,发现总会删除标记指针,索性直接这个链元素直接隐藏, entip->show = false; //并且上面的判断函数里面的返回该链对象Rect的函数都返回一个固定框,确保不会相交 grade++; } entip = entip->next; } while (entip != entip2); butip = butip->next; } while (butip != butip2); showvalue("grade:", grade, 0, 100); i++; showvalue("zhen", i, 0, 500); int bb = 0; do //循环判断敌机与本机是否接触,但这里使用图片的大小方块,判定距离有点大 { if (SDL_HasIntersection(&(plane1.srcr), entip->returect())) { showvalue("jz", entip->srcr.y, 0, 300); bb = 1; break; } entip = entip->next; } while (entip != entip2); if (bb) { break; } SDL_RenderPresent(renderer); ////////// SDL_Event event; while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_MOUSEMOTION:; case SDL_MOUSEBUTTONDOWN:; case SDL_MOUSEBUTTONUP: plane1.mouseplane(&event); break; case SDL_QUIT: return 0; } } //////*/ long current = SDL_GetTicks(); //测时间结束点 long cost = current - begin; long frame = 1000 / FRAMERATE; long delay = frame - cost; if (delay > 0) //通过上面的来计算一帧的时间。 { SDL_Delay(delay); } } showvalue("beybey", 0, WIDTH / 3, HEIGHT / 2); SDL_RenderPresent(renderer); SDL_Delay(2000); close(); return 0; } bool init() { // 初始化SDL if (SDL_Init(SDL_INIT_VIDEO) < 0) { std::cout << "SDL初始化失败。SDL错误:" << SDL_GetError() << std::endl; return false; } // 创建窗口 window = SDL_CreateWindow("SDL Font Rendering", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, WIDTH, HEIGHT, SDL_WINDOW_SHOWN); if (window == NULL) { std::cout << "窗口创建失败。SDL错误:" << SDL_GetError() << std::endl; return false; } // 创建渲染器 renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); if (renderer == NULL) { std::cout << "渲染器创建失败。SDL错误:" << SDL_GetError() << std::endl; return false; } // 设置渲染器绘制颜色为白色 SDL_SetRenderDrawColor(renderer, 0xFF, 0xFF, 0xFF, 0xFF); // 初始化SDL_ttf if (TTF_Init() == -1) { std::cout << "SDL_ttf初始化失败。SDL_ttf错误:" << TTF_GetError() << std::endl; return false; } font = TTF_OpenFont(FONT_NANE, ERROR_FONT_SIZOF); if (font == NULL) { std::cout << "字体加载失败。TTF错误:" << TTF_GetError() << std::endl; return false; } return true; } void showvalue(string a, int g, int x = 100, int y = 100) //这是一个显示字符的函数 { char yy[16]; sprintf(yy, "%s:%d", a.c_str(), g); SDL_Color color = {255, 0, 0, 0}; SDL_Surface *fontsurface = TTF_RenderText_Solid(font, yy, color); SDL_Texture *fontTexture = SDL_CreateTextureFromSurface(renderer, fontsurface); SDL_Rect textRect; textRect.x = x; textRect.y = y; textRect.w = fontsurface->w; textRect.h = fontsurface->h; SDL_FreeSurface(fontsurface); SDL_RenderCopy(renderer, fontTexture, NULL, &textRect); SDL_DestroyTexture(fontTexture); } void close() { // 释放字体资源 TTF_CloseFont(font); font = NULL; // 销毁渲染器和窗口 SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); renderer = NULL; window = NULL; // 退出SDL_ttf TTF_Quit(); // 退出SDL SDL_Quit(); } plane::plane() //飞机类的构造函数 { this->img = IMG_LoadTexture(renderer, PLANE_FILE); if (this->img == NULL) { SDL_Log("图片加载失败:%s", SDL_GetError()); return; } this->simg = IMG_Load(PLANE_FILE); if (this->simg == NULL) { SDL_Log("图片加载失败:%s", SDL_GetError()); return; }; this->planew = WIDTH / 5; //是图像大小为屏幕宽度的1/5 this->planeh = WIDTH / 5; //(int)( (float)(planew) /(float)(this->simg->w) * (float)(this->simg->h)); this->imgr = {0, 0, (this->simg->w), (this->simg->h)}; this->srcr = {WIDTH / 2 - planew / 2, HEIGHT - planeh * 2, planew, planeh}; } int plane::mouseplane(SDL_Event *event) ////把鼠标的位置传给图像方块 { SDL_Point mousep = {event->button.x, event->button.y}; switch (event->type) { case SDL_MOUSEMOTION: { if (move_no == SDL_TRUE) //按下且移动鼠标时才能移动 { showvalue("1", mousep.x, 0, 0); this->srcr.x = event->button.x - this->planew / 2; this->srcr.y = event->button.y - this->planeh / 2; move_no = SDL_TRUE; return 0; } break; } case SDL_MOUSEBUTTONDOWN: { if (SDL_PointInRect(&mousep, &(this->srcr))) //判断鼠标按下的位置是不是在图像的上 { showvalue("down", 1, 0, 100); move_no = SDL_TRUE; //在图像上按下了鼠标 return 0; } break; } case SDL_MOUSEBUTTONUP: { move_no = SDL_FALSE; //松开鼠标停止移动。 return 0; break; } default: break; } return 0; } SDL_Rect &plane::draw() { SDL_RenderCopy(renderer, this->img, &(this->imgr), &(this->srcr)); return this->srcr; } plane::~plane() { SDL_DestroyTexture(this->img); SDL_FreeSurface(this->simg); }; bullet::bullet() { this->img = IMG_LoadTexture(renderer, BULLET_FILE); if (this->img == NULL) { SDL_Log("图片加载失败:%s", SDL_GetError()); return; } this->simg = IMG_Load(BULLET_FILE); if (this->simg == NULL) { SDL_Log("图片加载失败:%s", SDL_GetError()); return; }; this->bulletw = WIDTH / 30; //根据屏幕宽度设置子弹的大小 this->bulleth = WIDTH / 18; this->show = true; //默认显示子弹 this->imgr = {0, 0, (this->simg->w), (this->simg->h)}; this->srcr = {WIDTH / 2, HEIGHT - 100, bulletw, bulleth}; } void bullet::move(SDL_Rect rect) //鼠标位置转换成子弹的位置。 { this->srcr.x = rect.x + rect.w / 2 - this->srcr.w / 2; this->srcr.y = rect.y; } void bullet::draw(int y) //显示子弹,并按照传入的数值每帧移动。 { this->srcr.y = this->srcr.y - y; if (this->show) { SDL_RenderCopy(renderer, this->img, &(this->imgr), &(this->srcr)); } return; } SDL_Rect *bullet::returect() { if (this->show) { return &(this->srcr); //如果依旧没有结束,始终是判断为显示,则输出该方块的位置 } else { SDL_Rect temp = {0, 3, 0, 0}; //如果接触了,位置始终是在这个点。 return &temp; } } bullet::~bullet() //子弹类的析构函数 { SDL_DestroyTexture(this->img); SDL_FreeSurface(this->simg); }; enemy::enemy() //敌机类的构造函数。 { this->img = IMG_LoadTexture(renderer, ENEMY_FILE); if (this->img == NULL) { SDL_Log("图片加载失败:%s", SDL_GetError()); return; } this->simg = IMG_Load(ENEMY_FILE); if (this->simg == NULL) { SDL_Log("图片加载失败:%s", SDL_GetError()); return; }; this->enemyw = WIDTH / 6; //按屏幕宽度的比值显示敌机 this->enemyh = WIDTH / 6; this->show = true; //srand(time(0)); //(int)( (float)(planew) /(float)(this->simg->w) * (float)(this->simg->h)); this->imgr = {0, 0, (this->simg->w), (this->simg->h)}; this->srcr = {(rand() % (WIDTH / this->enemyw)) * this->enemyw, -(this->enemyh), this->enemyw, this->enemyh}; } SDL_Rect &enemy::draw(int y) { this->srcr.y = this->srcr.y + y; if (this->show) { SDL_RenderCopy(renderer, this->img, &(this->imgr), &(this->srcr)); } return this->srcr; } SDL_Rect *enemy::returect() { if (this->show) //如果你是没有接触显示,则输出敌机的位置。 { return &(this->srcr); } else { SDL_Rect temp = {0, 0, 0, 0}; //如果接触了判断不显示,则始终输出该位置。 return &temp; } } enemy::~enemy() { SDL_DestroyTexture(this->img); SDL_FreeSurface(this->simg); }; //程序写得很蹩脚,我也仅仅是游戏爱好者,没有电脑,不足之处请恳请大家积极指导。

手机C4droid打飞机的评论 (共 条)

分享到微博请遵守国家法律