Discussion: How to create a memory game with dart and canvas

614 views
Skip to first unread message

Dart Learn

unread,
Sep 21, 2012, 4:37:41 AM9/21/12
to dartga...@googlegroups.com
This is about the project to learn dart in a group while developing games or other projects.

a) Memory game 

This game is about finding matching identical images. You have 8 different images. In a 4x4 (16 fields) matrix every and each image will be doubled (8x2=16). The goal is to find the matching identical images which are hidden. 


Not much of dart code but it's an easy starter und we will need canvas.

for the canvas beginners:

I am still reading about canvas, but
would this be a good approach to create the memory game?

Memorygame has 8 different images. Therefore we need a 4x4 grid (16 fields = 8 images each doubled)
Since there is no real implemented grid in cavas we create a 800px * 800px canvas.
We draw 5 horizontal and 5 vertical lines. We can now see 1 big box with 16 smaller "boxes" each 200px * 200px.
But canvas doesn't know anything about those boxes. There are no REAL boxes or rectangles yet.
Canvas knows only about onMouseDown (the position of mousecourser).
Therefore we create a class Box and create 16 Box objects. Every of those objects would be assigned
to draw a rectangle in one of the 16 grid boxes.

1-2-3-4
5-6-7-8
9-10-11-12
13-14-15-16

(origin X, origin Y, width, height)
The first object would draw its rectangle at 0,0,200,200 
The second object would draw its rectangle at 200,0,200,200
The 16th object would draw its rectangle at 600,600,200,200

Hmm actually we do not need those 5 horizontal and vertical lines, now we have the real rectangles "boxes".
Every box object needs an imageElement and id. To find identical images we would check for identical ids of the box objects.
I think the images and ids should be assigned on the creation of the box objects. So how do we assign to each object an image 
but track that the same image(also the same id of a box) can only be assigned to 2 boxes? How do we randomize the position/appearence of images within the canvas?

How to display an image for a clicked box?
There should always be a pair of clicks. 
The first click on one of the boxes would display the first image that is assigned to to that area of canvas
x=300, y=100 would be the second box. So display image of box2, keep the image visible.
The second click should display the second image. Now we see both images displayed for 2 sec. 
We check if the box ids are identical ( would mean identical images).
Where do we save lastClick(firstClick) and actualClick(secondClick)?
If images identical, keep them visible and flag both boxes to not react on any onMouseDown for them.
Clear the pair of clicks.
If images not identical show the original rectangles of the objects, clear the pair of clicks.
Keep on playing.

Those are just my first thoughts. It is meant to kick off the discussion. Everything is open to be changed if someone has a
better idea. Do not be shy :)

Dzenan Ridjanovic

unread,
Sep 25, 2012, 9:11:20 PM9/25/12
to dartga...@googlegroups.com
Very useful beginning of the game design. My comments:

>Hmm actually we do not need those 5 horizontal and vertical lines, now we have the real rectangles "boxes"?

We would not probably need lines.


>Every box object needs an imageElement and id. To find identical images we would check for identical ids of the box objects. I think the images and ids should be assigned on the creation of the box objects.

If the model is created first, images and ids would be assigned at the model level.

>So how do we assign to each object an image but track that the same image (also the same id of a box) can only be assigned to 2 boxes?

Only two cells of the same memory may use the same photo image.


>How do we randomize the position/appearence of images within the canvas?

In the dart:math library there is the Random class.

http://api.dartlang.org/docs/continuous/dart_math/Random.html


>How to display an image for a clicked box?

An image of the ImageElement type is created by querying the page.
ImageElement image = document.query('#image');

The context of the canvas has the method drawImage.
board.context.drawImage(image, x, y, width, height);


>There should always be a pair of clicks.
The first click on one of the boxes would display the first image that is assigned to to that area of canvas
x=300, y=100 would be the second box. So display image of box2, keep the image visible.
The second click should display the second image. Now we see both images displayed for 2 sec.
We check if the box ids are identical ( would mean identical images).

