Main Site Documentation

Best way to draw custom graphics on a Glide window


#1

Hi,

Just a quick question. The project I’m working on requires me to draw some custom graphics (Line drawing mainly)

I’m using Glide for the UI. Should I create an Image on the window and create a custom bitmap to draw on. Or should I draw directly onto the window it’s self.

        void InitMainGameWindow()
        {
            Image gameView = (Image)mainGameWindow.GetChildByName("gameImage");

            Bitmap view = new Bitmap(150, 150);
            view.DrawLine(Microsoft.SPOT.Presentation.Media.Color.White, 1, 0, 0, 50, 50);

            gameView.Bitmap = view;

            // or

            mainGameWindow.Graphics.DrawLine(Microsoft.SPOT.Presentation.Media.Color.White, 1, 0, 155, 50, 205);

            Glide.MainWindow = mainGameWindow;
        }

Also is there a way of getting more colours than black & White?

Cheers,

Jas


#2

Re color options
Use Colors.Red etc not Spot colors


#3

Thanks,

I realised the same after a little object browsing :wink:

For information, I’ve chosen to go with the Image bitmap method as it makes touch interface much easier.

Jas


#4

I’d be interested to see a screenshot of the finishes article


#5

Hi,

The drawn bitmap is in the top middle of the display in the attached picture. I’ve not done anything with the touch interface at the moment.

As you can see from the picture it’s an old school Wizardry type of game. The purple image slots will contain the character portraits in the party.

Here is the code that displays the bitmap:

        void InitMainGameWindow()
        {
            Image gameView = (Image)mainGameWindow.GetChildByName("gameImage");

            try
            {
                maze = new Maze(storageDev, mazePath, 0);
            }
            catch (Exception e)
            {
                FatalError(e.Message);
            }

            gameView.Bitmap = maze.View;

            Glide.MainWindow = mainGameWindow;
        }

Below is the Maze class where all the work gets done (I put the whole class as the work is done through out the class so it’s easier to paste that way :wink: ):

using System;
using Microsoft.SPOT;
using Microsoft.SPOT.Presentation.Media;
using GT = Gadgeteer;

namespace Tyrannt
{

    // all map handling and maze drawing are handled by this class
    // there is a readonly View bitmap which will contain the currently
    // rendered maze view.
    [Serializable]
    class Maze
    {

        #region Internal Varianbles

        private char[][] maze = new char[20][];
        private char[][] mazeSegment = new char[3][];
        private int _currentLevel = 0;
        private Bitmap _view = new Bitmap(151,151);
        private Color _currentColour;

        private int _x = 0;
        private int _y = 0;
        private int _direction = 0;

        private string _mazePath;

        private GT.StorageDevice _storageDev;

        #endregion

        #region Constructor

        public Maze(GT.StorageDevice storageDev, string path,int level)
        {
            _storageDev = storageDev;
            
            _mazePath = path;
            _currentLevel = level;
            InitialiseMaze();
            LoadMaze();
            SetColour("white");
        }

        private void InitialiseMaze()
        {
            for (int lp = 0; lp <= 19; lp++)
            {
                maze[lp] = new char[20];
            }
            for (int lp = 0; lp <= 2; lp++)
            {
                mazeSegment[lp] = new char[3];
            }
        }
        #endregion

        #region Properties
        public Bitmap View
        {
            get
            {
                GenerateSegment();
                RenderView();
                return _view;
            }
        }
        public string Path
        {
            set
            {
                _mazePath = value;
            }
        }
        #endregion

        #region Render Routines

        void GenerateSegment()
        {
            switch (_direction)
            {
                case 0: // North
                    mazeSegment[0][0] = maze[_x][_y - 1];
                    mazeSegment[0][1] = maze[_x][_y];
                    mazeSegment[0][2] = maze[_x][_y + 1];
                    mazeSegment[1][0] = maze[_x - 1][_y - 1];
                    mazeSegment[1][1] = maze[_x - 1][_y];
                    mazeSegment[1][2] = maze[_x - 1][_y + 1];
                    mazeSegment[2][0] = maze[_x - 2][_y - 1];
                    mazeSegment[2][1] = maze[_x - 2][_y];
                    mazeSegment[2][1] = maze[_x - 2][_y + 1];
                    break;
                case 1: // East
                    mazeSegment[0][0] = maze[_x - 1][_y];
                    mazeSegment[0][1] = maze[_x][_y];
                    mazeSegment[0][2] = maze[_x + 1][_y];
                    mazeSegment[1][0] = maze[_x - 1][_y + 1];
                    mazeSegment[1][1] = maze[_x][_y + 1];
                    mazeSegment[1][2] = maze[_x + 1][_y + 1];
                    mazeSegment[2][0] = maze[_x - 1][_y + 2];
                    mazeSegment[2][1] = maze[_x][_y + 2];
                    mazeSegment[2][1] = maze[_x + 1][_y + 2];
                    break;
                case 2: // South
                    mazeSegment[0][0] = maze[_x][_y + 1];
                    mazeSegment[0][1] = maze[_x][_y];
                    mazeSegment[0][2] = maze[_x][_y - 1];
                    mazeSegment[1][0] = maze[_x + 1][_y + 1];
                    mazeSegment[1][1] = maze[_x + 1][_y];
                    mazeSegment[1][2] = maze[_x + 1][_y - 1];
                    mazeSegment[2][0] = maze[_x + 2][_y + 1];
                    mazeSegment[2][1] = maze[_x + 2][_y];
                    mazeSegment[2][1] = maze[_x + 2][_y - 1];
                    break;
                case 3: // West
                    mazeSegment[0][0] = maze[_x + 1][_y];
                    mazeSegment[0][1] = maze[_x][_y];
                    mazeSegment[0][2] = maze[_x - 1][_y];
                    mazeSegment[1][0] = maze[_x + 1][_y - 1];
                    mazeSegment[1][1] = maze[_x][_y - 1];
                    mazeSegment[1][2] = maze[_x - 1][_y - 1];
                    mazeSegment[2][0] = maze[_x + 1][_y - 2];
                    mazeSegment[2][1] = maze[_x][_y - 2];
                    mazeSegment[2][1] = maze[_x - 1][_y - 2];
                    break;
            }
        }

