一、游戏分析

    相信大家对金山打字通、打字精灵等打字软件非常熟悉,想当年刚接触计算机时还靠它们的打字游戏练习打字基本功。这章的游戏DEMO就是一个打字小游戏,当然,它很简单,只是A~Z字母的打字练习小游戏。游戏的设计也不复杂,游戏开始时先初始化下落字母的个数和每次下落字母的概率,随着时间的进行,字母会从界面上方逐渐下落到界面底下,在这过程中你需要敲击键盘上与界面下落的字母相对应的键位,如果键位的字母与下落的字母一致,则记录打字正确数量,否则不记录,无论如何,敲击一次键盘记录一下敲击键盘数,当字母下落到界面底下时,字母停止下落,该字母被视为无效,相应地,也记录一次敲击数。正确率、敲击数等信息会在界面上显示,游戏还有倒计时,时间一到则被视为游戏结束。

二、游戏实现

   先定义一个字母表,字母表的实现为:
  ///LetterTable类实现
[csharp]  view plain copy print ?
  1. using System;
  2. namespace Typing
  3. {
  4. internal sealed class LetterTable
  5. {
  6. private static String[] LETTERS_TABLE =
  7. {
  8. "A", "B", "C", "D", "E", "F", "G",
  9. "H", "I", "J", "K", "L", "M", "N",
  10. "O", "P", "Q", "R", "S", "T", "U",
  11. "V", "W", "X", "Y", "Z"
  12. };
  13. /// <summary>
  14. /// 获取字母表长度
  15. /// </summary>
  16. /// <returns></returns>
  17. public static Int32 getLength()
  18. {
  19. return LETTERS_TABLE.Length;
  20. }
  21. /// <summary>
  22. /// 根据索引获取字母
  23. /// </summary>
  24. /// <param name="index"></param>
  25. /// <returns></returns>
  26. public static String getLetter(Int32 index)
  27. {
  28. return LETTERS_TABLE[index];
  29. }
  30. /// <summary>
  31. /// 根据字母获取字母码
  32. /// </summary>
  33. /// <param name="letter"></param>
  34. /// <returns></returns>
  35. public static Int32 getLetterCode(String letter)
  36. {
  37. Int32 code = 65;
  38. for (Int32 i = 0; i < LETTERS_TABLE.Length; i++)
  39. {
  40. if (getLetter(i).Equals(letter))
  41. {
  42. code = 65 + i;
  43. }
  44. }
  45. return code;
  46. }
  47. }
  48. }

///Letter类实现

