第一次用C语言图形库easyx写的游戏飞机大战,为什么游戏会不断加速啊,哪里出了问题?

本来一切正常,大概写到敌人移动的时候发现游戏会一直加速了
改了一下午了,还是这样(哭)

#include<stdio.h>
#include<graphics.h> 
#include<conio.h>
#include<math.h>

//关键字
enum my
{
    WIDTH = 480,
    HEIGHT = 700,
    WIDTH_player = 102,
    HEIGHT_player = 126,
    BULLET_number = 5,
    ENEMY_number = 10,
    ENEMY1, ENEMY2, ENEMY3
};

//飞机结构
struct plance
{
    int x, y;
    bool live;
    int width;
    int height;
    int hp;
    int type;

}player, bullet[BULLET_number], enemy[ENEMY_number];

//导入图片
IMAGE bk;
IMAGE img_palyer[2];
IMAGE img_bullet_player[2];
IMAGE img_enemy[3][2];

//图片加载函数
void LoadImage()
{
    loadimage(&bk, "./pictures/background.png");
    loadimage(&img_palyer[0], "./pictures/player1_yan.png");
    loadimage(&img_palyer[1], "./pictures/player1_yuan.png");
    loadimage(&img_bullet_player[0], "./pictures/bullet_yan.png");
    loadimage(&img_bullet_player[1], "./pictures/bullet_player_yuan.png");

    loadimage(&img_enemy[0][0], "./pictures/enemy1_yan.png");
    loadimage(&img_enemy[0][1], "./pictures/enemy1_yuan.png");
    loadimage(&img_enemy[1][0], "./pictures/enemy2_yan.png");
    loadimage(&img_enemy[1][1], "./pictures/enemy2_yuan.png");
    loadimage(&img_enemy[2][0], "./pictures/enemy3_yan.png");
    loadimage(&img_enemy[2][1], "./pictures/enemy3_yuan.png");
}

//敌人初始化函数
void enemyHp(int i)
{
    int randnum = rand() % 100;
    if (randnum <= 5)
    {
        enemy[i].type = ENEMY3;
        enemy[i].hp = 25;
        enemy[i].width = 169;
        enemy[i].height = 258;
    }
    else if (randnum >= 6 && randnum <= 40)
    {
        enemy[i].type = ENEMY2;
        enemy[i].hp = 10;
        enemy[i].width = 69;
        enemy[i].height = 99;
    }
    else
    {
        enemy[i].type = ENEMY1;
        enemy[i].hp = 5;
        enemy[i].width = 57;
        enemy[i].height = 43;
    }
}

//初始化数据函数
void gameInit()
{
    //初始化玩家
    LoadImage();
    player.x = WIDTH / 2 - WIDTH_player / 2;
    player.y = HEIGHT - HEIGHT_player;
    player.live = true;

    //初始化子弹
    for (int i = 0; i < BULLET_number; i++)
    {
        bullet[i].x = 0;
        bullet[i].y = 0;
        bullet[i].live = false;
    }

    //初始化敌人
    for (int i = 0; i < ENEMY_number; i++)
    {
        enemy[i].live = false;
        enemyHp(i);
    }
}

//绘制函数
void gameDraw()
{
    //绘制背景
    putimage(0, 0, &bk);
    //绘制玩家
    putimage(player.x, player.y, &img_palyer[0], NOTSRCERASE);
    putimage(player.x, player.y, &img_palyer[1], SRCINVERT);
    //绘制子弹
    for (int i = 0; i < BULLET_number; i++)
    {
        if (bullet[i].live)
        {
            putimage(bullet[i].x, bullet[i].y, &img_bullet_player[0], NOTSRCERASE);
            putimage(bullet[i].x, bullet[i].y, &img_bullet_player[1], SRCINVERT);
        }
    }
    //绘制敌人
    for (int i = 0; i < ENEMY_number; i++)
    {
        if (enemy[i].live)
        {
            if (enemy[i].type == ENEMY1)
            {
                putimage(enemy[i].x, enemy[i].y, &img_enemy[0][0], NOTSRCERASE);
                putimage(enemy[i].x, enemy[i].y, &img_enemy[0][1], SRCINVERT);
            }
            else if (enemy[i].type == ENEMY2)
            {
                putimage(enemy[i].x, enemy[i].y, &img_enemy[1][0], NOTSRCERASE);
                putimage(enemy[i].x, enemy[i].y, &img_enemy[1][1], SRCINVERT);
            }
            else if (enemy[i].type == ENEMY3)
            {
                putimage(enemy[i].x, enemy[i].y, &img_enemy[2][0], NOTSRCERASE);
                putimage(enemy[i].x, enemy[i].y, &img_enemy[2][1], SRCINVERT);
            }
        }
    }

}

//敌人生成
void creatEnemy()
{
    for (int i = 0; i < ENEMY_number; i++)
    {
        if (!enemy[i].live)
        {
            enemy[i].live = true;
            enemy[i].x = rand() % (WIDTH - 60);
            enemy[i].y = 0;
            break;
        }
    }
}

