Computer Science Canada

Map Maker

Author:  Prince Pwn [ Thu Jul 29, 2010 7:38 pm ]
Post subject:  Map Maker

This isn't complete but I was without internet access for a day and got bored. I was working on a Plants VS Zombies type game but this can also be altered into a map maker for any game. I only have the two left red tiles that are clickable and after you click on them, you can then click on the grid and "plant" different elements in each square. I plan to of course add graphics and clean up the code, but this is just so cool in my opinion I thought I'd share. I also plan to write out the grid into a file which would allow you to easily create game maps and save them, etc.

Turing:


% Plants vs Zombies
% by princepwn

type GRID :                 % Datatype making up each tile element
    record
        ID : int            % Unique ID
        STARTX : int        % Starting X
        STARTY : int        % Starting Y
        ENDX : int          % Ending X
        ENDY : int          % Ending Y
        PALLET : boolean    % If tile is clickable
        CONTENTS : string   % Whats in the tile
        COLOR : int         % Color of tile
    end record

const tileWidth : int := 10                                 % Number of spaces widthh-wise
const tileHeight : int := 7                                 % Number of spaces height-wise
var tile : array 0 .. tileWidth, 0 .. tileHeight of GRID    % Storage for entire tile
var tileSize : int := 50                                    % Size of each tile
var tileID : int := 0                                       % Save the tile ID

var selectedX, selectedY : int := 0                         % Report back clicked position
var selectedXY : string := ""                               % Report back current tile
var currentPlant : string := "EMPTY"                        % Selected plant
var warning : string := "(none)"
var solarPower : int := 50

var palletTile : array 0 .. tileWidth - 1 of int            % Pallet size for selecting plants
tile (0, 0).STARTX := 1                                     % Start tile at left
tile (0, 0).STARTY := 1                                     % Start tile at bottom

% Save tile data
for y : 0 .. tileHeight                                     % Go up and down through field
    for x : 0 .. tileWidth                                  % Go from left to right through field
        tileID += 1                                         % Increment counter
        tile (x, y).ID := tileID                            % Save tile ID
        tile (x, y).STARTX := x * tileSize                  % Tile's X location
        tile (x, y).STARTY := y * tileSize                  % Tile's Y location
        tile (x, y).ENDX := tile (x, y).STARTX + tileSize   % Ending X
        tile (x, y).ENDY := tile (x, y).STARTY + tileSize   % Ending Y
        tile (x, y).PALLET := false                         % Set all tiles to non-pallet
        tile (x, y).COLOR := white                          % Default color is white
        tile (x, y).CONTENTS := "EMPTY"                     % Each tile is empty
    end for
end for

% Output debugging info
var debugWindow := Window.Open ("graphics:900,10;position:30,450;offscreenonly")
% Default screen size *alligns tiles*
var gameWindow := Window.Open ("graphics:" + intstr ((tileWidth * tileSize) + 1) +
    "," + intstr ((tileHeight * tileSize) + 1) + ";position: 30,50;offscreenonly")

% Elements of creatures
type plant :
    record
        name : string
        health : int
        range : int
        power : int
        cost : int
        coords : string
    end record

% Assigning status to creatures
var peaShooter : plant
peaShooter.name := "Pea Shooter"
peaShooter.health := 10
peaShooter.range := tileWidth
peaShooter.power := 2
peaShooter.cost := 50

var peaShooter2 : plant
peaShooter2.name := "Pea Shooter 2"
peaShooter2.health := 15
peaShooter2.range := tileWidth
peaShooter2.power := 4
peaShooter2.cost := 100

var mouseX, mouseY, button, left, middle, right : int   % Keep track of mouse
Mouse.ButtonChoose ("multibutton")                      % Allows middle and right click
var keys : array char of boolean                        % Key input