>Where do we save lastClick(firstClick) and actualClick(secondClick)?

Board may have two properties for those two clicks.


>If images identical, keep them visible and flag both boxes to not react on any onMouseDown for them.
Clear the pair of clicks.
>If images not identical show the original rectangles of the objects, clear the pair of clicks.
Keep on playing.
 

-----------------------------------------------------------------------------------------------------------------------------------------------------

I am a big proponent of domain models.

http://programmers.stackexchange.com/questions/163185/torvalds-quote-about-good-programmer

Thus I propose that we discuss also a model of the game.

https://dl.dropbox.com/u/161496/dart/game/game_memory/game_memory.png

In this model, there are 4 concepts: Catalog, Memory, Cell and Photo.

There is no need to use the Catalog concept. However, the game would allow us to have at least one catalog (for example, the travel catalog) with a collection of photos from our trips. We would use those pictures to create appropriate images.

A catalog’s id is its name (bold and italics). A description is optional (not bold).

A photo’s id consists of the sequence number within the catalog’s name. A photo’s width and height are optional properties, since they may be derived from the image stored somewhere on the Web. A size may be small, medium or large, to help us select an image.

The id of a memory game is its name and the catalog’s name. A memory has a collection of cells, determined by the memory length (e.g., 4). Each cell is of the same length, which is a property of the memory (cellLength). A memory is not recalled until all image pairs are discovered. Some statistics may be kept, such as recallCount (some memories are more difficult) and the best recall time in seconds.

A cell has the row and column coordinates and also the coordinates of its twin. A hell is hidden until recalled together with its twin cell.

Once the model is discussed and improved, model views may be created: Board would be a view of the Memory concept and Box would be a view of the Cell concept. Application would be based on the Catalog concept. If there is no need to browse photos of a catalog and display them within a page, there would not be a corresponding view.
 

Claudio Dawson d'Angelis

unread,
Sep 26, 2012, 10:25:46 AM9/26/12
to dartga...@googlegroups.com
A quick and dirt draft about how boxes could modeled:

class BoxImg {
var imgPath='/path/to/img/files';
var imgID,hidden;

BoxImg(imgID){
this.imgID = imgID;
this.hidden= true;
init();
}

init(){
print('Sourcing imageElement from $imgPath/$imgID.png and displaying hidden image.');
}

compare(BoxImg otherBox){
print('Comparing images ${this.imgID} and ${otherBox.imgID}');
if(this.imgID == otherBox.imgID){
print('Matching images, we can now display them');
this.hidden = false;
otherBox.hidden = false;
}
else{
print('Not matching images');
}
}

}

And we can tie the this.hidden variable to a method that make clickable/unclickable an image elment.

An example of how it should work:

void main(){

BoxImg firstBox = new BoxImg(5);
BoxImg secondBox = new BoxImg(5);

BoxImg thirdBox = new BoxImg(4);
BoxImg fourthBox = new BoxImg(5);

firstBox.compare(secondBox);
thirdBox.compare(fourthBox);


...that will output this:

 
Sourcing imageElement from /path/to/img/files/5.png and displaying hidden image.
Sourcing imageElement from /path/to/img/files/5.png and displaying hidden image.
Sourcing imageElement from /path/to/img/files/4.png and displaying hidden image.
Sourcing imageElement from /path/to/img/files/5.png and displaying hidden image.
Comparing images 5 and 5
Matching images, we can now display them
Comparing images 4 and 5
Not matching images

Dart Learn

unread,
Sep 26, 2012, 1:54:41 PM9/26/12
to dartga...@googlegroups.com
I like the models idea. It looks like it is addressing  all stakeholders and is a good abstraction/ visualization.
But what level of details do we include into a domain model?
To me it looks like "Memory" will be doing the most businesslogic. 

here few pdf slides about modelling domain models. 
check out slide #10.
We should be right now at conceptual level.

Anyone suggestions how to improve the domain model?
Since modelling seems to be an iterating process, we can simultanously suggest ideas that our game should implement.


1) Do we need any server-side code? If yes, another domain for the model?
2) Let us allow the user to choose between 
game a) 4x4 fields (dzenans travel photos)
game b) 6x6 fields some animal photos
We would have 2 different directories (with images) on the server. Each for one of the games. Our sourcecode would be more dynamic.
3) We should have
a) highscore for all played games. Needed time and trys within one game to match all identical images. Save the values in a simple txt file on the server.
b) actual time counter, trys counter for the user when game is started.

