前几天空闲的时候,实现了一个2048游戏。除了可以设置行数和列数之外,支持修改显示名称,比如下面,改成神雕侠侣中的角色名称:
游戏逻辑比较简单,大家都应该玩过。
这里主要实现了四个类:game、gameboard还有colorblock和boardgridline。
game类主要用来实现游戏的控制,比如初始化、添加新的色块、移除色块、控制色块上下左右移动、改变积分,触发游戏结束等。
gameboard继承自canvas,实现了色块的合并、检测每个格子的状态等,另外提供了game控制色块移动的接口。
colorblock类继承自shape类,用于自定义色块的显示,包含xy坐标、颜色、显示文字等依赖属性,可以进行动画,另外还实现了具体的上下左右移动的方法。最初几个颜色是手动设置,等到色块越来越多,就随机生成一种颜色。
boardgridline也继承自shape类,用于绘制canvas底部的网格。
另外,游戏使用一个简单的文本文件保存设置,包括行数与列数,以及显示文字及其对应颜色,具体操作在settings类中。
最后,按键事件封装在keysnavigation中。
图标使用expression design制作:
游戏效果如下:
game.cs
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.windows.documents;
namespace game2048
{
public class game
{
public enum state
{
idel,
start,
running,
}
colorblock[,] fillstate;
private int score = 0;
private int step = 0;
public colorblock[,] fillstate
{
get
{
return fillstate;
}
}
gameboard board;
public game(gameboard board)
{
this .board = board;
fillstate = new colorblock[board.rowcount, board.columncount];
for ( int i = 0; i < board.rowcount; i++)
{
for ( int j = 0; j < board.columncount; j++)
{
fillstate[i, j] = null ;
}
}
}
public void init()
{
settings.load();
colorblock block = new colorblock(board);
colorblock block1 = new colorblock(board);
//fillstate[block.xindex, block.yindex] = block;
// fillstate[block1.xindex, block1.yindex] = block1;
//blocklist.add(block);
//blocklist.add(block1);
}
public void addnew()
{
if (board.hasnoplace())
{
gameover( false );
return ;
}
colorblock block = new colorblock(board);
//fillstate[block.xindex, block.yindex] = block;
//blocklist.add(block);
}
public void remove( int xindex, int yindex)
{
if (fillstate[yindex, xindex] != null )
{
board.children.remove(fillstate[yindex, xindex]);
fillstate[yindex, xindex] = null ;
}
}
public void toleft()
{
bool add = false ;
for ( int i = 0; i < board.columncount; i++)
{
for ( int j = 0; j < board.rowcount; j++)
{
if (fillstate[j, i] != null )
{
add |= fillstate[j, i].moveleft();
}
}
}
if (add)
{
addnew();
firesetpchanged();
}
}
public void toright()
{
bool add = false ;
for ( int i = board.columncount-1; i >=0 ; i--)
{
for ( int j = 0; j < board.rowcount; j++)
{
if (fillstate[j, i] != null )
{
add |= fillstate[j, i].moveright();
}
}
}
if (add)
{
addnew();
firesetpchanged();
}
}
public void toup()
{
bool add = false ;
for ( int i = 0; i < board.columncount; i++)
{
for ( int j = 0; j < board.rowcount; j++)
{
if (fillstate[j, i] != null )
{
add |= fillstate[j, i].moveup();
}
}
}
if (add)
{
addnew();
firesetpchanged();
}
}
public void todown()
{
bool add = false ;
for ( int i = 0; i < board.columncount; i++)
{
for ( int j = board.rowcount-1; j >=0; j--)
{
if (fillstate[j, i] != null )
{
add |= fillstate[j, i].movedown();
}
}
}
if (add)
{
addnew();
firesetpchanged();
}
}
public delegate void onscorechange( int score);
public event onscorechange onscorechangehandler;
public delegate void onstepchange( int step);
public event onstepchange onstepchangehandler;
public delegate void ongameover( bool success);
public event ongameover ongameoverhandler;
public void firesetpchanged()
{
step++;
if (onstepchangehandler != null )
onstepchangehandler(step);
}
/// <summary>
/// 增加积分
/// </summary>
/// <param name="offset"></param>
public void incscore( int offset)
{
score += offset;
if (onscorechangehandler != null )
{
onscorechangehandler(score);
}
}
public void gameover( bool success)
{
if (ongameoverhandler != null )
{
ongameoverhandler(success);
}
}
public void reset()
{
score = 0;
step = 0;
if (onstepchangehandler != null )
onstepchangehandler(step);
if (onscorechangehandler != null )
onscorechangehandler(score);
for ( int i = 0; i < board.rowcount; i++)
{
for ( int j = 0; j < board.columncount; j++)
{
remove(i, j);
}
}
}
}
}
gameboard.cs
using system;
using system.collections.generic;
using system.linq;
using system.text;
using system.windows.controls;
using system.diagnostics;
namespace game2048
{
public class gameboard : canvas, icontrolable
{
private int rowcount = 4;
public int rowcount
{
get
{
return rowcount;
}
set
{
rowcount = value;
}
}
private int columncount = 4;
public int columncount
{
get
{
return columncount;
}
set
{
columncount = value;
}
}
game game = null ;
public gameboard()
{
this .focusable = true ;
this .focus();
this .reset();
}
public void reset()
{
settings.load();
rowcount = settings.rowcount;
columncount = settings.columncount;
}
public void init(game game)
{
this .game = game;
game.init();
}
public void toleft()
{
game.toleft();
debug.writeline( "left" );
}
public void toright()
{
game.toright();
debug.writeline( "right" );
}
public void toup()
{
game.toup();
debug.writeline( "up" );
}
public void todown()
{
game.todown();
debug.writeline( "down" );
}
//合并,是否继续
public bool union( int xindex, int yindex, direction dirct)
{
switch (dirct)
{
case direction.left:
game.remove(xindex - 1, yindex);
break ;
case direction.right:
game.remove(xindex + 1, yindex);
break ;
case direction.up:
game.remove(xindex, yindex - 1);
break ;
case direction.down:
game.remove(xindex, yindex + 1);
break ;
default :
break ;
}
bool ret = game.fillstate[yindex, xindex].changetext();
if (ret)
{
game.gameover( true );
return false ;
}
game.incscore(game.fillstate[yindex, xindex].textindex);
return true ;
}
public int getstate( int xindex, int yindex)
{
if (xindex < 0 || xindex > columncount - 1)
return 0;
if (yindex < 0 || yindex > rowcount - 1)
return 0;
if (game.fillstate[yindex,xindex] == null )
return 0;
return game.fillstate[yindex, xindex].textindex;
}
public bool hasnoplace()
{
return this .children.count == this .rowcount * this .columncount+1;
}
public bool islocationfilled( int xindex, int yindex)
{
if (xindex < 0 || xindex > columncount-1)
return true ;
if (yindex < 0 || yindex > rowcount-1)
return true ;
if (game.fillstate[yindex, xindex] == null )
return false ;
return game.fillstate[yindex, xindex].textindex>0;
}
public void setstate( int xindex, int yindex,colorblock block)
{
game.fillstate[yindex, xindex] = block;
}
}
}
源码下载地址:2048小游戏
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。
原文链接:http://blog.csdn.net/congduan/article/details/42276619
dy("nrwz");