class Entity(Transformable): def __init__(self, sprite, **kwArgs): super().__init__(**kwArgs) self._sprite = sprite self._sprite.setTransform(self.getTransform().createChild()) self._collider = CollisionRect(self._sprite.getImage().width, self._sprite.getImage().height, t=self.getTransform().createChild()) self._collider.addListener(self) self._boundsDisplay = SceneObject(dataSrc = self._collider, t=self._collider.getTransform(), color=Color.Green, \ batch=pyglet.graphics.Batch(), group=LinePolygonMode) '''''''''''''''''''''''''''''''''''''''''''''''''' def update(self, dt): if self._sprite.update(dt): self._updateDimensions() self._collider.update(dt) def _updateDimensions(self): w, h = self._sprite.getDimensions() self._collider.resize(w, h) '''''''''''''''''''''''''''''''''''''''''''''''''' def notifyCollisions(self, colliderObj, otherColliders): if self._boundsDisplay: if otherColliders: self._boundsDisplay.setColor(Color.Red) else: self._boundsDisplay.setColor(Color.Green) '''''''''''''''''''''''''''''''''''''''''''''''''' def getSprite(self): return self._sprite
class RemoteSpaceJet(Transformable): _frameMap = {vec(-1, -1):0, vec(0, -1):1, vec(1, -1):2, \ vec(-1, 0):3, vec(0,0):4, vec(1,0):5, \ vec(-1, 1):6, vec(0, 1):7, vec(1, 1):8} def __init__(self, remoteController, yFaceDirection, **kwArgs): super().__init__(**kwArgs) rm = ResourceManager.activeManager # Set Systems self._controller = remoteController self._yFaceDirection = yFaceDirection # Set Characteristics self._alive = True self._armor = 3 self._health = 1000 self._velocity = vec(0,0) # Set Rendering and Physics Data self._sprite = Sprite(rm.request("SpaceJet.anim"), t=self.getTransform().createChild()) self._sprite.setFrame(1+3) self._explosionSprite = Sprite(rm.request("Explosion.anim"), t=self.getTransform().createChild()) self._explosionSprite.isDrawn = False self._explosionSound = rm.request("Explosion.mp3") self._bounds = CollisionRect(self._sprite.getWidth(), self._sprite.getHeight(), t=self.getTransform().createChild()) self._bounds.addEntity(self) #self._boundsDisplay = SceneObject(dataSrc = self._bounds, t=self._bounds.getTransform(), color=Color.Green, \ # batch=pyglet.graphics.Batch(), group=LinePolygonMode) # Set Flight Area self._flightAreaEdges = [-400+self._sprite.getWidth()/2, 400-self._sprite.getWidth()/2, \ yFaceDirection*(-300+self._sprite.getHeight()/2), -100*yFaceDirection] if yFaceDirection == -1: s = self._flightAreaEdges[2] self._flightAreaEdges[2] = self._flightAreaEdges[3] self._flightAreaEdges[3] = s self.rotate(math.pi) '''''''''''''''''''''''''''''''''''''''''''''''' # Update State Remotely def remoteUpdate(self, controlStruc): if(controlStruc): # Read Data From Control Structure health = controlStruc.get('health', self._health) position = controlStruc.get('position', self.getPosition()) velocity = controlStruc.get('velocity', self._velocity) frameNum = controlStruc.get('frame', self._sprite.getFrame()) # Set Alive and Position self._health = health self.setTranslation(position) # Set Velocity and Check for Movement self._velocity = velocity*self._yFaceDirection if(self._health > 0 and self._velocity != vec(0,0)): self._sprite.setFrame(frameNum) # Update State Locally -> No Message Received def update(self, dt): if self._alive: # Move according to last received velocity (aka 'Dead Reckoning') self.translate(self._velocity*dt) # Check Flight Area p = self.getPosition(); np = p.copy() fa = self._flightAreaEdges if p.x < fa[0]: np.x = fa[0] if p.x > fa[1]: np.x = fa[1] if p.y < fa[2]: np.y = fa[2] if p.y > fa[3]: np.y = fa[3] if p != np: self.setTranslation(np) # Update Sprite Data moving = False; direc = vec(0, 0) if(self._velocity != vec(0,0)): moving = True if(self._velocity.x != 0): direc.x = math.copysign(1, self._velocity.x) if(self._velocity.y != 0): direc.y = math.copysign(1, self._velocity.y) # Draw Sprite Accordingly self._sprite.setFrame(self._frameMap[vec(direc.x if self._yFaceDirection==1 else -direc.x, direc.y*self._yFaceDirection)]) if not moving and self._sprite.getFrame() != 4: self._sprite.setFrame(4) # Update Sprite and Bounds if self._sprite.update(dt): self._updateDimensions() self._bounds.update(dt) self._checkDeath(dt) def notifyCollisions(self, primitive, colliderSet): pass '''''''''''''''''''''''''''''''''''''''''''''''' def _checkDeath(self, dt): if self._health <= 0 and self._alive: self._explosionSprite.setAnimation("Iterating") self._explosionSprite.isDrawn = True self._explosionSound.play() self._alive = False self._explosionSprite.update(dt) if(self._explosionSprite.hasEnded()): self.removeFromWorld() def removeFromWorld(self): self._controller.removeEntity(self) self._bounds.removeEntity(self) self.getTransform().killSubtree() self.removeTransform() '''''''''''''''''''''''''''''''''''''''''''''''' def _updateDimensions(self): w, h = self._sprite.getDimensions() self._bounds.resize(w, h) def getCollisionPrimitive(self): return self._bounds def explosionEnded(self): return self._explosionSprite.hasEnded()
class SpaceJet(Transformable): _frameMap = {vec(-1, -1):0, vec(0, -1):1, vec(1, -1):2, \ vec(-1, 0):3, vec(0,0):4, vec(1,0):5, \ vec(-1, 1):6, vec(0, 1):7, vec(1, 1):8} def __init__(self, yFaceDirection, **kwArgs): super().__init__(**kwArgs) rm = ResourceManager.activeManager # Set Systems self._yFaceDirection = yFaceDirection # Set Characteristics self._alive = True self._armor = 3 self._health = 1000 self._speed = 550 self._velocity = vec(0,0) # Set Rendering and Physics Data self._sprite = Sprite(rm.request("SpaceJet.anim"), t=self.getTransform().createChild()) self._sprite.setFrame(1+3) self._explosionSprite = Sprite(rm.request("Explosion.anim"), t=self.getTransform().createChild()) self._explosionSprite.isDrawn = False self._explosionSound = rm.request("Explosion.mp3") self._bounds = CollisionRect(self._sprite.getWidth(), self._sprite.getHeight(), t=self.getTransform().createChild()) self._bounds.addEntity(self) #self._boundsDisplay = SceneObject(dataSrc = self._bounds, t=self._bounds.getTransform(), color=Color.Green, \ # batch=pyglet.graphics.Batch(), group=LinePolygonMode) # Set Flight Area self._flightAreaEdges = [-400+self._sprite.getWidth()/2, 400-self._sprite.getWidth()/2, \ yFaceDirection*(-300+self._sprite.getHeight()/2), -100*yFaceDirection] if yFaceDirection == -1: s = self._flightAreaEdges[2] self._flightAreaEdges[2] = self._flightAreaEdges[3] self._flightAreaEdges[3] = s # Create the default weapon from Weapon import LaserGun from Weapon import MissleLauncher self._velocity = vec(0,0) self._weapon = LaserGun(self, t=self.getTransform().createChild()) self._secondaryWep = MissleLauncher(self, t=self.getTransform().createChild()) '''''''''''''''''''''''''''''''''''''''''''''''' def update(self, dt): self.readKeyboardInput(dt) if self._sprite.update(dt): self._updateDimensions() self._bounds.update(dt) self._weapon.update(dt) self._secondaryWep.update(dt) return self._checkDeath(dt) def notifyCollisions(self, primitive, colliderSet): pass '''''''''''''''''''''''''''''''''''''''''''''''' def _checkDeath(self, dt): if self._health <= 0 and self._alive: self._explosionSprite.setAnimation("Iterating") self._explosionSprite.isDrawn = True self._explosionSound.play() self._alive = False self._explosionSprite.update(dt) if not self._alive and self._explosionSprite.hasEnded(): self.removeFromWorld() def removeFromWorld(self): from GameWorld import GameWorld GameWorld.activeWorld.removeEntity(self) self._bounds.removeEntity(self) self.getTransform().killSubtree() self.removeTransform() def readKeyboardInput(self, dt): if not self._alive: return actions = Keyboard.localKeyboard.getActions() moving = False for action in actions: if action.name == "Move": direc = action.params[0] direc = direc*self._yFaceDirection self._sprite.setFrame(self._frameMap[vec(direc.x if self._yFaceDirection==1 else -direc.x, direc.y*self._yFaceDirection)]) self.translate(direc*self._speed*dt) self._velocity = direc*self._speed # Check Flight Area p = self.getPosition(); np = p.copy() fa = self._flightAreaEdges if p.x < fa[0]: np.x = fa[0] if p.x > fa[1]: np.x = fa[1] if p.y < fa[2]: np.y = fa[2] if p.y > fa[3]: np.y = fa[3] if p != np: self.setTranslation(np) moving = True elif action.name == "FirePrimary": self._weapon.fire(vec(0, self._yFaceDirection)) elif action.name == "FireSecondary": self._secondaryWep.fire(vec(0, self._yFaceDirection)) if not moving and self._sprite.getFrame() != 4: self._sprite.setFrame(4) '''''''''''''''''''''''''''''''''''''''''''''''' def _updateDimensions(self): w, h = self._sprite.getDimensions() self._bounds.resize(w, h) def getCollisionPrimitive(self): return self._bounds def explosionEnded(self): return self._explosionSprite.hasEnded()