Hotspots: Admin Pages | Turn-in Site |
Current Links: Cases Final Project Summer 2007
Tips and Tricks for Graphics/Animation in Squeak
This tutorial is meant to elaborate on the concepts discussed in class that I used to employ some useful techniques for my project. I will briefly go over the basic concepts, but you will find much better resources on the coweb and in the class text. I will then discuss the more useful techniques that I developed for my project.
One of the problems I faced in this project was trying to decide how to do graphics with Squeak. Should I have morphs that draw using the Squeak environment from scratch or should I develop my images outside of the environment and import them. I decided the latter technique would give me the best results so that led me to the ImageMorph. Here are the methods I used when using this class.
- Form fromFileNamed: '<filename of image to load>' - This is useful for overriding the default image that is displayed and allows for it to be changed and redrawn at anytime. It uses the class method from form to build a Form from a given file name. You then pass it to the morph with the following method...
- self image: Form - It takes in the form created from the previous code and draws it to this morph's canvas. The resolution of the image must be scaled outside of the Squeak to get the proper resolution though.
- A note on image formats - I found that using GIF files proved to be the best way to do graphics because it allowed for me to customize the background using the squeak environment and allowed for a bit more dynamic customization. Most other formats can be loaded but won't have the transparent backgrounds behavior that GIF files have.
Morph and Layouts
One of the biggest issues I encountered was on how to position morphs correctly. I was drawing from my previous experience with Java and graphics layouts. It turns out Squeak behaves in pretty much exactly the opposite way that Java does. In java, you would create a layout and define how the layout would orient the objects. It turns out in Squeak, you create the layout and the basic way it will orient objects, but you let the child object define more specifically how to orient itself within the parent morph.
- ParentMorph layout: new ProportionalLayout - This bit of code establishes that any morph added to this one will be displayed proportionally to one another. There are some really good tutorials on that go in detail about this, I would use the SqueakMap Package Loader and look for the "TableLayout Tutorial Project" for more in depth explanation.
- (ChildMorph layoutFrame) leftFraction: <x origin> rightFraction: <x extent> topFraction: <y origin> bottomFraction: <y extent> - The way this works is that it establishes the where and what percentage of the parent morph the child should take up. The range goes from 0 - 1.0 and allows for morphs that don't have fixed sizes to be dynamically resized based on the size of the parent morph.
- ParentMorph addMorph: ChildMorph - After adjusting all the child's settings, adding it the morph will display it at the specified location.
- self position: newBounds center - (self extent // 2) - I found this as a handy way to center any morph to the absolute center of it's parent morph. You could add this line of code to the child morph and pass in the "bounds" attribute of the parent morph that is referenced as newBounds. This proved very useful in ensuring that all menus and events were centered relative to the main application window, not the Squeak environment world.
Here are the animation concepts I used to do my basic animation that is basically a glorified animated GIF that you would regularly encounter on the internet.
- self startStepping - The morph will run this line of code to register itself with the system to run specified code at the stepTime.
- stepTime - Putting in a method that returns the interval at which to process data. Needs to return an integer in that represents the number of ms. (i.e. 1000 = 1s)
- step - The code that should be run at the given stepTime interval.
Using these concepts I was able to do a very simple task of chaining together images together much like a digital flip-book. Here is the code I used to accomplish this:
stepCount Integer – the current iteration that the animation morph is in
filePrefix String – the prefix of the file to be loaded, step count is concatenated to this
to load the correct image to display.
animType Symbol – type of animation sequence to display to the user
"Initializes the animation"
stepCount := 0.
animType := animation.
(animation = #slap) ifTrue:[ filePrefix := 'slap-' ].
(newBounds notNil) ifTrue:[
self position: newBounds center - (self extent // 2).
"Changes image to be displayed"
| file |
stepCount := stepCount + 1.
file := filePrefix, stepCount asString, '.gif'.
self image: (Form fromFileNamed: file).
"Step to the next part of this animation's cycle"
(animType = #slap) ifTrue:[
(stepCount = 5)
ifTrue:[ self delete ]
ifFalse:[ self nextImage ]
"Step to the next part of this animation's cycle"
Using the above methods you should be able to produce a pretty simple and clean looking animation. Just save the following images and create Animate.st file. You can then instantiate it with "Animate new #slap" to see how it works.
Link to this Page