How to let a player not moving through the another entity(2d)?

I am making a maze game with ursina but I cannot force the player to not go through wall. I have tried to add collider but it doesnt do anything, cuz i must check the collisions than give them codes to execute. I added raycast but it does the same thing as collider.Plss help me

Here is my code.

from ursina import *
from ursina import physics
class top_down_controller(Entity):
    def __init__(self, model, color, scale = 1, texture = None, collider = 'box', ignore=[], position=[0,0]):
        super().__init__(
            model = model,
            color = color,
            scale = scale,
            texture = texture,
            collider = collider,
            ignore = ignore,
            vleft = -0.1,
            vright = 0.1,
            vup = 0.1,
            vdown = -0.1,
            position= position
            )
    def update(self):
        
        self.x += held_keys['a'] * self.vleft
        self.x += held_keys["d"] * self.vright
        self.y += held_keys['w'] * self.vup
        self.y += held_keys['s'] * self.vdown
        above = raycast(self.world_position, self.up, 0.51, ignore=[self], debug = True)
        above_left = raycast(self.world_position+Vec3(-0.5,0,0), self.up, 0.51, ignore = [self], debug = True)
        above_right = raycast(self.world_position+Vec3(0.5,0,0), self.up, 0.51, ignore = [self], debug = True)
        below = raycast(self.world_position, self.down, 0.51, ignore = [self], debug = True)
        below_left = raycast(self.world_position+Vec3(-0.5,0,0), self.down, 0.51, ignore = [self], debug = True)
        below_right = raycast(self.world_position+Vec3(0.5,0,0), self.down, 0.51, ignore = [self], debug = True)
        left = raycast(self.world_position, self.left, 0.51, ignore = [self], debug = True)
        left_above = raycast(self.world_position+Vec3(0,0.5,0), self.left, 0.51, ignore = [self], debug = True)
        left_down = raycast(self.world_position+Vec3(0,-0.5,0), self.left, 0.51, ignore = [self], debug = True)
        right = raycast(self.world_position, self.right, 0.51, ignore = [self], debug=True)
        right_above = raycast(self.world_position+Vec3(0,0.5,0), self.right, 0.51, ignore = [self], debug = True)
        right_down = raycast(self.world_position+Vec3(0,-0.5,0), self.right, 0.51, ignore = [self], debug = True)
        if any((above.hit, above_left.hit, above_right.hit)):
            self.vup = 0
        elif any((left.hit, left_above.hit, left_down.hit)):
            self.vleft = 0
        elif any((right.hit, right_above.hit, right_down.hit)):
            self.vright = 0
        elif any((below_right.hit, below.hit, below_left.hit)):
            self.vdown = 0
app  = Ursina()
e1 = Entity(model = 'quad', color = color.green, collider = 'box')
e = top_down_controller(model = 'quad', color = color.blue, position = [2,2], ignore = [e1])

app.run()

Upvotes: 0

Views: 60

Answers (1)

ali M
ali M

Reputation: 3

the problem was :raycast checking was incorrect because when "w" is pressed it must check for the top raycast but checked for the bottom one so the player gone through the wall until the bottom raycast hit the wall. which started from the middle of the player so half of the player would enter the wall until the wall hit bottom raycast.

I changed it so it will check for all controls separately. changed w with s and a with d in held_keys so you don't have to change raycasts definition ((change bottom with top and left with right. it takes a long time:( )) and added else so if the player is no longer hitting the wall it will be enabled again (I also wanted to upload a pic that explains more but I cant) fixed code:

from ursina import *
class top_down_controller(Entity):
    def __init__(self, model, color, scale = 1, texture = None, collider = 'box', ignore=[], position=[0,0]):
        super().__init__(
            model = model,
            color = color,
            scale = scale,
            texture = texture,
            collider = collider,
            ignore = ignore,
            vleft = -0.1,
            vright = 0.1,
            vup = 0.1,
            vdown = -0.1,
            position= position
            )
    def update(self):
        self.x += held_keys['d'] * self.vleft
        self.x += held_keys["a"] * self.vright
        self.y += held_keys['s'] * self.vup
        self.y += held_keys['w'] * self.vdown
        above = raycast(self.world_position, self.up, 0.51, ignore=[self], debug = True)
        above_left = raycast(self.world_position+Vec3(-0.5,0,0), self.up, 0.51, ignore = [self], debug = True)
        above_right = raycast(self.world_position+Vec3(0.5,0,0), self.up, 0.51, ignore = [self], debug = True)
        below = raycast(self.world_position, self.down, 0.51, ignore = [self], debug = True)
        below_left = raycast(self.world_position+Vec3(-0.5,0,0), self.down, 0.51, ignore = [self], debug = True)
        below_right = raycast(self.world_position+Vec3(0.5,0,0), self.down, 0.51, ignore = [self], debug = True)
        left = raycast(self.world_position, self.left, 0.51, ignore = [self], debug = True)
        left_above = raycast(self.world_position+Vec3(0,0.5,0), self.left, 0.51, ignore = [self], debug = True)
        left_down = raycast(self.world_position+Vec3(0,-0.5,0), self.left, 0.51, ignore = [self], debug = True)
        right = raycast(self.world_position, self.right, 0.51, ignore = [self], debug=True)
        right_above = raycast(self.world_position+Vec3(0,0.5,0), self.right, 0.51, ignore = [self], debug = True)
        right_down = raycast(self.world_position+Vec3(0,-0.5,0), self.right, 0.51, ignore = [self], debug = True)
        if any((above.hit, above_left.hit, above_right.hit)):
            self.vup = 0
        else:
            self.vup = 0.1
        if any((left.hit, left_above.hit, left_down.hit)):
            self.vleft = 0
        else:
            self.vleft = -0.1
        if any((right.hit, right_above.hit, right_down.hit)):
         self.vright = 0
        else:
            self.vright = 0.1

        if any((below_right.hit, below.hit, below_left.hit)):
            self.vdown = 0
        else:
            self.vdown = -0.1
app  = Ursina()
e1 = Entity(model = 'quad', color = color.green, collider = 'box')
e = top_down_controller(model = 'quad', color = color.blue, position = [2,2])

app.run()

Upvotes: 0

Related Questions