【面向对象】小游戏“终结者”程序的设计与实现

08年9月入学,12年7月毕业,结束了我在软件学院愉快丰富的大学生活。此系列是对四年专业课程学习的回顾,索引参见:http://blog.csdn.net/xiaowei_cqu/article/details/7747205


面向对象程序设计

这是我们学习程序设计的第一课。我也在这门课上第一次接触程语言、写代码。我们以影印版的《C++ Program Design : An Introduction to Programming and Object-Oriented Design 》为教材。


现在想来那段“入门”的经历真是痛苦不堪,很多概念难以理解,就只能一点点把书中的代码一遍遍的敲。但每次跑出一点小东西也都觉着兴奋到不行。大一末的时候有个“大”的课程设计:两人一组编写一个小游戏。我和小琦一组,写了一个比较简略的闯关游戏,这次经历之后才真的对编程有了“入门”的感觉。


小游戏"YingMu"


【游戏功能需求说明】

本游戏是基于日本漫画《灌篮高手》而设计的,相信大家对游戏中的人物都相当熟悉。在游戏中我们采用了键盘上、下、左、右控制玩家的移动,空格键发射子弹。如果玩家碰到敌人,则游戏结束;消灭所有敌人,则通关。游戏共分为两关,每一关的地图是随机产生的,敌人的移动速度也逐渐加快。虽然功能看似简单,但其中乐趣无穷,是一款集娱乐、冒险为一体的游戏。
我们这次是在Microsoft Visual C++ 6.0,  EzWindow library的开发环境下设计完成的,一些程序的功能我们一时没有想到好的方法来实现,所以在这款游戏中没有呈现给大家。相信在以后的学习中,我们能更好地掌握并对这款小游戏进行升级更新。

【游戏总类图】




【游戏中的关键类】

Player

enum Floor{FLoor1=0,Floor2,Floor3,Floor4};

class Player {
	public:
		//constructor
		Player(SimpleWindow &w);
	public:
    	//inspectors
	    SimpleWindow& GetWindow() const;//得到玩家所在窗口
		Position GetPosition() const;  //得到玩家当前位置
		Direction GetDirection() const;  //得到玩家当前的方向
		BitMap& GetBmp(const Direction &d,int i); //得到玩家在相应的方向及步子上位图
		const BitMap& GetBmp(const Direction &d,int i) const; 
		Floor GetFloor()const;  //得到玩家当前所在层数
		bool IsDying();   //检查玩家是否死掉
		bool AtRightEdge() const;    //检查玩家是否走到窗口边缘
		bool AtLeftEdge() const;

	    //Facilitators
		void Create();  //创建玩家(即将玩家“放”在游戏窗口中)
		void Kill();    //“杀死”玩家(从窗口中擦掉)
		void Move();    //使玩家在键盘操控下做相应的移动
		void Fire();    //发射子弹
		void OKUp();    //设置玩家是否可以在层之间跳跃
		void OKDown();
		void CannotUpDown();

        //mutators
		void SetPosition(const Position &p); //设置玩家当前所有位图的位置 
		void SetFloor(Floor &f);  //玩家跳跃之后改变层的数据成员
		void SetDirection(const Direction &d); //设置玩家当前的方向
	
		//data member 
		vector<Bullet*> bullets;   /****************************************/
			                       //方便GameController中检查子弹和敌人     //
		                           //状况,所以放在public域中,设置为可见   //
                                   /****************************************/
	private:
		//facilities
		void Draw();
		void Erase();  /****************************************************/
		               //用户不直接操纵图片,而是通过调用 Creat() 和 Kill() //
                       //所以定义为 private                                 //
		               /*****************************************************/
		// Data members
		SimpleWindow &Window;
		vector<vector<BitMap> > Bmp; 
		Direction CurrentDirection;
		Position CurrentPosition;
		bool bUpOk;
		bool bDownOk;
		Floor CurrentFloor;//当前所处的层                    
  • 29
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 79
    评论
语法分析是编译器前端的重要组成部分,它负责将词法分析器生成的词法单元转换为语法结构,并检查语法正确性。本文将介绍语法分析程序设计实现。 1. 语法分析器的分类 语法分析器可以分为自上而下的语法分析器和自下而上的语法分析器两种。 自上而下的语法分析器以文法的起始符号为目标,从上往下逐步展开,直到匹配输入串或者发现错误。常用的自上而下语法分析算法有递归下降分析法和预测分析法。 自下而上的语法分析器从输入符号出发,逐步将符号组合成更复杂的结构,直到符合文法的起始符号。常用的自下而上语法分析算法有LR分析法、SLR分析法、LALR分析法等。 2. 语法分析器的设计思路 语法分析器通常采用自上而下的递归下降分析法或者自下而上的LR分析法。以下是一个简单的递归下降分析法的设计思路: Step 1:定义语法规则 首先,需要定义文法规则,通常使用扩展巴科斯范式(EBNF)表示。 Step 2:设计语法分析函数 为每个非终结符设计一个语法分析函数函数的输入是当前的输入符号,输出是生成的语法树。 Step 3:实现语法分析器 将所有语法分析函数组合成一个语法分析器,从文法的起始符号开始逐步展开,直到匹配输入串或者发现错误。 3. 递归下降分析法的实现 递归下降分析法的实现可以采用以下步骤: Step 1:定义语法规则 假设我们要设计一个简单的表达式语法分析器,它的语法规则如下: ``` expr ::= term { (+|-) term } term ::= factor { (*|/) factor } factor ::= id | number | ( expr ) ``` Step 2:设计语法分析函数 为每个非终结符设计一个语法分析函数函数的输入是当前的输入符号,输出是生成的语法树。 ```c++ // expr ::= term { (+|-) term } ExprNode* parse_expr() { ExprNode* node = parse_term(); while (current_token.type == TOKEN_PLUS || current_token.type == TOKEN_MINUS) { Token op_token = current_token; eat(current_token.type); ExprNode* right = parse_term(); node = new BinaryOpNode(op_token, node, right); } return node; } // term ::= factor { (*|/) factor } ExprNode* parse_term() { ExprNode* node = parse_factor(); while (current_token.type == TOKEN_MULTIPLY || current_token.type == TOKEN_DIVIDE) { Token op_token = current_token; eat(current_token.type); ExprNode* right = parse_factor(); node = new BinaryOpNode(op_token, node, right); } return node; } // factor ::= id | number | ( expr ) ExprNode* parse_factor() { Token token = current_token; if (token.type == TOKEN_ID) { eat(TOKEN_ID); return new IdNode(token); } else if (token.type == TOKEN_NUMBER) { eat(TOKEN_NUMBER); return new NumberNode(token); } else if (token.type == TOKEN_LPAREN) { eat(TOKEN_LPAREN); ExprNode* node = parse_expr(); eat(TOKEN_RPAREN); return node; } else { error("Syntax error"); } } ``` Step 3:实现语法分析器 将所有语法分析函数组合成一个语法分析器,从文法的起始符号开始逐步展开,直到匹配输入串或者发现错误。 ```c++ // Parsing expression ExprNode* parse() { return parse_expr(); } // Main function int main() { // Lexical analysis std::vector<Token> tokens = lexer("1 + 2 * (3 - 4)"); // Syntax analysis current_token = tokens.begin(); ExprNode* root = parse(); // Print syntax tree root->print(); delete root; return 0; } ``` 4. LR分析法的实现 LR分析法的实现可以采用以下步骤: Step 1:定义语法规则 假设我们要设计一个简单的表达式语法分析器,它的语法规则如下: ``` expr ::= term { (+|-) term } term ::= factor { (*|/) factor } factor ::= id | number | ( expr ) ``` Step 2:生成LR分析表 使用LR分析器生成器,根据语法规则自动生成LR分析表。 Step 3:实现语法分析器 使用LR分析表和状态机,从输入符号出发,逐步将符号组合成更复杂的结构,直到符合文法的起始符号。 ```c++ // Main function int main() { // Lexical analysis std::vector<Token> tokens = lexer("1 + 2 * (3 - 4)"); // Syntax analysis LRParser parser("grammar.lr1"); ExprNode* root = parser.parse(tokens); // Print syntax tree root->print(); delete root; return 0; } ``` 5. 总结 本文介绍了语法分析器的设计实现,包括递归下降分析法和LR分析法。递归下降分析法简单易懂,但是对于左递归文法和二义性文法无法处理;LR分析法可以处理所有文法,但是需要生成LR分析表和状态机,实现复杂一些。在实际应用中,可以根据具体情况选择适合的语法分析算法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 79
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值