好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

WPF实现2048小游戏

        前几天空闲的时候,实现了一个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");

查看更多关于WPF实现2048小游戏的详细内容...

  阅读:59次