© 2012-2023 Conmajia
《倒水解密》用来打发时间很不错,规则是有 n 个容量不同的瓶子,任务是通过装水、倒水将 a 升水倒入容量为 b 的瓶子。游戏虽然简单,但可玩性高,有不同的难度变化,并且能锻炼玩家的心算能力,不失为很好的休闲方式。
游戏操作方式如下:
- 在瓶子上双击右键可以把瓶子灌满水
- 双击左键可以把瓶子里的水倒掉
- 将一个瓶子拖动到另一个瓶子上可以把水倒过去
下面是游戏的效果。
`Bottle` 类,表示瓶子,保存瓶子的关键属性如容量、储量,以及基本方法如倒入、倒出。该类实现了 `IVisible` 可视化接口。这个接口很简单,只提供了一个绘图方法,用于重绘瓶子自身并返回图像。使用这种方式,可以方便的修改瓶子的外观样式而不用修改其他部分代码。例如可以简单的用矩形画瓶子,也可以像上面的手机游戏截图一样用非常的漂亮的贴图来做。
这里我用画图鼠绘了一个丑陋的瓶子作为例子。
画瓶子核心代码如下:
public Bitmap Draw() {
int contentHeight = bounds.Height * content / capacity;
if (contentHeight > 0)
using(Brush b = new LinearGradientBrush(
new Rectangle(
0,
bounds.Height - contentHeight - 1,
bounds.Width, contentHeight
),
Color.LightBlue,
Color.DarkBlue,
90)) {
Rectangle contentRect = new Rectangle(
0,
bounds.Height - contentHeight,
bounds.Width, contentHeight
);
painter.FillRectangle(b, contentRect);
}
painter.DrawRectangle(
Pens.Silver,
0, 0,
bounds.Width - 1, bounds.Height - 1
);
string s = string.Format("{0}/{1}", content, capacity);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
2, 1
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
1, 2
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
2, 3
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.Black,
3, 2
);
painter.DrawString(
s,
SystemFonts.DefaultFont,
Brushes.White,
2, 2
);
return canvas;
}
倒水的核心代码如下:
public void DropIn(int amount) {
if (amount > 0) {
content += amount;
if (content > capacity)
content = capacity;
dirty = true;
}
}
public void DropOut(int amount) {
if (amount > 0 && amount < content)
content -= amount;
else
content = 0;
dirty = true;
}
用一个 `World` 类来存放所有瓶子,用于和游戏类交互,核心代码如下:
public class World {
List < Bottle > bottles = new List < Bottle > ();
public Bottle CreateBottle(int capacity) {
return CreateBottle(capacity, 0);
}
public Bottle CreateBottle(int capacity, int content) {
Bottle b = new Bottle(capacity, content);
bottles.Add(b);
arrangeBottles();
return b;
}
public void DestroyBottle() {
bottles.Clear();
}
public void DestroyBottle(Bottle b) {
bottles.Remove(b);
}
public void DestroyBottle(int capacity) {
List < Bottle > tmp = new List < Bottle > ();
foreach(Bottle b in bottles) {
if (b.Capacity != capacity)
tmp.Add(b);
}
bottles.Clear();
bottles.AddRange(tmp);
}
}
`Game` 游戏类,用于保存游戏世界,自动生成游戏和判定游戏胜利。
public class Game {
public void AutoGenerate(int difficaulty) {
if (difficaulty < 1)
return;
world.DestroyBottle();
int bottleCount = rand.Next(3, +difficaulty);
targetBottle = rand.Next(0, bottleCount - 1);
int maxAmount = 10;
for (int i = 0; i < bottleCount; i++) {
int cap = 0;
do
cap = rand.Next(3, maxAmount + difficaulty);
while (capacityInside(cap));
world.CreateBottle(cap);
}
targetAmount = rand.Next(1, world.Bottles[targetBottle].Capacity);
initiated = true;
}
bool capacityInside(int cap) {
foreach(Bottle b in world.Bottles) {
if (b.Capacity == cap)
return true;
}
return false;
}
public bool CheckSuccess() {
if (targetBottle > -1)
if (initiated && world.Bottles.Count > targetBottle)
return world.Bottles[targetBottle].Content == targetAmount;
return false;
}
}
游戏的计时、计步、界面操作等放在主窗体,这里不做赘述。
简单的实现,还有倒计时、高分榜等功能可以扩展,界面也可以做的更漂亮些,欢迎大家扩展。
源代码及工程文件(VS2010) 可以 点击下载
© Conmajia 2012