弹球游戏也算是经典小游戏之一,这次我试着自己写一个弹球小游戏。
新建项目:C#->win窗体应用程序->完成,开始写代码。
第一步先想一想这个游戏都有哪些要素:一个球,一个玩家控制的球拍,一系列砖块。他们都需要有哪些性质呢?
球:在屏幕上做直线移动,碰到别的东西反弹。
而反弹是什么呢,反弹就是改变速度方向。如果分解速度的话可以分解成x方向和y方向的速度,因为在这个游戏中球只可能碰到矩形物体,所以不考虑斜面。球只可能碰到与坐标轴平行的边界。这里说的坐标轴是win窗口上的坐标轴,向右为x轴正向,向左为y轴正向,窗口左上角是原点。
所以可以把反弹当作如果碰到与x轴平行的边界,那么与y轴平行的速度的分量变为原来的负值,如果碰到与y轴平行的边界,那么与x轴平行的速度的分量变为原来的负值。
球拍:球拍只可能随着玩家的控制做左右移动,而且碰到移动的边界的话就停止继续往前走。
砖块:砖块静止在场景中,如果被别的物体(球)碰撞就会消失。
因为C#是面向对象的,所以以上的三个东西就是三个class,而且显而易见的是他们有一些共同的性质,所以可以由一个class派生出来。
他们有什么共同的性质呢?
三个东西都得在场景中绘制出来,都可能与别的东西碰撞。
这就是一些性质:位置,边界,绘制,碰撞。
所以基类就应该有这些字段:位置信息,碰撞信息,边界信息。
这些方法:绘图,运动,是否碰撞。
位置,碰撞,边界三个东西说白了就是三个不同的矩形,只不过功能不太一样。
位置矩形确定了这个物体应该在什么地方画,碰撞矩形确定了这个物体怎么与别的东西碰撞。很多人认为这两个矩形应该是一回事,实际上在弹球这个游戏中这两个矩形确实也是一回事,但是为了类的可移植性,还是同时保留这两个信息吧。事实上,我做这个练习是为了以后写一个类似的“坦克大战”小游戏联系一下,毕竟刚开始学C#。
边界其实就是一个移动范围,确定了这个边界之后,这个物体就只能在这个边界范围内移动。也许会有人觉得所有物体共用一个边界就行了,何必每个物体储存自己的边界信息呢,这不是浪费空间吗?在这个游戏中确实也是所有物体用同一个边界信息的,可是在别的地方,比如有一个小怪,默认的状态是在城堡的门口巡逻,来来回回来来回回,这个时候这个信息就有用了,这个小怪的边界就是城堡门口的一片地方。
考虑到这三种信息都是一个矩形,所以我自己写了一个Bounds结构体来封装这个矩形,方便操作,代码如下:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace 弹球
{
/// <summary>
/// 边界:为简化问题,场景中每个物体都有其矩形碰撞边界
/// </