loop

    Mouse.Where (mouseX, mouseY, button)    % Obtain mouse information
    left := button mod 10                   % left = 0 or 1
    middle := (button - left) mod 100       % middle = 0 or 10
    right := button - middle - left         % right = 0 or 100

    Input.KeyDown (keys)                    % Watches for keyboard input

    % Tile drawing and manipulation
    for y : 0 .. tileHeight                 % Columns
        for x : 0 .. tileWidth              % Rows

            if (tile (x, y).CONTENTS = "EMPTY") then    % Is square empty
                tile (x, y).COLOR := white              % Set color to white
            elsif (tile (x, y).CONTENTS = "Pea Shooter") then        % Is square empty
                tile (x, y).COLOR := green
            elsif (tile (x, y).CONTENTS = "Pea Shooter 2") then        % Is square empty
                tile (x, y).COLOR := brightgreen
            end if

            if (tile (x, y).CONTENTS not= "EMPTY") then   % Is square occupied (been clicked)
                %tile (x, y).COLOR := black              % Set color to black
            end if

            Draw.FillBox (tile (x, y).STARTX, tile (x, y).STARTY,
                tile (x, y).ENDX, tile (x, y).ENDY, tile (x, y).COLOR) % Draw tile

            % Clickable pallet
            if (y = 0) then
                tile (x, y).PALLET := true
                Draw.FillBox (tile (x, y).STARTX, tile (x, y).STARTY, tile (x, y).ENDX, tile (x, y).ENDY, brightred)
                if (button = 1) then
                    %palletTile (y) := Pic.New (tile (x, y).STARTX, tile (x, y).STARTY, tile (x, y).ENDX, tile (x, y).ENDY)
                end if
            end if

            % Highlighted square
            if (mouseX > tile (x, y).STARTX and mouseX < tile (x, y).ENDX) and
                    (mouseY > tile (x, y).STARTY and mouseY < tile (x, y).ENDY) and
                    (mouseX < maxx and mouseY < maxy) then
                selectedX := x
                selectedY := y
                selectedXY := intstr (x) + "," + intstr (y)

                if left = 1 then

                    warning := ""

                    % Selecting a plant
                    if (selectedY not= 0) then
                        tile (x, y).CONTENTS := currentPlant
                    elsif (selectedXY = "0,0") then
                        currentPlant := "Pea Shooter"
                    elsif (selectedXY = "1,0") then
                        currentPlant := "Pea Shooter 2"
                    end if

                    % Warnings
                    if (selectedY not= 0 and tile (x, y).CONTENTS = "EMPTY") then
                        warning := "Please select a plant first!"
                    elsif (selectedY not= 0 and tile (x, y).CONTENTS not= "EMPTY") then    %%%%%%%%%%FIXXXXX
                        %warning := "Spot already taken!"
                    end if

                    %solarPower -= tile(x,y).CONTENTS

                    % Cost of plants
                    if tile (x, y).CONTENTS = "Pea Shooter" then
                        solarPower -= peaShooter.cost
                    elsif tile (x, y).CONTENTS = "Pea Shooter 2" then
                        solarPower -= peaShooter2.cost
                    end if

                    %Draw.FillBox (tile (x, y).STARTX, tile (x, y).STARTY, tile (x, y).ENDX, tile (x, y).ENDY, brightred)
                    %Pic.Draw (palletTile (y), tile (x, y).STARTX, tile (x, y).STARTY, picCopy)
                end if
                if right = 100 then
                    tile (x, y).CONTENTS := "EMPTY"
                end if
                if button = 0 then
                    %Draw.FillBox (tile (x, y).STARTX, tile (x, y).STARTY, tile (x, y).ENDX, tile (x, y).ENDY, brightblue)
                end if
            end if


            if not (keys (' ')) then
                % Debugging purposes
                Window.Select (debugWindow)
                cls
                /*"Mouse X: " + intstr (mouseX) + " Mouse Y: " + intstr (mouseY) + */
                Font.Draw (" Current Tile: " + selectedXY +
                    " Contents: " + tile (selectedX, selectedY).CONTENTS +
                    " Selected: " + currentPlant + " Sun: " + intstr (solarPower) +
                    " Warning: " + warning, 10, maxy - 20, defFontID, black)

                Window.Update (debugWindow)
                Window.Select (gameWindow)
            end if


            % Square outline
            Draw.Box (tile (x, y).STARTX, tile (x, y).STARTY, tileSize, tileSize, black)


        end for
    end for

    %Draw.FillBox (mouseX - tileSize div 10, mouseY - tileSize div 10, mouseX + tileSize div 10, mouseY + tileSize div 10, brightred)         % Outlines box size of tile on cursor

    View.Update
    cls

end loop

Author:  SNIPERDUDE [ Fri Jul 30, 2010 1:27 pm ]
Post subject:  RE:Map Maker

I found tile type selection to be a bit confusing, I had to scan the code to figure it out.

Author:  Tony [ Fri Jul 30, 2010 2:01 pm ]
Post subject:  RE:Map Maker

code:

elsif tile (x, y).CONTENTS = "Pea Shooter 2" then

This is a problem known as magic numbers, or in this case -- string literals.

This is a problem because when Michael Jackson's estate comes along and tells you to remove a character from your game, you have many references to find and "fix".

enums are a better approach. http://en.wikipedia.org/wiki/Enumerated_type

Strictly speaking, storing and comparing small integers is much more optimal. And since you are doing 140~280 such comparisons per frame, it might actually have a measurable impact.

Also
code:

            if (tile (x, y).CONTENTS not= "EMPTY") then   % Is square occupied (been clicked)
                %tile (x, y).COLOR := black              % Set color to black
            end if

This isn't doing anything.


: