恶魔轮盘c++游戏

#include<bits/stdc++.h>
#include <cstdlib>
#include <ctime>

 
void hp_bar();
void show_player();
void show_enemy();
void move_enemy();
void draw_background();
int generate_line();                    // 若返回 -1,表示生成线条失败

int create_p_b();                        // 创建自机的子弹
int create_e_b();                        // 创建敌机的子弹

int destroy_p_b(int index);
int destroy_e_b(int index);                // 删除一个子弹

#define FRAMERATE 20                    // 画面刷新的周期(ms)
#define FIRERATE 350                    // 射击间隔时间
#define E_FIRERATE 350                    // 敌人射击间隔
#define BLEED_TIME 150                    // 受伤闪烁时间

#define BACKGROUND 80                    // 绘制背景线条的周期

#define MAX_LINES 75                    // 最多同屏背景线条数目
#define MAX_PLAYER_BULLETS 40            // 最多同屏自机子弹数目
#define MAX_ENEMY_BULLETS 40            // 最多同屏敌机子弹数目


int player_pos[2] = { 30,30 };                        // 自机位置xy
int enemy_bullet[MAX_ENEMY_BULLETS][2];                // 敌人的子弹位置
int player_bullet[MAX_PLAYER_BULLETS][2];            // 自机的子弹位置
int enemy_pos[2] = { 580,240 };                        // 敌机位置
bool p_b_slots[MAX_PLAYER_BULLETS] = { false };        // 用于判断 player_bullet 的某个位置是否可用
bool e_b_slots[MAX_ENEMY_BULLETS] = { false };
int number_p_b = 0, number_e_b = 0;                    // 记录自机和敌机的子弹数,减少遍历压力

int player_health = 100, enemy_health = 100;

bool isBleeding_p = false, isBleeding_e = false;    // 用于实现命中后的闪烁效果


int background_line[MAX_LINES][3];                    // 背景的线条,三个参数分别是 x、y、长度
bool line_slots[MAX_LINES] = { false };
int number_lines = 0;                                // 记录背景线条数目


clock_t begin_time = 0;

int main()
{

    srand((unsigned)time(NULL));


    
    

    bool win = false, dead = false;

    clock_t firerate = clock();                        // 射击控制
    clock_t e_firerate = clock();                    // 控制敌机的射击
    clock_t runtime = clock();                        // 用于控制画面刷新频率
    clock_t bleed_p = clock(), bleed_e = clock();    // 用于实现受伤闪烁
    clock_t backgroundline_generate = clock();        // 用于生成背景线条
    


    bool leftshift = false;

    begin_time = clock();
    while (true)
    {

        if (clock() - runtime >= FRAMERATE)
        {
            runtime = clock();
            
            draw_background();
            hp_bar();// 画血条
            show_player();
            show_enemy();

            int n_p_b = 1, n_e_b = 1;                    // 计数,遍历子弹,刷新位置
            int p_b_toprocess = number_p_b, e_b_toprocess = number_e_b;    // 需要处理的子弹数
            for (int i = 0; i < MAX_PLAYER_BULLETS && (n_p_b <= p_b_toprocess || n_e_b <= e_b_toprocess); ++i)
            {
                if (n_p_b <= p_b_toprocess)                // 如果子弹已经处理完就不处理了
                {
                    if (p_b_slots[i] == true)
                    {
                        ++n_p_b;
                        player_bullet[i][0] += 3;
                    
                        if (player_bullet[i][0] >= 635)
                        {
                            destroy_p_b(i);    // 到达了屏幕最右端
                        }

                        // 碰撞检测,两个矩形
                        if ((player_bullet[i][0] + 5 >= enemy_pos[0] - 20 && player_bullet[i][0] - 5 <= enemy_pos[0] + 20) && (player_bullet[i][1] - 5 < enemy_pos[1] + 40 && player_bullet[i][1] + 5 > enemy_pos[1] - 40))
                            // 击中敌人
                        {
                            destroy_p_b(i);
                            enemy_health -= 8;
                            isBleeding_e = true;
                            bleed_e = clock();
                        }

                        fillrectangle(player_bullet[i][0] - 5, player_bullet[i][1] - 5, player_bullet[i][0] + 5, player_bullet[i][1] + 5);        // 画子弹
                    }

                }

                if (n_e_b <= e_b_toprocess)                // 敌人的子弹
                {
                    if (e_b_slots[i] == true)
                    {
                        ++n_e_b;
                        enemy_bullet[i][0] -= 3;
                        setfillcolor(RGB(255, 180, 20));
                        if (enemy_bullet[i][0] < 5)
                        {
                            destroy_e_b(i);
                        }

                        // 碰撞检测,两个矩形
                        if (enemy_bullet[i][0] - 5 < player_pos[0] + 25 && enemy_bullet[i][0] + 5 > player_pos[0] - 25 && enemy_bullet[i][1] - 5 < player_pos[1] + 25 && enemy_bullet[i][1] + 5 > player_pos[1] - 25)
                        {
                            // 击中自机
                            isBleeding_p = true;
                            destroy_e_b(i);
                            player_health -= 8;
                            bleed_p = clock();
                        }
                        fillrectangle(enemy_bullet[i][0] - 5, enemy_bullet[i][1] - 5, enemy_bullet[i][0] + 5, enemy_bullet[i][1] + 5);
                    }

                }
            }

            if (win || dead)
                break;
            FlushBatchDraw();

            move_enemy();

            if (player_health <= 0)
                dead = true;
            if (enemy_health <= 0)
            {
                win = true;
            }

            if (GetAsyncKeyState(VK_LSHIFT) & 0x8000)    // 按住 Shift 减速
            {
                leftshift = true;
            }
            else
            {
                leftshift = false;
            }

            if (GetAsyncKeyState(VK_UP) & 0x8000)
                // 玩家移动
            {
                if (player_pos[1] >= 28)
                    if (leftshift)
                        player_pos[1] -= 2;                // y 的正方向是向下的
                    else
                        player_pos[1] -= 5;
            }
            if (clock() - firerate >= FIRERATE && GetAsyncKeyState('Z') & 0x8000)
                // 玩家开火
            {
                firerate = clock();
                create_p_b();
            }
            if (GetAsyncKeyState(VK_DOWN) & 0x8000)
                // 玩家移动
            {
                if (player_pos[1] <= 452)
                    if (leftshift)
                        player_pos[1] += 2;
                    else
                        player_pos[1] += 5;
            }
            if (GetAsyncKeyState(VK_LEFT) & 0x8000)
                // 玩家移动
            {
                if (player_pos[0] >= 30)
                    if (leftshift)
                        player_pos[0] -= 2;
                    else
                        player_pos[0] -= 5;
            }
            if (GetAsyncKeyState(VK_RIGHT) & 0x8000)
                // 玩家移动
            {
                if (player_pos[0] <= 320)
                    if (leftshift)
                        player_pos[0] += 2;
                    else
                        player_pos[0] += 5;
            }


            if (clock() - e_firerate >= E_FIRERATE)
            {
                e_firerate = clock();
                create_e_b();
            }


            if (clock() - bleed_p >= BLEED_TIME)        // 受伤时间结束后关闭受伤闪烁效果
            {
                isBleeding_p = false;
            }

            if (clock() - bleed_e >= BLEED_TIME)        // 受伤时间结束后关闭受伤闪烁效果
            {
                isBleeding_e = false;
            }

            if (clock() - backgroundline_generate >= BACKGROUND)
            {
                backgroundline_generate = clock();
                generate_line();
            }
        }
    }
    if (win)
    {
        settextcolor(RGB(0, 254, 0));
        settextstyle(35, 0, L"黑体");
        outtextxy(150, 200, L"你打败了boss!你赢了!!");
    }
    else
    {
        settextcolor(RGB(254, 0, 0));
        settextstyle(35, 0, L"黑体");
        outtextxy(140, 200, L"你被boss打败了!");
    }
    FlushBatchDraw();
    Sleep(5000);
    EndBatchDraw();
    return 0;
}