Claudio Dawson d'Angelis

unread,
Sep 26, 2012, 2:27:22 PM9/26/12
to dartga...@googlegroups.com
1) Do we need any server-side code? If yes, another domain for the model?
Not necessary except for saving highscores (not a big deal).

2) Let us allow the user to choose between 
  game a) 4x4 fields (dzenans travel photos)
  game b) 6x6 fields some animal photos
We would have 2 different directories (with images) on the server. Each for one of the games. Our sourcecode would be more dynamic.

Yes, it comes very handy with 2 different dirs.

3) We should have
  a) highscore for all played games. Needed time and trys within one game to match all identical images. Save the values in a simple txt file on the server.
  b) actual time counter, trys counter for the user when game is started.

We could define a top-level function to catch the very first click on a box and get the current time and set the startTime variable. This function is called again at the end of the game, it gets the current time and subracts it from startTime
If we allow the user to type his name in case of highscore, we might choose JSON format to store data on the server.

Claudio Dawson d'Angelis

unread,
Sep 26, 2012, 2:32:38 PM9/26/12
to dartga...@googlegroups.com
Plus, there's also an other possibility to get the whole thing much easier: moves-based scores instead of time-based ones. What you think?

Dart Learn

unread,
Oct 1, 2012, 8:35:15 AM10/1/12
to dartga...@googlegroups.com
Sounds good.  Any other suggestions?

If not, we could proceed to the next lvl: specification level

At the specification level, you are communicating at a design level – but no 
particular language. Example: class diagram

Design the first draft for a class diagram. 

Any free online UML tools to colaborate?

Dzenan Ridjanovic

unread,
Oct 2, 2012, 9:10:24 AM10/2/12
to dartga...@googlegroups.com
Sorry for a very late response. I had a crazy week.

1) Do we need any server-side code? If yes, another domain for the model?

I would not do a server-side version right away. We do not need a database for this game, and images may be kept at Dropbox, for example. We will use a web link in the model for an image and not a real image. For game scores, we may need a text file, but I would leave for one of the last versions.


2) Let us allow the user to choose between
game a) 4x4 fields (dzenans travel photos)
game b) 6x6 fields some animal photos
We would have 2 different directories (with images) on the server. Each for one of the games. Our sourcecode would be more dynamic.

We should design a game to accept any number of collections of images. We do not need to do that at the very beginning, but the conceptual design should consider that possibility. I prefer to have a conceptual model rather comprehensive, but the first versions should have a minimal subset.


3) We should have
a) highscore for all played games. Needed time and trys within one game to match all identical images. Save the values in a simple txt file on the server.
b) actual time counter, trys counter for the user when game is started.

I also like a suggestion that Claudio made: “moves-based scores”. Again, we do not need to do the scoring in the first versions.
Message has been deleted

Dzenan Ridjanovic

