服务器之家:专注于服务器技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言 90后怀旧游戏超级玛丽的实现流程

C语言 90后怀旧游戏超级玛丽的实现流程

2022-03-01 14:47MAX在码字 C/C++

90后最风靡的游戏是什么?第一个联想到的肯定是插卡游戏机或者VCD加光盘运行在电视机上的超级玛丽了,它的经典绝对可以排在第一位,长大后的我们今天来用C语言重温一下

在你的童年记忆里,是否有一个蹦跳、顶蘑菇的小人已经被遗忘?

C语言 90后怀旧游戏超级玛丽的实现流程

如果你回忆起了它,你定然会觉得现在它幼稚、无聊,画面不漂亮,游戏不精彩……但请你记住:这才是真正的游戏,它给了你无限的欢乐!许多人只玩过红白机或者网上玩家自己制作的几个破Flash小游戏就还以为任天堂所骄傲的“马里奥”系列就这样子的,你们真的以为超级马里奥就是1985年的“踩蘑菇/采蘑菇”么?也许大家都管马里奥叫超级玛丽,踩蘑菇,这是谁宣传的?

谁认为马里奥就1个游戏?谁说马里奥没有一个是2000年后出的!

从32K的ROM卡带到4.3G的特制光盘,从1.79MHZ的8位处理器到主频数G的次世代主机,从画面简陋的2D时代到音色俱佳的3D动画……你们才知道多少就说什么“超级玛丽”是所谓的幼稚游戏呢?一点也不亚于怪物猎人,极品飞车,火影忍者等等!在华丽的3D游戏、CG 动画大行其道的今天,你们应该想想,游戏是为了看画面还是为了让你快乐,请你回想马里奥在以前给你带来的快乐,它不是最真实、最纯朴的快乐么?

所有曾经的马迷,如果你渴望重新找回超级马里奥在以前给你带来的快乐,那么,试试在百度上打 超级马里奥 吧!超级玛丽只是一个人们习惯性的叫法,任天堂出的这款游戏是马里奥系列.

有一些人说"超级玛丽"说只有1个游戏.连一点意思都没有.还说马里奥是美国出的.是美国1970年出的下流东西。这对马里奥的忠实者会造成很大的伤害.

根据我们的不完全统计,在周围的游戏玩家中:

知道马里奥的人 100%

对马里奥说成超级玛丽的人:95%

知道马里奥有其他游戏的人 5%

其实马里奥不包括同人游戏已经出了上百款了,加上HACK ROM【改版】那就更多了。

初次登场开始两年后,还默默无闻的马里奥又出现在《大金刚Jr.》中。游戏中马里奥反串了绑架大金刚的绑匪,是一个使用鞭子操纵着怪物的角色。之后在《网球》和《PUNCH OUT》游戏中还客串过裁判。马里奥的名字第一次出现在游戏标题中是《马里奥兄弟》这款游戏,而且他的弟弟路易也初次登场。渐渐地,马里奥的个性也开始显现出来。而且也是在这个时候,他开始作为游戏的主人公,并开始独当一面了。到了1985年,把马里奥捧成明星的决定之作《超级马里奥兄弟》登场。保留了用头顶、用脚踩等基本动作系统的同时,更是加入了身体变大、发射火炮等多彩的系统。因此,马里奥也就成了真正的动作英雄。特别是吃到蘑菇后,身体变大的系统,给人强烈的震撼。一时间本作成为广大玩家的宠儿,马里奥也终于坐上了明星的宝座。从此马里奥的动作英雄传说,便一发而不可收。续篇2代、3代,也是一经推出,便马上热销。之后,更是进入了马里奥的颠峰时代。不只是动作游戏,作为医生的《马里奥医生》和高尔夫球手《马里奥高尔夫》,已经完全确立了马里奥在当时整个日本游戏界的地位。随着《超级马里奥USA》等国际版本的推出,马里奥的人气在全世界开始爆发。1990年在美国进行的调查显示,美国人对马里奥的认知度甚至超过了美国本土的明星米老鼠。一个游戏角色能达到如此出名的地步,就连宫本茂也没有想到。

我们今天就来看看我们自己能不能写出这样一个游戏呢?

来,话不多说,直接开始,gogogo

代码有点多,有一千多行吧,请耐心观看,好好看好好学!!!

首先就是我们的各种结构体(子弹、硬币等等)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
struct ROLE
{
    int id;
    int x;//横坐标
    int y;//纵坐标
    int w;//图片宽度
    int h;//图片高度
    int xleft;//水平运动的左界限
    int xright;//水平运动的右界限
    int turn;//精灵的运动方向
    int jump;//精灵是否跳跃
    int iframe;//加载第几副精灵图,这样就能让精灵看上去动起来了
};
struct MAP        //储存地图的结构体
{
    int id;
    int x;
    int y;
};
struct BULLET      //子弹的结构体
{
    int x;
    int y;
    int turn;
    int iframe;
    int id;
};
struct COINT      //硬币的结构体
{
    int x;
    int y;
    double iframe;
};
struct ENEMY      //敌人的结构体
{
    int id;
    int x;
    int y;
    int turn;
    int iframe;
};