[csharp]  view plain copy print ?
  1. using System;
  2. using CEngine;
  3. using CGraphics;
  4. namespace Typing
  5. {
  6. internal class Letter
  7. {
  8. /// <summary>
  9. /// 字母
  10. /// </summary>
  11. private String m_letter;
  12. /// <summary>
  13. /// 字母码
  14. /// </summary>
  15. private Int32 m_code;
  16. /// <summary>
  17. /// 字母背景色
  18. /// </summary>
  19. private ConsoleColor m_backcolor;
  20. /// <summary>
  21. /// 字母前景色
  22. /// </summary>
  23. private ConsoleColor m_fontcolor;
  24. /// <summary>
  25. /// 字母活动情况
  26. /// </summary>
  27. private Boolean m_bAlive;
  28. /// <summary>
  29. /// 字母窗体位置
  30. /// </summary>
  31. private CPoint m_position;
  32. /// <summary>
  33. /// 随机数
  34. /// </summary>
  35. private static Random m_random = new Random();
  36. /// <summary>
  37. /// 构造函数
  38. /// </summary>
  39. public Letter()
  40. {
  41. }
  42. public String getLetter()
  43. {
  44. return this.m_letter;
  45. }
  46. public void setLetter(String letter)
  47. {
  48. this.m_letter = letter;
  49. }
  50. public Int32 getCode()
  51. {
  52. return this.m_code;
  53. }
  54. public void setCode(Int32 code)
  55. {
  56. this.m_code = code;
  57. }
  58. public Char getChar()
  59. {
  60. return (Char)this.m_code;
  61. }
  62. public ConsoleColor getBackcolor()
  63. {
  64. return this.m_backcolor;
  65. }
  66. public ConsoleColor getFontcolor()
  67. {
  68. return this.m_fontcolor;
  69. }
  70. public void setBackcolor(ConsoleColor color)
  71. {
  72. this.m_backcolor = color;
  73. }
  74. public void setFontcolor(ConsoleColor color)
  75. {
  76. this.m_fontcolor = color;
  77. }
  78. public Boolean getAlive()
  79. {
  80. return m_bAlive;
  81. }
  82. public void setAlive(Boolean bAlive)
  83. {
  84. this.m_bAlive = bAlive;
  85. }
  86. public CPoint getPosition()
  87. {
  88. return this.m_position;
  89. }
  90. public void setPosition(CPoint point)
  91. {
  92. this.m_position = point;
  93. }
  94. public void setPosition(Int32 x, Int32 y)
  95. {
  96. this.m_position.setX(x);
  97. this.m_position.setY(y);
  98. }
  99. /// <summary>
  100. /// 随机得到一个字母
  101. /// </summary>
  102. public void newLetter()
  103. {
  104. setLetter(LetterTable.getLetter(m_random.Next(0, 26)));
  105. setCode(LetterTable.getLetterCode(getLetter()));
  106. setBackcolor((ConsoleColor)m_random.Next(0, 16));
  107. setFontcolor((ConsoleColor)(15 - (Int32)getBackcolor()));
  108. setPosition(m_random.Next(1, 30), -1);
  109. setAlive(false);
  110. }
  111. /// <summary>
  112. /// 绘制字母
  113. /// </summary>
  114. /// <param name="draw"></param>
  115. public void draw(CDraw draw)
  116. {
  117. if (m_bAlive)
  118. {
  119. draw.setBackcolor(this.m_backcolor);
  120. draw.drawText(m_letter, m_position.getX(), m_position.getY(), 1, 1, this.m_fontcolor);
  121. }
  122. draw.setDrawSymbol(CSymbol.DEFAULT);
  123. draw.fillRect(m_position.getX(), m_position.getY() - 1, 1, 1, ConsoleColor.Black);
  124. }
  125. }
  126. }

定义一个字母管理类,用于管理所有下落的字母和配置字母的下落个数和每次下落字母的数量,字母管理类定义为:

///LetterManager类实现
[csharp]  view plain copy print ?
  1. using System;
  2. using System.Collections.Generic;
  3. using CGraphics;
  4. namespace Typing
  5. {
  6. internal sealed class LetterManager
  7. {
  8. private List<Letter> m_letters;
  9. /// <summary>
  10. /// 下落字母的个数
  11. /// </summary>
  12. private Int32 m_fallNum;
  13. private Random m_random;
  14. private Int32 m_fallRate;
  15. public LetterManager(Int32 num, Int32 rate)
  16. {
  17. this.m_random = new Random();
  18. this.m_fallNum = num;
  19. this.m_fallRate = rate;
  20. this.m_letters = new List<Letter>();
  21. for (Int32 i = 0; i < m_fallNum; i++)
  22. {
  23. Letter letter = new Letter();
  24. letter.newLetter();
  25. this.m_letters.Add(letter);
  26. }
  27. }
  28. public List<Letter> getLetters()
  29. {
  30. return this.m_letters;
  31. }
  32. public Int32 getFallNum()
  33. {
  34. return this.m_fallNum;
  35. }
  36. public Int32 getFallRate()
  37. {
  38. return this.m_fallRate;
  39. }
  40. public void setFallRate(Int32 rate)
  41. {
  42. if (rate < 0)
  43. {
  44. this.m_fallRate = 1;
  45. return;
  46. }
  47. this.m_fallRate = rate;
  48. }
  49. public void addFallNum(Int32 num)
  50. {
  51. if (num <= 0)
  52. {
  53. return;
  54. }
  55. this.m_fallNum += num;
  56. for (Int32 i = 0; i < num; i++)
  57. {
  58. Letter letter = new Letter();
  59. letter.newLetter();
  60. this.m_letters.Add(letter);
  61. }
  62. }
  63. public void draw(CDraw draw)
  64. {
  65. for (Int32 i = 0; i < m_letters.Count; i++)
  66. {
  67. m_letters[i].draw(draw);
  68. }
  69. }
  70. }
  71. }

最后为游戏类,实现游戏的逻辑,游戏类实现为:

///TypingGame类实现
[csharp]  view plain copy print ?
  1. using System;
  2. using System.Collections.Generic;
  3. using CEngine;
  4. using CGraphics;
  5. namespace Typing
  6. {
  7. public sealed class TypingGame : CGame
  8. {
  9. private LetterManager m_letBuilder;
  10. /// <summary>
  11. /// 打字正确个数
  12. /// </summary>
  13. private float m_rightCount;
  14. /// <summary>
  15. /// 打字个数
  16. /// </summary>
  17. private float m_typingCount;
  18. private CDraw m_draw;
  19. /// <summary>
  20. /// 倒计时
  21. /// </summary>
  22. private Int32 m_countDown;
  23. private Int32 m_lastTime;
  24. /// <summary>
  25. /// 下落速度控制
  26. /// </summary>
  27. private Int32 m_fallTime;
  28. /// <summary>
  29. /// 是否在打字
  30. /// </summary>
  31. private Boolean m_isType;
  32. private Random m_random;
  33. protected override void gameInit()
  34. {
  35. setTitle("控制台游戏之——键盘熟练工v1.0");
  36. m_letBuilder = new LetterManager(20, 2);
  37. setCursorVisible(false);
  38. setUpdateRate(40);
  39. m_rightCount = 0f;
  40. m_typingCount = 0f;
  41. m_countDown = 200;
  42. m_fallTime = 10;
  43. m_isType = false;
  44. m_random = new Random();
  45. m_draw = base.getDraw();
  46. m_draw.setDrawSymbol(CSymbol.RECT_SOLID);
  47. m_draw.drawRect(0, 0, 31, 25, ConsoleColor.White);
  48. m_draw.setDrawSymbol(CSymbol.DEFAULT);
  49. m_draw.fillRect(1, 0, 29, 1, ConsoleColor.Black);
  50. m_draw.setDrawSymbol(CSymbol.RHOMB_SOLID);
  51. m_draw.drawRect(31, 0, 9, 13, ConsoleColor.DarkYellow);
  52. m_draw.setDrawSymbol(CSymbol.RHOMB_SOLID);
  53. m_draw.drawRect(31, 12, 9, 13, ConsoleColor.DarkYellow);
  54. m_draw.drawText("倒计时:", 65, 2, ConsoleColor.Red);
  55. m_draw.drawText("正确率:", 65, 4, ConsoleColor.Green);
  56. m_draw.drawText("击键数:", 65, 6, ConsoleColor.Green);
  57. m_draw.drawText("FPS:", 65, 8, ConsoleColor.Green);
  58. m_draw.drawText("Rate:", 65, 10, ConsoleColor.Green);
  59. m_draw.drawText("操作:键盘A--Z键,根据下落的字母打击键盘对应的键位,正确率体现你的键盘操作熟悉程度。", new CRect(33, 14, 5, 10), ConsoleColor.DarkGreen);
  60. }
  61. protected override void gameDraw(CGraphics.CDraw draw)
  62. {
  63. m_letBuilder.draw(draw);
  64. draw.setBackcolor(ConsoleColor.Black);
  65. draw.drawText(m_countDown.ToString("000"), 73, 2, ConsoleColor.Red);
  66. if (m_typingCount != 0)
  67. {
  68. draw.drawText(((m_rightCount / m_typingCount) * 100).ToString("000") + "%", 73, 4, ConsoleColor.Red);
  69. }
  70. else
  71. {
  72. draw.drawText("0%", 73, 4, ConsoleColor.Red);
  73. }
  74. draw.drawText(m_typingCount.ToString("000"), 73, 6, ConsoleColor.Red);
  75. draw.drawText(getFPS().ToString(), 73, 8, ConsoleColor.Blue);
  76. draw.drawText(getUpdateRate().ToString(), 73, 10, ConsoleColor.Blue);
  77. }
  78. protected override void gameLoop()
  79. {
  80. if (m_fallTime == 0)
  81. {
  82. List<Letter> letters = m_letBuilder.getLetters();
  83. for (Int32 i = 0; i < letters.Count; i++)
  84. {
  85. //每个字母按几率下落
  86. if (m_random.Next(0, m_letBuilder.getFallNum() * m_letBuilder.getFallRate()) == i)
  87. {
  88. letters[i].setAlive(true);
  89. }
  90. //字母下落
  91. if (letters[i].getAlive())
  92. {
  93. letters[i].setPosition(letters[i].getPosition().getX(), letters[i].getPosition().getY() + 1);
  94. }
  95. //字母下落到地面
  96. if (letters[i].getPosition().getY() >= getClientRect().getHeight()-1)
  97. {
  98. letters[i].newLetter();
  99. m_typingCount++;
  100. }
  101. }
  102. m_fallTime = 5;
  103. }
  104. m_fallTime--;
  105. if (Environment.TickCount - m_lastTime > 1000)
  106. {
  107. m_lastTime = Environment.TickCount;
  108. m_countDown--;
  109. if (m_countDown == 0)
  110. {
  111. setGameOver(true);
  112. }
  113. }
  114. }
  115. protected override void gameExit()
  116. {
  117. m_letBuilder = null;
  118. base.getDraw().clear(ConsoleColor.Black);
  119. base.getDraw().drawText("Game Over!", 25, 10, ConsoleColor.Red);
  120. base.getDraw().drawText("Copyright (c) D-Zone Studio", 40, 10, ConsoleColor.White);
  121. Console.ReadLine();
  122. }
  123. protected override void gameKeyDown(CKeyboardEventArgs e)
  124. {
  125. if (!m_isType)
  126. {
  127. List<Letter> letters = m_letBuilder.getLetters();
  128. for (Int32 i = 0; i < letters.Count; i++)
  129. {
  130. if (letters[i].getAlive())
  131. {
  132. //是否打对字母
  133. if (letters[i].getChar().ToString() == e.getKey().ToString())
  134. {
  135. base.update(new CRect(letters[i].getPosition().getX(),letters[i].getPosition().getY(),1,1));
  136. letters[i].newLetter();
  137. m_rightCount++;
  138. break;
  139. }
  140. }
  141. }
  142. m_typingCount++;
  143. if (e.getKey() == CKeys.Escape)
  144. {
  145. setGameOver(true);
  146. }
  147. m_isType = true;
  148. }
  149. }
  150. protected override void gameKeyUp(CKeyboardEventArgs e)
  151. {
  152. m_isType = false;
  153. }
  154. }
  155. }

 从前面和现在这个游戏可以看到,不同游戏除了逻辑上设计上的不同之外,其他很多部分都是通用的,我们没必要每次写个小游戏都要做重复的编码工作,这也是写这个小游戏框架的原因及必要性。
   最后我们来欣赏下我们的劳动成果:

