搜索
有爱,有技术,有你^_^)y
╱人◕‿‿◕人╲订下契约(注册新用户)

合作站点账号登陆

QQ登录

只需一步,快速开始

快捷导航
楼主: dxxds
收起左侧

【教】给你的故事小游戏,C++兴趣入门(完结)

[复制链接]

该用户从未签到

9

主题

21

好友

6174

积分

序章

积分
6174
 楼主| 发表于 2013-3-17 10:29:20 | 显示全部楼层

给你的故事,C++的兴趣入门 10

本帖最后由 dxxds 于 2013-11-23 12:26 编辑

都已经学到类了,那咱们就可以做一些有意思的东西,和做一些很大的程序了,哦哈哈哈~~

所以在这里稍微的补充一点常识,就是关于内存分配的部分

一般我们在申请变量的时候,都要把变脸分配到一个内存空间里去

这个空间目前告诉你们其中的两个区(当然不止两个),分别是堆区和栈区

而我们目前的数据,全都分配到栈区了

这个区有一些好处:速度快,资源自动释放

然后这个区的缺点:空间很小,只有1M(具体看编译器设置了,但是都不会很大)

所以如果我们一直这么写程序的话,会出现数据申请失败的情况

接下来我说一下堆区,这里的数据是要自己申请和自己释放的,速度比栈区慢,但是空间很大,4G(32位机子)

像类这种数据量比较大的类型,我们一般会把它申请到堆中去

那现在就来给你们示范怎么申请堆数据

int main()
{
        int a = 10;               //栈空间
        int* b = new int(20);     //堆空间

        cout<<"a:"<<a<<endl;
        cout<<"b:"<<*b<<endl;

        delete b;                //b不会被系统自动回收,所以我们得自己写一下delete
        system("pause>nul");
        return 0;
}

这里用了一个新的关键字 new,new 会返回一个指针地址

表示在堆中申请一段空间,这个空间的大小是 int(四个字节)

然后把这个空间的首地址给了 指针 b

然后我们输出了 指针b里的数据

最后用delete关键字 删除b空间里的内容

OVER

听懂了吧,那么以此类推,这次我们把玛丽奥的数据申请到堆里

class Mario
{
public:
        string name;
        void init_name(const char* n)
        {
                name = n;
        }
        void show_name()
        {
                cout<<name<<endl;
        }
};


int main()
{
        Mario player_1;
        player_1.init_name("玛丽奥");
   
        Mario* player_2 = new Mario;
        (*player_2).init_name("路易基");
        
         cout<<"玩家1:";
        player_1.show_name();
        
         cout<<"玩家2:";
         (*player_2).show_name();
         
         system("pause>nul");
        return 0;
}


这样就可以看到,这两种申请内存的方式都成功了,玩家1是对象,玩家2是指针对象

这里出现了一个新的关键字 const
这里表示,它后面修饰的部分是一个常量,就是创建后就不能被修改了的意思

示范一下
const string gender_of_mario = "男"; //创建了一个常量:玛丽奥的性别(性别这玩意一般来说不能修改了……)

gender_of_mario = "女";  //会在这里妥妥的出错,不会编译通过

关于const就讲这么多,下面继续。

不过看调用玩家2的样子,总觉得有点别扭啊:不但要用*解引用,还要再在外面把它用括号括起来。写起来十分蛋疼

所以在这里,C语言给提供了一个不错新符号,用来代替这个

就是用 "->"

给你们示范一下

(*p).name;

p->name;

这俩等价,那我把上面的代码重写一次

int main()
{
        Mario player_1;
        player_1.init_name("玛丽奥");
   
        Mario* player_2 = new Mario;
        player_2->init_name("路易基");
        
         cout<<"玩家1:";
        player_1.show_name();
        
         cout<<"玩家2:";
         player_2->show_name();
         
         system("pause>nul");
        return 0;
}


好了,一样完成功能了,而且看起来舒服很多了

等到日后,名字很长的时候,就会越发觉得这个符号用着舒服的

内容有点少啊,我再写点儿

可以看到之前我用了 init_name 来给类成员初始化内容了对吧,并且前一课也用了

所以这里我教点新的东西给你们

就是C++里的构造函数,是一个和类同名的函数,没有返回类型

这个函数是每一个类里都有的函数,每一个都有,包括刚才的马里奥类

我写一下

class Mario
{
public:
        Mario(){}       //构造函数,编译器给的函数就是这样的,啥也不干
}