为了方便大家,我就把函数全写在一个类里面啦

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
class game        //整个游戏只设置了这一个类
{
private:
    ROLE role;
    MAP map[350];
    BULLET bullet[20];
    COINT coint[50];
    ENEMY enemy[20];
    IMAGE img_mapsky,img_p,img_map,img_ani,img_mapbk,img_home;
    int xmapsky;           //背景天空的起始横坐标
    int xmap;              //地图的起始坐标
    double v0;             //精灵跳跃的初速度            
    double h;              //精灵跳跃的高度
    double t;              //精灵跳跃的时间
    int ibullet;           //第几颗子弹
    int xbullet;           //子弹的x坐标
    int ybullet;           //子弹的y坐标
    int get_bullet;        //是否获得武器,0表示没有获得,1表示已获得
    POINT icoint;          //储存硬币的坐标
    POINT bomb[20];        //储存哪些地方爆炸了的坐标
    POINT temp;            //临时坐标。储存哪些地方爆炸了的坐标
    double score_frame;    //下面3个double型的变量用于控制各自图片的帧,以实现动画的效果。如画面中的流水
    double bomb_frame;
    double mapbk_frame;
    int win;               //玩家是否过关
    int pause;             //玩家是否按Esc(暂停键)
public:
    game();
    ~game();
    void start();          //处理游戏开始的界面,和按暂停键后的界面
    void init();           //初始化各项变量
    void move();           //控制主角移动
    void show();           //显示画面
    int isdie();           //判断主角是否已死
    int  GetCommand();     // 获取控制命令。参阅easyx
    void left();           //主角向左运动
    void right();          //主角向右运动
    void up();             //主角跳跃
    void init_shoot();     //初始化发射子弹
    void fall();           //主角自由落体或者向上跳跃
    int is_l_touch(int id);//主角的左边是否碰到墙或敌人,以及敌人是否碰到陆地的左边界
    int is_r_touch(int id);//主角的右边是否碰到墙或敌人,以及敌人是否碰到陆地的右边界
    int is_t_touch();      //主角的头是否碰到墙
    int is_b_touch(int id);//主角是否踩到敌人。
    int is_touch();        //主角是否吃到金币
    int is_land(ENEMY e);  //敌人是否站在陆地上
    void getbullet();      //获取子弹
    void shoot();          //发射子弹
    int eat(BULLET b);     //子弹是否打到敌人或者墙壁
    void end();            //处理游戏结束
};

接下来就是我们的常见的函数了——游戏初始化函数

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
void game::init()
{
    if(pause==1)
        return;
    role.id=1;
    role.x=X;
    role.y=Y;
    role.w=W;
    role.h=H;
    role.xleft=0;
    role.xright=role.w*6+STEP;
    role.iframe=1;
    role.turn=1;
    role.jump=0;
 
    xmapsky=0;
    xmap=0;
    v0=0;
    h=0;
    t=0;
    ibullet=-1;
    icoint.x=-1;
    icoint.y=-1;
    score_frame=0;
    bomb_frame=1;
    mapbk_frame=1;
    temp.x=-1;
    temp.y=-1;
    xbullet=41*role.w-10;
    ybullet=4*role.h-25;
    get_bullet=0;
    win=0;
    pause=0;
    score=0;
    int i;
    for(i=0;i<350;i++)
    {
        map[i].id=0;
        map[i].x=-1;
        map[i].y=-1;
        if(i<50)
        {
            coint[i].x=-1;
            coint[i].y=-1;
            coint[i].iframe=1;
        }
        if(i<20)
        {
            bullet[i].id=0;
            bullet[i].x=-1;
            bullet[i].y=-1;
            bullet[i].iframe=1;
            bullet[i].turn=-1; 
 
            enemy[i].id=0;
            enemy[i].x=-1;
            enemy[i].y=-1;
            enemy[i].turn=1;
            enemy[i].iframe=1;
 
            bomb[i].x=-1;
            bomb[i].y=-1;
        }
    }
    loadimage(&img_mapsky,"res\\mapsky.bmp",XSIZE,YSIZE*4);
    loadimage(&img_p,"res\\role.bmp");
    loadimage(&img_map,"res\\map.bmp");
    loadimage(&img_ani,"res\\ani.bmp");
    loadimage(&img_mapbk,"res\\mapbk.bmp");
    loadimage(&img_home,"res\\home.bmp",XSIZE,YSIZE*5);
 
    mciSendString("open 背景音乐.mp3 alias mymusic1", NULL, 0, NULL);
    mciSendString("open 子弹.mp3 alias mymusic2", NULL, 0, NULL);
    mciSendString("open 金币.mp3 alias mymusic3", NULL, 0, NULL);
    mciSendString("open 跳.mp3 alias mymusic4", NULL, 0, NULL);
    mciSendString("open 子弹打到敌人.mp3 alias mymusic5", NULL, 0, NULL);
    mciSendString("open 子弹撞墙.mp3 alias mymusic6", NULL, 0, NULL);
    mciSendString("open 踩敌人.mp3 alias mymusic7", NULL, 0, NULL);
    mciSendString("open 吃到武器.mp3 alias mymusic8", NULL, 0, NULL);  
    mciSendString("open 胜利.mp3 alias mymusic9", NULL, 0, NULL);
    mciSendString("open 死亡1.mp3 alias mymusic10", NULL, 0, NULL);
    mciSendString("open 死亡2.mp3 alias mymusic11", NULL, 0, NULL);
                                           
    for(i=0;i<300;i++)                 //以下都是编辑地图
    {
        map[i].id=1;
        map[i].x=i%100*role.w;
        if(i<100)
            map[i].y=9*role.h;
        else if(i>=100&&i<200)
            map[i].y=10*role.h;
        else
            map[i].y=11*role.h;
    }
    map[15].id=1,map[15].x=18*role.w,map[15].y=8*role.h;
    map[115].id=1,map[115].x=19*role.w,map[115].y=8*role.h;
    map[215].id=1,map[215].x=20*role.w,map[215].y=8*role.h;
 
    map[16].id=1,map[16].x=21*role.w,map[16].y=8*role.h;
    map[116].id=1,map[116].x=22*role.w,map[116].y=8*role.h;
    map[216].id=1,map[216].x=23*role.w,map[216].y=8*role.h;
 
    map[17].id=1,map[17].x=24*role.w,map[17].y=8*role.h;
    map[117].id=1,map[117].x=25*role.w,map[117].y=8*role.h;
    map[217].id=1,map[217].x=26*role.w,map[217].y=8*role.h;
 
    map[300].id=2,map[300].x=10*role.w,map[300].y=6*role.h;
    map[301].id=2,map[301].x=11*role.w,map[301].y=6*role.h;
    map[302].id=2,map[302].x=12*role.w,map[302].y=6*role.h;
 
    map[303].id=3,map[303].x=36*role.w,map[303].y=7*role.h;
    map[304].id=3,map[304].x=44*role.w,map[304].y=7*role.h;
 
    map[305].id=2,map[305].x=40*role.w,map[305].y=4*role.h;
    map[306].id=2,map[306].x=41*role.w,map[306].y=4*role.h;
    map[307].id=2,map[307].x=42*role.w,map[307].y=4*role.h;
 
    map[308].id=2,map[308].x=13*role.w,map[308].y=6*role.h;
 
    map[309].id=4,map[309].x=15*role.w,map[309].y=10*role.h;
 
    map[310].id=5,map[310].x=19*role.w,map[310].y=6*role.h;
    map[311].id=5,map[311].x=23*role.w,map[311].y=6*role.h;
    map[312].id=5,map[312].x=32*role.w,map[312].y=7*role.h;
    map[313].id=5,map[313].x=48*role.w,map[313].y=7*role.h;
    map[314].id=5,map[314].x=52*role.w,map[314].y=7*role.h;
    map[315].id=5,map[315].x=56*role.w,map[315].y=7*role.h;
 
    map[316].id=3,map[316].x=80*role.w,map[316].y=7*role.h;
    map[317].id=3,map[317].x=90*role.w,map[317].y=7*role.h;
 
    map[318].id=2,map[318].x=62*role.w,map[318].y=6*role.h;
 
    map[319].id=2,map[319].x=65*role.w,map[319].y=3*role.h;
    map[320].id=2,map[320].x=66*role.w,map[320].y=3*role.h;
    map[321].id=2,map[321].x=67*role.w,map[321].y=3*role.h;
    map[322].id=2,map[322].x=68*role.w,map[322].y=3*role.h;
    map[323].id=2,map[323].x=69*role.w,map[323].y=3*role.h;
 
    map[349].id=6,map[349].x=97*role.w,map[349].y=7*role.h;
 
    for(i=64;i<300;i+=100)
    {
        map[i].id=0;map[i].x=-1;map[i].y=-1;
        map[i+1].id=0;map[i+1].x=-1;map[i+1].y=-1;
        map[i+2].id=0;map[i+2].x=-1;map[i+2].y=-1;
 
        map[i+7].id=0;map[i].x=-1;map[i].y=-1;
        map[i+8].id=0;map[i+1].x=-1;map[i+1].y=-1;
        map[i+9].id=0;map[i+1].x=-1;map[i+1].y=-1;
 
        map[i+11].id=0;map[i].x=-1;map[i].y=-1;
        map[i+12].id=0;map[i+1].x=-1;map[i+1].y=-1;
        map[i+13].id=0;map[i+1].x=-1;map[i+1].y=-1;
    }
    map[64].id=4,map[64].x=64*role.w,map[64].y=10*role.h;
    map[71].id=4,map[71].x=71*role.w,map[71].y=10*role.h;
    map[75].id=4,map[75].x=75*role.w,map[75].y=10*role.h;
 
    enemy[0].id=1;enemy[0].x=6*role.w;enemy[0].y=8*role.h;enemy[0].turn=1;enemy[0].iframe=1;
    enemy[1].id=1;enemy[1].x=8*role.w;enemy[1].y=8*role.h;enemy[1].turn=1;enemy[1].iframe=1;
    enemy[2].id=1;enemy[2].x=27*role.w;enemy[2].y=8*role.h;enemy[2].turn=1;enemy[2].iframe=1;
    enemy[3].id=1;enemy[3].x=29*role.w;enemy[3].y=8*role.h;enemy[3].turn=1;enemy[3].iframe=1;
    enemy[4].id=1;enemy[4].x=31*role.w;enemy[4].y=8*role.h;enemy[4].turn=1;enemy[4].iframe=1;
    enemy[5].id=1;enemy[5].x=33*role.w;enemy[5].y=8*role.h;enemy[5].turn=1;enemy[5].iframe=1;
    enemy[6].id=1;enemy[6].x=35*role.w;enemy[6].y=8*role.h;enemy[6].turn=1;enemy[6].iframe=1;
    enemy[7].id=1;enemy[7].x=40*role.w;enemy[7].y=8*role.h;enemy[7].turn=1;enemy[7].iframe=1;
    enemy[8].id=1;enemy[8].x=82*role.w;enemy[8].y=8*role.h;enemy[8].turn=1;enemy[8].iframe=1;
    enemy[9].id=1;enemy[9].x=65*role.w;enemy[9].y=2*role.h;enemy[9].turn=1;enemy[9].iframe=1;
    enemy[10].id=1;enemy[10].x=69*role.w;enemy[10].y=2*role.h;enemy[10].turn=1;enemy[10].iframe=1;
    enemy[11].id=1;enemy[11].x=85*role.w;enemy[11].y=8*role.h;enemy[11].turn=1;enemy[11].iframe=1;
 
    for(i=0;i<4;i++)
    {
        coint[i].x=(10+i)*role.w;
        coint[i].y=5*role.h;
 
        coint[i+4].x=(67+i)*role.w;
        coint[i+4].y=8*role.w;
 
        coint[i+8].x=74*role.w;
        coint[i+8].y=(4+i)*role.w;
    }
    for(i=12;i<18;i++)
    {
        coint[i].x=(83-12+i)*role.w;
        coint[i].y=6*role.h;
 
        coint[i+6].x=(83-12+i)*role.w;
        coint[i+6].y=7*role.w;
    }
}