unread,
Oct 2, 2012, 9:23:11 AM10/2/12
to dartga...@googlegroups.com
I have made a design tool in Dart called Magic Boxes (https://github.com/dzenanr/magic_boxes). It does not use UML exactly, but it a minimal modeling formalism with concepts (boxes), attributes (items) and neighbors (relationships) in addition to concept identifiers and attribute types. A model may be transformed into JSON.

I use the JSON representation of a model to generate code for the model in Dartling (https://github.com/dzenanr/dartling). I have been working hard to produce a pub version of Dartling. The code is ready. Today, I will test it, and tomorrow (Wednesday) I will update a minimal documentation.

However, for the first versions, I would suggest that we code a model on our own, with Dart lists, for pedagogical reasons. Then, later on, I will produce the same game with Dartling and we will compare two models.

Dzenan Ridjanovic

unread,
Oct 2, 2012, 6:11:15 PM10/2/12
to dartga...@googlegroups.com
An example of a game with a model made by hand: https://github.com/dzenanr/car_parking_wout_dartling .

Dzenan Ridjanovic

unread,
Oct 2, 2012, 6:14:34 PM10/2/12
to dartga...@googlegroups.com
To "open" a model in Magic Boxes paste the JSON representation of the model and use the From JSON button in Magic Boxes.

Dzenan Ridjanovic

unread,
Oct 4, 2012, 8:50:53 AM10/4/12
to dartga...@googlegroups.com
The best way to learn is to explore, to consider alternatives and to compare. However, to explore you need a base. In our case, a base is a simple, minimal version of the game. This base may be even without a model. With different alternatives to make the game we will all learn a lot.

Dzenan Ridjanovic

unread,
Oct 6, 2012, 11:16:05 PM10/6/12
to dartga...@googlegroups.com
I have developed a base for the memory game


in 5 spirals (from a trivial one to a simple memory game with colors instead of images).


If you want to collaborate on future spirals give me your GitHub name so that I can invite you.

I would appreciate if, for each spiral, you ask questions and provide some basic explanations. Perhaps, we should start a blog where we can describe the game progress from spiral to spiral.

Claudio Dawson d'Angelis

unread,
Oct 9, 2012, 4:53:42 AM10/9/12
to dartga...@googlegroups.com
Dzenan I'm pretty busy these days, I will look at the code as soon as I can,  soRRRRRy :)
In the meanwhile I starred your project on github, my username is `claudiodangelis`

Dzenan Ridjanovic

unread,
Oct 10, 2012, 12:08:39 PM10/10/12
to dartga...@googlegroups.com
No worry. Take your time. I have added you as a collaborator on the educ_memory_game project.

Dart Learn

unread,
Oct 12, 2012, 11:54:11 AM10/12/12
to dartga...@googlegroups.com
I am right now busy too :/. For the next 2 weeks. But i bought yesterday the book from chris bucket. If i find few minutes of freetime i will check it out for stuff about gaming!

Claudio Dawson d'Angelis

unread,
Oct 17, 2012, 9:48:43 AM10/17/12
to dartga...@googlegroups.com
Dzenan, at a first glance it seems that there are some issues related to the delay on card flip-off. (I'm not looking at the code so I can't actually tell which method is). Tonight I will give a deeper look and I will be able to explain it better :))

Dzenan Ridjanovic

unread,
Oct 18, 2012, 8:46:10 AM10/18/12
to dartga...@googlegroups.com
I wanted a user to be fast when clicking on the second card with the same color. It stays on only if it is clicked while the first card is on. I also realized that something was wrong when I had to click more than is needed, even if I was fast. Be free to change it. It would be nice if we kept a list of problems and solutions, and another one with FAQ. A history of questions and problems, related to a spiral, is so valuable for other learners, and it is so easy to ignore the recording of problems, solutions, questions and answers. 

Dzenan Ridjanovic

unread,
Oct 26, 2012, 11:00:02 AM10/26/12
to dartga...@googlegroups.com
A bit of improvement in the last version: add circle to hidden cells; improve how twin cells are shown. However, there is still a case, when you have to use 3 clicks, instead of 2, to display the twin cells. Please, play and give me a feedback. Also, tell me what you would like to see in the next spiral.
Reply all
Reply to author
Forward
0 new messages