So now i have this issue where i try to make simple melee combat. I started with making a swoosh class ( a collider with a kill function) which is triggered from events i send to player char to return the node it hits.
However i want to trace this node smh to get the instance of my box class which has this node as its attribute, to call self.break method (nonexistent so far). I know that i probably could make a manager script storing every class and get the instance from their instances lists by getting name from automatically generated node names as it contains id and class id, but it be really slow and clumsy solution, which would make me rewrite a lot of start. Is there an easier way?
My swoosh script:
from panda3d.core import CollisionNode, CollisionBox, CollideMask, CollisionHandlerQueue
from reference import REFERENCE
class Swoosh():
NAMEID = 'Swoosh'
def __init__(self,wielder,ctrav):
if wielder.NAMEID != 'apple_char':
print('ya cant attach swoosh to non-player onjects')
self.wielder = wielder
self.node = self.wielder.node.attachNewNode(f'{self.NAMEID}_{self.wielder.NAMEID}')
self.cNode = CollisionNode(f"collision_{self.NAMEID}_{self.wielder.NAMEID}")
self.cNode.setFromCollideMask(CollideMask.bit(0))
self.cNodeP = self.node.attachNewNode(self.cNode)
self.cNode.add_solid(CollisionBox(self.cNodeP.getPos() + (-6, 0, 0), 3, 3, 1.5))
self.cNodeP.setPos(render,self.wielder.node.getPos())
self.qq = CollisionHandlerQueue()
ctrav.addCollider(self.cNodeP, self.qq)
self.cNodeP.show()
def YeetEnemy(self):
if len(self.qq.entries) > 0:
enemy = self.qq.entries[0]
for el in REFERENCE.damageble:
if enemy.getIntoNode().getName().find(el) != -1:
print(f'{enemy.getIntoNode().getName()} is yonked')
self.qq.clear_entries()
and thats the script above aka the char
from panda3d.bullet import BulletTriangleMeshShape, BulletTriangleMesh
from panda3d.bullet import BulletRigidBodyNode
from panda3d.core import CollisionHandlerPusher, CollideMask, CollisionNode, CollisionSphere, CollisionRay, \
CollisionHandlerQueue
from reference import REFERENCE
from Swoosh import Swoosh
class Char():
speed = 20
NAMEID = 'apple_char'
ORIGIN = (0,0,0)
def __init__(self,ctrav,pusher):
x,y,z = self.ORIGIN
self.model = loader.loadModel(REFERENCE.loadTexturePath('slime_1.bam'))
self.node = render.attachNewNode(self.NAMEID)
self.model.setPos(x,y,z)
self.node.setPos(x,y,z)
self.model.reparentTo(self.node)
self.futurepos = self.node.getPos()
self.qq = CollisionHandlerQueue()
self.cNode = CollisionNode(f'{self.NAMEID}')
self.cNodeP = self.model.attachNewNode(self.cNode)
self.cNodeP.setPos(x,y,z)
self.cNode.addSolid(CollisionSphere(center=(x, y, z), radius=2))
self.cNode.setFromCollideMask(CollideMask.bit(0))
self.cNode.setIntoCollideMask(CollideMask.bit(0))
#self.cNodeP.show()
self.gcNode = CollisionNode(f'Gcollision_{self.NAMEID}')
self.GroundColl = CollisionRay()
self.GroundColl.setOrigin(z, y, z)
self.GroundColl.setDirection(0, 0, -1)
self.gcNode.add_solid(self.GroundColl)
self.gcNode.setFromCollideMask(CollideMask.bit(1))
self.gcNodeP = self.node.attachNewNode(self.gcNode)
self.gcNodeP.setPos(self.node,0,0,0)
#self.gcNodeP.show()
self.floater = self.node.attachNewNode(f'camera_{self.NAMEID}')
self.floater.setPos(self.node,0,0,2)
self.floater.show()
ctrav.addCollider(self.gcNodeP, self.qq)
self.cNodeP.show()
pusher.horizontal = True
pusher.addCollider(self.cNodeP, self.node)
ctrav.addCollider(self.cNodeP, pusher)
self.lastDelta = [0,0]
self.node.setScale(2,2,2)
self.swoosh = Swoosh(self,ctrav)
self.cmddict = {
"up": self.Up,
"down": self.Down,
"left": self.Left,
"right": self.Right,
"shoot": self.beep,
'not shoot': self.boop,
'top' : self.top,
'bottom' : self.bottom
}
def Update_state(self,keypass,dt, tup):
self.futurepos = self.node.getPos(self.node)
dx, dy = tup
for k, v in keypass.items():
if v:
self.cmddict[k](dt)
self.node.setPos(self.node,self.futurepos)
entries = list(self.qq.entries)
if len(entries) == 0:
self.node.setZ(self.node,self.node.getZ()-1)
for entry in entries:
if entry.getIntoNode().getName() == "collision_tGround":
self.node.setZ(entry.getSurfacePoint(render).getZ()+4.5)
self.qq.clear_entries()
self.node.setHpr(dx, 0, 0)
self.floater.setPos(self.node.getPos())
def Up(self, dt):
self.futurepos.x -= self.speed * dt
def Down(self, dt):
self.futurepos.x += self.speed * dt
def Left(self, dt):
self.futurepos.y -= self.speed * dt
self.lastDelta = [-1,0]
def Right(self, dt):
self.futurepos.y += self.speed * dt
self.lastDelta = [1, 0]
def top(self, dt):
self.futurepos.z += self.speed * dt
def bottom(self, dt):
self.futurepos.z -= self.speed * dt
def beep(self,duduh):
self.swoosh.YeetEnemy()
def boop(self, b):
pass
#DEBUG METHODS
def changecNode(self,tup):
x,y,z = tup
x = x/10
y = y/10
z = z/10
and thats the storage of objects in the class and the nodename gen
from panda3d.core import CollisionNode, CollisionPolygon, CollisionHandlerPusher, CollideMask, CollisionHandlerQueue, \
CollisionBox, CollisionSphere
from reference import REFERENCE
class Box():
BOXES = {}
speed = 0
NAMEID = 'box'
@classmethod
def getInstances(cls,id):
if id == -1:
return cls.BOXES
else:
try:
return cls.BOXES[id]
except Exception as e:
REFERENCE.ReturnExceptionPretty(e)
def __new__(cls, *args, **kwargs):
obj = object.__new__(cls)
cls.BOXES[len(cls.BOXES)] = obj
return obj
def __init__(self,where,ctrav):
self.id = self.getId()
self.model = loader.loadModel(REFERENCE.loadTexturePath('Box_2.bam'))
self.node = render.attachNewNode(f'{self.NAMEID}[{self.id}]')
x, y, z = where
print(x,y,z)
self.model.setPos(x, y, z)
self.node.setPos(x, y, z)
self.model.reparentTo(self.node)
self.cNode = CollisionNode(f'collision_{self.NAMEID}[{self.id}]')
self.cNode.setFromCollideMask(CollideMask.bit(0))
self.cNode.setIntoCollideMask(CollideMask.bit(0))
self.cNodeP = self.model.attachNewNode(self.cNode)
self.cNodeP.setPos(render,x,y,z)
self.cNode.add_solid(CollisionBox((x,y,z), 1, 1, 1))
self.qq = CollisionHandlerQueue()
ctrav.addCollider(self.cNodeP, self.qq)
#self.cNodeP.show()
self.node.setScale(4,4,4)
print(self.cNodeP.getPos()-self.model.getPos(),self.cNodeP.getPos()-self.node.getPos())
def DBG(self,tup):
x,y,z = tup
self.node.setHpr(x,y,z)
def getId(self):
for k,v in self.BOXES.items():
if v == self:
return k
and thats the main loop
from panda3d.core import Vec3, CollisionHandlerPusher, CollisionHandlerQueue, AmbientLight
from panda3d.bullet import BulletWorld
from direct.showbase.ShowBase import ShowBase, CollisionTraverser
from panda3d.core import MouseWatcher
from panda3d.core import WindowProperties
from Char_spherecollision import Char
from dafollowcam import FollowCam
from cone import cone
from map import Map
from test_ground import test_ground
from wall import wall
from Box import Box
import cv2
winder = cv2.namedWindow('oooooooooo')
def noting(nut):
pass
cv2.createTrackbar('x','oooooooooo',30,100,noting)
cv2.createTrackbar('y','oooooooooo',0,100,noting)
cv2.createTrackbar('z','oooooooooo',10,100,noting)
class MyApp(ShowBase):
def __init__(self):
ShowBase.__init__(self)
self.dx,self.dy = 0,0
# Showbase augmentations
self.disable_mouse()
self.taskMgr.add(self.update, 'update')
self.setBackgroundColor(0,0,220,1)
self.ambientLight = AmbientLight("ambientLight")
self.ambientLight.setColor((15, 3, 3, 7))
render.setLight(render.attachNewNode(self.ambientLight))
#Usefull objects monitor etc
self.cTrav = CollisionTraverser()
self.pusher = CollisionHandlerPusher()
self.queue = CollisionHandlerQueue()
self.rat = MouseWatcher()
self.winder = WindowProperties()
self.winder.setCursorHidden(True)
self.winder.setMouseMode(WindowProperties.M_relative)
self.win.requestProperties(self.winder)
self.pusher = CollisionHandlerPusher()
# events listeners
self.accept("a", self.UpdateKeyMap, ["left", True])
self.accept("a-up", self.UpdateKeyMap, ["left", False])
self.accept("d", self.UpdateKeyMap, ["right", True])
self.accept("d-up", self.UpdateKeyMap, ["right", False])
self.accept("w", self.UpdateKeyMap, ["up", True])
self.accept("w-up", self.UpdateKeyMap, ["up", False])
self.accept("s", self.UpdateKeyMap, ["down", True])
self.accept("s-up", self.UpdateKeyMap, ["down", False])
self.accept("q", self.UpdateKeyMap, ["shoot", True])
self.accept("q-up", self.UpdateKeyMap, ["shoot", False])
self.accept("e", self.UpdateKeyMap, ["not shoot", True])
self.accept("e-up", self.UpdateKeyMap, ["not shoot", False])
self.accept("z", self.UpdateKeyMap, ["top", True])
self.accept("z-up", self.UpdateKeyMap, ["top", False])
self.accept("x", self.UpdateKeyMap, ["bottom", True])
self.accept("x-up", self.UpdateKeyMap, ["bottom", False])
self.MsX,self.MsY = None,None
#keymap
self.keyMap = {
"up": False,
"down": False,
"left": False,
"right": False,
"shoot": False,
'not shoot': False,
'top': False,
'bottom': False
}
# object instanciation
#self.map = Map((0,0,0),self.cTrav,self.queue)
self.grnd = test_ground(self.cTrav,self.queue)
#self.cones = []
#a,b,c = 0,0,0
#for i in range(5):
# a = a + 4
# placeholder = cone((a,b,c),self.cTrav)
# self.cones.append(placeholder)
self.boxes = []
a, b, c = 0, 0, 1
for i in range(5):
a = a + 3
placeholder = Box((a, b, c), self.cTrav)
self.boxes.append(placeholder)
self.character = Char(self.cTrav,self.pusher)
self.FCAM = FollowCam(self.cam,self.character.floater,self.cTrav, self.character.model)
#print(render.ls())
#print(self.character.qq,self.cones[0].qq,self.FCAM.qq)
def UpdateKeyMap(self, key, state):
self.keyMap[key] = state
def update(self,task):
dt = globalClock.getDt()
if self.mouseWatcherNode.hasMouse():
self.MsX = ((base.mouseWatcherNode.get_mouse_x() + 1) / 2) * base.win.get_x_size()
self.MsY = self.mouseWatcherNode.getMouseY()
self.size = self.get_size()
self.dx,self.dy = int(self.size[0]/2) - self.MsX, int(self.size[1]/2) - self.MsY
x,y,z = cv2.getTrackbarPos('x','oooooooooo'),cv2.getTrackbarPos('y','oooooooooo'),cv2.getTrackbarPos('z','oooooooooo')
if x != 0 and y != 0 and z != 0:
for box in self.boxes:
box.DBG((x,y,z))
self.character.Update_state(self.keyMap, dt, (self.dx,self.dy))
self.FCAM.update()
if self.keyMap['shoot']:
pass
return task.cont
app = MyApp()
app.run()
Also, yes ik the gravity (collision ray) is broken, please don’t point that out (its like salt in my eyes). i try to figure it out but sadly so far no good.