Yes, I meant that I specified a CollisionSphere in the egg file, although I have removed that one so I am just using the one I created with code right now as I realized I don’t need it.
That seems to be the problem. I’ll look into the page!
I did call base.disableMouse() and removed the base.drive.node(). Thank you so much!
I have encountered a new problem. If I call fireballHitPlayer, collisions with walls no longer work. I think this is due to having the same collisiontraverser so it overwrites? I read the manual and it said I would need to call the self-made collisiontraverser. How would I do that?
Thank you!
# home
import os, sys, inspect, thread, time
sys.path.insert(0, "/Users/Hoshizora/Desktop/112_TP/LeapSDK/lib")
import Leap
from Leap import CircleGesture, KeyTapGesture, ScreenTapGesture, SwipeGesture
from direct.showbase.ShowBase import ShowBase
from direct.task import Task
from direct.showbase.DirectObject import DirectObject
from direct.gui.DirectGui import DirectFrame, DirectLabel, DirectButton
from direct.gui.OnscreenText import OnscreenText
from panda3d.core import *
from direct.task.Task import Task
from panda3d.core import CollisionHandlerQueue, CollisionHandlerEvent, CollisionHandlerPusher
from panda3d.core import CollisionNode, CollideMask, CollisionTraverser
from panda3d.core import CollisionRay
from direct.fsm.FSM import FSM
import player
import environment
import enemy
import leapmotion
import menu
class GameRun(FSM):
def __init__(self):
FSM.__init__(self, 'GameRun')
self.request('Menu')
def enterMenu(self):
self.accept("Menu-Start", self.request, ["Game"])
self.accept("Menu-Quit", self.quit)
self.menu.show()
def exitMenu(self):
self.ignore("Menu-Start")
self.ignore("Menu-Quit")
self.menu.hide()
class Game(ShowBase):
def __init__(self):
ShowBase.__init__(self)
# import leap motion
self.leap = leapmotion.LeapMotion()
# disable mouse control
base.disableMouse()
# Load the map.
self.environ = self.loader.loadModel("models/backgroundCollide2")
# Reparent the model to render.
self.environ.reparentTo(self.render)
# Apply scale and position transforms on the model.
myTexture = loader.loadTexture("models/backgroundtexture.jpg")
self.environ.setTexGen(TextureStage.getDefault(), TexGenAttrib.MWorldPosition)
self.environ.setTexture(myTexture)
self.environ.setScale(1, 1, 1)
self.environ.setPos(0, 0, 0)
self.environ.reparentTo(render)
# import flybot, enemy, and player
self.flyBot = FlyBot()
self.player = player.Player(self.flyBot)
# self.numbEnemies = 0
self.enemies = [enemy.Enemy(2)]
# display player stats
self.display = self.player.displayStats()
# run collision settings
self.cTrav = CollisionTraverser()
# Set up collision for environment
self.backgroundCollide = CollisionRay()
self.backgroundNode = CollisionNode('backgroundCollider')
self.backgroundNode.addSolid(self.backgroundCollide)
self.backgroundNode.setFromCollideMask(CollideMask.bit(0))
self.backgroundNode.setIntoCollideMask(CollideMask.allOff())
self.backgroundCollider = self.environ.attachNewNode(self.backgroundNode)
self.environHandler = CollisionHandlerQueue()
# call all functions that deal with collisions
# taskMgr.add(self.swordHitEnemy, 'killEnemy')
self.wallCollisions()
# taskMgr.add(self.fireballHitPlayer, 'fireballHits')
# show collision-debugging purposes
self.cTrav.showCollisions(render)
# run quitGame
self.quitGame()
# Set up initial camera position
base.camera.setPos(0, 0, 0)
base.camera.setHpr(0, 0, 0)
base.camera.reparentTo(self.flyBot.flyBot)
# import first person view from player file
self.cameraControl = player.cameraControl(self.flyBot)
# import leap motion control
# self.leapControl = player.swordControl(self.leap, self.player)
# taskMgr.add(self.leapControl.swingsword, 'swingsword')
# spawn new enemies
# taskMgr.doMethodLater(10, self.spawnEnemies, 'createNewEnemy')
# test enemy movements
# taskMgr.add(self.test, 'test')
# Game AI
AI = GameAI(self.enemies, self.flyBot)
# taskMgr.add(AI.checkGameState, 'checkGameState')
# taskMgr.add(AI.makeDecision, 'enemyStateDetermination')
taskMgr.add(self.update, 'update')
def quitGame(self):
textObject = OnscreenText(text = 'ESC to exit game', pos=(-0.25, -0.05), scale = 0.05, parent = base.a2dTopRight)
# The key esc will exit the game
self.accept('escape', sys.exit)
def spawnEnemies(self, task):
# self.numbEnemies += 1
if len(self.enemies) < 10:
# default state is stay
newEnemy = enemy.Enemy(3)
self.enemies.append(newEnemy)
task.delayTime += 1
return task.again
def test(self, task):
for enemy in self.enemies:
enemy.lookAtPlayer(self.flyBot)
enemy.move(self.flyBot)
return task.cont
def update(self, task):
print(self.flyBot.flyBot.getX(), self.flyBot.flyBot.getY())
return task.cont
# Collision functions, called in init
'''
fix bug!!! --> player moves when this function is called?? don't know why
'''
def wallCollisions(self):
# Pusher so that the player cannot move past the walls
self.pusher = CollisionHandlerPusher()
base.cTrav.addCollider(self.flyBot.playerCollider, self.pusher)
self.pusher.addCollider(self.flyBot.playerCollider, self.flyBot.flyBot)
'''
fix bug!!! kills all enemy
'''
def swordHitEnemy(self, task):
# When the sword collides with enemy, enemy dies
for enemy in self.enemies:
playerKill = CollisionHandlerEvent()
self.cTrav.addCollider(enemy.collider, playerKill)
playerKill.addInPattern('%fn-into-%in')
# perform the task
kill = DirectObject()
kill.accept('enemy-into-swordCollider', enemy.killEnemy)
if not enemy.isAlive:
self.enemies.remove(enemy)
return task.cont
'''
fix bug!!! doesn't do damage with multiple enemies?? don't know why
'''
def fireballHitPlayer(self, task):
for enemy in self.enemies:
if enemy.fireballFired.isLive:
cTrav = CollisionTraverser()
# When fireball collides with player, player health reduces
playerDamage = CollisionHandlerEvent()
playerDamage.addInPattern('%fn-into-%in')
cTrav.addCollider(self.flyBot.playerCollider, playerDamage)
# perform the tasks
damagePlayer = DirectObject()
damagePlayer.accept('player-into-FireballCollider', self.receiveDamage)
self.fireballRemove = DirectObject()
self.fireballRemove.accept('player-into-FireballCollider', enemy.fireballFired.removeFireball(task))
return task.done
# reduce health in player's stats and removes fireball
def receiveDamage(self, task):
# remove the display screen
self.player.displayText.removeNode()
# create new display screen with new stats
self.player.health -= 5
self.player.displayStats()
# allow camera and player to move independently
class FlyBot(DirectObject):
def __init__(self):
self.flyBot = base.loader.loadModel('models/flyBot')
self.flyBot.setScale(1, 1, 1)
self.flyBot.setPos(0, 0, 4)
self.flyBot.setHpr(0, 0, 0)
self.flyBot.reparentTo(render)
self.moved = False
self.playerCollide = CollisionSphere(0, 0, 0, 2)
self.playerNode = CollisionNode('player')
self.playerNode.addSolid(self.playerCollide)
self.playerNode.setFromCollideMask(CollideMask.bit(0))
self.playerNode.setIntoCollideMask(CollideMask.allOff())
self.playerCollider = self.flyBot.attachNewNode(self.playerNode)
# self.flyBotHandler = CollisionHandlerQueue()
# self.playerCollider.show()
# Game AI
class GameAI(DirectObject):
def __init__(self, enemies, flyBot):
self.enemies = enemies
self.flyBot = flyBot
self.state = ['moveToPlayer', 'moveToChest', 'stay']
# check the state of the game
def checkGameState(self, task):
self.movingToPlayer = 0
self.movingToChest = 0
self.stay = 0
self.around = 0
for enemy in self.enemies:
# count how many enemeis are in each state
if enemy.state == 0:
self.movingToPlayer += 1
elif enemy.state == 2:
self.movingToChest += 1
elif enemy.state == 2:
self.stay += 1
# check if the enemy is around the player
if self.aroundPlayer(self.flyBot, enemy):
self.around += 1
# print 'state:', (self.movingToPlayer, self.stay, self.around, len(self.enemies))
return task.cont
'''
add chest part when it goes to that
'''
# determine state of the enemy
def makeDecision(self, task):
for enemy in self.enemies:
# print enemy, enemy.state
# if enemy is around the player, move to the player
if self.aroundPlayer(self.flyBot, enemy):
enemy.state = 0
# if less than three enemies are moving to player and less than two around player and is not moving, set the enemy state to moving to player
elif self.movingToPlayer < 3 and self.around < 2 and enemy.state == 2:
enemy.state = 0
# or else, stop the enemy from moving
else:
enemy.state = 3
# print enemy, enemy.state
return task.cont
# check if enemy is within 10 unit radius of the player
def aroundPlayer(self, flyBot, enemy):
player = flyBot.flyBot
enemy = enemy
if enemy.isAlive:
pX = player.getX()
pY = player.getY()
eX = enemy.enemyModel.getX()
eY = enemy.enemyModel.getY()
deltaX = eX - pX
deltaY = eY - pY
return ((deltaX)**2 + (deltaY)**2)**0.5 <= 100
app = Game()
app.run()```