为系统开发星球大战游戏程序
分类:www.1145.com

近来,大家的系统已经发展到了自然较为完善的水准,当然最佳三个练习系统,它不容许跟正式的windows或linux比较,但麻雀虽小五腑俱全,大家的连串也许能帮衬客商在其下面开垦出好多复杂但又有趣的应用程序的,它所显现的成效完全能够称得上是多少个鲁棒的操作系统。

小编们看看第一个有趣的应用程序:不法则窗口。
多多独居特色的应用程序,一大特征之一正是畸形窗口,奇形怪状的窗体形态确实轻松给人万象更新的痛感,不法规窗口重即便把窗体的某某个用透明色来表现,未来大家就来品尝一下,在app.c中形成以下代码:

void main() {
    int win;
    char buf[150*70];
    win = api_openwin(buf, 150, 70, 255, "noterec");
    api_boxfilwin(win, 0, 50, 34, 69, 255);
    api_boxfilwin(win, 115, 50, 149, 69, 255);
    api_boxfilwin(win, 50, 30, 99, 49, 255);
    for (;;) {
        if (api_getkey(1) == 0x1c) {
            break;
        }
    }
    api_closewin(win);
    return;
}

地点代码先创建三个窗体,然后把窗体的好八个部分填充成透明色,于是窗体形态产生三个有趣的非矩形,下边代码完毕后,运转起来景况如下:

www.1145.com 1

那边写图片描述

接下去大家再看看二个越来越有趣的客户程序,线团火球!在app.c中增多代码如下:

struct POINT {
    int x;
    int y;
};

void main() {
    int win;
    char buf[216*237];
    struct POINT table[18] = {
    {204,129},{195,90},{172,58},{137,38},{98,34},
    {61,46},{31,73},{15,110},{15,148},{31,185},
    {61,212},{98,224},{137,220},{172,200},{195,168},
    {204,129}
    };

    win = api_openwin(buf, 216, 237, -1, "bball");
    api_boxfilwin(win, 8, 29, 207, 228, 255);
    int i = 0, j = 0, dis = 0;
    for (i = 0; i <= 14; i++) {
      for(j = i+1; j <= 15; j++) {
          dis = j - i;
          if (dis >= 8) {
             dis = 15 - dis;
          }
          if (dis != 0) {
             api_linewin(win, table[i].x, table[i].y,
                         table[j].x, table[j].y, 8-dis);
          }
      }
    }

    api_refreshwin(win, 8, 29, 207, 228);
    for (;;) {
        if (api_getkey(1) == 0x1c) {
            break;
        }
    }
    api_closewin(win);

    return;    
}

地点代码运维后效果如下:

www.1145.com 2

此处写图片描述

绘制出来的图画是还是不是极度惊艳,特别灿烂,我们的种类平台依然蛮给力的。

接下去我们要放大招,开采贰个有意思的星球战争游戏。星球战役是一款像素级游戏,它的形制让小编想起早年,大致是98年,所谓Computer刚传入中华,系统也许DOS时,那时候上Computer课最欢快的实在有娱乐可玩。代码相比长,我们分段达成,首先在app.c中输入以下代码:

#define win_width 240

void putstr(int win, char *winbuf,char * charset,
 int x, int y, int col, unsigned char *s) {
    int c, x0, i = 0, j;
    char *p, *q, t[2];
    x = x*8+8;
    y = y*16+29;
    x0 = x;
    while (s[i] != 0) {
        i++;
    }

    api_boxfilwin(win, 8, y, win_width - 8 , y+15, 0);

    q = winbuf + y * win_width; 
    t[1] = 0;
    for (;;) {
        c = *s;
        if (c == 0) {
            break;
        }

        if (c != ' ') {
            if ('a' <= c && c <= 'h') {
                p = charset + 16 * (c-'a');
                q += x;
                for (i = 0; i < 16; i++) {

                    if ((p[i] & 0x80) != 0) {q[0] = col;}
                    if ((p[i] & 0x40) != 0) {q[1] = col;}
                    if ((p[i] & 0x20) != 0) {q[2] = col;}
                    if ((p[i] & 0x10) != 0) {q[3] = col;}
                    if ((p[i] & 0x08) != 0) {q[4] = col;}
                    if ((p[i] & 0x04) != 0) {q[5] = col;}
                    if ((p[i] & 0x02) != 0) {q[6] = col;}
                    if ((p[i] & 0x01) != 0) {q[7] = col;}

                    q += win_width; 
                }
                q -= win_width * 16 + x;
            } else if((c>='i' && c <= 'z') || (c>='A' && c <= 'Z')){
                t[0] = *s;
                api_putstrwin(win, x, y, col,1,t);
            }
        }

        s++;
        x += 8;
    }

    api_refreshwin(win,  8, y, win_width - 8, y+15);
}



void main() {
    int win, i, j, ix, iy, fx;
    char winbuf[win_width * 237], invstr[32*6], s[12];
    char* p = winbuf;

    char invstr0[36] = {' ' , 'a','b','c','d',' ' ,'a','b','c','d', ' ',
                         'a','b','c','d',' ',  'a','b','c','d',' ',
                           'a','b','c','d', ' ',
                         0};

    char charset[18 * 8] = {
    0x00, 0x00, 0x00, 0x43, 0x5f, 0x5f, 0x5f, 0x7f,
    0x1f, 0x1f, 0x1f, 0x1f, 0x00, 0x20, 0x3f, 0x00,

    0x00, 0x0f, 0x7f, 0xff, 0xcf, 0xcf, 0xcf, 0xff,
    0xff, 0xe0, 0xff, 0xff, 0xc0, 0xc0, 0xc0, 0x00,

    0x00, 0xf0, 0xfe, 0xff, 0xf3, 0xf3, 0xf3, 0xff,
    0xff, 0x07, 0xff, 0xff, 0x03, 0x03, 0x03, 0x00,

    0x00, 0x00, 0x00, 0xc2, 0xfa, 0xfa, 0xfa, 0xfe,
    0xf8, 0xf8, 0xf8, 0xf8, 0x00, 0x04, 0xfc, 0x00,

    0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
    0x01, 0x43, 0x47, 0x4f, 0x5f, 0x7f, 0x7f, 0x00,

    0x18, 0x7e, 0xff, 0xc3, 0xc3, 0xc3, 0xc3, 0xff,
    0xff, 0xff, 0xe7, 0xe7, 0xe7, 0xe7, 0xff, 0x00,

    0x00, 0x00, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
    0x80, 0xc2, 0xe2, 0xf2, 0xfa, 0xfe, 0xfe, 0x00,

    0x00, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18,
    0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x00
    };

    win = api_openwin(winbuf, win_width, 237, -1, "invader");
    api_boxfilwin(win, 8, 29, win_width - 6, 228, 0);
    //putstr(win, winbuf, 22, 0, 7, "HIGH:00000000");

restart:
    fx = 18;
    char fly[8] = {'e', 'f', 'g', 0};
    putstr(win, winbuf, charset, 18, 11, 6, fly);

nextgroup:
    ix =  7;
    iy = 1;
    int invline = 6;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 20; j++) {
            invstr[i * 32 + j] = invstr0[j];
        }
        putstr(win, winbuf,charset, ix, iy + i, 2, invstr + i * 32);
    }


    api_refreshwin(win, 8, 29, 207, 228);

    for(;;) {
        if (api_getkey(1) == 0x1c) {
            break;
        }
    }

    api_closewin(win);

    return;
}

putstr函数有四个效果与利益,当输入字符在'a'到'h'之间时,它依照点阵表charset,通过设置某些像素点的颜色来绘制图像。此中参数x,y是图像起初坐标,最终二个参数s用来支配图像绘制的法子,举个例子当末了的s内容为"abcd"时,该函数从charset表中抽出前四行数据,当中每壹个数值都在报告代码在绘制哪一个像素点,它的绘图原理与早前我们疏解的怎么样绘制字符是平等的。大家先看看上面代码运维起来后的景观:

www.1145.com 3

这边写图片描述

代码绘制了三排外星人和一架大战机,在main函数中,代码:

restart:
    fx = 18;
    char fly[8] = {'e', 'f', 'g', 0};
    putstr(win, winbuf, charset, 18, 11, 6, fly);

制图的便是壁画底部的歼击机,而代码片段:

nextgroup:
    ix =  7;
    iy = 1;
    int invline = 6;
    for (i = 0; i < 3; i++) {
        for (j = 0; j < 20; j++) {
            invstr[i * 32 + j] = invstr0[j];
        }
        putstr(win, winbuf,charset, ix, iy + i, 2, invstr + i * 32);
    }

则是绘制了美术上方的三排外星人。

随之我们要想艺术让图像动起来,那就必要运用到大家前边做过的放大计时器。首先,大家先增加代码,让飞机依据大家按钮输入以便实现左右运动,由此大家增添日下代码:

void putstr(int win, char *winbuf,char * charset,
 int x, int y, int col, unsigned char *s) {
 ....
 }

 void waitting(int i, int timer, char* keyflag) {
    int j;
    if (i > 0) {
        api_settimer(timer, i);
        i = 128;
    } else {
        i = 0x1c;
    }

    for(;;) {
        j = api_getkey(1);
        if (i == j) {
            break;
        }

        if (j == 0x24) {
          //key j
            keyflag[0] = 1;
        }
        if (j == 0x25) {
            //key k
            keyflag[1] = 1;
        }
        if (j == 0x39) {
            //key space
            keyflag[2] = 1;
        }
    }

    return;
}

void main() {
    char keyflag[6];
    ....
    nextgroup:
    ....
    keyflag[0] = 0;
    keyflag[1] = 0;
    keyflag[2] = 0;

    for(;;) {
        waitting(4, timer, keyflag);
        if (keyflag[0] != 0 && fx > 1) {
           //fighter fly to left
           fx--;
           fly[0] = 'e', fly[1] = 'f', fly[2] = 'g', fly[3] = ' ';
           fly[4] = 0;
           putstr(win, winbuf, charset, fx, 11, 6, fly); 
           keyflag[0] = 0;
        }
        if (keyflag[1] != 0 && fx < 24) {
           fx++;
           fly[0] = ' ', fly[1] = 'e', fly[2] = 'f', fly[3] = 'g';
           fly[4] = 0;
           putstr(win, winbuf, charset, fx, 11, 6, fly);
           keyflag[1] = 0;
        }
    }
}

waitting 函数的意义是伺机沙漏放回结果,同期监察和控制键盘按钮,假如客商在键盘上点击开关'j',那么它经过调用api_getkey就能够收获对应扫描码,也正是0x24, 就算客商点击开关'k',那么相应的扫描码为0x25,在main函数里,大家加多一个for循环,在中间大家调用waitting函数获取顾客开关音信,当顾客按下'j'后,大家把飞机向左移动三个单位,然后刷新窗口,假如客户点击的是k,那么大家把飞机向右移动三个单位,然后刷新窗口,上边代码完毕后,编译加载到设想机,运维程序后,尝试按下按钮'j',大家能够开采飞机一直向左移动,知道达到窗口左边界停止,效果如下:

www.1145.com 4

此地写图片描述

飞机能活动后,大家供给外星人也飘飘起来,因而大家增加如下代码:

void main () {
....
    for(;;) {
        waitting(4, timer, keyflag);
        ....
                //move aliens
        if (movewait != 0) {
            movewait--;
        } else {
            movewait = movewait0;
            if (ix + idir > 12 || ix + idir < 1) {
                if (iy + invline == 13) {
                   //game over
                   break;
                }
                idir = -idir;
                putstr(win, winbuf, charset,ix + 1, iy, 0, "  ");
                iy++;
            } else {
                ix += idir;
            }
            for (i = 0; i < invline; i++) {
                putstr(win, winbuf,charset, ix, iy + i, 2, invstr + i * 32);
            }
        } 
    }   
}

地方代码先把外星人向右移动,直到边缘时,iy++,那就使得外星人向下活动,与此同期idir = -idir; 使得外星人最先反向运动,一贯到左臂边缘,这种活动一向在实行,直到外星人的y坐标做够大时,游戏停止。

www.1145.com 5

此处写图片描述

