Length of laser display

=======game======
from Game_Configure7 import *
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
story = '''Story
When codemao went out to find a gift 
for a small partner who liked it, a group 
of exotic animals would be able to take it 
away. Codemao finds where they hide, but 
it's hard to save a little, and use your 
ingenuity to help codemao!
'''
control = ''' Control 
w   ----   up
s   ----   down 
a   ----   left
d   ----   right
mouse_left ---- shoot

'''


class Game_Run(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        #self.disableMouse()
        self.configure = myConfigure(1400, 1000, 'map')
        self.configure.Window()
        self.text_1 = self.configure.Screen_Text(text_text=story, pos_pos=(0, 0.75), bg_bg=(0.7, 0.4, 0.8, 1),scale_scale=0.1,)
        self.text_2 = self.configure.Screen_Text(text_text=control, pos_pos=(0, 0), bg_bg=(0.3, 0.6, 0.9, 1),scale_scale=0.1)
        self.dialog_1 = self.configure.Dialog(frameSize_frameSize=(-0.5, 0.5, 0.1, -0.1), fadeScreen_fadeScreen=1,pos_pos=(0, 0, -0.8), color_color=(0.1, 0.9, 0.9, 1))
        self.button_1 = self.configure.Button(text_text='Start Game', parent_parent=self.dialog_1, command_command=self.Start, scale_scale=0.15,pos_pos=(0, 0, -0.05))
        self.dialog_1['frameTexture'] = 'brass.png'
        self.text_1['frame'] = (0.8, 0.6, 0.7, 1)
        self.text_2['frame'] = (0.8, 0.9, 0.7, 1)
        self.configure.Fence((-580, 0, 0, 580, 0, 0, 5), (0, 350, 0))
        self.configure.Fence((-580, 0, 0, 580, 0, 0, 5), (0, -350, 0))
        self.configure.Fence((0, -350, 0, 0, 350, 0, 5), (580, 0, 0))
        self.configure.Fence((0, -40, 0, 0, 350, 0, 5), (-580, 0, 0))
        self.configure.Fence((0, -150, 0, 0, -350, 0, 5), (-580, 0, 0))
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (33, 270, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (20, 260, 0))
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (33, 250, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (45, 260, 0))
        
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (-45, 310, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (-58, 300, 0))
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (-45, 290, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (-33, 300, 0))
        self.pusher = CollisionHandlerPusher()
        self.cTrav = CollisionTraverser()
        self.pusher.setHorizontal(True)
        self.state = {
            "up": False,
            "down": False,
            "left": False,
            "right": False,
            "shoot": False
        }
        self.accept('w', self.UpdateState, ['up', True])
        self.accept('w-up', self.UpdateState, ['up', False])
        self.accept('s', self.UpdateState, ['down', True])
        self.accept('s-up', self.UpdateState, ['down', False])
        self.accept('a',self.UpdateState, ['left', True])
        self.accept('a-up', self.UpdateState, ['left', False])
        self.accept('d', self.UpdateState, ['right', True])
        self.accept('d-up', self.UpdateState, ['right', False])
        self.accept('mouse1', self.UpdateState, ['shoot', True])
        self.accept('mouse1-up', self.UpdateState, ['shoot', False])

        # hLight = AmbientLight("ambient light")
        # hLight.setColor((0.1, 0.1, 0.1, 1))
        # self.hlnp = render.attachNewNode(hLight)
        # render.setLight(self.hlnp)
        self.search_speed = Vec3(0, 50, 0)
        self.varyangle = Vec2(0, 1)
        self.pusher.add_in_pattern("%fn-into-%in")
        self.accept('wood-into-fence', self.Change)
        self.accept('player-into-needle', self.Attach)

    def Attach(self,entry):
        print('Hello!')

    def Change(self,entry):
        self.search_speed = -self.search_speed
        self.varyangle = -self.varyangle

    def Start(self):
        self.text_1.destroy()


        self.text_2.destroy()
        self.dialog_1.hide()
        self.map_1 = self.configure.Map()
        self.player = Player()
        taskMgr.add(self.update, "update")
        # playerLight = PointLight("move light")
        # playerLight.setColor((1, 1, 1, 1))
        # playerLight.setAttenuation((0.6, 0.01, 0))
        # self.playerlnp = self.player.actor.attachNewNode(playerLight)
        # self.playerlnp.setPos(0,0,100)
        # render.setLight(self.playerlnp)
        base.camLens.setFov(60)
        self.woodmen = Enemy_woodmen()
        self.needle = Enemy_needle()

    def UpdateState(self, controlName, controlState):
        self.state[controlName] = controlState
    def update(self, task):
        dt = globalClock.getDt()
        self.player.update(self.state,dt)
        self.woodmen.update(self.player,self.search_speed,self.varyangle,dt)
        return Task.cont

    
game = Game_Run()
game.run()

========Game_Configure7===========
from panda3d.core import *
from panda3d.core import TextNode
from direct.gui.DirectGui import *
from direct.actor.Actor import Actor
import random

class myConfigure():
    def __init__(self, Width, Height, Model):
        self.width = Width
        self.height = Height
        self.model = Model
    def Window(self):
        self.window = WindowProperties()
        self.window.setSize(self.width, self.height)
        base.win.requestProperties(self.window)
    def Map(self):
        self.map = loader.loadModel(self.model)
        self.map.reparentTo(render)
        return self.map
    def Screen_Text(self, text_text='Welcome', pos_pos=(-0.8, 0.3), bg_bg=(0.6, 0.4, 0.3, 1), scale_scale=0.1,):
        self.text = OnscreenText(text=text_text,
                                 pos=pos_pos,
                                 bg=bg_bg,
                                 scale=scale_scale,
                                 wordwrap=25)
        return self.text
    def Dialog(self, frameSize_frameSize, fadeScreen_fadeScreen, pos_pos, color_color):
        self.dialog = DirectDialog(frameSize=frameSize_frameSize,
                                   fadeScreen=fadeScreen_fadeScreen,
                                   relief=DGG.FLAT)
        self.dialog.setPos(pos_pos)
        self.dialog.setColor(color_color)
        return self.dialog
    def Button(self, text_text, parent_parent, command_command, scale_scale, pos_pos):
        self.button = DirectButton(text=text_text,
                                   parent=parent_parent,
                                   command=command_command,
                                   scale=scale_scale,
                                   pos=pos_pos)
        return self.button
    def Fence(self, size, pos_pos):
        fenceSolid = CollisionTube(size[0], size[1], size[2], size[3], size[4], size[5], size[6])
        fenceNode = CollisionNode("fence")
        fenceNode.addSolid(fenceSolid)
        fence = render.attachNewNode(fenceNode)
        fence.setPos(pos_pos)

class ActorObject():
    def __init__(self, pos, modelName, modelAnims, maxHealth, maxSpeed, modelScale, colliderName):
        self.actor = Actor(modelName, modelAnims)
        self.actor.reparentTo(render)
        self.actor.setPos(pos)
        self.actor.setScale(modelScale)
        self.maxHealth = maxHealth
        self.health = maxHealth
        self.maxspeed = maxSpeed
        self.walking = False
        capsule = CollisionSphere(0, 0, 0, 10)
        colliderNode = CollisionNode(colliderName)
        colliderNode.addSolid(capsule)
        self.collider = self.actor.attachNewNode(colliderNode)
        self.PoAcc = 0
        self.NeAcc = 550.0
        self.velocity = Vec3(0, 7, 0)
    def move(self,dt):
        speed = self.velocity.length()
        if speed > self.maxspeed:
            self.velocity.normalize()
            self.velocity *= self.maxspeed
            speed = self.maxspeed
        if not self.walking:
            respeed = self.NeAcc * dt
            if respeed > speed:
                self.velocity = Vec3(0, 0, 0)
            else:
                respeeda = -self.velocity
                respeeda.normalize()
                respeeda *= respeed
                self.velocity += respeeda
        self.actor.setPos(self.actor.getPos() + self.velocity * dt)
class Player(ActorObject):
    def __init__(self):
        ActorObject.__init__(self,
                             (-50, 0, 0),
                             "codemao",
                             {
                                 "walk": "codemao_walk",
                                 "stand":"codemao_stand"
                             },
                             5,
                             80,
                             0.4,
                             'player'
                             )

        base.pusher.addCollider(self.collider, self.actor)
        base.cTrav.addCollider(self.collider, base.pusher)

        self.ray = CollisionRay(0, 0, 0, 0, -1, 0)
        rayNode = CollisionNode("playerRay")
        rayNode.addSolid(self.ray)
        self.rayCollision  = self.actor.attachNewNode(rayNode)
        #self.rayCollision .show()
        self.rayQueue = CollisionHandlerQueue()
        base.cTrav.addCollider(self.rayCollision , self.rayQueue)


        mask = BitMask32()
        mask.setBit(1)
        self.collider.node().setIntoCollideMask(mask)
        mask = BitMask32()
        mask.setBit(1)
        self.collider.node().setFromCollideMask(mask)

        mask = BitMask32()
        mask.setBit(2)
        rayNode.setFromCollideMask(mask)
        mask = BitMask32()
        rayNode.setIntoCollideMask(mask)


        self.laser_weapon = loader.loadModel("laser")
        self.laser_weapon.reparentTo(self.actor)
        self.laser_weapon.setPos(-30,0,40)
        self.laser_weapon.setLightOff()
        self.laser_weapon.hide()

    def update(self, keys,dt):
        ActorObject.move(self,dt)
        self.acceleration = 600
        self.walking = False
        if keys["up"]:
            self.walking = True
            self.velocity.addY(self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (0, -220, 80))
            self.actor.setH(180)
            base.cam.setH(self.actor.getH()+180)
        if keys["down"]:
            self.walking = True
            self.velocity.addY(-self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (0, 220, 80))
            self.actor.setH(0)
            base.cam.setH(self.actor.getH() + 180)
        if keys["left"]:
            self.walking = True
            self.velocity.addX(-self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (220, 0, 80))
            self.actor.setH(270)
            base.cam.setH(self.actor.getH()+180)
        if keys["right"]:
            self.walking = True
            self.velocity.addX(self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (-220, 0, 80))
            self.actor.setH(90)
            base.cam.setH(self.actor.getH() + 180)
        if self.walking:
            walkControl = self.actor.getAnimControl("walk")
            if not walkControl.isPlaying():
                self.actor.loop("walk")
        else:
            self.actor.stop("walk")
            self.actor.loop("stand")
        if keys["shoot"]:
            if self.rayQueue.getNumEntries() > 0:
                self.rayQueue.sortEntries()
                rayHit = self.rayQueue.getEntry(0)
                hitPos = rayHit.getSurfacePoint(render)
                beamLength = (hitPos -self.actor.getPos() ).length()
                self.laser_weapon.setSy(beamLength)
                self.laser_weapon.show()
        else:
            self.laser_weapon.hide()
class Enemy_woodmen(ActorObject):
    def __init__(self):
        ActorObject.__init__(self,
                             (150, 0, 0),
                             "woodmen",
                             {
                                 "walk": "woodmen_walk",
                                 "stand": "woodmen_stand",
                                 "die":"woodmen_die",
                                 "attack":"woodmen_shoot"
                             },
                             5,
                             10,
                             0.8,
                             'wood'
                             )

        # mask = BitMask32()
        # mask.setBit(2)
        #
        # self.collider.node().setIntoCollideMask(mask)
        base.pusher.addCollider(self.collider, self.actor)
        base.cTrav.addCollider(self.collider, base.pusher)

        self.detectiondistance = 100
        self.acceleration = 200
        self.standard  = Vec2(0, 1)
        self.attackWaitTimer = 0.3
        self.a = 100
    def update(self,player,search_speed,varyangle,dt):
        ActorObject.move(self, dt)
        position_vevtor = player.actor.getPos() - self.actor.getPos()
        position_vevtor2D = position_vevtor.getXy()
        distanceToplayer = position_vevtor2D.length()
        position_vevtor2D.normalize()
        if distanceToplayer > self.detectiondistance:
            self.walking = True
            self.heading = self.standard.signedAngleDeg(varyangle)
            self.velocity = search_speed
        elif distanceToplayer < self.detectiondistance and distanceToplayer > 30:
            self.heading = self.standard.signedAngleDeg(position_vevtor2D)
            self.walking  = True
            self.velocity += position_vevtor * self.acceleration * dt
        elif self.attackWaitTimer > 0 and distanceToplayer <= 30:
            self.heading = self.standard.signedAngleDeg(position_vevtor2D)
            self.walking = False
            self.velocity = Vec3(0, 0, 0)
            self.attackWaitTimer -= dt
            self.actor.setControlEffect('walk', 0)
            self.actor.setControlEffect('attack', 1)
            attackControl = self.actor.getAnimControl("attack")
            if self.attackWaitTimer <= 0 :
                self.attackWaitTimer = random.uniform(0.5, 0.7)
                self.actor.play("attack")
                self.a -= 1
                print(self.a)
        if self.walking:
            self.actor.enableBlend()
            self.actor.setControlEffect('walk', 0.7)
            self.actor.setControlEffect('attack', 0.3)
            walkingControl = self.actor.getAnimControl("walk")
            if not walkingControl.isPlaying():
                self.actor.loop("walk")
                self.actor.loop("attack")
        else:
            self.actor.stop("walk")
            self.actor.stop("attack")
            self.actor.loop("stand")
        self.actor.setH(self.heading + 180)
class Enemy_needle(ActorObject):
    def __init__(self):
        ActorObject.__init__(self,
                             (270, 0, -2),
                             "GroundNeedle",
                             {
                                 "motion": "GroundNeedle_motion",
                                 "stop": "GroundNeedle_stop",
                             },
                             5,
                             0,
                             0.5,
                             'needle'
                             )
        needlenode = NodePath('needlelist')
        for i in range(-220,-50,20):
            needle = needlenode.attachNewNode('needle')
            needle.setPos(40,i,0)
            self.actor.instanceTo(needle)

        for i in range(50,220,20):
            needle = needlenode.attachNewNode('needle')
            needle.setPos(80,i,0)
            self.actor.instanceTo(needle)
        needlenode.reparentTo((render))
        self.actor.loop("motion")[quote="1111, post:1, topic:25333, full:true"]
=======game======
from Game_Configure7 import *
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
story = '''Story
When codemao went out to find a gift 
for a small partner who liked it, a group 
of exotic animals would be able to take it 
away. Codemao finds where they hide, but 
it's hard to save a little, and use your 
ingenuity to help codemao!
'''
control = ''' Control 
w   ----   up
s   ----   down 
a   ----   left
d   ----   right
mouse_left ---- shoot

'''


class Game_Run(ShowBase):
    def __init__(self):
        ShowBase.__init__(self)
        #self.disableMouse()
        self.configure = myConfigure(1400, 1000, 'map')
        self.configure.Window()
        self.text_1 = self.configure.Screen_Text(text_text=story,
                                                 pos_pos=(0, 0.75),
                                                 bg_bg=(0.7, 0.4, 0.8, 1),
                                                 scale_scale=0.1,)
        self.text_2 = self.configure.Screen_Text(text_text=control,
                                                 pos_pos=(0, 0),
                                                 bg_bg=(0.3, 0.6, 0.9, 1),
                                                 scale_scale=0.1)
        self.dialog_1 = self.configure.Dialog(frameSize_frameSize=(-0.5, 0.5, 0.1, -0.1),
                                              fadeScreen_fadeScreen=1,
                                              pos_pos=(0, 0, -0.8),
                                              color_color=(0.1, 0.9, 0.9, 1))
        self.button_1 = self.configure.Button(text_text='Start Game',
                                              parent_parent=self.dialog_1,
                                              command_command=self.Start,
                                              scale_scale=0.15,
                                              pos_pos=(0, 0, -0.05))
        self.dialog_1['frameTexture'] = 'brass.png'
        self.text_1['frame'] = (0.8, 0.6, 0.7, 1)
        self.text_2['frame'] = (0.8, 0.9, 0.7, 1)
        self.configure.Fence((-580, 0, 0, 580, 0, 0, 5), (0, 350, 0))
        self.configure.Fence((-580, 0, 0, 580, 0, 0, 5), (0, -350, 0))
        self.configure.Fence((0, -350, 0, 0, 350, 0, 5), (580, 0, 0))
        self.configure.Fence((0, -40, 0, 0, 350, 0, 5), (-580, 0, 0))
        self.configure.Fence((0, -150, 0, 0, -350, 0, 5), (-580, 0, 0))
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (33, 270, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (20, 260, 0))
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (33, 250, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (45, 260, 0))
        
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (-45, 310, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (-58, 300, 0))
        self.configure.Fence((-8, 0, 0, 8, 0, 0, 5), (-45, 290, 0))
        self.configure.Fence((0, -8, 0, 0, 8, 0, 5), (-33, 300, 0))
        self.pusher = CollisionHandlerPusher()
        self.cTrav = CollisionTraverser()
        self.pusher.setHorizontal(True)
        self.state = {
            "up": False,
            "down": False,
            "left": False,
            "right": False,
            "shoot": False
        }
        self.accept('w', self.UpdateState, ['up', True])
        self.accept('w-up', self.UpdateState, ['up', False])
        self.accept('s', self.UpdateState, ['down', True])
        self.accept('s-up', self.UpdateState, ['down', False])
        self.accept('a',self.UpdateState, ['left', True])
        self.accept('a-up', self.UpdateState, ['left', False])
        self.accept('d', self.UpdateState, ['right', True])
        self.accept('d-up', self.UpdateState, ['right', False])
        self.accept('mouse1', self.UpdateState, ['shoot', True])
        self.accept('mouse1-up', self.UpdateState, ['shoot', False])

        # hLight = AmbientLight("ambient light")
        # hLight.setColor((0.1, 0.1, 0.1, 1))
        # self.hlnp = render.attachNewNode(hLight)
        # render.setLight(self.hlnp)
        self.search_speed = Vec3(0, 50, 0)
        self.varyangle = Vec2(0, 1)
        self.pusher.add_in_pattern("%fn-into-%in")
        self.accept('wood-into-fence', self.Change)
        self.accept('player-into-needle', self.Attach)

    def Attach(self,entry):
        print('Hello!')

    def Change(self,entry):
        self.search_speed = -self.search_speed
        self.varyangle = -self.varyangle

    def Start(self):
        self.text_1.destroy()
        self.text_2.destroy()
        self.dialog_1.hide()
        self.map_1 = self.configure.Map()
        self.player = Player()
        taskMgr.add(self.update, "update")
        # playerLight = PointLight("move light")
        # playerLight.setColor((1, 1, 1, 1))
        # playerLight.setAttenuation((0.6, 0.01, 0))
        # self.playerlnp = self.player.actor.attachNewNode(playerLight)
        # self.playerlnp.setPos(0,0,100)
        # render.setLight(self.playerlnp)
        base.camLens.setFov(60)
        self.woodmen = Enemy_woodmen()
        self.needle = Enemy_needle()

    def UpdateState(self, controlName, controlState):
        self.state[controlName] = controlState
    def update(self, task):
        dt = globalClock.getDt()
        self.player.update(self.state,dt)
        self.woodmen.update(self.player,self.search_speed,self.varyangle,dt)
        return Task.cont

    
game = Game_Run()
game.run()



========Game_Configure7===========
from panda3d.core import *
from panda3d.core import TextNode
from direct.gui.DirectGui import *
from direct.actor.Actor import Actor
import random

class myConfigure():
    def __init__(self, Width, Height, Model):
        self.width = Width
        self.height = Height
        self.model = Model
    def Window(self):
        self.window = WindowProperties()
        self.window.setSize(self.width, self.height)
        base.win.requestProperties(self.window)
    def Map(self):
        self.map = loader.loadModel(self.model)
        self.map.reparentTo(render)
        return self.map
    def Screen_Text(self, text_text='Welcome', pos_pos=(-0.8, 0.3), bg_bg=(0.6, 0.4, 0.3, 1), scale_scale=0.1,):
        self.text = OnscreenText(text=text_text,
                                 pos=pos_pos,
                                 bg=bg_bg,
                                 scale=scale_scale,
                                 wordwrap=25)
        return self.text
    def Dialog(self, frameSize_frameSize, fadeScreen_fadeScreen, pos_pos, color_color):
        self.dialog = DirectDialog(frameSize=frameSize_frameSize,
                                   fadeScreen=fadeScreen_fadeScreen,
                                   relief=DGG.FLAT)
        self.dialog.setPos(pos_pos)
        self.dialog.setColor(color_color)
        return self.dialog
    def Button(self, text_text, parent_parent, command_command, scale_scale, pos_pos):
        self.button = DirectButton(text=text_text,
                                   parent=parent_parent,
                                   command=command_command,
                                   scale=scale_scale,
                                   pos=pos_pos)
        return self.button
    def Fence(self, size, pos_pos):
        fenceSolid = CollisionTube(size[0], size[1], size[2], size[3], size[4], size[5], size[6])
        fenceNode = CollisionNode("fence")
        fenceNode.addSolid(fenceSolid)
        fence = render.attachNewNode(fenceNode)
        fence.setPos(pos_pos)

class ActorObject():
    def __init__(self, pos, modelName, modelAnims, maxHealth, maxSpeed, modelScale, colliderName):
        self.actor = Actor(modelName, modelAnims)
        self.actor.reparentTo(render)
        self.actor.setPos(pos)
        self.actor.setScale(modelScale)
        self.maxHealth = maxHealth
        self.health = maxHealth
        self.maxspeed = maxSpeed
        self.walking = False
        capsule = CollisionSphere(0, 0, 0, 10)
        colliderNode = CollisionNode(colliderName)
        colliderNode.addSolid(capsule)
        self.collider = self.actor.attachNewNode(colliderNode)
        self.PoAcc = 0
        self.NeAcc = 550.0
        self.velocity = Vec3(0, 7, 0)
    def move(self,dt):
        speed = self.velocity.length()
        if speed > self.maxspeed:
            self.velocity.normalize()
            self.velocity *= self.maxspeed
            speed = self.maxspeed
        if not self.walking:
            respeed = self.NeAcc * dt
            if respeed > speed:
                self.velocity = Vec3(0, 0, 0)
            else:
                respeeda = -self.velocity
                respeeda.normalize()
                respeeda *= respeed
                self.velocity += respeeda
        self.actor.setPos(self.actor.getPos() + self.velocity * dt)
class Player(ActorObject):
    def __init__(self):
        ActorObject.__init__(self,
                             (-50, 0, 0),
                             "codemao",
                             {
                                 "walk": "codemao_walk",
                                 "stand":"codemao_stand"
                             },
                             5,
                             80,
                             0.4,
                             'player'
                             )

        base.pusher.addCollider(self.collider, self.actor)
        base.cTrav.addCollider(self.collider, base.pusher)

        self.ray = CollisionRay(0, 0, 0, 0, -1, 0)
        rayNode = CollisionNode("playerRay")
        rayNode.addSolid(self.ray)
        self.rayCollision  = self.actor.attachNewNode(rayNode)
        #self.rayCollision .show()
        self.rayQueue = CollisionHandlerQueue()
        base.cTrav.addCollider(self.rayCollision , self.rayQueue)


        mask = BitMask32()
        mask.setBit(1)
        self.collider.node().setIntoCollideMask(mask)
        mask = BitMask32()
        mask.setBit(1)
        self.collider.node().setFromCollideMask(mask)

        mask = BitMask32()
        mask.setBit(2)
        rayNode.setFromCollideMask(mask)
        mask = BitMask32()
        rayNode.setIntoCollideMask(mask)


        **self.laser_weapon = loader.loadModel("laser")**
**        self.laser_weapon.reparentTo(self.actor)**
**        self.laser_weapon.setPos(-30,0,40)**
**        self.laser_weapon.setLightOff()**
**        self.laser_weapon.hide()**

    def update(self, keys,dt):
        ActorObject.move(self,dt)
        self.acceleration = 600
        self.walking = False
        if keys["up"]:
            self.walking = True
            self.velocity.addY(self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (0, -220, 80))
            self.actor.setH(180)
            base.cam.setH(self.actor.getH()+180)
        if keys["down"]:
            self.walking = True
            self.velocity.addY(-self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (0, 220, 80))
            self.actor.setH(0)
            base.cam.setH(self.actor.getH() + 180)
        if keys["left"]:
            self.walking = True
            self.velocity.addX(-self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (220, 0, 80))
            self.actor.setH(270)
            base.cam.setH(self.actor.getH()+180)
        if keys["right"]:
            self.walking = True
            self.velocity.addX(self.acceleration*dt)
            base.cam.setPos(self.actor.getPos() + (-220, 0, 80))
            self.actor.setH(90)
            base.cam.setH(self.actor.getH() + 180)
        if self.walking:
            walkControl = self.actor.getAnimControl("walk")
            if not walkControl.isPlaying():
                self.actor.loop("walk")
        else:
            self.actor.stop("walk")
            self.actor.loop("stand")
        if keys["shoot"]:
            if self.rayQueue.getNumEntries() > 0:
                self.rayQueue.sortEntries()
                rayHit = self.rayQueue.getEntry(0)
                hitPos = rayHit.getSurfacePoint(render)
                beamLength = (hitPos -self.actor.getPos() ).length()
                self.laser_weapon.setSy(beamLength)
                self.laser_weapon.show()
        else:
            self.laser_weapon.hide()
class Enemy_woodmen(ActorObject):
    def __init__(self):
        ActorObject.__init__(self,
                             (150, 0, 0),
                             "woodmen",
                             {
                                 "walk": "woodmen_walk",
                                 "stand": "woodmen_stand",
                                 "die":"woodmen_die",
                                 "attack":"woodmen_shoot"
                             },
                             5,
                             10,
                             0.8,
                             'wood'
                             )

        # mask = BitMask32()
        # mask.setBit(2)
        #
        # self.collider.node().setIntoCollideMask(mask)
        base.pusher.addCollider(self.collider, self.actor)
        base.cTrav.addCollider(self.collider, base.pusher)

        self.detectiondistance = 100
        self.acceleration = 200
        self.standard  = Vec2(0, 1)
        self.attackWaitTimer = 0.3
        self.a = 100
    def update(self,player,search_speed,varyangle,dt):
        ActorObject.move(self, dt)
        position_vevtor = player.actor.getPos() - self.actor.getPos()
        position_vevtor2D = position_vevtor.getXy()
        distanceToplayer = position_vevtor2D.length()
        position_vevtor2D.normalize()
        if distanceToplayer > self.detectiondistance:
            self.walking = True
            self.heading = self.standard.signedAngleDeg(varyangle)
            self.velocity = search_speed
        elif distanceToplayer < self.detectiondistance and distanceToplayer > 30:
            self.heading = self.standard.signedAngleDeg(position_vevtor2D)
            self.walking  = True
            self.velocity += position_vevtor * self.acceleration * dt
        elif self.attackWaitTimer > 0 and distanceToplayer <= 30:
            self.heading = self.standard.signedAngleDeg(position_vevtor2D)
            self.walking = False
            self.velocity = Vec3(0, 0, 0)
            self.attackWaitTimer -= dt
            self.actor.setControlEffect('walk', 0)
            self.actor.setControlEffect('attack', 1)
            attackControl = self.actor.getAnimControl("attack")
            if self.attackWaitTimer <= 0 :
                self.attackWaitTimer = random.uniform(0.5, 0.7)
                self.actor.play("attack")
                self.a -= 1
                print(self.a)
        if self.walking:
            self.actor.enableBlend()
            self.actor.setControlEffect('walk', 0.7)
            self.actor.setControlEffect('attack', 0.3)
            walkingControl = self.actor.getAnimControl("walk")
            if not walkingControl.isPlaying():
                self.actor.loop("walk")
                self.actor.loop("attack")
        else:
            self.actor.stop("walk")
            self.actor.stop("attack")
            self.actor.loop("stand")
        self.actor.setH(self.heading + 180)
class Enemy_needle(ActorObject):
    def __init__(self):
        ActorObject.__init__(self,
                             (270, 0, -2),
                             "GroundNeedle",
                             {
                                 "motion": "GroundNeedle_motion",
                                 "stop": "GroundNeedle_stop",
                             },
                             5,
                             0,
                             0.5,
                             'needle'
                             )
        needlenode = NodePath('needlelist')
        for i in range(-220,-50,20):
            needle = needlenode.attachNewNode('needle')
            needle.setPos(40,i,0)
            self.actor.instanceTo(needle)

        for i in range(50,220,20):
            needle = needlenode.attachNewNode('needle')
            needle.setPos(80,i,0)
            self.actor.instanceTo(needle)
        needlenode.reparentTo((render))
        self.actor.loop("motion")

Hello, everyone, I have a problem in this program, that is, I loaded a laser for player as a laser weapon self.laser [weapon], and then set the length of the laser by obtaining the distance between the player and the enemy, but no matter how to set the length of the laser, it always shows abnormal, it can’t reach the surface of the enemy, but it is a little bit worse. Who can help me to see this problem!

I don’t really want comb through that entire program to find the piece of code in which you set the length of the laser–could you post an excerpt containing just that code, please?

OK, yes!

        self.laser_weapon = loader.loadModel("laser")
        self.laser_weapon.reparentTo(self.actor)
        self.laser_weapon.setPos(-30,0,40)
        self.laser_weapon.setLightOff()
        self.laser_weapon.hide()

    def update(self, keys,dt):
        ActorObject.move(self,dt)
        self.acceleration = 600
        self.walking = False
       ......
        if keys["shoot"]:
            if self.rayQueue.getNumEntries() > 0:
                self.rayQueue.sortEntries()
                rayHit = self.rayQueue.getEntry(0)
                hitPos = rayHit.getSurfacePoint(render)
                beamLength = (hitPos -self.actor.getPos() ).length()
                self.laser_weapon.setSy(beamLength)
                self.laser_weapon.show()
        else:
            self.laser_weapon.hide()

Ah, thank you! :slight_smile:

Hmm… For the most part, your code looks correct to me. I do note one thing, however:

When you load your laser-model, you set its position to (-30, 0, 40). This means that it’s somewhat offset from the position of your actor, and thus the distance between your actor and the target (which you’re using to calculate the “beam length”) may not quite match the distance between the start of the laser-model and the target.

(Specifically, I’m guessing that the z-coordinate is fine, but that the x-coordinate is the problem.)

If that offset is important, you could perhaps account for it when you calculate the “beam-length”:

If the actor has been modelled facing the x-direction, and thus the laser is offset either forwards or backwards relative to the actor, then you could simply add 30 to or subtract 30 from your “beam length”, as appropriate.

If that doesn’t help, then it’s possible that the problem lies in your beam-model: your code above seems to assume that the beam has a base length of 1.0, and that it starts at (0, 0, 0) and extends forward for 1 unit. If that’s not the case in the actual model, then the scaling may not produce the desired results.

Well, I’ve noticed all the problems you mentioned. But what I want to express is not this problem, but when setting the laser length. When the length exceeds a certain range, the displayed length will not change with the change of the set value. For example, I set 300 to display a length, but when I set 500 to display a length, the displayed length is the same, but the set value does change. I think it has something to do with the lighting or display of the scene? But I turned off all the lights and it didn’t seem to work.

Hmm… Let me see if I’m understanding correctly:

You’re saying that if you modify your code above so that, instead of “self.laser_weapon.setSy(beamLength)” you have “self.laser_weapon.setSy(300)”, you get a laser that’s 300 units long. However, if you modify it so that you have “self.laser_weapon.setSy(500)”, the laser seems to still be 300 units long, not 500. Is that correct?

If so, then I doubt that it’s a matter of lighting. It’s possible, I suppose, that your laser is hitting the camera’s view-distance and being clipped–but if that’s the case, then I would expect the same to happen to your level-geometry, too.

Would you post a screenshot of the bug, please? It might help me to see what’s happening. (The forum should upload the screenshot automatically if you drop the image-file into your reply on this forum.)

Otherwise, what happens if you change the “far”-distance on your camera? (If you’re using the default camera, then you should be able to do this with something like “base.camLens.setFar(<some value>)”.)

I intercepted two pictures of different distances. Now I set the length of the laser to be the distance between the player and the fence, but the length can’t reach the fence in any case.

I tested using the “base. Camlens. Setfar” method, but it didn’t work. And when I load the laser model alone, its length is normal. I don’t know what’s affecting it here.

Hum, very strange.

All right, another thought: Could you perhaps make your collision objects visible? I’m wondering whether it’s not perhaps larger or closer than intended.

To do this, go to the places where collision objects are made. You should have a CollisionNode, which is placed into a NodePath. On that NodePath, call the “show” method.

For example, in your “Fence” method, you create a CollisionNode called “fenceNode”, which is attached to “render”, and the result stored in the variable named “fence”. The return value of “render.attachNewNode”, which is stored in “fence”, is the NodePath. Thus you would call “fence.show()” just after the call to “attachNewNode”.

[edit]
In addition, I do think that the laser looks a little shorter in the case in which the “beamLength” is lesser, which brings me back to the laser model. Could you post the contents of the laser’s egg-file here, please?
[/edit]

By the way, is that enemy a modified version of the one from my tutorial? If so, that’s cool! :slight_smile:

It turned out to be the tutorial you did. That’s great. Thank you very much for this tutorial. It really helped me a lot. A lot of what I’m doing now is done by referring to your tutorial, and I did try to make some changes to some models!


laser is a cylinder in 1 centimeter.

Ah, I’m really glad that you’re finding the tutorial useful! :smiley: I’m happy that it’s proving useful to people. :slight_smile:

Looking at the output that you just posted, it looks like the ray is hitting the expected spot: around 345 on the y-axis. The beam-length is a little shorter than expected–but perhaps your character wasn’t standing at exactly (0, 0, 0). In any case, it’s close enough to 345 that I would still expect the laser to be close to the expected length, and it looks like it isn’t.

Thus right now I’m still inclined to suspect the model. You say that it’s one centimetre–but Panda doesn’t operate in metres or centimetres, instead having an arbitrary “unit”, which, depending on your scaling, could correspond to a variety of measures. Thus it’s hard to say how many units long the model is based on how many centimetres long it is.

So, could you post the actual text-contents of the laser egg-file, please? If you open up your “laser.egg” file, you should find that the contents are just text–and since the model is fairly simple, the file should hopefully not be too long.

OK, I’ve loaded my drawn egg file on it. I used to open the egg file, but I don’t know much about it now. I can’t read it.

laser.egg (23.7 KB)

Hmm… The file does look correct: it goes from roughly 0 to roughly 1 in the forward-direction, which is what I’d expect.

So, another thought: Looking again at the two screenshots that you posted together, I note that the laser appears to end at roughly the same point in both cases. My thought then is that perhaps the collision-objects aren’t quite where we think they are.

So, could you please make your collision-objects visible, and post a screenshot of that?

I described the process for doing so above; let me quote it here for the same of convenience:

To do this, go to the places where collision objects are made. You should have a CollisionNode, which is placed into a NodePath. On that NodePath, call the “show” method.

For example, in your “Fence” method, you create a CollisionNode called “fenceNode”, which is attached to “render”, and the result stored in the variable named “fence”. The return value of “render.attachNewNode”, which is stored in “fence”, is the NodePath. Thus you would call “fence.show()” just after the call to “attachNewNode”.

OK, can you see if this is the result you want to see?

It is what I wanted to see, and that’s very strange. The collider seems to be just where expected.

Hmm… Okay, another idea then: looking again at your code, I see that you’re applying a scale to your player-character’s model. If your laser-model is parented below that character-model, then the character-model’s scale is applied to the laser-model, too. Thus the actual scale that’s applied to your laser is “character-model-scale * laser-model-scale”. And since your character-model is given a scale between 0 and 1–i.e. it’s scaled down–the laser model becomes smaller.

In fact, I think that this very well may be the problem.

If so, then what I suggest is this: Change your “ActorObject” class so that, instead of just having a model, it has a model and a “base” (or whatever you want to call it) NodePath, with the model being parented below the “base” NodePath. Use the “base” NodePath to move and rotate your ActorObject, but apply your scaling value to the model.

This should allow you to parent the laser-model beneath the “base” NodePath, thus having it move and turn with the ActorObject–but since it’s not parented below the model, it shouldn’t take on the model’s scaling.

Oh, it’s really caused by setting the proportion of loading objects. I finally solved this problem. Thank you so much!

1 Like

It’s my pleasure! :slight_smile: I’m sorry that it took so long for us to find the problem!

It doesn’t matter, it also saved me a long time! This really makes me feel very happy! Ha-ha

Then I’m very glad, both that you did so gain, and for having been of service. :slight_smile: