Totem Ball Game
De DigiWiki.
(Différences entre les versions)
Ligne 3 : | Ligne 3 : | ||
* Placez le script gametotem.lsl dans un cube nomée "gametotem" | * Placez le script gametotem.lsl dans un cube nomée "gametotem" | ||
* Placez la shpere "gameball" dans l'inventaire du cube "gametotem" | * Placez la shpere "gameball" dans l'inventaire du cube "gametotem" | ||
- | * Cliquer sur le cube " | + | * Cliquer sur le cube "gametotem" pour démarrer le jeu |
gametotem.lsl | gametotem.lsl |
Version actuelle en date du 19 mai 2015 à 23:45
- Placez le script gameball.lsl dans une sphere nomée "gameball"
- Prendre la shpere "gameball" dans votre inventaire
- Placez le script gametotem.lsl dans un cube nomée "gametotem"
- Placez la shpere "gameball" dans l'inventaire du cube "gametotem"
- Cliquer sur le cube "gametotem" pour démarrer le jeu
gametotem.lsl
// gametotem.lsl // game_field_size defines the range of the game perimeter integer game_field_size = 10; // the list of balls we have spawned, so we know who to clean up list balls = []; // a function to spawn one ball spawn_ball(integer is_red) { // turn physics off, so the totem isn't shifted around llSetStatus(1, FALSE); // spawn a new object, "gameball" must be in this object's inventory llRezObject("gameball", llGetPos()+<0,0,1>, <-3+llFrand(6),-3+llFrand(6),1>, ZERO_ROTATION, is_red); llSetStatus(1, TRUE); } // a function to sends a message using the private channel send_message(key child_id, string message) { llShout(1235, (string)child_id+" "+message); } // function to cleanup all the balls we have spawned despawn_balls() { integer i; for(i = 0; i < llGetListLength(balls); i++) { send_message(llList2Key(balls, i), "die"); } } // function to reset our scanner and gameballs reset() { // stop a previous sensor if there was one llSensorRemove(); // cleanup any previous balls that might be around despawn_balls(); // spawn 3 red balls, and 3 blue balls spawn_ball(TRUE); spawn_ball(TRUE); spawn_ball(TRUE); spawn_ball(FALSE); spawn_ball(FALSE); spawn_ball(FALSE); // set a green message over the totem's head llSetText("Let the game begin!", <0,255,0>, 1.0); // turn on our sensor that actually runs the game logic every 1.0 sec llSensorRepeat("","",ACTIVE,200.0, 3.1415926, 1.0); } default { state_entry() { llSetText("Touch me to start.", <255, 255,255>, 1.0); } on_rez(integer param) { llSetText("Touch me to start.", <255, 255,255>, 1.0); } // touching the totem turns the game on and off. touch(integer total) { llSetText("Starting...", <255, 255,255>, 1.0); state started; } } state started { state_entry() { reset(); } // object_rez is fired to notify us that // llRezObject successfully spawned a new child object_rez(key child_id) { // keep track of the new child, for later clean up balls += child_id; } // touching the totem turns the game on and off. touch(integer total) { // clean up any spawned balls despawn_balls(); llSetText("Touch me to start.", <255,255,255>, 1.0); // switch to the default 'stopped' state state default; } sensor(integer total) { integer blue_count = 0; integer red_count = 0; integer i; for(i = 0; i < total; i ++) { string name = llDetectedName(i); if( name == "redgameball" || name == "bluegameball" ) { vector pos = llGetPos(); float dist = llVecDist(pos, llDetectedPos(i)); if( dist > game_field_size ) { // send a message out on the game channel: "reset" // all the nearby listen events will fire // but the key filter in gameball's listen handler // makes sure the only the correct ball resets send_message((string)llDetectedKey(i),"reset " +(string)(pos.x)+" "+(string)pos.y+" "+(string)pos.z); } } } // check the victory condition for(i = 0; i < total; i ++) { if( llDetectedName(i) == "redgameball" ) { red_count++; } else if( llDetectedName(i) == "bluegameball" ) { blue_count++; } } if( red_count == 0 ) { llSetText("Blue wins! Touch to reset.", <255,0,0>, 1.0); llSensorRemove(); } else if( blue_count == 0 ) { llSetText("Red wins! Touch to reset.", <255,0,0>, 1.0); llSensorRemove(); } } }
gameball.lsl
// gameball.lsl // last_collide will serve as a marker to help us enforce game rules string last_collide = ""; // this keeps track of our listening key, 0 means not listenting, > 0 // is a unique identifier integer listen_id = 0; // reset is called to clean up our variables // and make sure we are properly listening reset_listener () { // if we had a listener already, remove it first if (listen_id > 0) { llListenRemove (listen_id); listen_id = 0; } // now register a listener for channel 1235 listen_id = llListen (1235, "", "", ""); } // reset position is used by the listen event handler // it moves us back into the game, using llSetPos () reset_position (float x, float y, float z) { // turn off physics while we teleport the object llSetStatus (1, FALSE); // if physics is on, you can't use llSetPos () // since you must create and apply forces to account for any movement // but with it off, we can simply set the position without fuss. llSetPos (<x, y, z+2>); // start 3 meters above the game totem // turn physics back on and drop the ball on the totem llSetStatus (1, TRUE); } // reset the ball's current color, this is used by listen, in reaction to a reset message // implement critical game logic as well, since it determines if colors should swap based // on who hit who last reset_color () { // if the last collision was // a game ball of some kind but not our own color if ((last_collide == "redgameball" || last_collide == "bluegameball") && llGetObjectName () != last_collide ) { // swap our color if (llGetObjectName () == "redgameball") { llSetColor (<0, 0, 255>, ALL_SIDES); llSetObjectName ("bluegameball"); } else if (llGetObjectName () == "bluegameball") { llSetColor (<255, 0, 0>, ALL_SIDES); llSetObjectName ("redgameball"); } } } default { // when the gameball is created enforce some standards on the ball state_entry () { // the object we are attached to must be a regulation size llSetPrimitiveParams ([PRIM_SIZE, <.6,.6,.6>]); // and must be a 90% hollow sphere llSetPrimitiveParams ([PRIM_TYPE, PRIM_TYPE_SPHERE, 0, // holeshape <0.0, 1.0, 0.0>, // cut 90.0, // hollow <0.0, 0.0, 0.0>, // twist <0.0, 1.0, 0.0> // dimple ]); if (llGetObjectName () == "Object") { llSetObjectName ("gameball"); } // it must obey physical laws llSetStatus (1, TRUE); // it must use a blank texture // from lswiki: this is the key of the 'Blank' texture llSetTexture ("5748decc-f629-461c-9a36-a35a221fe21f", ALL_SIDES); // attach our listener reset_listener (); // forget about previous collisions last_collide = ""; } // when the ball is created on_rez (integer start_param) { // use the optional start_param to determine which color reset_listener (); // forget about previous collisions last_collide = ""; if (start_param == 0) { llSetColor (<0, 0, 255>, ALL_SIDES); llSetObjectName ("bluegameball"); } else { llSetColor (<255, 0, 0>, ALL_SIDES); llSetObjectName ("redgameball"); } } // when the ball collides with something collision_start (integer total_number) { string other = llDetectedName (0); // if we collided with some other gameball, write it down if (other == "redgameball" || other == "bluegameball") { last_collide = other; } else if (llDetectedType (0) & AGENT) { // if we collided with an agent, consider ourselves kicked. last_collide = (string) llDetectedKey (0); // this code gets a vector of magnitude 2, // pointing away from the avatar that kicked us. vector kick_vector = llGetPos () - llDetectedPos (0); kick_vector.z = 0; kick_vector = llVecNorm (kick_vector)*2; // use this vector as a force vector and apply it to the ball llApplyImpulse (kick_vector, FALSE); } } // when the ball is touched by someone touch (integer total_number) { last_collide = ""; vector kick_vector = llGetPos () - llDetectedPos (0); // scale to a fixed magnitude: 2 in the case of a touch kick_vector.z = 0; kick_vector = llVecNorm (kick_vector)*2; kick_vector.z = .1; llApplyImpulse (kick_vector, FALSE); } listen (integer channel, string name, key id, string message) { // llParseString2List will split the input message on spaces list cmdline = llParseString2List (message, [" "], [" "]); // the first param must be this object's key string k = llList2String (cmdline, 0); if (k == (string) llGetKey ()) { string s = llList2String (cmdline, 1); llWhisper (0, "Gameball received command: "+s); if (s == "reset") { // if it is, then we need to reset float x = llList2Float (cmdline, 2); float y = llList2Float (cmdline, 3); float z = llList2Float (cmdline, 4); reset_color (); reset_position (x, y, z); last_collide = ""; // reset the last collision } else if (s == "die") { llDie (); } } } }