client.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123
  1. # all imports needed by the engine itself
  2. from direct.showbase.ShowBase import ShowBase
  3. # initialize the engine
  4. base = ShowBase()
  5. # initialize the client
  6. from direct.distributed.ClientRepository import ClientRepository
  7. from panda3d.core import URLSpec, ConfigVariableInt, ConfigVariableString
  8. from direct.gui.OnscreenText import OnscreenText
  9. from panda3d.core import TextNode
  10. base.accept("escape", exit)
  11. # Function to put instructions on the screen.
  12. def addInstructions(pos, msg):
  13. return OnscreenText(text=msg, style=1, fg=(0, 0, 0, 1), shadow=(1, 1, 1, 1),
  14. parent=base.a2dTopLeft, align=TextNode.ALeft,
  15. pos=(0.08, -pos - 0.04), scale=.06)
  16. # Function to put title on the screen.
  17. def addTitle(text):
  18. return OnscreenText(text=text, style=1, pos=(-0.1, 0.09), scale=.08,
  19. parent=base.a2dBottomRight, align=TextNode.ARight,
  20. fg=(1, 1, 1, 1), shadow=(0, 0, 0, 1))
  21. title = addTitle("Panda3D: Tutorial - Distributed Network (NOT CONNECTED)")
  22. inst2 = addInstructions(0.06, "esc: Close the client")
  23. inst2 = addInstructions(0.12, "See console output")
  24. def setConnectedMessage():
  25. title["text"] = "Panda3D: Tutorial - Distributed Network (CONNECTED)"
  26. base.accept("client-ready", setConnectedMessage)
  27. #
  28. # CLIENT
  29. #
  30. class GameClientRepository(ClientRepository):
  31. def __init__(self):
  32. dcFileNames = ['../direct.dc']
  33. # a distributed object of our game.
  34. self.distributedObject = None
  35. self.aiDGameObect = None
  36. ClientRepository.__init__(
  37. self,
  38. dcFileNames = dcFileNames,
  39. threadedNet = True)
  40. # Set the same port as configured on the server to be able to connect
  41. # to it
  42. tcpPort = ConfigVariableInt('server-port', 4400).getValue()
  43. # Set the IP or hostname of the server we want to connect to
  44. hostname = ConfigVariableString('server-host', '127.0.0.1').getValue()
  45. # Build the URL from the server hostname and port. If your server
  46. # uses another protocol then http you should change it accordingly.
  47. # Make sure to pass the connectMethod to the ClientRepository.__init__
  48. # call too. Available connection methods are:
  49. # self.CM_HTTP, self.CM_NET and self.CM_NATIVE
  50. self.url = URLSpec('http://{}:{}'.format(hostname, tcpPort))
  51. # Attempt a connection to the server
  52. self.connect([self.url],
  53. successCallback = self.connectSuccess,
  54. failureCallback = self.connectFailure)
  55. def lostConnection(self):
  56. """ This should be overridden by a derived class to handle an
  57. unexpectedly lost connection to the gameserver. """
  58. # Handle the disconnection from the server. This can be a reconnect,
  59. # simply exiting the application or anything else.
  60. exit()
  61. def connectFailure(self, statusCode, statusString):
  62. """ Something went wrong """
  63. # here we could create a reconnect task to try and connect again.
  64. exit()
  65. def connectSuccess(self):
  66. """ Successfully connected. But we still can't really do
  67. anything until we've got the doID range. """
  68. # Mark interest for zone 1, 2 and 3. There won't be anything in them,
  69. # it's just to display how it works for this small example.
  70. self.setInterestZones([1, 2, 3])
  71. # This method checks whether we actually have a valid doID range
  72. # to create distributed objects yet
  73. if self.haveCreateAuthority():
  74. # we already have one
  75. self.gotCreateReady()
  76. else:
  77. # Not yet, keep waiting a bit longer.
  78. self.accept(self.uniqueName('createReady'), self.gotCreateReady)
  79. def gotCreateReady(self):
  80. """ Ready to enter the world. Expand our interest to include
  81. any other zones """
  82. # This method checks whether we actually have a valid doID range
  83. # to create distributed objects yet
  84. if not self.haveCreateAuthority():
  85. # Not ready yet.
  86. return
  87. # we are ready now, so ignore further createReady events
  88. self.ignore(self.uniqueName('createReady'))
  89. print("Client Ready")
  90. base.messenger.send("client-ready")
  91. # Start the client
  92. GameClientRepository()
  93. base.run()