void hp_bar()
{
    setlinecolor(RGB(255, 255, 255));
    line(0, 481, 640, 481);                                        // 一条分割线
    settextstyle(20, 0, L"黑体");
    outtextxy(10, 485, L"BOSS的生命值:");
    outtextxy(10, 520, L"玩家的生命值:");
    setfillcolor(RGB(0, 255, 1));
    setlinecolor(WHITE);
    rectangle(160, 515, 560, 540);                                // 血条外框
    setfillcolor(RGB(0, 255, 1));
    setlinecolor(RGB(255, 255, 255));
    if (player_health > 0)
        fillrectangle(160, 515, 160 + player_health * 4, 540);    // 玩家血条
    setlinecolor(WHITE);
    rectangle(160, 485, 560, 510);                                // 敌人血条外框
    setfillcolor(RGB(230, 0, 1));
    setlinecolor(RGB(255, 255, 255));
    if (enemy_health > 0)
        fillrectangle(160, 485, 160 + enemy_health * 4, 510);    // 敌人血条

}

void show_player()
{
    if (isBleeding_p)
        setfillcolor(RGB(255, 0, 0));
    else
        setfillcolor(RGB(150, 180, 210));
    fillrectangle(player_pos[0] - 25, player_pos[1] - 25, player_pos[0] + 25, player_pos[1] + 25);
    setfillcolor(RGB(100, 200, 180));
    fillrectangle(player_pos[0], player_pos[1] + 5, player_pos[0] + 40, player_pos[1] - 5);
}

void show_enemy()
{
    if (isBleeding_e)
        setfillcolor(RGB(255, 0, 0));
    else
        setfillcolor(RGB(0, 130, 125));
    fillrectangle(enemy_pos[0] - 20, enemy_pos[1] - 40, enemy_pos[0] + 20, enemy_pos[1] + 40);
    setfillcolor(RGB(100, 200, 180));
    fillrectangle(enemy_pos[0], enemy_pos[1] + 5, enemy_pos[0] - 40, enemy_pos[1] - 5);
}

void move_enemy()
{
    static bool angle_v;        // 控制敌机的竖直移动方向,true 为向上,到边缘就换向
    static bool angle_h;        // 控制敌机的水平移动方向,true 为向左,到边缘就换向
    static clock_t interval;    // 定时随机换向

    if (clock() - interval >= 2000)
    {
        interval = clock();
        if (rand() % 2)            // 一般的概率换向
            angle_v = !angle_v;
        if (rand() % 2)
            angle_h = !angle_h;
    }

    if (angle_v == true)        // 到了地图边缘就调头
        enemy_pos[1] -= 3;
    else
        enemy_pos[1] += 3;
    if (angle_h == true)
        enemy_pos[0] -= 3;
    else
        enemy_pos[0] += 3;


    if (enemy_pos[1] >= 440)
        angle_v = true;
    else if (enemy_pos[1] <= 40)
        angle_v = false;


    if (enemy_pos[0] >= 580)
        angle_h = true;
    else if (enemy_pos[0] <= 380)
        angle_h = false;

}

void draw_background()
{
    setlinecolor(WHITE);
    int n_b_l = number_lines;        // 待处理线条数目
    for (int i = 0; i < MAX_LINES && (n_b_l > 0); ++i)
    {
        if (line_slots[i] == true)
        {
            if (background_line[i][0] + background_line[i][2] <= 0)        // 说明线条出了屏幕
            {
                --number_lines;
                line_slots[i] = false;
            }
            else
            {
                background_line[i][0] -= 10;                // 线条移动
                line(background_line[i][0], background_line[i][1], background_line[i][0] + background_line[i][2], background_line[i][1]);
            }
            --n_b_l;
        }

    }
}

int generate_line()
{
    if (number_lines >= MAX_LINES)
        return -1;
    ++number_lines;
    for (int i = 0; i < MAX_LINES; ++i)
    {
        if (line_slots[i] == false)
        {
            line_slots[i] = true;
            background_line[i][0] = 640;                // 线条出现于屏幕最右边
            background_line[i][1] = rand() % 480;        // 线条高度随机
            background_line[i][2] = 10 + rand() % 50;    // 线条长度随机在 10-50 像素之间

            break;
        }
    }
    return 0;
}