试玩链接: http://download.csdn.net/detail/hwenycocodq520/4630387

四、结语

   实话说,这个游戏DEMO实现得比较仓促,代码写得比较凌乱,但都是些简单的逻辑,相信大家都能看得明白。

C#游戏编程:《控制台小游戏系列》之《七、键盘熟练工实例》相关推荐

  1. 如何用python开发游戏_手把手教你用Python完成一个控制台小游戏-阿里云开发者社区...

    很多人想学Python程序设计或者已经了解过一点Python程序设计基础,却没办法开发出一个项目. 今天,通过演示一个简单的控制台小游戏制作,手把手教你如何用Python编写一个游戏程序,即便你是个新 ...

  2. c++编程拼图小游戏

    如何才能提供自己的编程水平,就要千锤百炼.今天给大家推荐的是拼图小游戏:采用 c++ 编写, 主要使用到了两个类, 分别是 GameFrame 和 Picture.GameFrame 负责游戏界面的初 ...

  3. 零基础编程桌球小游戏

    对于零基础的同学来说自己编程一个小游戏之类的会有很大的成就感吧.那么我就来分享一些编程小游戏的技巧.就拿一个台球在台球桌上动来说吧.对于零基础的人来说要不急不躁慢慢的来.我分享的代码可能有些简化,不见 ...

  4. flash编程可以用c语言,C语言写的小游戏和FLASH小游戏有何区别呢-c语言编程手机软件...

    C语言写的小游戏和FLASH小游戏有何区别呢-c语言编程手机软件 (2010-12-05 17:12:08) 标签: 杂谈 分类: 随笔 同题有大大的区分c语言写游戏可以直接挪用体系api举行编著,合 ...

  5. python游戏编程入门书籍推荐-游戏编程入门书籍推荐:想要游戏编程尽快入门这些书不要错过...

    游戏编程一直都是编程之中的一大热点,这也是由于游戏本身的火热造成的结果,所以每年都有很多人在关注着游戏编程.介于此小编今天就来将一些好的游戏编程入门书籍推荐给大家,希望对想要了解和学习游戏编程的朋友能 ...

  6. python游戏编程入门 免费-python游戏编程入门 python游戏编程入门课

    python游戏编程入门 python游戏编程入门课 什么是python游戏编程入门?首先我们需要认识什么是Python Python既是一个软件工具包,也是一种语言.Python软件包包含了一个名为 ...

  7. python游戏编程入门免费_python游戏编程入门 python游戏编程入门课

    python游戏编程入门 python游戏编程入门课 什么是python游戏编程入门?首先我们需要认识什么是Python Python既是一个软件工具包,也是一种语言.Python软件包包含了一个名为 ...

  8. 小学生python游戏编程4----拼图游戏

    小学生python游戏编程4----拼图游戏 主要设计 应用知识点 1.python知识点 1.1 函数定义与使用 1.2 random 2.pygamezero知识点 2.1 基本框架,取上节中讲到 ...

  9. 【源码+教程】Java课设项目_12款最热最新Java游戏项目_Java游戏开发_Java小游戏_飞翔的小鸟_王者荣耀_超级玛丽_推箱子_黄金矿工_贪吃蛇

    马上就要期末了,同学们课设做的如何了呢?本篇为大家带来了12款热门Java小游戏项目的源码和教程,助力大家顺利迎接暑假![源码+教程]Java课设项目_12款最热最新Java游戏项目_Java游戏开发 ...

  10. 怎么开发联机小游戏_微信小游戏创意大赛火热进行中,小游戏联机对战引擎免费用...

    腾讯云为小游戏开发者升级工具箱 小游戏联机对战引擎免费用 由微信小游戏举办的"微信小游戏创意大赛"正在火热进行中.12月23日,腾讯云宣布,除了给创意大赛的参赛者提供基础云资源,还 ...

