Using a Tile Class
Using a Tile Class
Using a Tile Class
Using a Tile Class
Using a Tile Class
Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class
Using a Tile Class Using a Tile Class
Using a Tile Class
Go Back  Xtreme Visual Basic Talk > > > Using a Tile Class


Reply
 
Thread Tools Display Modes
  #1  
Old 11-05-2012, 01:35 PM
VB_Alien VB_Alien is offline
Senior Contributor
 
Join Date: Apr 2004
Posts: 854
Default Using a Tile Class


I'm trying to get away from using structure arrays,
in hopes that by using a class, i wouldn't have to
keep typing in all the structure properties, every time
i use them. By using a class, everything needed is
already there and all i have to do is include it in my
program.

The thing is, i have never worked with them before
and i need some advice on how a class should be used.

When i use structures, i have to make a tile structure and
a map structure array and then pass the tile properties to
to map properties.

Is this how a class object works to?

Would i have to make a tile class and a map class and
then pass properties from the tile class to the map class?

***On a side note***

I was using RpgMaker today and i ran the game i made
and i noticed that my character could walk over top of
a tree. I shut down the game and went to the editor and
to the tilesets and set the 2 bottom portions of the tree to
not walkable. Then i started my game again and my character
couldn't walk through the bottom parts of the tree but it could
still walk over the top portions of the tree. I went back and
set the 2 top portions of the tree as a new layer and started
the game again. This time, i couldn't walk through the bottom
parts of the tree and the 2 top parts of the tree, me character
was standing behind them.

I didn't recopy the tree tiles to the map, i only changed the
tile properties. This is how i would like to set my editor up
to do.

What is involved in doing this? Some sort of (update map)
sub routine?
Reply With Quote
  #2  
Old 11-05-2012, 08:23 PM
passel's Avatar
passelUsing a Tile Class passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

No, not a map update routine. What you updated was the tile, so the properties would be part of the tile (whether structure or class, there isn't much difference in the basic construction, so if you have a structure, it could be converted to a class fairly easily).
The base map should be a very basic (simple) thing since you have to have a large array of them. Ideally, it would be a simple array of a single primitive type, like an integer, that was a "pointer" or key to what object was at that location. The object at that location would have all the attributes, such as walkable, and level, and image, or portal, etc.
So you wouldn't have to recopy the tree tiles to the map, they were already associated with some location on the map. You just change the property of the tree and when you walk into a tile with a tree, it checks the object to see if it is passable, or whether it should be drawn before the player, or after.

Expanding a little on what I said about class and structure, while there isn't much difference in basic constructure and how they are referenced in code, there are difference in what can be done with them, how they are instantiated (created), and the purpose for choosing one over the other. You may very well want to use both in some cases.
A structure is more rigid, and is best for things that won't need to come and go. They are a value object, rather than a reference object, so have more overhead if you want to pass them as parameters to a subroutine. You can't inherit from structures, so you can't use them as the basis for an extended type (other than copy and pasting the code into a new structure).
They are allocated in different areas of programming memory, and there are considerations there.
Since there are numerous tutorials, and discussions elsewhere, I'm not going to go on about it here.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 11-05-2012 at 08:35 PM.
Reply With Quote
  #3  
Old 11-05-2012, 10:02 PM
VB_Alien VB_Alien is offline
Senior Contributor
 
Join Date: Apr 2004
Posts: 854
Default

Because of it's portability, i heard that using classes
is a much better way to go, when basically using the
same code in a lot of other projects.

Instead of retyping everything, every time i make a
new project, i just grab the relevant class and drop it
in my project and i'm ready to go.

As for your explanation of how a class and class properties
work, i'm not sure that i follow you but i'll take a stab at it.

If i understood you right, your saying the - lets say the tile class,
will hold all the tile information. This would include things like grass -
tree - house - water and other stuff like, Isanimated - walkable -
isTransparent, things like that.

Again, if i understood you correctly, the only properties that i should
be putting in the map class is it destination x and y - source x and y
locations.

After an actual game is made with the map, a sub routine in the game
code will check the tile properties and act accordingly.

Did i get it right or do i need another lesson?

Also, if you would, could you look at my tile class and tell me if i
layed it out right? Thank-you

Code:
Public Class Tiles

    Private _DestX As Integer
    Private _DestY As Integer
    Private _SourceX As Integer
    Private _SourceY As Integer
    Private _Walkable As Boolean
    Private _Layer As Integer
    Private _Transparent As Boolean

    Public Property DestX As Integer
        Get
            Return _DestX
        End Get

        Set(value As Integer)
            _DestX = value
        End Set
    End Property

    Public Property DestY As Integer
        Get
            Return _DestY
        End Get

        Set(value As Integer)
            _DestY = value
        End Set
    End Property

    Public Property SourceX As Integer
        Get
            Return _SourceX
        End Get

        Set(value As Integer)
            _SourceX = value
        End Set
    End Property

    Public Property SourceY As Integer
        Get
            Return _SourceY
        End Get

        Set(value As Integer)
            _SourceY = value
        End Set
    End Property

    Public Property Layer As Integer
        Get
            Return _Layer
        End Get

        Set(value As Integer)
            _Layer = value
        End Set
    End Property

    Public Property Walkable As Boolean
        Get
            Return _Walkable
        End Get

        Set(value As Boolean)
            _Walkable = value
        End Set
    End Property

    Public Property Transparent As Boolean
        Get
            Return _Transparent
        End Get

        Set(value As Boolean)
            _Transparent = value
        End Set
    End Property
End Class
Do i even need the source and dest x and y
properties in a tile class?
Reply With Quote
  #4  
Old 11-06-2012, 05:18 PM
passel's Avatar
passelUsing a Tile Class passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

To be honest, I'm not that strongly into implementing classes, so I tend to keep things simple. For instance, in my mind the reason to implement properties in a class is to control access to the members, verify limits, disallow assignments that would break your class. These are all good things, especially if you're creating a class to be used by others, but in a lot of cases, the code I see is simple Gets and Sets, without any guard code at all, and if that is all the property is going to do, then I would just make the member public and not have to generate all the property code to provide public access to private members.
If the class was a control, then that would probably be a different matter, since the properties would probably be exposed in the IDE, but I don't know for sure. I'm not well indoctrinated into the proper or expected uses of classes, so if you want proper advice, I'm not the one to ask.
Game programming is a bit of a different animal to a lot of other types of programming, so the rules are different. Ideally, you would want a language that gave you enough control, or was geared toward not generating garbage, so you could layout all your buffers and other working areas, and your memory footprint would be set and your process would not have to worry about arbitrary interruptions by the runtime environment to do garbage collection.
Arcade type games in a .Net Managed environment will always have those issues.
Anyway, off track a bit.
Whether you need source and dest x and y properties in a tile class I guess depends on what they are used for. I don't know if you've looked at my "503" example elsewhere, and I'm not sure what the last version I posted even contains, struture or class wise, but I'll use some code from a version to illustrate a use of class and structure, but by no means a definitive example. They served the purpose I wanted as this particular project evolved, but are just exploratory, and are stepping stones to something better down the road.
First, lets look at a structure from that code.
Code:
Public Structure TileObjectType
  Public id As Integer                                'This is the index in the object array where this object is stored. Our linked list uses this.
  Public PrevObj As Integer                           'The id of an object linked in "front" of this object
  Public NextObj As Integer                           'The id of an object linked "behind" this object
  Public TileRect As Rectangle                        'The position and size of this object (for drawing, and perhaps eventually hit test, etc).
  Public bmpId As Integer                             'The index into the spriteBmps list of the bitmap associated with this object
  Public DrawSelectionRectangle As Boolean            'Will draw a white rectangle around the object if this is set true
  Private BaseX As Short                              'The game area is divided into a grid (256x256) squares, each square being 1024x1024 pixels
  Private BaseY As Short                              'These two values (BaseX,BaseY) identify what square this object is currently in
  Public Shared spriteBmps As New List(Of Bitmap)     'The bitmaps that these objects share.  Only one copy of the bitmap itself.
  Public Shared bmpCnt As Integer                     'Keep track of how many bitmaps we have stored in our list (without having to access the list)
  Public Shared UnlinkedList As Integer

  Public Shared Sub init()
    'Initial the blocks to indicate nothing is linked to them.
    For i As Integer = 0 To 255
      For j As Integer = 0 To 255
        Game.BaseTileObjects(i, j) = -1
      Next
    Next
  End Sub

  Public Sub LinkTile()
    Dim bx, by As Short
    Dim FirstObj As Integer

    bx = CShort(Game.GameToBlock(TileRect.X))    'determine which block it falls in
    by = CShort(Game.GameToBlock(TileRect.Y))
    BaseX = bx                              'Save the block coordinates that we are linked to, so we can unlink
    BaseY = by                              'if we're at the front of the list

    FirstObj = Game.BaseTileObjects(bx, by)
    If FirstObj <> -1 Then                  'If this block has at least one object linked to it Then
      Game.gameObjects(FirstObj).PrevObj = id    '  Link me to it as a predecessor
    End If
    NextObj = FirstObj                      'Link the first obj to me as a successor
    PrevObj = -1                            'I'm at the beginning, no other objects before me
    Game.BaseTileObjects(bx, by) = id            'Link the block base link to me
  End Sub

  Public Sub unLinkTile()
    If PrevObj = -1 Then     'if we're at the front of the list then
      Game.BaseTileObjects(BaseX, BaseY) = NextObj  'link our nextObj to the base link
    Else
      Game.gameObjects(PrevObj).NextObj = NextObj   'link my next obj to the previous object's NextObj
    End If
    If NextObj <> -1 Then
      Game.gameObjects(NextObj).PrevObj = PrevObj   'link my Prev obj to the next objects PrevObj
    End If
  End Sub

  Public Shared Sub AddBmp(ByRef b As Bitmap)
    spriteBmps.Add(b)            'Add a bitmap to our List of objects we can draw
    bmpCnt = spriteBmps.Count    'Make the total publicly available
  End Sub

  Public Sub DefineTile(bmpIdx As Integer, x As Integer, y As Integer)
    bmpId = bmpIdx                                                                    'Associate the list index of the bitmap with this object
    TileRect = New Rectangle(x, y, spriteBmps(bmpId).Width, spriteBmps(bmpId).Height) 'save the object location and size information
    LinkTile()
  End Sub

  Public Sub Draw(ByVal g As Graphics)
    Dim dx As Integer, dy As Integer

    'The "player"'s position is always in the center of the window
    'This code will compare this object's position to the player's, and if it is close enough
    'to possibly be visible on screen, it draws itself.

    'This if block prevents cars from disappearing as we transition the edges of our world
    'Since this example is designed to wrap seamlessly rather than stop at the edge, when we near
    'the edge of our world we have to see the things at the opposite end of our world.
    'The world is 262,144 pixels by 262,144 pixels, so when we are at the edge of our world,
    'objects on the other side of the divide are around 262,000 pixels away mathematically.
    'This check will "wrap" the coordinates that fall in a 2,144 band (Game.GameSize-260000) at the edges to
    'make them relative to the object (i.e. the relative coordinate will be in the range of +/- 2,144)
    'Same logic is done for the dy value.

    dx = TileRect.X - CInt(Game.fLocationX) 'Compute my position, relative to the "player"
    If dx < -260000 Then
      dx += Game.GameSize
    ElseIf dx > 260000 Then
      dx -= Game.GameSize
    End If

    dy = TileRect.Y - CInt(Game.fLocationY)  'Compute my position, relative to the "player"
    If dy < -260000 Then
      dy += Game.GameSize
    ElseIf dy > 260000 Then
      dy -= Game.GameSize
    End If

    'If the relative coordinate is in the range (-500 to 500) it is drawn, relative to the center of the screen (where the player is).
    'Since the screen area of the form is limited to a number less than 700, the distance from center to edge is less than 350.
    'Assuming 350, an offscreen object at 500 pixels away could have a radius up to a 150 pixels and still not "flash" into view. 

    If Math.Abs(dx) < 500 And Math.Abs(dy) < 500 Then   'Anything more than 500 axis pixels away are out of sight, don't draw them
      With Form1.picPlayer
        g.DrawImage(spriteBmps(bmpId), dx, dy)
        If DrawSelectionRectangle Then
          g.DrawRectangle(Pens.White, dx, dy, TileRect.Width, TileRect.Height)
        End If
      End With
    End If
  End Sub
End Structure
A thing to note is that the structure contains data, a lot of it public so the "game" logic can get to it easily, and some of it Shared, so there is only one instance of that particular thing, which is part of the "class", not part of an instance of the "class".
Another thing to note, is I can change this structure to a class simply by changing the word "Structure" at the top and bottom to "Class".
If I run the code after this change, I will get a null instance exception the first time I try to initialize members of the class, which will point out the spot where I need to add one line to create an instance of the class, before I try to do anything with it.

{Split the post into two parts because it exceeded the 10000 character limit by a fair amount.
So, continue below.}
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #5  
Old 11-06-2012, 05:19 PM
passel's Avatar
passelUsing a Tile Class passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Code:
    For i As Single = 0 To 780
      For j As Single = 0 To 780
        ' Game.gameObjects(k) = New TileObjectType    'If you change "Structure" to "Class", you have to instantiate an object
        Game.gameObjects(k).id = k                        'The index into the GameObject array serves as our "pointer" to the structure, so we save it for reference
        x = sr.Next(262140)
        y = sr.Next(262140)
        Game.gameObjects(k).DefineTile(sr.Next(TileObjectType.bmpCnt), x, y)  'assign a random bitmap from our list to this location
        k += 1                                                 'Increment our object count (used as a unique Id number, and index into our object array)
      Next
    Next
After that one line is added (the commented out line above with "New" in it), the code runs and works as it did before.
The code above scatters 609961 objects (of our TileObject Structure, or Class) randomly across a 262140 x 262140 pixel game area.
It originally did the random scatter in a more orderly grid fashion, hence the nested i,j loop (although the i,j usage has been removed). So, the same result could now come from simply having a single loop, "For k = 0 to 609960" and remove the "k += 1" from inside the loop.
So, how are we keeping track of these 609+ thousand objects scattered around the gaming area. Well, there is a Class called Game, which you see above as Game.this and Game.that. This is a "Static" class, in that all the members and methods are declared shared so you don't have to instantiate the class. You will access it through the class name (just like Math.Sin, Math.Cos, etc..).
In this case, the Game Class has an array of the TileObjectType (whether Class or Structure), and this array is dimensioned to allow up to one million of these objects to exist. So, that is an arbitrary limit imposed on this particular game, no more than one million objects can exist at a time (it is not really a game, just an exploration of placing a large number of items over a large virtual area, and being able to move through, the area, draw the area, and select objects in an efficient manner).
The "DefineTile" method that is being called does a few things.
1. It assigns a random bitmap, of arbitrary size, from a list of bitmaps to the object.
2. It places the object at a random point in the 262144 x 262144 pixel gaming area.
3. It updates a rectangle that is part of the class/structure that defines that location and size (based on the selected bitmap size).
4. It updates a 256 x 256 array of integers, which logically divides the 262144 x 262144 area into smaller 1024 x 1024 pixel blocks. The 256 x 256 array's values are essentially a link to the last object that randomly fell into that 1024 x 1024 pixel block. The previous "last object" that fell in that block is linked to the latest object added to the block. So if you determined that you need to draw the objects in that 1024 x 1024 pixels block because part of the block is visible on the screen, you would just traverse the list and draw those objects. On average, this allows you to ignore 99.97% of the 609+ thousand objects when drawing or doing pick testing, or collision testing with your player. You only need to look at the stuff near you.

Does that answer your question about source and dest x,y? I don't know. Does it help your understanding of a tile class?, probably not. There are so many different ways to organize and accomplish a goal, there is no single right or best answer.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.

Last edited by passel; 11-06-2012 at 05:36 PM.
Reply With Quote
  #6  
Old 11-06-2012, 09:12 PM
VB_Alien VB_Alien is offline
Senior Contributor
 
Join Date: Apr 2004
Posts: 854
Default

I think i got more of a lesson about structures than
i did using classes. I had no idea that a structure
could have so much complicated code inside of it.

I thought it's only purpose was to hold properties
of a numerical, boolean and string, nature. I really
got wowed by your structure example. Thank-you.

I see classes setup like that all the time but i had
no idea a structure could do the same thing.

Anyway, i think you are right. There isn't any certain
one way to layout a class. It all depends on the nature
of the program, that will be using it.

I've got a hint on how i may start my class and use it.

Thanks for helping me.
Reply With Quote
  #7  
Old 11-07-2012, 12:01 AM
Rockoon's Avatar
Rockoon Rockoon is offline
Joseph Koss

* Guru *
 
Join Date: Aug 2003
Location: Unfashionable End
Posts: 3,615
Default

The real difference between structures and classes is only that classes are considered reference types and structures are considered value types.

The emergent differences in performance, capability, overhead, and usage patterns all stem from enforcing the reference vs value type policy. Think of it like having two different drivers in otherwise identical cars.

My "rule of thumb" has always been to use a class only in cases where the reference semantics are clearly necessary.

I find this policy to be beneficial because now simply knowing whether something is a class or not conveys important information to me, primarily that mutating a structure variable will never cause side-effects with other variables in other parts of the program, and that mutating a class variable almost certainly will cause side-effects with other variables in other parts of the program (those side-effects are usually desired, or else it would have been a structure)
Reply With Quote
  #8  
Old 11-07-2012, 06:28 AM
passel's Avatar
passelUsing a Tile Class passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

A common error, illustrating some of what Rockoon is saying, is this.
Say you have two variables, a and b defined as being of type myObject.
If you do :
a = b
a.This = something
a.That = somethingElse

If myObject was a structure, then a was set to a copy of b, and when you change the value of some members of a, it has no effect on b, which is what a novice programmer would expect.
But, if myObject was a class, then b is a reference to an instance of myObject (assuming it was instantiated).
a = b now makes "a" a reference to the same object that b was referencing.
Now when the you change member values using "a", if you use "b" to look at the members you will see they have "also changed". Of course, they didn't "also change", since a and b are referencing (or pointing to) the same object, you've change the object pointed to by a and b. You didn't change a or b itself.
In the case of a structure, logically a and b do not point to a structure, they are copies of the structure, and modifying "a" modifies structure "a", and modifying "b" modifies structure b.

So structures are better than classes right? No. Each serves its purpose.
Creating linked lists, or binary trees, or organizing objects in multiple views require "pointers" or references to objects, so are easier and cleaner to do by using reference types, i.e. class objects.
You can create linked lists, binary trees or other reference type organizational structures using structures, but that involves creating an array of structures and using the array index to a given element of the structure as the "reference" or pointer to an object. While I've done this, and still do this, to provide "references" to structures, it can add an additional level of hierarchy in a line of code using the "reference" that wouldn't be necessary with a class object, and can look awkward.

Another observation that I didn't mention, and probably shouldn't influence the decision when choosing structures vs classes, is that the code I referenced above has a running memory footprint of around 51 MB when using an array of one million of those structures, and because they are structures, the memory for all one million is allocated.
When I change the structure to a class, now the memory for the objects are not preallocated, only the million references. So the loop instantiates 609+ thousand of the objects, and the memory footprint of the running executable is around 63 MB.
So, a class object will require more memory per object than a structure, because of the flexible nature of class objects. But, if you have very dynamic number of object requirements, where they come into being, and then are disposed of, your memory footprint can grow and shrink as necessary with class objects, whereas using structures, expanding and shrinking an array of them could be done, but is more work and probably slower than doing what class objects do naturally.
In a gaming environment, you generally would want to avoid dynamic growing and shrinking of your game's resource requirements anyway, since that is taking time away from the game itself.
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #9  
Old 11-07-2012, 07:32 PM
VB_Alien VB_Alien is offline
Senior Contributor
 
Join Date: Apr 2004
Posts: 854
Default

This is some very useful information, so i have copied
it all and put it in notepad, for future reference.

Basically, all i wanted to use a class for was for portability
reasons. Instead of typing and retyping a structure, every
time i wanted to make a different program, i just wanted to
be able to drop in a tile and map class, into the program and
i'm all set to go.

This seems to be working, having a public structure inside a
public class, so i think i'll stick with this for now. I'm not using
them in games right now, just map editors and i don't think there
is much chance of those 2 classes, hogging up memory.

The code is a lot neater looking when you don't have 2 or more
structures, typed out, right in the main form. All you do from there
is to dimension your structures with one or 2 very small dimming
statements and they are ready to receive data.

I'm happy with what i have learned and i thank all of you for your
input.
Reply With Quote
  #10  
Old 11-08-2012, 03:41 PM
passel's Avatar
passelUsing a Tile Class passel is offline
Sinecure Expert

Super Moderator
* Guru *
 
Join Date: Jun 2003
Location: Upstate New York, usa
Posts: 8,024
Default

Just because you had structures, they didn't have to be typed right in the top of the main form. They could always have been in a separate file, for reuse, or decluttering.
Code:
'The code in "Form1.vb"
Public Class Form1
  Dim Flintstone As Struct1
  Dim Rubble As Struct2

  Private Sub Button1_Click(sender As System.Object, e As System.EventArgs) Handles Button1.Click
    Flintstone.Wilma = 1.5
    Flintstone.Fred = CInt(3 * Flintstone.Wilma)
    Debug.Print(Flintstone.Fred.ToString)
    Debug.Print(Rubble.Barney.ToString)
  End Sub
End Class



'=============== The code in Struct1.vb ====================
Public Structure Struct1
  Public Fred As Integer
  Public Wilma As Single
End Structure

Public Structure Struct2
  Public Barney As Boolean
  Public Betty As Short
End Structure
Decided to add a second structure so the name of the file being struct1.vb doesn't really fit.
Should be something less specific like "BedrockCouples.vb"
__________________
There Is An Island Of Opportunity In The Middle of Every Difficulty.
Miss That, Though, And You're Pretty Much Doomed.
Reply With Quote
  #11  
Old 11-08-2012, 05:48 PM
VB_Alien VB_Alien is offline
Senior Contributor
 
Join Date: Apr 2004
Posts: 854
Default

So. It looks like the structures are in a
module now and not a class. Jeeessss,
why didn't i think of that. LOL
Reply With Quote
  #12  
Old 11-08-2012, 06:16 PM
Rockoon's Avatar
Rockoon Rockoon is offline
Joseph Koss

* Guru *
 
Join Date: Aug 2003
Location: Unfashionable End
Posts: 3,615
Default

Another thing you may use some day is the fact that you may also nest structure definitions:

Code:
Public Structure GameState
  ...
  Public Structure GameEntity
    ...
  End Structure

  Public Structure GameTile
    ...
  End Structure

  Public npcs As List(Of GameEntity)
  Public map As List(Of List(Of GameTile))

End Structure
Reply With Quote
Reply


Currently Active Users Viewing This Thread: 1 (0 members and 1 guests)
 
Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is Off
HTML code is Off

Forum Jump

Advertisement:





Free Publications
The ASP.NET 2.0 Anthology
101 Essential Tips, Tricks & Hacks - Free 156 Page Preview. Learn the most practical features and best approaches for ASP.NET.
subscribe
Programmers Heaven C# School Book -Free 338 Page eBook
The Programmers Heaven C# School book covers the .NET framework and the C# language.
subscribe
Build Your Own ASP.NET 3.5 Web Site Using C# & VB, 3rd Edition - Free 219 Page Preview!
This comprehensive step-by-step guide will help get your database-driven ASP.NET web site up and running in no time..
subscribe
Using a Tile Class
Using a Tile Class
Using a Tile Class Using a Tile Class
Using a Tile Class
Using a Tile Class
Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class Using a Tile Class
Using a Tile Class
Using a Tile Class
 
Using a Tile Class
Using a Tile Class
 
-->