当我们的类里没有构造函数的时候,也就是之前的几次代码。

编译器就会默认为我们隐含添加一个构造函数,然后这个构造函数啥也不干

然后当我们创建了这个类的对象时,就会自动运行一下这个函数,一定会运行,不用我们调用

给你们示范一下

class Mario
{
public:
        Mario()                //构造函数
        {
                cout<<"玛丽奥出现了"<<endl;
        }
};


int main()
{
        Mario player_1;
         
         system("pause>nul");
        return 0;
}


看到了吧,我们只是创建了这个对象,函数就执行了。

所以我们可以很方便的用这个函数给我们的类成员做初始化工作。

现在我把之前的代码再用构造函数重写一次

看代码

class Mario
{
private:
        string name;
public:
        Mario(const char* n)                //构造函数
        {
                name = n;
        }
        void init_name(const char* n)
        {
                name = n;
        }
        string get_name()                        //换了种写法,就别复制前面的了
        {

                return name;
        }
};

int main()
{
        /*在这里用构造函数初始化了一下成员变量name,大家看一下格式*/

        Mario player_1("玛丽奥");
         Mario* player_2 = new Mario("路易基");
         
         cout<<"玩家1:"<<player_1.get_name()<<endl;
         cout<<"玩家2:"<<player_2->get_name()<<endl;
         
         system("pause>nul");
        return 0;
}


代码写的很简洁了

那就基本上要结束了

在结束之前,再讲一个和构造函数相对的,就是析构函数

它会在对象被销毁之前执行,也就是结束的时候执行

和构造函数一样,如果我们不写,编译器就添加一个啥也不干的析构函数

上代码

class Mario
{
public:
        Mario()                //构造函数
        {
                cout<<"玛丽奥被创建了,游戏开始"<<endl;
        }

        ~Mario()        //析构函数,格式就是比构造函数多一个 " ~ "
        {
                cout<<"玛丽奥被销毁了,“哒哒哒~”,你挂了"<<endl;
        }
};


int main()
{
        Mario player_1;
         
         system("pause>nul"); //在这里停顿一下,按任意键后执行
        return 0;
}

会看到,最后,析构函数也执行了,说明我们已经运行到了main函数的末尾

大家应该还记得,函数结束后,会把自己申请的所有栈空间变量删除

所以,析构函数在被删除之前,执行了。

那如果是堆呢

int main()
{
        Mario* player_2 = new Mario;
         system("pause>nul");
        return 0;
}


如果我们不写delete

就会发现,析构函数没执行,也就是说,这个对象没有被删除,一直留在内存里,然后我们再也没法删了它了(想删掉它么?关机吧!)

现在加一句

int main()
{
        Mario* player_2 = new Mario;
         system("pause>nul");
        delete player_2;                //在这里销毁它,销毁前会运行一次析构函数
        return 0;
}


OK 讲解完毕,文字多了点,但是内容不多,就两点:
创建堆空间变量
构造/析构函数

慢慢看吧
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

14

好友

6217

积分

序章

积分
6217
发表于 2013-3-17 22:44:05 | 显示全部楼层
楼主辛苦了 ,
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

12

主题

54

好友

1万

积分

喵星人

这里是❤犯二傲娇吃货卖萌晓受受❤喵~o(≧v≦)o~

积分
14552
发表于 2013-3-18 17:28:05 | 显示全部楼层
明显我是打算把这个帖子收藏起来慢慢看=w=
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

9

主题

21

好友

6174

积分

序章

积分
6174
 楼主| 发表于 2013-3-19 08:31:47 | 显示全部楼层

给你的故事,C++的兴趣入门 11

本帖最后由 dxxds 于 2013-11-23 12:13 编辑

感觉最近更新的几次帖子的趣味性略有降低了
其实这和我最近的工作心态有关啊,过的不是很顺的时候,人就容易发挥失常啊……
感情也出现了问题,倒不是说哥和妹子出现危机,而是我一直单身……
像我这样从小玩游戏,生化危机各种过的人来说,现在玩个什么单身危机那也是很正常的了……

算了,这都是小事,不去管它。

前几篇内容相对枯燥并且在第十篇来了一个超大篇幅超高攻击的持久攻击技能,相信各位都有点虚了
所以秉着对各位的歉意,我决定放一篇更长的主动AOE技能来满足各位的心理需要和生理需要。

现在进入正题:创造游戏之初的人物职业选择部分

话说,我曾经对各种网游的总结,那就是:最终都是拼宝石……
并一直信誓旦旦的讲给身边的哥们儿,让他们给我一个游戏宗师的称号什么的

不过现在我顿悟了,那都是错的
网游的最终是什么?穿衣服!就是你能看到我也能看到的那一层在现实里不算是布料的布料

什么属性,耐久,那都是假的,最终满足我的,一定是那最漂亮的几套,最漂亮的,一定是那属性最好的

几套……
并且我们会在一开始的时候,就选好了那几套
为什么?
因为我们已经玩了很多遍,熟得不能再熟了
在职业确定下来的那一刻,衣服也就确定了,你穿或不穿,它们就在那,不离不弃。

于是我们在游戏里定义了一个日后会由我们操控的角色类,它会是什么职业(电脑)还不知道

class role        //角色
{
public:
    int LV;        //等级
    int HP;        //血值
    int AT;        //攻击力
    void show_state(){cout<<"等级:"<<LV<<"血量:"<<HP<<"攻击力:"<<AT<<endl<<endl;}
};


以后它是啥职业咱不管,但是这些属性是一定跑不掉的(目前有三个,但是真实游戏里会有很多很多)

然后我们再把其它类(职业)也写上,然后重用这些属性,也就是说我们再写具体职业的时候,这三个属

性我们就不写了,直接拿来用,怎么做?

像这样,我写两个职业,战士和法师

class warrior : public role    //战士,继承了角色类
{
public:
    warrior(){LV=1; HP=100; AT=10; cout<<"初始化了战士属性"<<endl;}
};

class magician : public role    //法师,继承了角色类
{
public:
    magician(){LV=1; HP=50; AT=20; cout<<"初始化了法师属性"<<endl;}
};


是public继承,以后都这么写private什么的继承很少很少能用到,继承就是说它拥有父类(role)的所有

public和protected的变量和函数。

那private里的变量和函数会怎么样,篇幅有限,我简短说明

假设有个父类是父亲类,里面有属性是:年龄。身高,胡子
有个继承类是女儿类,就要继承父类的属性,但是我显然不想让女儿继承胡子这个属性
所以我可以把胡子属性放到private里,这样,女儿就不会长胡子了,然后游戏后续可能有刮胡刀什么的

就会因为女儿没有胡子属性而失灵什么的,你们自己搞

好,那现在回来,说完继承,我们看看效果
在main里创建战士和法师

int main()
{   
    role* player = new warrior;    //创建了战士的资源
    player->show_state(); //显示战士属性
    delete player;        //删除战士资源
   
    player = new magician;    //创建了法师的资源
    player->show_state(); //显示法师属性
    delete player;        //删除法师资源
   
     system("pause>nul"); return 0;
}


都看懂了吧?那这一讲结束了

看完帖子的都不给哥回复啊混蛋!!!

签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

7

主题

11

好友

7885

积分

序章

积分
7885
发表于 2013-3-19 22:01:32 | 显示全部楼层
好有意思哦!
赞一个赞一个!
虽然还没有看完,但是看了两节觉得LZ卖萌卖得好棒!
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

3

好友

2639

积分

Continue

积分
2639
发表于 2013-3-20 13:22:17 | 显示全部楼层
越来越复杂了,已经停留在指针那里几天了,没有进展~~
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

9

主题

21

好友

6174

积分

序章

积分
6174
 楼主| 发表于 2013-3-20 13:36:49 | 显示全部楼层

这么不用心啊,要把我的教程全部学完才算入门呢

有啥不懂的就问我
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

17

主题

48

好友

5094

积分

序章

积分
5094
发表于 2013-3-21 11:04:06 | 显示全部楼层
滷煮太可愛 快到我碗裡來!
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

3

好友

2639

积分

Continue

积分
2639
发表于 2013-3-21 12:50:04 | 显示全部楼层
dxxds 发表于 2013-3-20 13:36
这么不用心啊,要把我的教程全部学完才算入门呢

有啥不懂的就问我

最近都比较忙,没什么时间看,而且指针的定义好难理解呢。嗯~~我注册这个帐号就是想向你请教呢。
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

3

好友

2639

积分

Continue

积分
2639
发表于 2013-4-7 13:58:46 | 显示全部楼层
好帖不能沉,顶上去
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

1

主题

19

好友

1085

积分

Continue

积分
1085
发表于 2013-4-8 00:58:51 | 显示全部楼层
C++的编译器推荐使用GCC的升级版——GPP。至于Windows平台可以使用MingW
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

2

主题

9

好友

2783

积分

Continue

积分
2783
发表于 2013-4-8 18:34:35 | 显示全部楼层
终于有救了QAQ
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

9

主题

21

好友

6174

积分

序章

积分
6174
 楼主| 发表于 2013-4-20 10:03:20 | 显示全部楼层
本帖最后由 dxxds 于 2013-4-20 10:07 编辑

给你的故事,C++的兴趣入门 12

感觉之前的都写的太长了,会有很多人看不下去,所以这次我写短,希望能有人继续关注

上一节课已经写了职业的具体分工实现,那有了职业,咱就要给各个职业加上不同的技能,不然你可不会玩它

class role        //角色
{
public:
    int LV;        //等级
    int HP;        //血值
    int AT;        //攻击力
    void show_state();
    virtual ~role(){ cout<<"删除了role资源"<<endl;};  //虚函数,为了能执行子类析构函数,顺利删除资源而写。这句会被子类析构函数覆盖,实际上不会执行
    virtual void skill()=0;        //虚函数,为了能调用子类的同名函数
};

void role::show_state()
{
    cout<<"等级:"<<LV<<"血量:"<<HP<<"攻击力:"<<AT<<endl<<endl;
}

class warrior : public role    //战士,继承了角色类
{
public:
    warrior()
    {
        LV=1; HP=100; AT=10; cout<<"初始化了战士属性"<<endl;
    }
    ~warrior()
    {
        cout<<"删除了战士资源"<<endl<<endl;
    }
    void skill()
    {
        cout<<"战士技:劈砍!"<<endl;
    }
};

class magician : public role    //法师,继承了角色类
{
public:
    magician()
    {
        LV=1; HP=50; AT=20; cout<<"初始化了法师属性"<<endl;
    }
    ~magician()
    {
        cout<<"删除了法师资源"<<endl<<endl;
    }
    void skill()
    {
        cout<<"法师技:冰箭!"<<endl;
    }
};

int main()
{
    role* player = new warrior; //role变成了战士
    player->skill(); //自然这里就是战士的技能
    delete player;  //删了它,接下来让它变成法师

    player = new magician; //变成了法师
    player->skill(); //自然这里就是法师的技能
    delete player; //删了它 准备结束程序

    system(pause>nul);
    return 0;
}

可以看到我相对上一节课,只是在role类里多增加了一个skill的函数和一个~role的析构函数,并在之前加了一个virtual,表示这个函数是虚的。

这个虚函数类似一个JAVA里的interface,也就是接口。意思是让所有继承role的类,都必须实现这个函数,不然就报错

至于为什么要写这个函数?
因为role自己不知道将来在main里会变成战士还是法师,所以这里空下,交给子类实现。
但是这个函数必须要有,因为role不能调用子类有的而父类(也就是role自己)没有的函数方法

虚函数有两种,一种是可以自己(父类)实现的,还有一种是自己(父类)不能实现的

能实现的那种,前面加上“virtual”,然后直接写就行了。
不能实现的,前面加上“virtual”,后面加上 “=0”,就行了。

虚函数和一般函数的区别是啥?
区别就是,看下面这句
role* player = new warrior;
这句代码里有两个类,一个是role,一个是warrior
那如果这两个类里都有一个同名函数,那player执行哪个?

答案就是
如果函数是虚函数,就执行player子类的(warrior)
如果它不是虚函数,就执行player自己的(role)



OK 没啥难的吧?那就到这啦。
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

3

主题

13

好友

4534

积分

懒人

积分
4534
发表于 2013-4-20 10:08:47 | 显示全部楼层
虽然对于我来说讲的太简单了,不过还是顶一个~~~关注后续哦~~
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

该用户从未签到

9

主题

21

好友

6174

积分

序章

积分
6174
 楼主| 发表于 2013-4-20 10:10:38 | 显示全部楼层
Eeyore 发表于 2013-4-20 10:08
虽然对于我来说讲的太简单了,不过还是顶一个~~~关注后续哦~~

还请务必多关注
签名被小宅喵吞掉了~~~~(>_<)~~~~
回复 支持 反对

使用道具 举报

本版积分规则

小黑屋|手机版|技术宅(Z站|基宅) ( 粤ICP备18082987号-1 )

GMT+8, 2025-7-15 09:57 , Processed in 0.108133 second(s), 32 queries , Redis On.

Copyright © 2018 技术宅社区

Powered by Discuz! X3.5

快速回复 返回顶部 返回列表