最新文章

  1. GitHub万星资源:强化学习算法实现,教程代码样样全,还有详细学习规划
  2. php 启动手机浏览器,php实现读取手机客户端浏览器的类
  3. RewriteCond 详解
  4. OO模式-Composite
  5. 2台电脑一根网线传文件_用1根网线直连2台电脑,能干嘛?
  6. Linux C/C++开发环境搭建指针
  7. Atiti.ui原理与gui理论
  8. 风控中英文术语手册(银行_消费金融信贷业务)
  9. idea护眼主题全套设置
  10. matlab 帕多瓦数列 通项公式_matlab通分.ppt
  11. lwip系列一之数据的收发
  12. C#如何获取本机IP地址,两种方法
  13. 撰写英文专利权利要求的写作要求
  14. Oracle12C静默安装 Centos7
  15. 免费自学编程的12个网站,不用再花钱啦
  16. 《区块链技术与应用》北大肖臻老师——课程笔记【21-23】
  17. 从用户文件到系统驱动,全面清理c盘
  18. 半监督学习模型: 半监督的SVM
  19. C# Winform开发 弹出式输入框 文本框
  20. 报告称谷歌仍为工科生最具吸引力雇主

热门文章

  1. windows下实现socketpair函数
  2. swaggerUI接口版本管理
  3. mysql查看当前表字符集_mysql 字符集设置查看
  4. Linux常用命令使用方法大搜刮
  5. 大型企业信息化中的BPM 和SOA 实战
  6. 解析java中方法的重载和重写之间的区别与联系
  7. 2023年成人高考标准拿证流程(入学前入学后)
  8. 如何将GB7714-2015格式的参考文献表转换为bib文件
  9. 《当代青年血槽已空图鉴》
  10. (训练三)王朗自然保护区---数据集部分补充说明:计算xml文件里面目标数量   生成训练和测试的txt文件