子弹的移动函数(别放弃,加油)

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
void game::move()
{  
    MyTimer tt;
    int c;
    int k=0;                              //控制发射子弹的频率和敌人的移动速度
    int n=0;                              //控制发射子弹的频率
    while(true)
    {
        tt.Sleep(25);
        t=sqrt(2*HIGH/G)/14;       
        k++;
        if(k==1000)
            k=0;
        if(kbhit()&&win==0)
        {
            c=GetCommand();
            if(c&CMD_LEFT)
                left();
            if(c&CMD_RIGHT)
                right();
            if((c&CMD_UP)&&role.jump==0)
                up();
            if(c&CMD_ESC)
            {
                pause=1;
                break;
            }
            if(c&CMD_SHOOT&&get_bullet==1)
            {
                if(n==0)
                {
                    init_shoot();
                    n=1;
                }
                n++;
                if(k%10==0&&n>10)
                {
                    init_shoot();
                }
            }
            else
                n=0;
        }
        if(-xmap+role.x==97*role.w)
        {
            mciSendString("stop mymusic1", NULL, 0, NULL);
            mciSendString("play mymusic9", NULL, 0, NULL);
        }
        if(-xmap+role.x>95*role.w)
        {
            
            win=1;
            role.x+=STEP;
            if(role.x-STEP>XSIZE)
                break;
        }
        if(is_b_touch(1)==0)
            role.jump=1;
        if(role.jump==1)
            fall();
        if(isdie()==1)
        {
            mciSendString("stop mymusic1", NULL, 0, NULL);
            mciSendString("play mymusic11", NULL, 0, NULL);
            life--;
            return;
        }
        if(k%2==0)               //敌人的运动
        {
            for(int i=0;i<20;i++)
            {
                if(enemy[i].id==1)
                {
                    if(is_land(enemy[i])==1)
                    {
                        if(enemy[i].turn==1)
                            enemy[i].x+=STEP;
                        else
                            enemy[i].x-=STEP;
                    }
                    if(is_land(enemy[i])==0||is_l_touch(3)==1||is_r_touch(3)==1)
                    {
                        if(enemy[i].turn==1)
                            enemy[i].x-=STEP;
                        else
                            enemy[i].x+=STEP;
                        enemy[i].turn*=-1;
                    }
                    enemy[i].iframe*=-1;
                }
            }
        }
        int boom=0;
        if(is_b_touch(2)==1)                     //如果主角“踩到”敌人
            boom=1;
        getbullet();                             //获取子弹
        if(get_bullet==1)
            shoot();
 
        BeginBatchDraw();
        show();
        FlushBatchDraw();
 
        if((is_l_touch(2)==1||is_r_touch(2)==1))
        {
            mciSendString("stop mymusic1", NULL, 0, NULL);
            mciSendString("play mymusic10", NULL, 0, NULL);
            life--;
            pause=0;
            putimage(role.x,role.y,role.w,role.h,&img_p,2*role.w,role.h,SRCAND);
            putimage(role.x,role.y,role.w,role.h,&img_p,2*role.w,0,SRCPAINT);
            return;
        }
    }
}

游戏的显示函数(人物、子弹、敌人、分数等等显示),bug改了一大推,累的半死,希望同学能吸取教训,别学我

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
void game::show()
{
    if(xmapsky==-XSIZE)
        xmapsky=0;
    putimage(xmapsky,0,&img_mapsky);     //显示背景
    putimage(XSIZE+xmapsky,0,&img_mapsky);
 
    if(is_touch()==1)
        score_frame=1;
    if(score_frame!=0)                  //碰到硬币,显示得分
    {      
        switch((int)score_frame)
        {
        case 1:
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,0,11*role.h,SRCAND);
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,0,10*role.h,SRCPAINT);
            break;
        case 2:
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,role.w,11*role.h,SRCAND);
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,role.w,10*role.h,SRCPAINT);
            break;
        case 3:
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,2*role.w,11*role.h,SRCAND);
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,2*role.w,10*role.h,SRCPAINT);
            break;
        case 4:
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,3*role.w,11*role.h,SRCAND);
            putimage(xmap+icoint.x,icoint.y,role.w,role.h,&img_ani,3*role.w,10*role.h,SRCPAINT);
            break;
        default:
            break;
        }  
        score_frame+=0.2;
        if(score_frame==5)
            score_frame=0;
    }
    int i;
    for(i=0;i<350;i++)             //显示地图,天空上的地图和硬币
    {
        if(map[i].id==1)
        {
            putimage(xmap+map[i].x,map[i].y,role.w,role.h,&img_map,0,0);
        }
        else if(map[i].id==2)
        {
            putimage(xmap+map[i].x,map[i].y,role.w,role.h,&img_map,0,role.h);
        }
        else if(map[i].id==3)
        {
            putimage(xmap+map[i].x,map[i].y,2*role.w,2*role.h,&img_map,0,9*role.h);
        }
        else
        {
            if(map[i].id==4)
            {
                switch((int)mapbk_frame)
                {
                case 1:
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,0,10*role.h,SRCAND);
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,0,8*role.h,SRCPAINT);
                    break;
                case 2:
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,3*role.w,10*role.h,SRCAND);
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,3*role.w,8*role.h,SRCPAINT);
                    break;
                default:
                    break;
                }  
            }
            else if(map[i].id==5)
            {
                switch((int)mapbk_frame)
                {
                case 1:
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,0,2*role.h,SRCAND);
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,0,0,SRCPAINT);
                    break;
                case 2:
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,3*role.w,2*role.h,SRCAND);
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,3*role.w,0,SRCPAINT);
                    break;
                default:
                    break;
                }  
            }
            else if(map[i].id==6)
            {
                switch((int)mapbk_frame)
                {
                case 1:
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,0,6*role.h,SRCAND);
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,0,4*role.h,SRCPAINT);
                    break;
                case 2:
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,3*role.w,6*role.h,SRCAND);
                    putimage(xmap+map[i].x,map[i].y,3*role.w,2*role.h,&img_mapbk,3*role.w,4*role.h,SRCPAINT);
                    break;
                default:
                    break;
                }  
            }
            mapbk_frame+=0.003;
            if(mapbk_frame>2.9)
            {
                mapbk_frame=1;
            }
        }
        if(i<50)
        {
            if(coint[i].x!=-1||coint[i].y!=-1)
            {
                switch((int)coint[i].iframe)
                {
                case 1:
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,0,9*role.h,SRCAND);
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,0,8*role.h,SRCPAINT);
                    break;
                case 2:
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,role.w,9*role.h,SRCAND);
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,role.w,8*role.h,SRCPAINT);
                    break;
                case 3:
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,2*role.w,9*role.h,SRCAND);
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,2*role.w,8*role.h,SRCPAINT);
                    break;
                case 4:
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,3*role.w,9*role.h,SRCAND);
                    putimage(xmap+coint[i].x,coint[i].y,role.w,role.h,&img_ani,3*role.w,8*role.h,SRCPAINT);
                    break;
                default:
                    break;
                }  
                coint[i].iframe+=0.125;
                if(coint[i].iframe==5)
                    coint[i].iframe=1;
            }
        }
    }
    if(get_bullet==0)
    {
 
        switch((int)mapbk_frame)
        {
            case 1:
                putimage(xmap+xbullet,ybullet,52,25,&img_ani,0,12*role.h+25,SRCAND);
                putimage(xmap+xbullet,ybullet,52,25,&img_ani,0,12*role.h,SRCPAINT);
                break;
            case 2:
                putimage(xmap+xbullet,ybullet,52,25,&img_ani,52,12*role.h+25,SRCAND);
                putimage(xmap+xbullet,ybullet,52,25,&img_ani,52,12*role.h,SRCPAINT);
                break;
            default:
                break;
        }  
 
    }
    for(i=0;i<20;i++)             //显示子弹
    {
        if(get_bullet==1)
        {
            if(bullet[i].id==1)
            {
                if(bullet[i].iframe==1)
                {
                    putimage(bullet[i].x,bullet[i].y,role.w,role.h,&img_ani,0,3*role.h,SRCAND);
                    putimage(bullet[i].x,bullet[i].y,role.w,role.h,&img_ani,0,2*role.h,SRCPAINT);
                }
                else
                {
                    putimage(bullet[i].x,bullet[i].y,role.w,role.h,&img_ani,role.w,3*role.h,SRCAND);
                    putimage(bullet[i].x,bullet[i].y,role.w,role.h,&img_ani,role.w,2*role.h,SRCPAINT);
                }  
            }
        }
        if(enemy[i].id==1)
        {
            if(enemy[i].iframe==1)                           //显示敌人
            {
                putimage(xmap+enemy[i].x,enemy[i].y,role.w,role.h,&img_ani,0,role.h,SRCAND);
                putimage(xmap+enemy[i].x,enemy[i].y,role.w,role.h,&img_ani,0,0,SRCPAINT);
            }
            else
            {
                putimage(xmap+enemy[i].x,enemy[i].y,role.w,role.h,&img_ani,role.w,role.h,SRCAND);
                putimage(xmap+enemy[i].x,enemy[i].y,role.w,role.h,&img_ani,role.w,0,SRCPAINT);
            }
            
        }
        if(bomb[i].x!=-1||bomb[i].y!=-1)
        {
            switch((int)bomb_frame)
            {
            case 1:
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,0,6*role.h,SRCAND);
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,0,4*role.h,SRCPAINT);
                break;
            case 2:
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,2*role.w,6*role.h,SRCAND);
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,2*role.w,4*role.h,SRCPAINT);
                break;
            case 3:
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,4*role.w,6*role.h,SRCAND);
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,4*role.w,4*role.h,SRCPAINT);
                break;
            case 4:
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,6*role.w,6*role.h,SRCAND);
                putimage(xmap+bomb[i].x-role.w/2,bomb[i].y-role.h/2,2*role.w,2*role.h,&img_ani,6*role.w,4*role.h,SRCPAINT);
                break;
            default:
                break;
            }  
            bomb_frame+=0.25;
            if(bomb_frame==5)
            {
                bomb[i].x=-1;
                bomb[i].y=-1;
                bomb_frame=1;
            }
        }
    }
    int n=score;
    char s1[20]="当前得分:";
    char s2[10];
    itoa(n,s2,10);
    RECT r1={10,10,110,40};
    RECT r2={110,10,150,40};
    setfont(20, 0,"宋体");
    drawtext(s1, &r1, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    drawtext(s2, &r2, DT_CENTER | DT_VCENTER | DT_SINGLELINE);
    if(role.iframe==1)                           //显示主角
    {
        if(role.turn==1)
        {
            putimage(role.x,role.y,role.w,role.h,&img_p,0,role.h,SRCAND);
            putimage(role.x,role.y,role.w,role.h,&img_p,0,0,SRCPAINT);
        }
        else
        {
            putimage(role.x,role.y,role.w,role.h,&img_p,4*role.w,role.h,SRCAND);
            putimage(role.x,role.y,role.w,role.h,&img_p,4*role.w,0,SRCPAINT);
        }
    }
    else
    {
        if(role.turn==1)
        {
            putimage(role.x,role.y,role.w,role.h,&img_p,role.w,role.h,SRCAND);
            putimage(role.x,role.y,role.w,role.h,&img_p,role.w,0,SRCPAINT);
        }
        else
        {
            putimage(role.x,role.y,role.w,role.h,&img_p,3*role.w,role.h,SRCAND);
            putimage(role.x,role.y,role.w,role.h,&img_p,3*role.w,0,SRCPAINT);
        }
    }
}

马里奥的碰撞检测,这里当时写的时候,想了半天的逻辑

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
int game::is_l_touch(int id)
{
    int x,y;
    int i;
    if(id==1)                                    //id==1表示主角是否碰到id为1的地图,及游戏中黄色的地图
    {
        x=-xmap+role.x;
        y=role.y;
        for(i=0;i<350;i++)
        {
            if(map[i].id!=0&&map[i].id<4)
            {
                POINT m[2];
 
                m[0].x=map[i].x;
                m[0].y=map[i].y;
 
                m[1].x=map[i].x+role.w;
                m[1].y=map[i].y;
 
                if(map[i].id==3)
                {
                    if(((y-m[1].y)/role.h==0||(y-m[1].y-role.h)/role.h==0)&&x>m[1].x&&x<m[1].x+role.w)
                        return 1;
                }
                else
                {
                    if((y-m[1].y)/role.h==0&&x>m[0].x&&x<m[1].x)
                        return 1;
                }
            }
        }
        return 0;
    }
    else if(id==2)                                 //id==2表示主角是否碰到敌人的左边
    {
        x=-xmap+role.x;
        y=role.y;
        for(i=0;i<20;i++)
        {
            if(enemy[i].id!=0)
            {
                POINT m[2]; 
 
                m[0].x=enemy[i].x;
                m[0].y=enemy[i].y;
 
                m[1].x=enemy[i].x+role.w;
                m[1].y=enemy[i].y;
 
                if((y-m[1].y)/role.h==0&&x>m[0].x&&x<m[1].x)         
                    return 1;
            }
        }
        return 0;
    }
    else                                        //id==3表示敌人是否碰到地图的左边
    {
        int j;
        for(j=0;j<20;j++)
        {
            if(enemy[j].id!=0)
            {
                x=enemy[j].x;
                y=enemy[j].y;
            
                for(i=0;i<350;i++)
                {
                    if(map[i].id!=0&&map[i].id<4)
                    {
                        POINT m[2];
     
                        m[0].x=map[i].x;
                        m[0].y=map[i].y;
 
                        m[1].x=map[i].x+role.w;
                        m[1].y=map[i].y;
 
                        if(map[i].id==3)
                        {
                            if(((y-m[1].y)/role.h==0||(y-m[1].y-role.h)/role.h==0)&&x>m[1].x&&x<m[1].x+role.w)
                                return 1;
                        }  
                        else
                        {
                            if((y-m[1].y)/role.h==0&&x>m[0].x&&x<m[1].x)
                                return 1;
                        }  
                    }
                }
            }
        }
        return 0;
    }
}
int game::is_r_touch(int id)
{
    int x,y;
    int i;
    if(id==1)
    {   
        x=-xmap+role.x+role.w;
        y=role.y;
 
        for(i=0;i<350;i++)
        {
            if(map[i].id!=0&&map[i].id<4)
            {
                POINT m[2];
 
                m[0].x=map[i].x;
                m[0].y=map[i].y;
 
                m[1].x=map[i].x+role.w;
                m[1].y=map[i].y;
 
                if(map[i].id==3)
                {
                    if(((y-m[0].y)/role.h==0||(y-m[0].y-role.h)/role.h==0)&&x>m[0].x&&x<m[1].x)
                        return 1;
                }
                else
                {
                    if((y-m[0].y)/role.h==0&&x>m[0].x&&x<m[1].x)
                        return 1;
                }
            }
        }
        return 0;
    }
    else if(id==2)
    {
        x=-xmap+role.x+role.w;
        y=role.y;
 
        for(i=0;i<20;i++)
        {
            if(enemy[i].id!=0)
            {
                POINT m[2];
 
                m[0].x=enemy[i].x;
                m[0].y=enemy[i].y;
 
                m[1].x=enemy[i].x+role.w;
                m[1].y=enemy[i].y;
 
                if((y-m[0].y)/role.h==0&&x>m[0].x&&x<m[1].x)
                    return 1;
            }
        }
        return 0;
    }
    else
    {
        int j;
        for(j=0;j<20;j++)
        {
            if(enemy[j].id!=0)
            {
                x=enemy[j].x+role.w;
                y=enemy[j].y;
            
                for(i=0;i<350;i++)
                {
                    if(map[i].id!=0&&map[i].id<4)
                    {
                        POINT m[2];
 
                        m[0].x=map[i].x;
                        m[0].y=map[i].y;
 
                        m[1].x=map[i].x+role.w;
                        m[1].y=map[i].y;
 
                        if(map[i].id==3)
                        {
                            if(((y-m[0].y)/role.h==0||(y-m[0].y-role.h)/role.h==0)&&x>m[0].x&&x<m[1].x)
                                return 1;
                        }
                        else
                        {
                            if((y-m[0].y)/role.h==0&&x>m[0].x&&x<m[1].x)
                                return 1;
                        }
                    }
                }
            }
        }
        return 0;
    }
}
int game::is_t_touch()
{
    int x,y;
    x=-xmap+role.x;
    y=role.y;
 
    for(int i=0;i<350;i++)
    {
        if(map[i].id!=0&&map[i].id<4)
        {
            POINT m[2];
 
            m[0].x=map[i].x;
            m[0].y=map[i].y;
 
            m[1].x=map[i].x;
            m[1].y=map[i].y+role.h;
 
            if((x-m[1].x)/role.w==0&&y>m[0].y&&y<m[1].y)
                return 1;
        }
    }
    return 0;
}
int game::is_b_touch(int id)
{
    if(id==1)
    {
        int x,y;
        x=-xmap+role.x;
        y=role.y+role.h;
 
        for(int i=0;i<350;i++)
        {
            if(map[i].id!=0&&map[i].id<4)
            {
                POINT m[2]; 
 
                m[0].x=map[i].x;
                m[0].y=map[i].y;
 
                m[1].x=map[i].x;
                m[1].y=map[i].y+role.h;
 
                if(map[i].id==3)
                {
                    if(((x-m[0].x)/role.w==0||(x+role.w-m[0].x-2*role.w)/role.w==0)&&y>=m[0].y&&y<m[1].y)
                        return 1;
                }
                else
                {
                    if((x-m[0].x)/role.w==0&&y>=m[0].y&&y<m[1].y)
                        return 1;
                }
            }
        }
        return 0;
    }
    else if(id==2)
    {
        int x,y;
        x=-xmap+role.x;
        y=role.y+role.h;
 
        for(int i=0;i<20;i++)
        {
            if(enemy[i].id!=0)
            {
                POINT m[2];
 
                m[0].x=enemy[i].x;
                m[0].y=enemy[i].y;
 
                m[1].x=enemy[i].x;
                m[1].y=enemy[i].y+role.h;
 
                if((x-m[0].x)/role.w==0&&y>m[0].y&&y<m[1].y)
                {
                    mciSendString("play mymusic7 from 0", NULL, 0, NULL);
                    score+=10;
                    bomb[i].x=enemy[i].x;
                    bomb[i].y=enemy[i].y;
                    enemy[i].id=0;
                    enemy[i].iframe=-1;
                    enemy[i].turn=1;
                    enemy[i].x=-1;
                    enemy[i].y=-1;
                    return 1;
                }
            }
        }
        return 0;
    }
    return 0;
}
int game::is_touch()
{
    int i,j;
    POINT r[2];
    r[0].x=-xmap+role.x;
    r[0].y=role.y;
    r[1].x=-xmap+role.x+role.w;
    r[1].y=role.y+role.h;
    for(i=0;i<50;i++)
    {
        if(coint[i].x!=-1||coint[i].y!=-1)
        {
            POINT c[4];
 
            c[0].x=coint[i].x;
            c[0].y=coint[i].y;
 
            c[1].x=coint[i].x+role.w;
            c[1].y=coint[i].y;
 
            c[2].x=coint[i].x;
            c[2].y=coint[i].y+role.h;
 
            c[3].x=coint[i].x+role.w;
            c[3].y=coint[i].y+role.h;
 
            for(j=0;j<4;j++)
            {
                if(c[j].x>=r[0].x&&c[j].y>=r[0].y&&c[j].x<=r[1].x&&c[j].y<=r[1].y)
                {
                    mciSendString("play mymusic3 from 0", NULL, 0, NULL);
                    score+=20;
                    icoint.x=coint[i].x;
                    icoint.y=coint[i].y;
 
                    coint[i].x=-1;
                    coint[i].y=-1;
                    coint[i].iframe=1;
 
                    return 1;
                }
            }
        }
    }
    return 0;
}
int game::is_land(ENEMY e)
{
    POINT r[2];
    r[0].x=e.x;
    r[0].y=e.y+role.h;
 
    r[1].x=e.x+role.h;
    r[1].y=e.y+role.h;
 
    for(int i=0;i<350;i++)
    {
        if(map[i].id!=0&&map[i].id<4)
        {
            POINT m[3];
 
            m[0].x=map[i].x;
            m[0].y=map[i].y;
            
            m[1].x=map[i].x+role.w;
            m[1].y=map[i].y;
 
            m[2].x=map[i].x;
            m[2].y=map[i].y+role.h;
 
            if(e.turn==1)
            {
                if((r[1].x-m[0].x)/role.w==0&&r[1].y>=m[0].y&&r[1].y<m[2].y)
                    return 1;
            }
            else
            {
                if((r[0].x-m[1].x)/role.w==0&&r[0].y>=m[0].y&&r[0].y<m[2].y)
                    return 1;
            }
        }
    }
    return 0;
}

