Alright,

I've come a bit further by reading some of balazar_brothers code. Though I can't get it to run with the present version of soya because it is based on an older one and looks like some things have changed.


I'm stuck now trying to get a fruit to dissapear when a player comes near it.

I've managed to make it "fly" (speed.y), but not disappear or change scale.

Attached is the code. It's based on the tofu demo code.


Hints are welcome :)


NicoEchániz




Nicolás Echániz wrote:
Hi,

I'm programming a little test game, based on the tofu demo.
It's been going quite well so far: I managed to model and add my static elements and have players interact with them (by clicking), but other things haven't gone so fine.

In the game, fruits are to be spawned on trees and they must drop (fall and collide with the ground) when the tree is shaken by a player. Players are supposed to interact with these fruits eating them (fruits should disappear when eaten and get respawned after a while).

I have other items in the game that will have user interaction, like mud which can be picked up and thrown at other users to slow them down.

I'm not sure as to what classes I should use for these objects, and how to manage their events as the events are triggered by Player interaction but "executed" or done on the object or other player.

Reading the tofu code I guessed I might use tofu.RaypickCollidedMobileWithGravity for the falling fruits and maybe tofu.AnimatedModel for the trees but couldn't get far. I haven't even been able to get my "interactive" models displayed on the scene.

Is there any documentation or other code examples appart from the tofu code and demo to study? A short snippet describing how to add such an object in a scene would do most of the trick :)


Thanks,

Nico.

_______________________________________________
Soya-user mailing list
Soya-user@gna.org
https://mail.gna.org/listinfo/soya-user

# TOFU
# Copyright (C) 2005-2007 Jean-Baptiste LAMY
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

import sys, os, os.path, struct, random
import soya, soya.sphere, soya.cube, soya.tofu as tofu, cerealizer, soya.cerealizer4soya, soya.sdlconst as sdlconst, soya.widget, soya.label3d
from soya.tofu.sides import *

soya.path.append(os.path.join(os.path.dirname(sys.argv[0]), "data"))

tofu.SAVED_GAME_DIR = "/tmp/tofu_demo"

mode = sys.argv[1][2:]
tofu.set_side(mode)


class PlayerID(tofu.PlayerID):
  def __init__(self, filename, password):
    tofu.PlayerID.__init__(self, filename, password)

tofu.LOAD_PLAYER_ID = PlayerID.loads


class Player(tofu.Player):
  def __init__(self, player_id):
    tofu.Player.__init__(self, player_id)
    
    level = tofu.Level.get("demo")
    
    mobile = PlayerMobile()
    mobile.set_xyz(108.0, -6.0, 107.0)
    label = soya.label3d.Label3D(mobile, player_id.filename)
    label.y = 3
    label.lit = 0
    label.auto_flip = 1
    mobile.level = level
    self.add_mobile(mobile)

    
tofu.CREATE_PLAYER = Player

class MainLoop(tofu.MainLoop):
  def begin_round(self):
    self.events = soya.process_event()
    tofu.MainLoop.begin_round(self)
   
      
class Level(tofu.Level):
  def __init__(self):
    tofu.Level.__init__(self)
    

def create_demo_level():
  
  level = Level()
  level.static_part = static_part = soya.World(level)

  terrain = soya.Terrain(static_part)
  terrain.from_image(soya.Image.get("mapK.png"))
  terrain.multiply_height(50.0)
  terrain.scale_factor = 1.5
  terrain.texture_factor = 1.0
  terrain.y = -35.0
  terrain.set_material_layer(soya.Material.get("ground" ),  0.0,  26.5)
  terrain.set_material_layer(soya.Material.get("grass"), 26.5,  30.0)
  terrain.set_material_layer(soya.Material.get("snow"  ), 30.0,  50.0)

  lado1 = {}
  lado2 = {}
  
  lado1["banio"] = soya.Body(static_part, soya.Model.get("banio"))
  lado1["banio"].set_xyz(32.0, 2.6, 40.0)
  lado1["puerta"] = soya.Body(static_part, soya.Model.get("puerta"))
  lado1["puerta"].set_xyz(32.0, 2.6, 40.0)
  lado1["trono"] = soya.Body(static_part, soya.Model.get("kgadero"))
  lado1["trono"].set_xyz(27.0, 3.4, 38.0)

  lado2["banio"] = soya.Body(static_part, soya.Model.get("banio"))
  lado2["banio"].set_xyz(165.0, 2.6, 165.0)
