Pages

Thursday, 23 June 2011

HTML 5

Introduction

Hi all, this I will not talk about second Life, but I will focus on newer web technologies. This Week's topic is about HTML 5 and CSS 3 and I will talk about, compatibilities and I will also do some sample code. HTML 5 is not a completed language and not all browsers support its features. Some browsers show better capabilities than others in this task.

Browser Wars

The wars between browsers is always on and as time passes browsers improve their HTML 5 compatibilities to offer better support than others. Currently all major browsers offer quite good HTML 5 support with IE9 having the least ratings from the other browsers. The website http://www.findmebyip.com/litmus/ shows a list of browsers together with their compatibilities. As it can be seen Google's Chrome and Apple's Safari seem to do a pretty good job. In fact both Google and Apple give a lot of importance to this technology in their development. Chrome's quick and seamless updates continue to improve the product and to add more and more HTML 5 support.

The website http://html5test.com/ provides a list of your browsers supported and unsupported features together with an overall rating. Well we all  did this test in Web Technologies class and the first thing I noticed is the huge difference in rating between chrome and IE 9. Chrome (12.0.742.100) currently scores 328/450 while IE9 only scores 141/450. I also notice that my browser had problems using WebGL technology, something which my friend's Chrome browsers did not.

I was a bit disappointed at first and did not know what cause the problem. The new browsers promise that a simple install of the browsers will include all features, but this was not exactly true in my case. I immediately though it was a problem with my graphic's card driver, and I was right. I have an ATI HD Raedon Graphic Card, which is not Recent, but not very old neither. I found several articles about ATI chips not supporting WebGL, and from the ATI Website I downloaded a new driver that supports this technology. It seams that ATI issued newer drivers to all chips considered as non legacy. These new drivers add support to WebGL. I tried WebGL on several other PC's with the chrome browsers. All new graphic cards seem to do pretty well but graphic cards considered as Legacy are not supported. Finally I was able to view some WebGL Demos online.

Differences between HTML4/CSS2 and HTML5/CSS3

HTML5 Introduces a lot of new features but some old tags will be no longer supported and newer tags must be used.  HTML5 adds support for the Header and Footer tags that can display information in the web document. Other new tags provide better structure to the document. Other interesting elements are the media elements and the canvas element. These tags are new in HTML 5 and offer better media support that in the past was only available through web extensions such as adobe's flash player.

Media elements illustrated on the website www.w3schools.com include:

TagDescription
<audio>For multimedia content, sounds, music or other audio streams
<video>For video content, such as a movie clip or other video streams
<source>For media resources for media elements, defined inside video or audio elements
<embed>For embedded content, such as a plug-in

These elements allow you to play media directly from the browser. The supported browser codecs may vary although HTML5 provides for a set of standard codecs that should be supported. An even more interesting new element is the canvas element. This element allows programmers to draw things using Scripts. I used to do a similar thing using the Canvas in Java Applets, but working totally in the web browser is another thing. Speaking about Applets, the Applet tag will no longer be supported but applets can still be used by using the object tag and adding the right mime_type in the attribute type.

CSS3 is completely backwards compatible and therefore no old code must be changed. CSS3 provides new styling such as:
  • Selectors
  • Box Model
  • Backgrounds and Borders
  • Text Effects
  • 2D/3D Transformations
  • Animations
  • Multiple Column Layout
  • User Interface

New features about borders are introduced. The feature border-radius produces round corners. It has been around for a while in some browsers although IE only stared supporting it on version 9. To make this feature in CSS2 you would have to use several images to obtain the rounded features and than place them on the corners. Well most border features seem to be supported by all major browsers although some features may be still in a testing phase.

Another interesting feature in CSS3 is the text shadow. Although still not supported in IE9, this feature will make part of the new CSS standards. Without this feature shadow could only be used by suer imposing two text lines.

The most interesting parts of CSS3 are surely the 2D and 3D transformations that allow you to manipulate objects but changing their 2D and 3D positions on the screen. This includes rotating, skewing and scaling objects. Most of the features are still a work in progress but on the W3schools.com you can find several examples of using the already  supported tags.

Together with CSS3 and HTML5 new JavaSript features are also added. these new features include:
  • Web Storage
  • Web SQL Storage
  • Offline application cache
  • Web Workers
  • Web Sockets

Some Hands On

The task for todays week is to use two new fetures of:
  • HTML5
  • CSS3
  • new JS
Well in this exercise  I wanted to try so many things, but I had little time, so I decided to make some code to try various features, without actually caring about the website looks and uses. My idea was to try the new features that I would had used earlier in this course if they where supported. All my code works in Chrome but was not tested in other browsers. since some tools use the webkit, they will probably work only on chrome and safari.

To start with I decided to use the canvas elements, so I made various canvas elements in my HTML Body.


<h1>HTML5 Tryout</h1>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>
<canvas></canvas>

The first thing I wanted to try out is the border radius that produces round corners. In the first weeks exercise, I remember that I could not do it in IE 8 and I had to use several pictures to do it. Now it can be done in a single line of CSS.

border-radius:25px;

Then I decide why not add some shadow to the canvas so I used the box-shadow property 
box-shadow:10px 10px 5px #888888; where
box-shadow:h-shadow v-shadow colour
h and v shadow are the positions of the shadow and can be eithier positive or negative.

Finally I added a border to the canvas and added the colour orange. Then I said, why not use some new CSS transformations. The code below shows my entire CSS.

<style type="text/css"> 
canvas
{
width:100px;
height:75px;
border-radius:25px;
box-shadow:10px 10px 5px #888888;
background-color:orange;
border:1px solid black;
}
canvas:nth-child(odd)
{
-webkit-transform:rotate(0deg);
-webkit-animation-name: myfirst;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-delay: 0s;
-webkit-animation-iteration-count: infinite;
}

canvas:nth-child(even)
{
-webkit-transform:rotate(30deg);
-webkit-animation-name: mysecond;
-webkit-animation-duration: 2s;
-webkit-animation-timing-function: linear;
-webkit-animation-delay: 0s;
-webkit-animation-iteration-count: infinite;
}


@-webkit-keyframes myfirst 
{
0%   {-webkit-transform:rotate(0deg);}
20%  {-webkit-transform:rotate(10deg);}
40%  {-webkit-transform:rotate(20deg);}
60% {-webkit-transform:rotate(30deg);}
80% {-webkit-transform:rotate(20deg);}
100% {-webkit-transform:rotate(10deg);}
}
@-webkit-keyframes mysecond
{
0%   {-webkit-transform:rotate(30deg);}
20%  {-webkit-transform:rotate(20deg);}
40%  {-webkit-transform:rotate(10deg);}
60% {-webkit-transform:rotate(0deg);}
80% {-webkit-transform:rotate(10deg);}
100% {-webkit-transform:rotate(20deg);}
}

I decide to use the new selectors features of CSS to choose the odd canvases and the event canvases separately.  I created key frames with the rotation transformation at different angles in different percentages of the key frame. When selected, the canvas objects are assigned the appropriate keyframe, the duration of the animation, the timing function and the iteration count. In this example the objects keyframe duration is set to two seconds and iterations are infinite. This way the animation never stops.

Now that we have the canvas all set up, why not draw on it. I decided to draw on all even canvas objects. Drawing in Java Script is not easy and requires some thought. The code below shows some javascript.

var obj= document.querySelectorAll("canvas:nth-child(even)");

for (var i = obj.length >>> 0; i--;) { 
var ctx=obj[i].getContext('2d');
for (var x = 0.5; x < 500; x += 20) {
  ctx.moveTo(x, 0);
  ctx.lineTo(x, 375);
}
for (var y = 0.5; y < 500; y += 20) {
  ctx.moveTo(0,y);
  ctx.lineTo(375, y);
}

ctx.strokeStyle = "red";
ctx.stroke();
}

The function document.querySelectorAll() retrieves a list of objects and puts them into the obj variable. In this case the objects are all canvas elements. Only the even canvas elements are selected. A for loop is used to iterate through each object. for each element, a ctx variable is used to store the 2D context of the canvas. Here you can draw and it will become cisible on the canvas.There are various objects that can be drawn but I decided to draw a grid. To draw a grid you must first learn how to draw a line. This is easy, and only two functions are needed. the function moveTo() is used to select the initial drawing position. This function needs the x and y coordinates. The second function LineTo also takes the x and y coordinates and draws a line from the initial starting position to the given coordinates. Using these functions, the lines are drawn and kept in memory, but are not final and therefore not visible. The strokeStyle property sets the stroke colour and the stroke() function draws the line. To create the grid I used two for loops, one to draw vertical lines and another to draw horizontal ones.

Finally I wanted to try the output tag and the local storage features offered by javascript.
The following code shows how I used them.

<script type="text/javascript">
  window.localStorage['value'] =document.querySelectorAll("canvas").length;
</script>
<p>There are currently <output id="result"></output> Canvas objects on the screen</p>

<script type="text/javascript">
 document.getElementById('result').textContent = window.localStorage['value'] ;
</script>

The context in which the code was used does not really make any sense, I just wanted to try out the features. In n initial script, I store the value of the number of canvas elements on screen in a local storage called 'value'. Then I display a paragraph of text with an empty output tag inside. Later on in the code I run another script that gets the number stored in the local storage and injects it in the output tag, which is then displayed in the paragraph.

The image below shows a screenshot of the final output of the code.

Below is a link to my website where I uploaded this page.

Conclusion

I found using HTML5 features much easier than expected, although I did not perform any particularly difficult tasks. HTML5 really adds something to the web and is much more powerful than its predecessor. With the new styling and scripting, anything can be done pretty much with HTML 5 eliminating the need of other external tools. I see this as a good thing especially for the users that will only need to download a browser and nothing more. Lets hope HTML 5 is finished earlier than expected so we can start benefit from it's features.

Thursday, 16 June 2011

Further into Second Life

Introduction

This week's post will be about some more advanced objects with second life and about SL's ability to connect people all over the world.

In this post I will talk about:

  • Communicating with other SL users which are abroad
  • Building a Notecard  giver
  • Building a Post Box system
  • Building an object that interacts with a Web Page


Communicating on-line

 In the last lesson a student was in Costa Rica for a holiday and decided to take the opportunity to make a little experiment with us. The student joined the lesson using Skype to make a video chat with the class. It was interesting to see how today's technology allows visual chat from all over the world.

In a second part of the lesson, all students logged to Second Life including the student in Costa Rica. We tried to do a lesson for building objects. All students teleported to a sand box where the lecturer showed us different objects and SL scripts. Later on in the lesson, we travelled to different SL worlds to further explore the game. Seeing how easy people can communicate over from different places using SL shows the communicative power of this game.

Building a Note Card Giver

The note card giver is an object that dispatches note cards to SL Avatars. There are various types of Note Card  givers. Some give note cards to avatars on touch, while others do it when an avatar passes near by. In this case I chose to give a note card to every avatar passing by. The Code Below shows how the Note Card giver works.

string notecard = "Note1";
integer freq = 1;
integer maxList = 100;
list given;


default
{
    state_entry()
    {
        llSensorRepeat("", "",AGENT, 20, PI, freq);
        llSetText("", <1.0, 1.0, 1.0>, 1.0);
    }
 
    sensor(integer num_detected)
    {
        integer i;
        key detected;
     
        for(i=0;i<num_detected;i++)
        {
            detected = llDetectedKey(i);
         
            if( llListFindList(given, [detected]) < 0 )
            {
                given += llDetectedKey(i);
             
                llGiveInventory(detected, notecard);
                if (llGetListLength(given) >= maxList)
                {
                    given = llDeleteSubList(given,0,10);
                }                              
            }
        }              
    }
}


The string variable notecard holds the name of the note card that will be passed to the avatar. The integer frequency holds the number of seconds of intervals between each sensor checking. maxList is an integer that holds the number of avatars that will be stored in a list of already contacted avatars. The object starts by calling the function  llSensorRepeat() on state entry. This function causes a sensor to check for avatars every second.

In llSensorRepeat("", "",AGENT, 20, PI, freq) 

AGENT is a mask that allow the sensor to locate avatars through SL Legacy Names
The number 20 is the number of meters the sensor 
PI is the arc of the sensor. PI means that the sensor works 360 degrees.
freq is the number of seconds of each interval of the sensor.

 When the sensor detects something the function sensor(integer num_detected) is called. The function uses a for loop to go through all detections. When an avatar is detected, his name is checked in a list of previously detected avatars, to avoid giving the note card to the same avatar all over again. If the avatar is new, his name is added to the name list and the avatar is given a notecard. llGiveInventory() passes the notecard to the avatar. Finally the function checks the length of the list using the llGetListLength() function. if the function exceeds the maximum number of names, llDeleteSubList(given,0,10); delete the first 10 names in the list. This note card giver is not ideal in a crowded place as 100 names is not a lot, and you would risk the note card giver to keep trying to send note cards to the same avatar. The note card that will be handed to the avatar must be placed in the contents of the card giver.

For the note card giver object a used a thin square prim with a white texture. The image below shows the card giver passing a note card to an avatar.


Building a Post Box System

The post box system is a system designed to pass messages to its owner. In this case I decided to let avatars drag notecards into the postbox such that they can be received by my avatar. The post box object is made up of a cuboid base, a semi circular face. The post box can be seen in the image below.


The code below shows the script of the post box system.


default
{
    state_entry() {
        llAllowInventoryDrop(TRUE);
    }
    touch_start(integer total_number) {
        llSay(0,"Create a notecard and drop it into the mailbox");
    }
 
    changed(integer mask) {
        if (mask & (CHANGED_INVENTORY | CHANGED_ALLOWED_DROP)){

            integer i;
            for (i=0; i<llGetInventoryNumber(INVENTORY_ALL); i++) {
                string name = llGetInventoryName(INVENTORY_ALL, i);
                integer type = llGetInventoryType(name);
                if (type != INVENTORY_SCRIPT) {
                    integer perms = llGetInventoryPermMask(name, MASK_OWNER);
                    if ((perms & PERM_TRANSFER) == PERM_TRANSFER &&
                        (perms & PERM_COPY) == 0) {
         
                        // keep track so you don't thank someone for a
                        // notecard that someone else gave you!
                        llSay(0, "Thanks for the "+name);
                         llGiveInventory(llGetOwner(), name);
            llRemoveInventory(name);
                    } else {
                        llSay(0, "Sorry, "+name+" isn't nocopy, trans");
                        llRemoveInventory(name);
                    }
                }
            }
        }
    }

On state entry, the object calls  llAllowInventoryDrop(TRUE); to allow objects to be dragged in the post box system. On touch the avatars are instructed to create a note card and drop it into the post box using the llSay Method. Dragging something in an object calls the changed event. This event takes in a mask that when compared to other masks, the change can be identifies.

"if (mask & (CHANGED_INVENTORY | CHANGED_ALLOWED_DROP))" checks for changes in the inventory and the changed allowed drop state. The function then loops for items in the inventory of the object. If the object is not a script the inventory mask of the ovner of the object with respect to the item is obtained. If the object dragged is not a copy, it is given to the owner of the post box and then removed from the post box. If the item is a copy it is not copied to the owners inventory, but it is removed immediately.

Building an object that interacts with a Web Page

For interacting with a web page I created a flat square prim that returns the number of SL sign-ups. This value is obtained from a web page. The code below shows the script of the object.

string SL_STATS_URL = "http://secondlife.com/httprequest/homepage.php";
key gRequestid;

default
{
    touch_end(integer p) {
        gRequestid = llHTTPRequest(SL_STATS_URL, [HTTP_METHOD, "GET"], "");
    }
    http_response(key requestID, integer status, list metadata, string body) {
        if (requestID == gRequestid) {
            list lines = llParseString2List(body, ["\n"], []);
            integer i = llListFindList(lines, ["signups"]);
            llSay(0, "There are currently "+llList2String(lines, i+1)+
                     " signups");
        }
    }
}

On touch the function llHTTPRequest() sends an http request and returns a request ID that identifies the request. On the event http_response, if the request id of the response is that requested, the lines of the returned request are inserted in a list. Lines are obtained using the function  llParseString2List() that parses a sting into a list of strings given the split parameters, in this case, a space of a carriage return. Note that the web page http://secondlife.com/httprequest/homepage.php returns several values regarding SL statistics.  llListFindList() searches through a list to compare a particular string and returns the index of that list position if found. In this case we are looking for the string Sigups. Finally the object uses llSay to output the number of signups. This number is the next in the list so llList2String(lines, i+1) is used to recover it, where i is the position os the string "sigups" in the list.

Conclusion

Advanced scripting in SL can become quite complicated as the various pre-existing methods and events must be explored before creating an object. This involves a great deal of time, which in my opinion is too much to spend on a game. Fortunately most objects can be found pre-existing on the net, and with little modification, they can be manipulated to satisfy the users needs. 

Wednesday, 8 June 2011

Creating Basic Objects in SL

Introduction

In last week's post I talked about creating objects in SL and tried to create some complicated ones. I did not however try to create objects requested for my degree, instead I took the opportunity to take a look into second life and programming in SL. Well from this week on I will try to create several objects starting with the very basic objects such as a chair. This post will cover:
  • Building a chair on which the avatar can sit properly
  • Building an object that responds to commands
  • Building an object that can send emails

Building a chair

Building a chair in SL is not very hard but aligning objects is. To create the chair I decided to create a cubic prim to create a chair leg. Then I extended the prim to a thin and long cuboid form to resemble a chair leg. I made four copies of the prim and tried to align them. Aligning in SL is difficult and requires some patience. There are external tools that can be used to create and align objects in SL but I chose to stick to the standard SL viewer tools.

The picture below shows a chair leg.


This picture shows four chair legs being aligned.

Creating the bottom of the chair is easier. Only one flat prim is required and is placed on the aligned legs. The back of the chair is made up of another flat prim placed vertically on the chair base. All object are then linked together. Finally I chained the chair colour to brown.

The picture below shows the last version of the chair.


The chair has also some scripts to allow the avatar to sit properly on it. To create the script I used the select face feature that allow the user to select a face on a group of linked prims. On this face I created the script below.

default
{
    state_entry()
    {
   llSitTarget(<0.0, 0.0, 0.1>, ZERO_ROTATION);
    }
}


The llSitTarget() function requires a vector where the avatar will sit and the rotation of the avatar. With the given parameters the avatar sits correctly i the middle of the chair. The picture below shows the avatar sitting on a chair.


Building an object that reacts to commands

In last weeks post I created a car that moves forward and backward when the avatar touches it. This week I decided to make something easier but something that works as it should. For this purpose I decided to create a light bulb that when touched lights on and off.

The bulb is made of a cylinder to recreate the bulb base and a sphere to form the bulb top. Both prims are linked together. The prims have a plain texture different from that of the chair. The sphere part has a 36% transparency to make the bulb look more real. Both objects have scripts to light the top part of the bulb.

The script for the sphere part:

default
{
    state_entry()
    {
        llListen(989,"Cylinder",NULL_KEY,"On");
        llSetColor(<0.5,0.5,0.5>, ALL_SIDES);
    }

  listen( integer channel, string name, key id, string message )
    {
         state On;
    }
    touch_start(integer total_number)
    {
       state On;
    }
}

state On 
{
     state_entry()
    {
        llListen(989,"Cylinder",NULL_KEY,"On");
        llSetColor(<1.0,1.0,0.0>, ALL_SIDES);
    }
    
  listen( integer channel, string name, key id, string message )
{
    state default;
}

    touch_start(integer total_number)
    {
       state default;
    }
}

The Prim has two states, the default state and the on state. Both states have similar code. On state entry in the default state, the script starts listening on channel 989 for an object called Cylinder to say the message On. In case this occurs the listen method is invoked. This method sets the prim's state to On. The function  llSetColor(<0.5,0.5,0.5>, ALL_SIDES); sets the prims colour. It takes two parameter, the first is a vector that represent the colour in RGB form, and the second parameter is the side number or all sides. The vector used for colour does not take the RGB colours are the normal integers we are normally used to, but uses a sum to render the integer to floats less than 1.0. To change an RGB colour to this type, you need to divide it by 255. The vector <0.5,0.5,0.5> is the LSL colour equivalent to (128,128,128) in the normal RGB format where the 0.5 is rounded from 0.502. The state has another event called touch start that changes the state to On.

The State On is similar to the default state, but instead changes the colour to yellow rather than grey. this state also listens for messages thrown by the Cylinder Object. When the listen event is invoked, the default state is triggered and the bulb is switch off and set back to its greyish colour. Touching the bulb in the On state also switches it off (by setting the default state).

The code for the Cylindrical part is simple. Up on touch the object throws the llSay method to send the message On. The message is sent on the channel 989, which is the same channel the cylindrical object is listening on. This way a message is sent between the two prims and the bulb is switched on and off.

default
{
    state_entry()
    {
    }

    touch_start(integer total_number)
    {
       llSay(989,"On");
    }
}

The default bulb state. The bulb is off.


The On bulb state. The bulb is On.

Building an object that can send emails


For this exercise I decided to create a flat prim that listens to what avatars say. Depending on what they say a mail can be sent. The code below shows the script for the prim.

default
{
    state_entry()
    {
        llListen(0,"",NULL_KEY,"");
    }

     listen( integer channel, string name, key id, string message )
    {
    string messagetype = llGetSubString(message,0,4);
    string messagestring = llGetSubString(message,5,-1);
    
    if (messagetype == "mail:")
    {    
    llEmail( "mail@hotmail.com", "Message From SL", messagestring);
    }
    }
}

This prim has only one state. On state entry the prim starts listening for what avatars say. When an avatar says something the message starts listening. When the message starts with "mail:", the rest of the message is sent by email. In the listen event, the function  llGetSubString(message,0,4) gets the first four characters of the messages the avatars say. This string is put in the variable messagetype. The rest of the string is put in the variable called messagestring. If the message type is equal to "mail:" the message string is sent by mail. E-mails can be sent using the llEmail() function. This function takes mail address, subject and message as parameters.

Conclusion

Scripting in LSL is not easy, especially when dealing with rotation and vectors. Fortunately a lot of examples can be found on the Second Life Wiki. A lot of material is available online and examples can be found for practically everything.  I find LSL to be most interesting part of SL. This week I focused more on the listen function as it is very interesting how objects can interact with other objects and with avatars.

In general Building object in SL takes time. Aligning and resizing objects is not easy as it should be. Building the object visuals takes a lot of time but with the help of external tools, these procedures can be made easier. With the addition of scripts SL become a powerful social tool where an avatar interacts with a new world. 

Thursday, 2 June 2011

The Second Life Experience

Introduction

This week's post will be about using Second Life and the SL Scripting Language. I will talk about how all students in my class met in a virtual world and tried to make a virtual lesson while sitting next to each other in class. I will also talk about some very basic scripting done during the lesson and afterwards.

Moving Around 

It was fun meeting in a virtual world going around using avatars and chatting with friends. It is a good experiment that lets you learn the game more quickly as people in the class room share their experience with each other. During this session we started the first lessons about scripting in Second Life. The first thing to do is to go in a place where the avatar is allowed to build and edit objects. The whole class teleported to a sandbox that allows users to create objects called prims.

In Second Life all objects are prims. Prim is short for primitive and refers the 3D shapes that users uses to build objects. There are several default prims available when building an object from scratch. The image below was taken from the Second Life Wikia and shows the basic Prim shapes

Prim types in Second Life
BoxPrismSphereCylinder
Prim type box.jpgPrim type prism.jpgPrim type sphere.jpgPrim type cylinder.jpg
TorusTubeRing
Prim type torus.jpgPrim type tube.jpgPrim type ring.jpg

Prims can be Linked to each other to form bigger objects and can be stored in the inventory under the objects folder. All students tried to create their own object in second life. My choice was not exactly a good one for a beginner. In fact I immediately wanted to create a car, something which I still haven't managed to do, mostly because of the time it requires. During the lesson I created several objects and tried some basic scripting. Objects can be worn as clothes or gadgets or  be fixed in a place, such as chairs.

Scripting in LSL

The first thing to understand in LSL is how it works. LSL is an event driven language. Events are predefined in the game. A list of valid events can be found on http://wiki.secondlife.com/wiki/Category:LSL_Events. Objects also have states. All Objects have a default State, but other states can be created. An object may react differently to the same events, depending on the state the object is in. Objects can go from state to state simply by using the command 'state nameOfState;'. A commonly used event is state_entry. This event is triggered immediately when a state is changed and commands in this event are executed on state entry.

The first steps in trying to make a car was to create the tires. I created four cylindrical prims and gave them a dark black colour. For the body of the car I simply made a cuboid and placed it on the four tyres. I Linked the five objects together and set the object as physical. Like this I obtained a car look - a-like body. Since I did not have a lot of time, I did not try to improve the car looks, because I preferred trying some scripting.

To create a new script I selected the object and clicked on the content tab and then on the new script button. The New script is not blank, but contains a default state with two events and methods. The first event is the state_entry() event which I already mentioned, while the other event is touch_start() which is triggered when an object is touched by an avatar. The events contained the method llSay() which launches a chat message to all users within 20 meters. Other similar functions like llShout() and llWisper() do the same job but have different ranges.

What makes a car special, is the ability to move. I decided to experiment with the method llMoveToTarget() to make the car move. Using the function llGetPos(), I got the current vector position of the object and stored it into a vector called pos.

vector pos = llGetPos();

The function llMoveToTarget() requires the new vector position ad the time to travel to that position. I used this function to make the car move forward.

llMoveToTarget(pos + <10.0,10.0,0.0>,10.0);

Well using this function, the car does not always move to the desired destination. The image below shows the car going in the air in an uncontrolled manner.

In my experiment, the car should have moved forward for ten seconds. That works on solid flat land, but when the land below is not flat, the car's movements become unexpected. While experimenting, I also tried different states. I created the state moving that is triggered when the default state is touched. In this State, if the user touches the car, it moves in reverse mode. The code is similar to moving forward.

 llMoveToTarget(pos + <-10.0,-10.0,0.0>,10.0);

The object is then returned to the original state. Currently, the only way to travel using this car is to sit on it and then touch it. Hopefully I will be able to do much better in future.


The Entire Script code for the very primitive car can be found below:

  1. default
  2. {
  3.     state_entry()
  4.     {
  5.         llSay(0, "Hi, there!");
  6.     }

  7.     touch_start(integer total_number)
  8.     {
  9.         llSay(0, "You may sit here.");
  10.         
  11.         vector pos = llGetPos();

  12.          llMoveToTarget(pos + <10.0,10.0,00.0>,10.0);  
  13.     state moving;
  14.     }
  15. }

  16. state moving
  17.     state_entry()
  18.     {
  19.         llSay(0, "Stop Me Please");
  20.     }

  21.     touch_start(integer total_number)
  22.     {
  23.      
  24.          vector pos = llGetPos();

  25.    llMoveToTarget(pos + <-10.0,-10.0,0.0>,10.0);
  26.    
  27.       state default;
  28.     } 
  29.     
  30. }


Conclusion

I must say that although I was not that interested at first, using Second Life in class was fun. Seeing and chatting with people over second life makes you realise how SL can be a powerful socialising tool. There also seems to be a lot of users who spend their time creating interesting and complicated objects that make the experience even better. Apart from the coding side which is the part that I'm mostly interested in, SL proved to be move interesting than I thought. After a similar experience, one must always take a class photo.