从地点我们得以见见,飞机挪到左臂时,外星人移动到左臂。接着大家要完成客商按下空格键时,飞机能发出炮弹,而且剖断一旦炮弹击中外星人后,外星人会被扑灭掉,这些效能的落到实处重要依据下边代码:

for(;;) {
       if (laserwait != 0) {
            laserwait--;
            keyflag[2] = 0;
        }
        ....
       //draw laser bullet
        if (ly > 0) {
            if (ly < 8) {
                if (ix < lx && lx < ix + 25 && iy <= ly && ly < iy + invline) {
                    putstr(win, winbuf, charset, ix, ly, 2, invstr + (ly - iy) * 32);
                }//if (ix < lx ...)
                else {
                    putstr(win, winbuf, charset, lx, ly, 0, "  ");
               }
            }//if(ly < 13)
            ly--;
            if (ly > 0) {
                char c[2] = {'h', 0};
                putstr(win, winbuf,charset, lx, ly, 3, c);
            } // if(ly > 0)

            if (ix < lx && lx < ix + 25 && iy <= ly && ly < iy + invline) {
               p = invstr + (ly - iy) * 32 + (lx - ix);
               if (*p != ' ' ) {
                   //hit
                   for(p--; *p != ' '; p--) {}
                   for (i = 1; i < 5; i++) {
                       p[i] = ' ';
                   }
                  putstr(win, winbuf, charset, ix, ly, 2, invstr+(ly-iy)*32);
                  for(; invline > 0; invline--) {
                      for(p = invstr + (invline-1)*32; *p != 0; p++) {
                          if (*p != ' ') {
                              goto alive;
                          }
                      }
                  } 
            gameover:
                  //hit all 
                  movewait0 -= movewait0 / 3;
                  char gameover[12] = {'G','A','M','E',' ','O','V','E','R'};
                  putstr(win, winbuf, charset, 15, 6, 1, gameover);
                  waitting(10, timer, keyflag);

                  goto nextgroup;
            alive:
                  ly = 0;
               }
            } //if(ix < lx...)

        }//if (ly > 0)
    }
}

www.1145.com,上边代码使得,当客商点击空格键时,程序就绸缪从飞机处发射出导弹。代码片段:

 if (ly > 0) {
                char c[2] = {'h', 0};
                putstr(win, winbuf,charset, lx, ly, 3, c);
            } // if(ly > 0)

它的效应是,若是顾客点击了空格,同偶然候外星人还尚未侵袭到飞机所在的势力范围,那么大家就绘制二个从底层向上发射的炮弹,接下去的点不清代码是,当炮弹发射后,判断炮弹是或不是击中外星人,要是打到了,被打中的外星人要从荧屏上海消防失掉,那某个逻辑完成的情况如下:

www.1145.com 6

此间写图片描述

从上海体育地方能够见到,法国红的竖线块便是飞机发射出的导弹,中间那排外星人被击毙了,所以在荧屏上从未有过出示出来。借使外星人下落到飞机所在中度,那么有娱乐截止,借使外星人全体被击毙,那么战机成功保卫地球,游戏也终结:

www.1145.com 7

此地写图片描述

游戏截止后,"GAME OVE奥迪Q5"会打字与印刷到分界面上,然后全数娱乐重来叁回。

本条星球战斗游戏是系统基本开拓到此,大家做过的杰出复杂的顾客程序,它调用了大致具有api,举个例子窗口绘制,字符串输出,时钟,键盘监听等等,那么些纷纭程序的中标运行,在必然水平上注脚,我们的连串基本具有一定水准的琐碎和鲁棒性,纵然它不行与专门的学业操作系统同日而语,但正是它再轻便,再繁缛,它也对得起贰个“操作系统”的称呼。

更详实的教授和代码调节和测验演示进程,请参谋录制
Linux kernel 哈克er, 从零营造本人的基石

越多本事消息,饱含操作系统,编译器,面试算法,机器学习,人工智能,请看管我的众生号:

www.1145.com 8

这里写图片描述

本文由金沙APP发布于www.1145.com,转载请注明出处:为系统开发星球大战游戏程序

上一篇:在巴黎和15个国家的同学一起学法语 下一篇:没有了
猜你喜欢
热门排行
精彩图文