#  lado2["trono"].rotate_y(140.0)
  lado2["trono"] = soya.Body(static_part, soya.Model.get("kgadero"))
  lado2["trono"].set_xyz(160.0, 3.4, 163.0)
  
  arbolito1 = soya.Body(static_part, soya.Model.get("arbolito"))
  arbolito1.set_xyz(90.0, -8.1, 107.0)
  
  sun = soya.Light(static_part)
  sun.directional = 1
  sun.diffuse = (1.0, 0.8, 0.4, 1.0)
  sun.rotate_x(-45.0)

  level.atmosphere = soya.SkyAtmosphere()
  level.atmosphere.ambient = (0.3, 0.3, 0.4, 1.0)
  level.atmosphere.fog = 1
  level.atmosphere.fog_type  = 0
  level.atmosphere.fog_start = 20.0
  level.atmosphere.fog_end   = 50.0
  level.atmosphere.fog_color = level.atmosphere.bg_color = (0.2, 0.5, 0.7, 1.0)
  level.atmosphere.skyplane  = 1
  level.atmosphere.sky_color = (1.5, 1.0, 0.8, 1.0)
  
  def create(Class, position = None, front = None, **kargs):
    p = Class(**kargs)
    level.add_mobile(p)
    if position: p.move(position)
    if front   : p.look_at(front)
    return p
  
  pera1 = FallingStaticItem("pera")
  pera1.spawn(level, soya.Point(None, 90.0, -7, 107.0))
  pera2 = FallingStaticItem("pera")
  pera2.spawn(level, soya.Point(None, 87.0, -7.8, 109.0))
  pera3 = FallingStaticItem("pera")
  pera3.spawn(level, soya.Point(None, 84.0, -7.6, 108.0))
  
  static_part.filename = "demo_static_part"; static_part.save()
  level      .filename = "demo"            ; level      .save()
  
  level.discard()


ACTION_TAKEN         = "t"

class FallingStaticItem(tofu.SpeedInterpolatedMobile, tofu.RaypickCollidedMobileWithGravity, Multisided):
  @side ("single", "client")
  def __init__(self, filename):
    super(FallingStaticItem, self).__init__()
    self.model = soya.Model.get(filename)
    self.bot = 1
    self.filename = filename
    self.local = 0
    self.solid = 1
    self.radius = 1
    
  @side("server")
  def __init__(self, filename):
    super(FallingStaticItem, self).__init__()
    self.model = soya.Model.get(filename)
    self.bot = 1
    self.filename = filename
    self.local = 1
    self.solid = 1
    self.radius = 1
    
  def spawn(self, level, position=None):
    level.add_mobile(self)
    if position:
      self.move(position)
    self.visible = 1

  def generate_actions(self):
    for character in [char for char in self.level.mobiles
                      if isinstance(char, PlayerMobile)]:
      if self.distance_to(character.center) < self.radius*4:
        self.send_action(ACTION_TAKEN)
        character.send_action(ACTION_FEED)

  def do_action(self, action, character=None):
    if action == ACTION_TAKEN:
# This Works 
      self.speed.y = .1

# This does not work
#      self.scale = (0.5,0.5,0.5)
#      self.send_action("invisible")
#      self.visible = 0

cerealizer.register(FallingStaticItem)


