开发者

Clickable Tiles

I recently decided to learn and make small 2D game using XNA framework. So i started by editing an example in "XNA 4.0 Game Development by Example" book by Kurt Jaegers and atm i'm stuck at displaying sprites.. I would like to make something like mahjong solitaire where tiles are destroyed when you select two same pieces. So Im displaying a board with random pieces but dont know how to draw clicked tile in different color to show that i've selected it. That's main Game1 class:

public class Game1 : Microsoft.Xna开发者_开发百科.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Texture2D titleScreen;
    Texture2D backgroundscreen;
    Texture2D playingTiles;
    Board gameBoard;
    Vector2 gameBoardDisplayOrigin = new Vector2(70, 89);
    enum GameStates { TitleScreen, Playing };
    GameStates gameState = GameStates.TitleScreen;
    Rectangle EmptyPiece = new Rectangle(247, 165, 40, 40);
    const float MinTimeSinceLastInput = 0.25f;
    float timeSinceLastInput = 0.0f;


    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        this.IsMouseVisible = true;
        graphics.PreferredBackBufferWidth = 800;
        graphics.PreferredBackBufferHeight = 600;
        graphics.ApplyChanges();
        gameBoard = new Board();

        base.Initialize();
    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);

        // TODO: use this.Content to load your game content here

        titleScreen = Content.Load<Texture2D>(@"Textures\TitleScreen");
        backgroundscreen = Content.Load<Texture2D>(@"Textures\Background");
        playingTiles = Content.Load<Texture2D>(@"Textures\MSuXTiles");
    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// all content.
    /// </summary>
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    /// /// *******************   UPDATE   *********************
    /// ********************************************************
    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();



        // TODO: Add your update logic here
        switch (gameState)
        {
            case GameStates.TitleScreen:
                if (Keyboard.GetState().IsKeyDown(Keys.Space))
                {
                    gameBoard.ClearBoard();
                    gameBoard.GenerateNewTiles();
                    //playerScore = 0;
                    gameState = GameStates.Playing;
                }
                break;
            case GameStates.Playing:
                timeSinceLastInput += (float)gameTime.ElapsedGameTime.TotalSeconds;
                if (timeSinceLastInput >= MinTimeSinceLastInput)
                {
                    HandleMouseInput(Mouse.GetState());

                }



                //gameBoard.GenerateNewTiles();
                break;
        }


        base.Update(gameTime);
    }


    /// **********************   DRAW   ************************
    /// ********************************************************
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        // TODO: Add your drawing code here
        if (gameState == GameStates.TitleScreen)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(titleScreen, new Rectangle(0, 0, this.Window.ClientBounds.Width,
                this.Window.ClientBounds.Height), Color.White);
            spriteBatch.End();
        }
        if (gameState == GameStates.Playing)
        {
            spriteBatch.Begin();
            spriteBatch.Draw(backgroundscreen, new Rectangle(0, 0,
                this.Window.ClientBounds.Width, this.Window.ClientBounds.Height), Color.White);
            for (int x = 0; x < Board.BoardWidth; x++)
                for (int y = 0; y < Board.BoardHeight; y++)
                {
                    int pixelX = (int)gameBoardDisplayOrigin.X + (x * GameTile.TileWidth);
                    int pixelY = (int)gameBoardDisplayOrigin.Y + (y * GameTile.TileHeight);
                    //rysujemy tlo dla przezroczystych obrazkow
                    /*spriteBatch.Draw(
                        playingTiles,
                        new Rectangle(pixelX, pixelY, GameTile.TileWidth, GameTile.TileHeight),
                        EmptyPiece,
                        Color.White);*/
                    spriteBatch.Draw(
                        playingTiles,
                        new Rectangle(pixelX, pixelY, GameTile.TileWidth, GameTile.TileHeight),
                        gameBoard.GetSourceRect(x, y),
                        Color.White);


                }
            //this.Window.Title = playerScore.ToString();
            spriteBatch.End();
        }

        base.Draw(gameTime);
    }


    //input handling
    private void HandleMouseInput(MouseState mouseState)
    {
        int x = ((mouseState.X - (int)gameBoardDisplayOrigin.X) / GameTile.TileWidth);
        int y = ((mouseState.Y - (int)gameBoardDisplayOrigin.Y) / GameTile.TileHeight);
        if ((x >= 0) && (x < Board.BoardWidth) &&
          (y >= 0) && (y < Board.BoardHeight))
        {
            if (mouseState.LeftButton == ButtonState.Pressed)
            {
                gameBoard.TintSelectedTile(x, y);
                timeSinceLastInput = 0.0f;

            }
            if (mouseState.RightButton == ButtonState.Pressed)
            {
                timeSinceLastInput = 0.0f;
            }
        }
    }
}

Board class :

class Board
{
    Random rand = new Random();

    public const int BoardWidth = 10;
    public const int BoardHeight = 10;