        private void RenderView()
        {
            MazeBorder();
            if (mazeSegment[0][0] == '#' || mazeSegment[0][0] == '=')
            {
                NearLeftWall();
                if (mazeSegment[0][0] == '=')
                    NearLeftDoor();
            }
            else
            {
                if (mazeSegment[1][0] == '#')
                {
                    NearLeftTurn();
                    if (mazeSegment[0][0] == '=')
                        NearLeftTurnDoor();
                }
            }
            if (mazeSegment[0][2] == '#' || mazeSegment[0][2] == '=')
            {
                NearRightWall();
                if (mazeSegment[0][2] == '=')
                    NearRightDoor();
            }
            else
            {
                if (mazeSegment[1][2] == '#')
                {
                    NearRightTurn();
                    if (mazeSegment[0][2] == '=')
                        NearRightTurnDoor();
                }
            }
            if (mazeSegment[1][1] != '#' && mazeSegment[1][1] != '=')
            {
                if (mazeSegment[1][0] == '#' || mazeSegment[1][0] == '=')
                {
                    LeftWall();
                    if (mazeSegment[1][0] == '=')
                        LeftDoor();
                }
                else
                {
                    if (mazeSegment[2][0] == '#')
                        if (mazeSegment[0][0] == '#')
                            LeftTurnBlocked();
                        else
                            LeftTurn();
                }
                if (mazeSegment[1][2] == '#' || mazeSegment[1][2] == '=')
                {
                    RightWall();
                    if (mazeSegment[1][2] == '=')
                        RightDoor();
                }
                else
                {
                    if (mazeSegment[2][2] == '#')
                        if (mazeSegment[0][2] == '#')
                            RightTurnBlocked();
                        else
                            RightTurn();
                }
                if (mazeSegment[2][1] == '#' || mazeSegment[2][1] == '=')
                {
                    FarWall();
                    if (mazeSegment[2][1] == '=')
                        FarDoor();
                }
            }
            if (mazeSegment[1][1]=='#' || mazeSegment[1][1]=='=')
            {
                NearWall();
                if (mazeSegment[1][1]=='=')
                    NearDoor();
            }
        }

        #endregion

        #region Maze Drawing Routines

        private void MazeBorder()
        {
            Clear();
            DrawLine(0, 0, 0, 150);
            DrawLine(0, 150, 150, 150);
            DrawLine(150, 150, 150, 0);
            DrawLine(150, 0, 0, 0);
        }

        private void NearLeftWall()
        {
            DrawLine(0, 0, 15, 15);
            DrawLine(15, 15, 15, 135);
            DrawLine(15, 135, 0, 150);
        }

        private void NearLeftDoor()
        {
            // TODO
            DrawLine(0, 20, 3, 23);
            DrawLine(3, 23, 3, 147);
        }

        private void NearRightWall()
        {
            DrawLine(150, 0, 135, 15);
            DrawLine(135, 15, 135, 135);
            DrawLine(135, 135, 150, 150);
        }

        private void NearRightDoor()
        {
            // TODO
            DrawLine(150, 20, 147, 23);
            DrawLine(147, 23, 147, 147);
        }

        private void NearLeftTurn()
        {
            DrawLine(0, 15, 15, 15);
            DrawLine(15, 15, 15, 135);
            DrawLine(15, 135, 0, 135);
        }

        private void NearLeftTurnDoor()
        {
            // TODO
            DrawLine(0, 23, 3, 23);
            DrawLine(3, 23, 3, 135);
        }

        private void NearRightTurn()
        {
            DrawLine(150, 15, 135, 15);
            DrawLine(135, 15, 135, 135);
            DrawLine(135, 135, 150, 135);
        }

