Skip to content

Commit

Permalink
Added basic Multiplayer!
Browse files Browse the repository at this point in the history
  • Loading branch information
mandaw2014 committed Apr 19, 2022
1 parent 44a8883 commit bae451f
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 13 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Rally

A Simple 3D Racing (Rally) Game Made In Python With The Ursina Engine
A Simple 3D Racing Game Made In Python With The Ursina Engine

So far the game includes:

Expand All @@ -16,6 +16,8 @@ Camera Shake

A Garage where you can change the colour of the car

Multiplayer

So far I have been working on this game for a month. Feel free to leave comments or feedback on how I can improve the game

# Installation
Expand All @@ -38,6 +40,10 @@ python main.py

Then you're all set :)

# Multiplayer

To run multiplayer, run the server.py file, and then run the main.py. This will start a server that you can join with multipler clients. Right now, it's only localhost. You can change this if you want in the code.

# Controls

W - Drive
Expand Down
17 changes: 14 additions & 3 deletions car.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@
sign = lambda x: -1 if x < 0 else (1 if x > 0 else 0)

class Car(Entity):
def __init__(self, position = (0, 0, 0), topspeed = 25, acceleration = 0.4, friction = 0.6, camera_speed = 8, drift_speed = 35):
def __init__(self, position = (0, 0, 0), rotation = (0, 65, 0), topspeed = 25, acceleration = 0.4, friction = 0.6, camera_speed = 8, drift_speed = 35):
super().__init__(
model = "car.obj",
texture = "car-red.png",
position = position,
rotation = (0, 65, 0),
rotation = rotation,
collider = "box",
scale = (1, 1, 1)
)
Expand Down Expand Up @@ -308,4 +308,15 @@ def update_camera_pos(self):
def shake_camera(self):
camera.x += random.randint(-1, 1) * self.shake_amount
camera.y += random.randint(-1, 1) * self.shake_amount
camera.z += random.randint(-1, 1) * self.shake_amount
camera.z += random.randint(-1, 1) * self.shake_amount

class CarRepresentation(Entity):
def __init__(self, position = (0, 0, 0), rotation = (0, 65, 0)):
super().__init__(
parent = scene,
model = "car.obj",
texture = "car-red.png",
position = position,
rotation = rotation,
scale = (1, 1, 1)
)
73 changes: 64 additions & 9 deletions main.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,20 @@
from ursina import *
from ursinanetworking import *
from direct.stdpy import thread
# from direct.actor.Actor import Actor

from car import Car
from car import Car, CarRepresentation

from main_menu import MainMenu

from tracks.sand_track import SandTrack
from tracks.grass_track import GrassTrack
from tracks.snow_track import SnowTrack

# application.development_mode = False

app = Ursina()
window.borderless = False
window.fullscreen = True
window.cog_button.disable()
window.show_ursina_splash = True

# Loading car textures
Expand All @@ -27,7 +28,7 @@ def load_car_textures():
except Exception as e:
print("error starting thread", e)

car = Car((0, 0, 4), topspeed = 30)
car = Car((0, 0, 4), (0, 0, 0), topspeed = 30)
car.disable()

sand_track = SandTrack(car)
Expand All @@ -38,19 +39,73 @@ def load_car_textures():
car.grass_track = grass_track
car.snow_track = snow_track

main_menu = MainMenu(car, sand_track, grass_track, snow_track)
car.multiplayer = True

# ai_car = Entity(position = (0, 0, 0), rotation = (0, 0, 0), scale = (1, 1, 1))
# actor = Actor("./assets/ai/ai_car.gltf", {"drive": "./assets/ai/ai_car.gltf"})
# actor.reparentTo(ai_car)
# actor.loop("drive")
main_menu = MainMenu(car, sand_track, grass_track, snow_track)

PointLight(parent = camera, color = color.white, position = (0, 10, -1.5))
AmbientLight(color = color.rgba(100, 100, 100, 0.1))

Sky()

if car.multiplayer == True:
client = UrsinaNetworkingClient("localhost", 25565)
easy = EasyUrsinaNetworkingClient(client)

players = {}
players_target_pos = {}
players_target_rot = {}