    private GameTile[,] boardOfTiles = new GameTile[BoardWidth, BoardHeight];
    //constructor
    public Board()
    {
        ClearBoard();
    }
    public void ClearBoard()
    {
        for (int x = 0; x < BoardWidth; x++)
            for (int y = 0; y < BoardHeight; y++)
                boardOfTiles[x, y] = new GameTile("Empty,Four");
    }
    //methods
    public Rectangle GetSourceRect(int x, int y)
    {
        return boardOfTiles[x, y].GetSourceRect();
    }
    public string GetSquare(int x, int y)
    {
        return boardOfTiles[x, y].TileType;
    }
    public void SetSquare(int x, int y, string tileName)
    {
        boardOfTiles[x, y].SetTile(tileName);
    }
    public void RandomPiece(int x, int y)
    {
        boardOfTiles[x, y].SetTile(GameTile.TileTypes[rand.Next(0, GameTile.MaxTilesColumnIndex),
            rand.Next(0, GameTile.MaxTilesRowIndex)]);
    }
    public void GenerateNewTiles()
    {

        for (int y = 0; y < Board.BoardHeight; y++)
            for (int x = 0; x < Board.BoardWidth; x++)
            {
                if (GetSquare(x, y) == "Empty,Four")
                {
                    RandomPiece(x, y);
                }
            }
    }

} and GameTile class:

class GameTile
{
    public static string[,] TileTypes =
    {
        {"Circle,One", "Circle,Two", "Circle,Three", "Circle,Four", "Circle,Five",
        "Circle,Six", "Circle,Seven", "Circle,Eight", "Circle,Nine"},

        {"Bamboo,One", "Bamboo,Two", "Bamboo,Three", "Bamboo,Four", "Bamboo,Five",
        "Bamboo,Six", "Bamboo,Seven", "Bamboo,Eight", "Bamboo,Nine"},

        {"Character,One", "Character,Two", "Character,Three", "Character,Four", "Character,Five",
        "Character,Six", "Character,Seven", "Character,Eight", "Character,Nine"},

        {"Honor,One", "Honor,Two", "Honor,Three", "Honor,Four", "Something1,Five",
        "Something2,Six", "Something3,Seven", "Something4,Eight", "Something5,Nine"},

        {"Dragon,One", "Dragon,Two", "Dragon,Three", "Empty,Four", "Something6,Five",
        "Something7,Six", "Something8,Seven", "Something9,Eight", "Something10,Nine"},

        {"Flower,One", "Flower,Two", "Flower,Three", "Flower,Four", "Something11,Five",
        "Something12,Six", "Something13,Seven", "Something14,Eight", "Something15,Nine"},

        {"Season,One", "Season,Two", "Season,Three", "Season,Four", "Something16,Five",
        "Something17,Six", "Something18,Seven", "Something19,Eight", "Something20,Nine"}
    };




    public const int TileHeight = 40;
    public const int TileWidth = 40;

    public const int MaxTilesRowIndex = 9;
    public const int MaxTilesColumnIndex = 7;

    private const int textureOffsetX = 1;
    private const int textureOffsetY = 1;
    private const int texturePaddingX = 1;
    private const int texturePaddingY = 1;

    private string tileType = "";

    public string TileType
    {
        get { return tileType; }
    }

    //konstruktory
    public GameTile(string type)
    {
        tileType = type;
    }
    //metody
    public void SetTile(string type)
    {
        tileType = type;
    }



    public Rectangle GetSourceRect()
    {
        int x = textureOffsetX;
        int y = textureOffsetY;


        foreach (string s in tileType.Split(','))
        {
            switch(s)
            {
                case "One":
                    //y = y;
                    break;
                case "Two":
                    y = y + (TileHeight + texturePaddingY);
                    break;
                case "Three":
                    y = y + 2 * (TileHeight + texturePaddingY);
                    break;
                case "Four":
                    y = y + 3 * (TileHeight + texturePaddingY);
                    break;
                case "Five":
                    y = y + 4 * (TileHeight + texturePaddingY);
                    break;
                case "Six":
                    y = y + 5 * (TileHeight + texturePaddingY);
                    break;
                case "Seven":
                    y = y + 6 * (TileHeight + texturePaddingY);
                    break;
                case "Eight":
                    y = y + 7 * (TileHeight + texturePaddingY);
                    break;
                case "Nine":
                    y = y + 8 * (TileHeight + texturePaddingY);
                    break;

                case "Circle":
                    //x = x;
                    break;
                case "Bamboo":
                    x = x + (TileWidth + texturePaddingX);
                    break;
                case "Character":
                    x = x + 2 * (TileWidth + texturePaddingX);
                    break;
                case "Honor":
                    x = x + 3 * (TileWidth + texturePaddingX);
                    break;
                case "Dragon":
                    x = x + 4 * (TileWidth + texturePaddingX);
                    break;
                case "Flower":
                    x = x + 5 * (TileWidth + texturePaddingX);
                    break;
                case "Season":
                    x = x + 6 * (TileWidth + texturePaddingX);
                    break;
            }
        }
        return new Rectangle(x, y, TileHeight, TileWidth);
    }




}

and that's how it looks atm: http://i55.tinypic.com/2yuizbl.png


An easy thing you can do is, in the SpriteBatch.Draw() call for the clicked, tile, change Color.White into some other color--maybe a Red. This will cause the tile to be shaded the new color.

If you'd prefer some other effect, you can render your clicked tile to a separate RenderTarget2D, perform any enhancements you'd like to that render target, and then draw the render target to the back buffer.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