可以选择关卡,设置自定义地图。
winform,windows窗体程序开发。
一、任务描述:
1.题目:推箱子小游戏2.功能描述:
(1)箱子只能推动而不能拉动。一次只能推动一个箱子。
(2)在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出现箱子无法移动或者通道被堵住的情况。
(3)本游戏的目的就是把所有的箱子都推到目标位置上。
(4)通过使用键盘的方向键来控制移动方向。
(5)具有重玩本关、跳过本关的功能。
二、功能设计:
(1).能够显示主菜单和界面:允许玩家对游戏关卡进行设置,增设关卡,把编辑好的关卡进行存储,并能弹出窗体提示当前设计完成的关卡数;
(2).能够实现键盘操作功能:使用上、下、左、右方向键控制工人的移动方向,空格键重玩;
(3).能够把放置到目的地的箱子进行变色显示;
(4).游戏胜负判断功能:当玩家把箱子移动到指定位置时,成功通过当前关卡;(5).可以切换上一关、下一关、增加关卡以及重玩当前关卡;
(6).可以判断当前的关卡数,在处于第一关和最后一关时分别不能进行“前一关”和“后一关”操作,并弹出窗体进行提示;
主要分为三个层。
主要窗体层
开始界面
菜单栏设置
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
using ModeLayer;
using DataLayer;
using System.Threading;
namespace UILayer
{
public partial class MainForm : Form
{
//游戏管理者
GameManager manager = null;
//游戏菜单窗体
GameMenuForm gmf = null;
public MainForm()
{
InitializeComponent();
//窗体位于桌面中间
this.StartPosition = FormStartPosition.CenterScreen;
}
//由游戏的行列数动态改变窗体的大小
private void ChangeFormSize()
{
int width = manager.Gezi * manager.CurentMapRow;
int height = manager.Gezi * manager.CurentMapCol;
this.Size = new Size(height, width);
//MessageBox.Show ("");
}
//窗体最小化
private void MinSizeForm()
{
this.WindowState = FormWindowState.Minimized;
}
//关闭窗体
private void CloseForm()
{
Application.Exit();
}
//改变窗体的背景
private void ChangeBackImg()
{
Bitmap Img = manager.CurentBmp;
if (Img == null) return;
Bitmap originalBmp = (Bitmap)Img.Clone();
int n = 20;
Bitmap currentBmp = new Bitmap(originalBmp.Width, originalBmp.Height);
//Graphics gCurrentBmp = Graphics.FromImage(currentBmp);
//gCurrentBmp.FillRectangle(Brushes.White, new Rectangle(0, 0, currentBmp.Width, currentBmp.Height));
//gCurrentBmp.Dispose();
Graphics gPictureBox =panel1.CreateGraphics();
int width = originalBmp.Width; // 表示每一块百叶窗的宽度
int heightPerSlice = originalBmp.Height / n; // 表示每块百叶窗的高度 = 图片高度 / 百叶窗数目
for (int i = 0; i < heightPerSlice; i++) // (for i...)循环处理每一页百叶窗的第i行,从第0行到第heightPerSlice - 1行
{
for (int k = 0; k < n; k++) // 循环k表示依次处理n页百叶窗,从第0到第n-1页
{
for (int j = 0; j < width; j++) // 循环枚举每一页百叶窗的第j列
{
currentBmp.SetPixel(j, k * heightPerSlice + i,
originalBmp.GetPixel(j, k * heightPerSlice + i));
}
}
// 将currentBmp按拉伸图像的方式画回pictureBox1上。
gPictureBox.DrawImage(currentBmp,
new Rectangle(0, 0, panel1.Width, panel1.Height), // 表示目标画板(pictureBox1)的绘图范围
new Rectangle(0, 0, currentBmp.Width, currentBmp.Height), // 表示图片源(currentBmp)的绘图范围
GraphicsUnit.Pixel);
System.Threading.Thread.Sleep(3); // 挂起线程,即让程序停顿100毫秒,再继续执行for循环。
}
gPictureBox.Dispose();
originalBmp.Dispose();
currentBmp.Dispose();
}
//加载
private void MainForm_Load(object sender, EventArgs e)
{
//窗体传值用的委托
Action actChangeFormSize = new Action(ChangeFormSize);//改变窗体大小的委托
Action actChangeImg = new Action(ChangeBackImg);//改变窗体背景的委托
Action actMinForm = new Action(MinSizeForm);//窗体最小化的委托
Action actCloseForm = new Action(CloseForm);//关闭窗体的委托
manager = new GameManager(panel1);//初始化一个游戏管理者
panel1.Invalidate();
//获取第i关的高和宽
int width = manager.Gezi * manager.CurentMapRow;
int height = manager.Gezi * manager.CurentMapCol;
this.Size = new Size(width, height);
//菜单窗体
gmf = new GameMenuForm(manager);
//注册委托
gmf.MinSizeForm1 = actMinForm;
gmf.CloseForm = actCloseForm;
//gmf.ChangeMainFormSize = act;
manager.ChangeMainFormSize = actChangeFormSize;
manager.ChangeBackImg = actChangeImg;
gmf.Width = this.ClientSize.Width / 5;
gmf.Height = this.ClientSize.Height;
gmf.Show();
gmf.TopMost = true;
//gmf.Hide();
gmf.Opacity = 0.5;
//菜单窗体停靠在主窗体左边
int top = this.ClientRectangle.Top;
int left = this.ClientRectangle.Left;
Point poin = this.PointToScreen(new Point(left, top));
gmf.Location = poin;
}
//重回时间
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.DrawImage(manager.CurentBmp, panel1.ClientRectangle);
}
//按下按钮触发
private void MainForm_KeyDown(object sender, KeyEventArgs e)
{
manager.keyDownOrreStep = true;
manager.RoleTryTo(e);
}
protected override void OnClosed(EventArgs e)
{
base.OnClosed(e);
//结束整个程序
Application.Exit();
}
private void MainForm_MouseMove(object sender, MouseEventArgs e)
{
//窗体移动
if (isdrow)
{
//根据鼠标的移动大小,移动窗口
this.Left += MousePosition.X - currentPositionX;
this.Top += MousePosition.Y - currentPositionY;
currentPositionY = MousePosition.Y;
currentPositionX = MousePosition.X;
}
//菜单栏隐藏
int top = this.ClientRectangle.Top;
int left = this.ClientRectangle.Left;
Point poin = this.PointToScreen(new Point(left, top));
gmf.Location = poin;
if (e.X < this.Width / 5 && e.X > 10)
{
gmf.Show();
}
else
{
gmf.Hide();
}
}
private void MainForm_SizeChanged(object sender, EventArgs e)
{
try
{
gmf.Width = 130;
gmf.Height = this.ClientSize.Height;
//panel1.Invalidate();
}
catch (Exception)
{
}
}
private void MainForm_Move(object sender, EventArgs e)
{
if (gmf == null)
{
return;
}
int top = this.ClientRectangle.Top;
int left = this.ClientRectangle.Left;
Point poin = this.PointToScreen(new Point(left, top));
gmf.Location = poin;
}
#region 无边款窗体移动
int currentPositionX = 0;
int currentPositionY = 0;
bool isdrow = false;
private void panel1_MouseDown(object sender, MouseEventArgs e)
{
isdrow = true;
currentPositionX = MousePosition.X;
currentPositionY = MousePosition.Y;
}
private void panel1_MouseLeave(object sender, EventArgs e)
{
//恢复起始状态
currentPositionX = 0;
currentPositionY = 0;
isdrow = false;
}
private void panel1_MouseUp(object sender, MouseEventArgs e)
{
isdrow = false;
}
#endregion
}
}
数据层
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using ModeLayer;
using System.Runtime.Serialization.Formatters.Binary;
using System.IO;
namespace DataLayer
{
public static class MapInfo
{
/// <summary>
/// 获取MapInfo文件里面的信息;
/// </summary>
/// <returns></returns>
public static List<Map> ReadMapInofFile()
{
List<Map> listMapDal = null;
if (!File.Exists("MapInfo.bin"))
return null;
try
{
using (FileStream fs = new FileStream("MapInfo.bin", FileMode.Open, FileAccess.Read))
{
BinaryFormatter bf = new BinaryFormatter();
listMapDal = bf.Deserialize(fs) as List<Map>;
if (listMapDal == null)
{
//MessageBox.Show("listMap==null");
return null;
}
}
}
catch (Exception)
{
//MessageBox.Show("读取文件失败");
throw;
}
return listMapDal;
}
/// <summary>
/// 存储ListMap
/// </summary>
/// <param name="listMap"></param>
/// <returns></returns>
public static bool SaveMapInfoToMapInfoFile(List<Map> listMap)
{
bool mark = true;
try
{
using (FileStream fs = new FileStream("MapInfo.bin", FileMode.OpenOrCreate, FileAccess.Write))
{
BinaryFormatter bf = new BinaryFormatter();
bf.Serialize(fs, listMap);
}
}
catch (Exception)
{
mark = false;
}
return mark;
}
}
}
地图层
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using System.Resources;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace ModeLayer
{
[Serializable]
public class Map : IDisposable,ICloneable
{
/// <summary>
/// 深拷贝;
/// </summary>
/// <returns></returns>
public object Clone()
{
return new Map(Col, Row)
{
_logicMap = DeepCopyLogicMap(),
_col = Col,
_row = _row,
//_reallMap = _reallMap.Clone() as Bitmap,
//_box = _box.Clone() as Bitmap,
//_road = _road.Clone() as Bitmap,
//_role = _role.Clone() as Bitmap,
//_target = _target.Clone() as Bitmap,
//_wall = _wall.Clone() as Bitmap
};
}
/// <summary>
/// 释放资源
/// </summary>
public void Dispose()
{
_box.Dispose();
//_reallMap.Dispose();
_road.Dispose();
_role.Dispose();
_target.Dispose();
_wall.Dispose();
}
public char[,] DeepCopyLogicMap()
{
char[,] ch = new char[_row, _col];
for (int i = 0; i < _row; i++)
{
for (int j = 0; j < _col; j++)
{
ch[i, j] = _logicMap[i, j];
}
}
return ch;
}
char[,] _logicMap;
//默认值;
private int _col = 6;//行
private int _row = 6;//列
//private Bitmap _reallMap = null;//地图画布;
private static Bitmap _box = null;//路障;
private static Bitmap _road = null;//路;
private static Bitmap _role = null;//角色;
private static Bitmap _target = null;//目标;
private static Bitmap _wall = null;//墙
/// <summary>
/// 设置这个位置的状态;
/// </summary>
/// <param name="x"></param>
/// <param name="y"></param>
/// <param name="ch"></param>
public void SetMapState(int x, int y, char ch)
{
_logicMap[x, y] = ch;
}
/// <summary>
/// 使用默认值构建地图;大小为6*6
/// </summary>
public Map()
{
InitImg();
}
private void InitImg()
{
ResourceManager rsm = Properties.Resources.ResourceManager;
_role = new Bitmap((rsm.GetObject("role") as Image), new Size(60, 60));
_box = new Bitmap((rsm.GetObject("box") as Image), new Size(60, 60));
_road = new Bitmap((rsm.GetObject("road") as Image), new Size(60, 60));
_target = new Bitmap((rsm.GetObject("target") as Image), new Size(60, 60));
_wall = new Bitmap((rsm.GetObject("Wall") as Image), new Size(60, 60));
//_reallMap = new Bitmap(60 * _row, 60 * _col);
}
/// <summary>
/// 自定义地图;
/// </summary>
/// <param name="col">列</param>
/// <param name="row">行</param>
public Map(int col, int row)
{
_col = col;
_row = row;
_logicMap = new char[_row, _col];
InitImg();
}
/// <summary>
/// 获取逻辑地图
/// </summary>
public char[,] LogicMap
{
get
{
return _logicMap;
}
}
/// <summary>
/// 获取逻辑地图的列数
/// </summary>
public int Col
{
get
{
return _col;
}
}
/// <summary>
/// 获取逻辑地图的行数;
/// </summary>
public int Row
{
get
{
return _row;
}
}
/ <summary>
/ 真是的地图
/ </summary>
//public Bitmap ReallMap
//{
// get
// {
// return _reallMap;
// }
// set
// {
// _reallMap = value;
// }
//}
/// <summary>
/// 障碍物
/// </summary>
public Bitmap Box
{
get
{
return _box;
}
set
{
_box = value;
}
}
/// <summary>
/// 路
/// </summary>
public Bitmap Road
{
get
{
return _road;
}
set
{
_road = value;
}
}
/// <summary>
/// 人物
/// </summary>
public Bitmap Role
{
get
{
return _role;
}
set
{
_role = value;
}
}
/// <summary>
/// 目标
/// </summary>
public Bitmap Tatget
{
get
{
return _target;
}
set
{
_target = value;
}
}
/// <summary>
/// 墙;
/// </summary>
public Bitmap Wall
{
get
{
return _wall;
}
set
{
_wall = value;
}
}
}
}