Skip to main content

Posts

Simplified TeaTime

The next Croquet release, code-named "Hedgehog", will be centered around a real replicated object model, rather than the ad-hoc meta sends in Jasmine. See Andreas' and David's OOPSLA presentation (PDF) for an overview.

Connecting fields

Quick Recipe To connect field a in obj1 to field b in obj2 , use this: obj2 startScript: #b: when: {obj1. #aChanged} Now for the whole story ... Problem A colleague of mine wanted to make a drop-down list, where the options are not just set once, but provided and updated by the application. So, of course, when the options in the application changes, the items of the list widget have to be set to this new value. Nothing easier than that, just write a handler: onOptionsChanged     <on: optionsChanged in: app>     listWidget items: app options HOWEVER, he wanted to build this programmatically, not using a separate method. So, he easily came up with the following: listWidget startScript : #items: withArguments: {app options} when: {app. #optionsChanged} HOWEVER, this does not work as intended because the arguments to the script are evaluated only once, rather than every time the script is triggered. Well, this is what blocks are for, right? ...

Scripts in Croquet

Tao asked for a "Tweak & Croquet" tutorial. I don't have time right now to actually write one, but here's some sample code anyway. Using scripts is easy and useful, even without the Tweak GUI. Just use #startScript: to run some method as a script. Inside a script, you can use loops and anything you like, just throw in a wait to account for time. Like, to animate the color of a frame, you could use this method (just add it to your TeapotMorph ): animateColorFor: aFrame [ 0 to: 360 do: [:hue | aFrame material color: (Color h: hue s: 1.0 v: 1.0). self wait: 0.01] ] repeat This changes the color every 10 ms, and you can start it from the initializeDefaultSpace method: self startScript: #animateColorFor: withArguments: {someFrame}. Here is something that does not loop forever, but finishes after one cycle: jump: aFrame | v g | v := 0@1@0. g := 0@-0.05@0. [aFrame translation y >= 0] whileTrue: [ a...

Tweak Tutorial

Andreas posted a BankAccount and ATM tutorial. This nicely demonstrates some of the basic Tweak concepts such as fields, events, triggers, and handlers, as well as introducing UI aspects like players, costumes, updating etc.

Print-Quality Screenshots

For high-quality prints you need high-quality screenshots. This means very high resolution, and nice anti-aliasing. Just grabbing the screen produces rather unpleasant results ( screenshot , 80 KB, 800x600 pixels). With normal OpenGL rendering you get rarely more than screen resolution, and anti-aliasing quality very much depends on your graphics board. So what to do? Tiled Rendering comes to the rescue. Instead of rendering the whole image at once, we render smaller portions of the scene, and then arrange the tiles into a large picture. However, just pointing the camera at each tile will not work as intended, the perspective would change from tile to tile. What is needed instead is to construct partial viewing frustums that together exactly recreate the whole frustum. This sounds like a lot of math, but actually it is quite simple: gluPerspective: fov aspect: aspect zNear: near zFar: far tile: rect | cotangent radians w h | radians := (fov/2.0) degreesToRadians. cotan...