//敌人移动函数
void EnemyMove(int speed)
{
    
    for (int i = 0; i < ENEMY_number; i++)
    {
        printf("%d:(%d,%d),%d\n", i, enemy[i].x, enemy[i].y, enemy[i].live);
        if (enemy[i].live )
        {
            if (enemy[i].y < HEIGHT)
            {
                enemy[i].y += 1;
            }
            else
            {
                enemy[i].live = false;
            }
            if (enemy[i].x > 10 && enemy[i].x < WIDTH - enemy[i].width - 10)
            {
                enemy[i].x += pow(-1, rand())*(rand() % 15);
            }
        }
    }
}

//子弹生成函数
void creatBullet()
{
    for (int i = 0; i < BULLET_number; i++)
    {
        if (!bullet[i].live)
        {
            bullet[i].x = player.x + WIDTH_player / 2;
            bullet[i].y = player.y;
            bullet[i].live = true;
            break;
        }
    }

}

//子弹移动函数
void BulletMove(int speed)
{
    for (int i = 0; i < BULLET_number; i++)
    {
        if (bullet[i].live)
        {

            bullet[i].y -= speed;
            if (bullet[i].y < 0)
            {
                bullet[i].live = false;
            }
        }
    }
}

//角色移动函数
void playerMove(int speed)
{
#if 0
    //检测按键是否按下
    if (_kbhit())
    {
        //1_getch()阻塞函数(<conio.h>为非标准库,移植性差)(百度):getch()是编程中所用的函数,这个函数是一个不回显函数,当用户按下某个字符时,函数自动读取,无需按回车,有的C语言命令行程序会用到此函数做游戏,但是这个函数并非标准函数,要注意移植性!
        char key = _getch();
        switch (key)
        {
        case 'W':
        case 'w':
            player.y -= speed;
            break;
        case 'S':
        case 's':
            player.y += speed;
            break;
        case 'A':
        case 'a':
            player.x -= speed;
            break;
        case 'D':
        case 'd':
            player.x += speed;
            break;
        }
    }

#elif 1
    //2使用windows函数获取键盘输入(非阻塞函数)(检测字母按键必须用大写)
    if (GetAsyncKeyState(VK_UP) || GetAsyncKeyState('W'))
    {
        if (player.y > 0)//边界限制判断和刷新率限制
        {
            player.y -= speed;
        }
    }
    if (GetAsyncKeyState(VK_DOWN) || GetAsyncKeyState('S'))
    {
        if (player.y < HEIGHT - HEIGHT_player / 2)//边界限制判断
        {
            player.y += speed;
        }
    }
    if (GetAsyncKeyState(VK_LEFT) || GetAsyncKeyState('A'))
    {
        if (player.x > 0 - WIDTH_player / 2)//边界限制判断
        {
            player.x -= speed;
        }
    }
    if (GetAsyncKeyState(VK_RIGHT) || GetAsyncKeyState('D'))
    {
        if (player.x < WIDTH - WIDTH_player / 2 )//边界限制判断
        {
            player.x += speed;
        }
    }
#endif // 0
    static DWORD ta = 0, tb = 0;
    if (GetAsyncKeyState(VK_SPACE) && tb - ta >50)
    {
        creatBullet();
        ta = tb;
    }
    tb = GetTickCount();
}


//游戏主体
int main()
{
    initgraph(WIDTH, HEIGHT, SHOWCONSOLE);
    gameInit();
    //双缓冲绘图(B-F-E)(不然画面会一卡一卡的)
    BeginBatchDraw();
    while (1)
    {
        gameDraw();
        FlushBatchDraw();
        playerMove(10);        
        BulletMove(5);
        creatEnemy();
        EnemyMove(5);        
    }
    EndBatchDraw();
    return 0;
}
阅读 2.1k
2 个回答

因为你没提供那些图片,所以我也看不到效果。
单纯从代码上看,你的那个主 while 循环没看到任何延迟处理,也就是说你一个 turn 的周期是看你的机器速度,我没做过游戏,但我理解不应该是这样的吧?

目前问题已经解决,游戏也基本完成
解决方法就是在while循环中加sleep(数值);
如:

//游戏主体
int main()
{
    initgraph(WIDTH, HEIGHT);//打包时删去showconsole,关闭控制台
    gameInit();
    //双缓冲绘图(B-F-E)(不然画面会一卡一卡的)
    BeginBatchDraw();
    while (1)
    {
        gameDraw();
        FlushBatchDraw();
        enemyko();
        gamelevel();
        playerMove(10);
        BulletMove(45);
        PlayerKO();
        showdata();
        Sleep(10);//控制刷新频率        
    }
    EndBatchDraw();

    return 0;
}

项目全部源文件可见https://github.com/yehu1999/ACE-COMBAT-8-retrogression.git

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