int create_p_b()
{
    if (number_p_b > MAX_PLAYER_BULLETS)            // 空间不够
        return -1;
    for (int i = 0; i < MAX_PLAYER_BULLETS; ++i)    // 搜索 slots,寻找空位
    {
        if (p_b_slots[i] == false)
        {
            p_b_slots[i] = true;
            player_bullet[i][0] = player_pos[0] + 45;
            player_bullet[i][1] = player_pos[1];    // 创建子弹
            ++number_p_b;
            break;
        }
    }
    return 0;
}

int create_e_b()
{
    if (number_e_b > MAX_ENEMY_BULLETS)                // 空间不够
        return -1;
    for (int i = 0; i < MAX_ENEMY_BULLETS; ++i)        // 搜索 slots,寻找空位
    {
        if (e_b_slots[i] == false)
        {
            e_b_slots[i] = true;
            enemy_bullet[i][0] = enemy_pos[0] - 45;
            enemy_bullet[i][1] = enemy_pos[1];        // 创建子弹
            ++number_e_b;
            break;
        }
    }
    return 0;
}

int destroy_p_b(int index)
{
    if (index > MAX_PLAYER_BULLETS - 1)
        return -2;
    if (p_b_slots[index] == false)
        return -1;
    p_b_slots[index] = false;
    --number_p_b;
    return 0;
}

int destroy_e_b(int index)
{
    if (index > MAX_ENEMY_BULLETS - 1)
        return -2;
    if (e_b_slots[index] == false)
        return -1;
    e_b_slots[index] = false;
    --number_e_b;
    return 0;v
}
————————————————

                            版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
                        
原文链接:https://blog.youkuaiyun.com/2401_84685243/article/details/138583868

### C++实现恶魔轮盘游戏C++中创建一个简单的“恶魔轮盘赌”游戏可以基于随机数生成器来模拟。这个游戏通常涉及玩家选择一个数字,程序随即从一组预设的选项里抽取一个作为胜利条件。 ```cpp #include <iostream> #include <cstdlib> // For rand() and srand() #include <ctime> // For time() using namespace std; int main(){ int playerChoice; const int maxNumber = 6; // 假设有六个槽位, 类似于手枪的弹巢 bool isPlayerAlive = true; cout << "欢迎来到恶魔轮盘游戏!" << endl; cout << "请输入您猜测的位置 (1-" << maxNumber << "): "; cin >> playerChoice; if(playerChoice < 1 || playerChoice > maxNumber){ cout << "输入错误! 范围应在1到" << maxNumber << "." << endl; return 0; } srand(static_cast<unsigned>(time(0))); // 初始化随机种子 int bulletPosition = (rand() % maxNumber) + 1; while(isPlayerAlive && bulletPosition != playerChoice){ cout << "\n点击扳机... 空响!\n"; do{ cout << "再次尝试? 输入新位置 (1-" << maxNumber << ") 或者按其他键退出: "; char choice; cin.clear(); // 清除之前的输入状态 cin.ignore(numeric_limits<streamsize>::max(), '\n'); // 忽略缓冲区中的旧数据 if(!(cin >> choice)){ break; } playerChoice = choice - '0'; // 将字符转换成整型数值 }while((playerChoice >= 1 && playerChoice <= maxNumber)); if (!(playerChoice >= 1 && playerChoice <= maxNumber)) { cout << "再见!"; break; } } if(bulletPosition == playerChoice){ cout << "\n砰!\n很遗憾,这次运气不佳..." << endl; }else{ cout << "\n感谢参与本局游戏。\n希望下次还能见到你!" << endl; } return 0; } ``` 这段代码实现了基本的游戏逻辑[^1]。通过`rand()`函数生成了一个介于1至最大槽数之间的随机整数表示子弹所在位置;而用户的输入决定了触发机关时所指向的位置。当两者相匹配,则认为发生了不幸事件;反之则继续循环直到用户决定停止或遭遇失败结局。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值