        private void NearRightTurnDoor()
        {
            // TODO
            DrawLine(150, 23, 147, 23);
            DrawLine(147, 23, 147, 135);
        }

        private void NearWall()
        {
            DrawLine(15, 15, 15, 135);
            DrawLine(15, 135, 135, 135);
            DrawLine(135, 135, 135, 15);
            DrawLine(135, 15, 15, 15);
        }

        private void NearDoor()
        {
            DrawLine(40, 135, 40, 40);
            DrawLine(40, 40, 110, 40);
            DrawLine(110, 40, 110, 135);
            DrawCircle(85, 100, 5);
        }

        private void LeftWall()
        {
            DrawLine(15, 15, 50, 50);
            DrawLine(50, 50, 50, 100);
            DrawLine(50, 100, 15, 135);
            DrawLine(15, 135, 15, 15);
        }

        private void LeftDoor()
        {
            DrawLine(25, 125, 25, 37);
            DrawLine(25, 37, 45, 57);
            DrawLine(45, 57, 45, 105);
            DrawCircle(77, 40, 2);
        }

        private void RightWall()
        {
            DrawLine(135, 15, 100, 50);
            DrawLine(100, 50, 100, 100);
            DrawLine(100, 100, 135, 135);
            DrawLine(135, 135, 135, 15);
        }

        private void RightDoor()
        {
            DrawLine(125, 125, 125, 37);
            DrawLine(125, 37, 105, 57);
            DrawLine(105, 57, 105, 105);
            DrawCircle(77, 110, 2);
        }

        private void LeftTurnBlocked()
        {
            DrawLine(15, 50, 50, 50);
            DrawLine(50, 50, 50, 100);
            DrawLine(50, 100, 15, 100);
            DrawLine(15, 100, 15, 50);
        }

        private void RightTurnBlocked()
        {
            DrawLine(135, 50, 100, 50);
            DrawLine(100, 50, 100, 100);
            DrawLine(100, 100, 135, 100);
            DrawLine(135, 100, 135, 50);
        }

        private void LeftTurn()
        {
            DrawLine(0, 50, 50, 50);
            DrawLine(50, 50, 50, 100);
            DrawLine(50, 100, 0, 100);
            DrawLine(0, 100, 0, 50);
        }

        private void RightTurn()
        {
            DrawLine(150, 50, 100, 50);
            DrawLine(100, 50, 100, 100);
            DrawLine(100, 100, 150, 100);
            DrawLine(150, 100, 150, 50);
        }

        private void FarWall()
        {
            DrawLine(50, 50, 50, 100);
            DrawLine(50, 100, 100, 100);
            DrawLine(100, 100, 100, 50);
            DrawLine(100, 50, 50, 50);
        }

        private void FarDoor()
        {
            DrawLine(60, 100, 60, 60);
            DrawLine(60, 60, 90, 60);
            DrawLine(90, 60, 90, 100);
            DrawCircle(77, 85, 3);
        }
        #endregion

        #region IO Tools
        private void LoadMaze()
        {
            // read in the text file and convert to a string.
            string path = _mazePath + @ "\store\" + _currentLevel + ".map";
            byte[] rawBytes = _storageDev.ReadFile(path);
            char[] rawCharacters = System.Text.UTF8Encoding.UTF8.GetChars(rawBytes);
            string tmpMap = new string(rawCharacters);
            // Now split the text file into lines using the \r character from the text file
            // note this will leave the \n character at the end of each line
            string[] lines = tmpMap.Split('\r');
            // Get the header, removing the trailing \n
            string header = lines[0].TrimEnd('\n');
            // check maze version and the dimensions of the maze
            string[] bits = header.Split('|');
            string ver = bits[0];
            int width = int.Parse(bits[1]);
            int height = int.Parse(bits[2]);
            if (ver != "1.0")
            {
                throw new Exception("Maze version is incorrect");
            }
            for (int y = 1; y <= height; y++)
            {
                char[] row = lines[y].Trim('\n').ToCharArray();
                for (int x = 0; x < width; x++)
                {
                    if (row[x] == '0')
                    {
                        _x = x;
                        _y = y - 1;
                        _direction = 2;
                    }
                    maze[x][y-1] = row[x];
                }
            }
        }
        #endregion

        // Bitmap tools
        #region Bitmap Tools
        public void Clear()
        {
            _view.Clear();
        }

        public void SetColour(string colour)
        {
            switch (colour.ToLower())
            {
                case "yellow":
                    _currentColour = Colors.Yellow;
                    break;
                case "red":
                    _currentColour = Colors.Red;
                    break;
                case "black":
                    _currentColour = Colors.Black;
                    break;
                default:
                    _currentColour=Colors.White;
                    break;
            }
        }
        
        public void DrawLine(int x1, int y1, int x2, int y2)
        {
            _view.DrawLine(_currentColour, 1, x1, y1, x2, y2);
        }

        public void DrawCircle(int x, int y, int radius)
        {
            _view.DrawEllipse(_currentColour, x, y, radius, radius);
        }
        #endregion
    }
}