最后的游戏结束函数,写到这里的时候感受到了巨大的成就感

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
void game::end()
{
    MyTimer tt;
    EndBatchDraw();
    if(isdie()==1||win==1)
        pause=0;
    if(pause==1)
        return;
    if(win==1)
        tt.Sleep(5000);
    else
        tt.Sleep(2700);
    mciSendString("close all", NULL, 0, NULL); 
    tt.Sleep(1000);
    
    if(win==1)
    {
        pause=0;
        score=0;
        life=0;
        mciSendString("open 通关.mp3 alias mymusic13", NULL, 0, NULL);
        mciSendString("play mymusic13", NULL, 0, NULL);
        putimage(0,-3*YSIZE,&img_home);
        tt.Sleep(7000);
        mciSendString("close mymusic13", NULL, 0, NULL);
    }
    else
    {
        score=0;
        if(life==0)
        {
            mciSendString("open 游戏结束.mp3 alias mymusic12", NULL, 0, NULL);
            mciSendString("play mymusic12", NULL, 0, NULL);
            putimage(0,-YSIZE,&img_home);
            tt.Sleep(5500);
            mciSendString("close mymusic12", NULL, 0, NULL);
        }
        else
        {
            cleardevice();
            outtextxy(XSIZE/2-43,YSIZE/3,"生命还剩下:");
            if(life==1)
                outtextxy(XSIZE/2,YSIZE/2-20,"1");
            else if(life==2)
                outtextxy(XSIZE/2,YSIZE/2-20,"2");
            tt.Sleep(2000);
        }
    }
    cleardevice();
}

最后用主函数进行调用

?
1
2
3
4
5
6
7
8
9
10
11
12
13
void main()
{
    game g;
    while(true)
    {
        g.start();
        g.init();
        mciSendString("play mymusic1 repeat", NULL, 0, NULL);
        g.show();
        g.move();
        g.end();
    }
}

用时一个星期,终于把这个难啃的骨头咽下去了,写的时候时不时也会想起自己的童年,那真是一段不能忘记的时光,希望可以让大家从中感受到编程的快乐,也希望大家可以给UP主一个关注,非常感谢大家了!!!

C语言 90后怀旧游戏超级玛丽的实现流程

C语言 90后怀旧游戏超级玛丽的实现流程

到此这篇关于C语言 90后怀旧游戏超级玛丽的实现流程 的文章就介绍到这了,更多相关C语言 超级玛丽内容请搜索服务器之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持服务器之家!

原文链接:https://blog.csdn.net/weixin_45713725/article/details/121120129

延伸 · 阅读

精彩推荐