selfId = -1

@client.event
def GetId(id):
global selfId
selfId = id
print(f"My ID is : {selfId}")

@easy.event
def onReplicatedVariableCreated(variable):
global client
variable_name = variable.name
variable_type = variable.content["type"]

if variable_type == "player":
players_target_pos[variable_name] = Vec3(-80, -30, 15)
players_target_rot[variable_name] = Vec3(0, 90, 0)
players[variable_name] = CarRepresentation((-80, -30, 15), (0, 90, 0))

if selfId == int(variable.content["id"]):
players[variable_name].color = color.red
players[variable_name].visible = False

@easy.event
def onReplicatedVariableUpdated(variable):
players_target_pos[variable.name] = variable.content["position"]
players_target_rot[variable.name] = variable.content["rotation"]

@easy.event
def onReplicatedVariableRemoved(variable):
variable_name = variable.name
variable_type = variable.content["type"]

if variable_type == "player":
destroy(players[variable_name])
del players[variable_name]

def update():
if car.multiplayer == True:
for p in players:
players[p].position += (Vec3(players_target_pos[p]) - players[p].position) / 25
players[p].rotation += (Vec3(players_target_rot[p]) - players[p].rotation) / 25

easy.process_net_events()

def input(key):
if car.multiplayer == True:
client.send_message("MyPosition", tuple(car.position))
client.send_message("MyRotation", tuple(car.rotation))

if main_menu.main_menu.enabled == False and main_menu.settings_menu.enabled == False and main_menu.maps_menu.enabled == False and main_menu.garage_menu.enabled == False and main_menu.controls_menu.enabled == False:
if key == "escape":
main_menu.pause_menu.enabled = not main_menu.pause_menu.enabled
Expand Down
1 change: 1 addition & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
ursina==4.1.1
ursinanetworking==2.1.4
numpy
31 changes: 31 additions & 0 deletions server.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
from ursina import *
from ursinanetworking import *

print("Hello from the Server!")

server = UrsinaNetworkingServer("localhost", 25565)
easy = EasyUrsinaNetworkingServer(server)

@server.event
def onClientConnected(client):
easy.create_replicated_variable(
f"player_{client.id}",
{ "type" : "player", "id" : client.id, "position": (0, 0, 0), "rotation" : (0, 0, 0)}
)
print(f"{client} connected!")
client.send_message("GetId", client.id)

@server.event
def onClientDisconnected(client):
easy.remove_replicated_variable_by_name(f"player_{client.id}")

@server.event
def MyPosition(client, newpos):
easy.update_replicated_variable_by_name(f"player_{client.id}", "position", newpos)

@server.event
def MyRotation(client, newrot):
easy.update_replicated_variable_by_name(f"player_{client.id}", "rotation", newrot)

while True:
easy.process_net_events()
8 changes: 8 additions & 0 deletions tracks/grass_track.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ def __init__(self, car):

self.wall_trigger = Entity(model = "cube", position = (25, -40.2, 65), collider = "box", rotation = (0, 90, 0), scale = (40, 20, 3), visible = False)
self.wall_trigger_ramp = Entity(model = "cube", position = (-82, -34, -64), collider = "box", rotation = (0, 90, 0), scale = (40, 20, 3), visible = False)

self.boundaries.disable()
self.wall1.disable()
self.wall2.disable()
self.wall3.disable()
self.wall4.disable()
self.wall_trigger.disable()
self.wall_trigger_ramp.disable()

def update(self):
if self.enabled == True:
Expand Down
14 changes: 14 additions & 0 deletions tracks/snow_track.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,20 @@ def __init__(self, car):
self.disable()
self.finish_line.disable()
self.boundaries.disable()
self.wall1.disable()
self.wall2.disable()
self.wall3.disable()
self.wall4.disable()
self.wall5.disable()
self.wall6.disable()
self.wall7.disable()
self.wall8.disable()
self.wall9.disable()
self.wall10.disable()
self.wall11.disable()
self.wall12.disable()
self.wall_trigger.disable()
self.wall_trigger_end.disable()

def update(self):
if self.enabled == True:
Expand Down

0 comments on commit bae451f

Please sign in to comment.