ACTION_MOVE_FORWARD  = "^"
ACTION_STOP_MOVING   = "-"
ACTION_MOVE_BACKWARD = "v"
ACTION_TURN_LEFT     = "<"
ACTION_STOP_TURNING  = "|"
ACTION_TURN_RIGHT    = ">"
ACTION_JUMP          = "J"
ACTION_FEED          = "f"


CONTROL_KEYS = [
  [sdlconst.K_UP, sdlconst.K_DOWN, sdlconst.K_LEFT, sdlconst.K_RIGHT, sdlconst.K_LSHIFT], # Local player #1
  [sdlconst.K_e, sdlconst.K_x, sdlconst.K_s, sdlconst.K_d, sdlconst.K_z],                 # Local player #2
  [sdlconst.K_y, sdlconst.K_b, sdlconst.K_g, sdlconst.K_h, sdlconst.K_t],                 # Local player #3
  ]

STATES = {"CAGO":"Cagaste!", "VACIO":"Come!", "LLENO":"Caga!", "LEJOS":"Acercate!"}
TEMP_STATES = ["CAGO", "LEJOS"]
Game_Interface= soya.widget.Group()
GI_state = soya.widget.Label(Game_Interface, "")


class PlayerMobile(tofu.SpeedInterpolatedMobile, tofu.AnimatedMobile, tofu.RaypickCollidedMobileWithGravity):
  def __init__(self, filename=None):
    super(PlayerMobile, self).__init__()
    
    self.model        = soya.AnimatedModel.get("balazar")
    self.control_keys = CONTROL_KEYS[0]

    self.state = "VACIO"
    self.previous_state = None
    self.food = 0
    self.eaten = []
    
  def generate_actions(self):
      
    for event in soya.MAIN_LOOP.events:
      if   event[0] == sdlconst.KEYDOWN:
        if   (event[1] == sdlconst.K_q) or (event[1] == sdlconst.K_ESCAPE): soya.MAIN_LOOP.stop()
        elif event[1] == self.control_keys[0]: self.send_action(ACTION_MOVE_FORWARD)
        elif event[1] == self.control_keys[1]: self.send_action(ACTION_MOVE_BACKWARD)
        elif event[1] == self.control_keys[2]: self.send_action(ACTION_TURN_LEFT)
        elif event[1] == self.control_keys[3]: self.send_action(ACTION_TURN_RIGHT)
        elif event[1] == self.control_keys[4]: self.send_action(ACTION_JUMP)

        if self.state in TEMP_STATES:
          if self.state == "CAGO":
            self.state = "VACIO"
          else:
            self.state = self.previous_state
          GI_state.set_text(STATES[self.state])

      elif event[0] == sdlconst.KEYUP:
        if   event[1] == self.control_keys[0]: self.send_action(ACTION_STOP_MOVING)
        elif event[1] == self.control_keys[1]: self.send_action(ACTION_STOP_MOVING)
        elif event[1] == self.control_keys[2]: self.send_action(ACTION_STOP_TURNING)
        elif event[1] == self.control_keys[3]: self.send_action(ACTION_STOP_TURNING)


      elif event[0] == sdlconst.MOUSEBUTTONDOWN:
        camera = soya.MAIN_LOOP.camera
        mouse = camera.coord2d_to_3d(event[2], event[3])
        result = self.level.raypick(camera, camera.vector_to(mouse))
        if result:
          self.impact, normal = result
          target = self.impact.parent

          if hasattr(target, "model"):
            if str(target.model) == "<SimpleModel kgadero>":
              if self.state == "LLENO": 
                if self.distance_to(target)< 6.5:
                  self.state = "CAGO"
                  self.food = 0
                  for item in self.eaten:
                    item.spawn(self.level)
                else:
                  if self.state != "LEJOS":
                    self.previous_state = str(self.state)
                  self.state = "LEJOS"
                
            elif str(target.model) == "<SimpleModel puerta>":
              if self.distance_to(target):
                target.turn_y(110.0)

      if self.state != self.previous_state:
        print "A", self.food, self.state
        GI_state.set_text(STATES[self.state])
      
            
        
  def do_action(self, action):
    animation = ""
    if   action == ACTION_MOVE_FORWARD : self.speed.z = -0.35; animation = "marche"
    elif action == ACTION_STOP_MOVING  : self.speed.z =  0.0 ; animation = "attente"
    elif action == ACTION_MOVE_BACKWARD: self.speed.z =  0.2 ; animation = "recule"
    
    elif action == ACTION_TURN_LEFT:
      self.speed.rotate_lateral( 5.0)
      if self.speed.z == 0.0: animation = "tourneG"
      
    elif action == ACTION_STOP_TURNING :
      self.speed.reset_orientation_scaling()
      if self.speed.z == 0.0: animation = "attente"
      
    elif action == ACTION_TURN_RIGHT:
      self.speed.rotate_lateral(-5.0)
      if self.speed.z == 0.0: animation = "tourneD"
      
    elif action == ACTION_JUMP:
      if self.speed.y == 0.0: self.speed.y = 0.6

    if action == ACTION_FEED:
      self.food += 1
      if self.food >= 3:
        self.food = 3
        self.state = "LLENO"
        print "B", self.food, self.state
        GI_state.set_text(STATES[self.state])
    
    if self.speed.y: animation = "chute"
    if animation: self.set_animation(animation)
    
    self.set_current_state_importance(2)
    
  def do_physics(self):
    super(PlayerMobile, self).do_physics()
    
    if    self.speed.y <  0.0: self.set_animation("chute")
    elif (self.speed.y == 0.0) and (self.current_animation == "chute"):
      if   self.speed.z < 0.0: self.set_animation("marche")
      elif self.speed.z > 0.0: self.set_animation("recule")
      else:                    self.set_animation("attente")
      
  def control_owned(self):
    super(PlayerMobile, self).control_owned()

    local_mobiles = [mobile for mobile in self.level.mobiles if mobile.local]
    
    self.control_keys = CONTROL_KEYS[min(len(local_mobiles), len(CONTROL_KEYS)) - 1]

    if len(local_mobiles) == 1:
      soya.MAIN_LOOP.camera = soya.TravelingCamera(soya.MAIN_LOOP.scenes[0])
      soya.MAIN_LOOP.camera.back = 90.0
      group = soya.widget.Group()
      group.add(soya.MAIN_LOOP.camera)
      soya.widget.FPSLabel(group)
      soya.set_root_widget(group)

      traveling = soya.ThirdPersonTraveling(self)
      traveling.distance = 4.0
      soya.MAIN_LOOP.camera.add_traveling(traveling)
      soya.MAIN_LOOP.camera.zap()

      GI_state.set_text(STATES[self.state])
      Game_Interface.add(GI_state)
      soya.root_widget.add(Game_Interface)


      
  def control_lost(self):
    super(PlayerMobile, self).control_lost()

    if self.control_keys == CONTROL_KEYS[0]:
      soya.MAIN_LOOP.camera.parent.remove(soya.MAIN_LOOP.camera)
      soya.MAIN_LOOP.camera = None
      soya.set_root_widget(None)
      

cerealizer.register(PlayerMobile)
cerealizer.register(Level , soya.cerealizer4soya.SavedInAPathHandler(Level ))
cerealizer.register(Player, soya.cerealizer4soya.SavedInAPathHandler(Player))

if (mode == "server") or (mode == "single"): create_demo_level()
if (mode == "client") or (mode == "single"): soya.init("K-ga-2", 800, 600, 0)
  
if (mode == "single"): logins = sys.argv[2:]
  
if (mode == "client"):
  tofu.HOST = sys.argv[2]
  logins = sys.argv[3:]

if (mode == "client") or (mode == "single"):
  tofu.PLAYER_IDS = [PlayerID(login, "test") for login in logins]

  
main_loop = MainLoop()

main_loop.main_loop()
_______________________________________________
Soya-user mailing list
Soya-user@gna.org
https://mail.gna.org/listinfo/soya-user

Reply via email to