from ursina import *
from ursina.prefabs.first_person_controller import First_Person_Controller
import random
app = Ursina()
# — Environment —
# The Ground/Base
ground = Entity(model=‘cube’, collider=‘box’, scale=(64, 1, 64), texture=‘white_cube’, color=color.dark_gray)
# Walls of the Base
wall_1 = Entity(model=‘cube’, collider=‘box’, scale=(64, 5, 1), pos=(0, 2.5, 32), texture=‘white_cube’, color=color.gray)
wall_2 = Entity(model=‘cube’, collider=‘box’, scale=(64, 5, 1), pos=(0, 2.5, -32), texture=‘white_cube’, color=color.gray)
wall_3 = Entity(model=‘cube’, collider=‘box’, scale=(1, 5, 64), pos=(32, 2.5, 0), texture=‘white_cube’, color=color.gray)
wall_4 = Entity(model=‘cube’, collider=‘box’, scale=(1, 5, 64), pos=(-32, 2.5, 0), texture=‘white_cube’, color=color.gray)
# — Player & Weapon —
player = First_Person_Controller()
player.cursor.visible = True
gun = Entity(model=‘cube’, parent=camera.ui, scale=(0.1, 0.1, 0.4), pos=(0.5, -0.4, 0.5), color=color.black)
# — Game Logic —
zombies = []
score = 0
score_text = Text(text=f’Score: {score}', position=(-0.8, 0.45), scale=2)
def input(key):
if key == 'left mouse down':
\# Shooting logic
bullet = Entity(model='sphere', scale=0.2, color=color.yellow, pos=player.position + (0,1.5,0) + camera.forward, collider='sphere')
bullet.animate_position(bullet.position + (camera.forward \* 50), duration=0.5, curve=curve.linear)
destroy(bullet, delay=0.5)
\# Check for hits
hit_info = raycast(camera.world_position, camera.forward, distance=50)
if hit_info.hit:
if hit_info.entity in zombies:
destroy(hit_info.entity)
zombies.remove(hit_info.entity)
update_score()
def update_score():
global score
score += 1
score_text.text = f'Score: {score}'
# — Enemies —
class Zombie(Entity):
def \__init_\_(self, \*\*kwargs):
super().\__init_\_(model='cube', color=color.green, scale=(1, 2, 1), collider='box', \*\*kwargs)
def update(self):
\# Move towards player
dist = distance(self.position, player.position)
if dist > 1:
self.look_at(player.position)
self.position += self.forward \* time.dt \* 3
if dist < 1.5:
print("Game Over! The zombies got you.")
quit()
def spawn_zombie():
x = random.randint(-30, 30)
z = random.randint(-30, 30)
\# Don't spawn on top of the player
if abs(x) > 5 or abs(z) > 5:
new_zombie = Zombie(position=(x, 1, z))
zombies.append(new_zombie)
\# Repeat spawning every 2 seconds
invoke(spawn_zombie, delay=2)
spawn_zombi
e()
# Lighting
Sky()
DirectionalLight(y=2, z=3, shadows=True)
app.run()