def setGameData(w, h, Switchstate=None, Log=None, Quake=None, Flash=None, Fade=None, SetCursor=None): FlxG._cache = {} FlxG.width = w FlxG.height = h _muted = 1.0 _volume = 1.0 _musicVolume = 1.0 _masterVolume = 0.5 FlxG._musicPosition = -1 mouse = FlxPoint() FlxG._switchState = Switchstate FlxG._log = Log _quake = Quake _flash = Flash _fade = Fade _setCursor = SetCursor FlxG.unfollow() FlxG._keys = [] FlxG._oldKeys = [] for i in range(7): FlxG._keys.append(0) FlxG._oldKeys.append(0) FlxG.levels = FlxArray() FlxG.scores = FlxArray() level = 0 score = 0
class FlxLayer(FlxCore): def __init__(self): FlxCore.__init__(self) self._children = FlxArray() #@desc Adds a new FlxCore subclass (FlxSprite, FlxBlock, etc) to the list of children #@param Core The object you want to add def add(self, Core): #Layer.add(self,Core) return self._children.add(Core) #@desc Automatically goes through and calls update on everything you added, override this function to handle custom input and perform collisions def update(self): FlxCore.update(self) for i in range(len(self._children)): if ((self._children[i] != None) and self._children[i].exists and self._children[i].active): self._children[i].update() #@desc Automatically goes through and calls render on everything you added, override this loop to do crazy graphical stuffs I guess? def render(self): FlxCore.render(self) for i in range(len(self._children)): if ((self._children[i] != None) and self._children[i].exists and self._children[i].visible): self._children[i].render() #@desc Override this function to handle any deleting or "shutdown" type operations you might need (such as removing traditional Flash children like Sprite objects) def destroy(self): self._children.clear()
class FlxLayer(FlxCore): def __init__(self): FlxCore.__init__(self) self._children = FlxArray(); #@desc Adds a new FlxCore subclass (FlxSprite, FlxBlock, etc) to the list of children #@param Core The object you want to add def add(self,Core): #Layer.add(self,Core) return self._children.add(Core) #@desc Automatically goes through and calls update on everything you added, override this function to handle custom input and perform collisions def update(self): FlxCore.update(self); for i in range( len(self._children)): if((self._children[i] != None) and self._children[i].exists and self._children[i].active): self._children[i].update(); #@desc Automatically goes through and calls render on everything you added, override this loop to do crazy graphical stuffs I guess? def render(self): FlxCore.render(self); for i in range(len(self._children)): if((self._children[i] != None) and self._children[i].exists and self._children[i].visible): self._children[i].render(); #@desc Override this function to handle any deleting or "shutdown" type operations you might need (such as removing traditional Flash children like Sprite objects) def destroy(self): self._children.clear()
def __init__(self, MapData, TileGraphic, CollisionIndex=1, DrawIndex=1): #image = pyglet.resource.image("data/logo.png") FlxCore.__init__(self) self.CollideIndex = CollisionIndex self.DrawIndex = 1 self._ci = CollisionIndex self.widthInTiles = 0 self.heightInTiles = 0 self._data = FlxArray() #c; #cols:Array; rows = open(MapData).read().split("\n") rows.reverse() rows = rows[2:] self.heightInTiles = len(rows) for r in range(self.heightInTiles): cols = rows[r].split(",") if (len(cols) <= 1): self.heightInTiles -= 1 continue if (self.widthInTiles == 0): self.widthInTiles = len(cols) for c in range(self.widthInTiles): self._data.append(int(cols[c])) self._pixels = TileGraphic self._rects = FlxArray() self._p = FlxPoint() self._tileSize = self._pixels.height self.width = self.widthInTiles * self._tileSize self.height = self.heightInTiles * self._tileSize self.numTiles = self.widthInTiles * self.heightInTiles for i in range(self.numTiles): if (self._data[i] >= DrawIndex): self._rects.append( FlxRect(self._tileSize * self._data[i], 0, self._tileSize, self._tileSize)) else: self._rects.append(None) #self._block = FlxBlock(0,0,self._tileSize,self._tileSize,None); self._screenRows = int(Math.ceil(FlxG.height / self._tileSize) + 1) if (self._screenRows > self.heightInTiles): self._screenRows = self.heightInTiles self._screenCols = int(Math.ceil(FlxG.width / self._tileSize) + 1) if (self._screenCols > self.widthInTiles): self._screenCols = self.widthInTiles self._tileObjects = range(self._pixels.width / self._pixels.height) i = 0 while (i < self._pixels.width / self._pixels.height): collide = FlxCore.NONE if (i >= self.CollideIndex): collide = self.allowCollisions self._tileObjects[i] = FlxTile(self, i, self._tileSize, self._tileSize, (i >= self.DrawIndex), collide) i += 1
def __init__(self,MapData, TileGraphic, CollisionIndex=1, DrawIndex=1): #image = pyglet.resource.image("data/logo.png") FlxCore.__init__(self); self.CollideIndex = CollisionIndex;self.DrawIndex = 1; self._ci = CollisionIndex; self.widthInTiles = 0; self.heightInTiles = 0; self._data = FlxArray(); #c; #cols:Array; rows = open(MapData).read().split("\n"); rows.reverse() rows=rows[2:] self.heightInTiles = len(rows); for r in range(self.heightInTiles): cols = rows[r].split(","); if(len(cols) <= 1): self.heightInTiles-=1; continue; if(self.widthInTiles == 0): self.widthInTiles = len(cols); for c in range(self.widthInTiles): self._data.append(int(cols[c])); self._pixels = TileGraphic self._rects = FlxArray(); self._p = FlxPoint(); self._tileSize =self._pixels.height; self.width = self.widthInTiles*self._tileSize; self.height = self.heightInTiles*self._tileSize; self.numTiles = self.widthInTiles*self.heightInTiles; for i in range(self.numTiles): if(self._data[i] >= DrawIndex): self._rects.append(FlxRect(self._tileSize*self._data[i],0,self._tileSize,self._tileSize)); else: self._rects.append(None); #self._block = FlxBlock(0,0,self._tileSize,self._tileSize,None); self._screenRows =int( Math.ceil(FlxG.height/self._tileSize)+1); if(self._screenRows > self.heightInTiles): self._screenRows = self.heightInTiles; self._screenCols = int(Math.ceil(FlxG.width/self._tileSize)+1); if(self._screenCols > self.widthInTiles): self._screenCols = self.widthInTiles; self._tileObjects = range(self._pixels.width/self._pixels.height) i=0 while(i < self._pixels.width/self._pixels.height): collide=FlxCore.NONE if(i>= self.CollideIndex): collide=self.allowCollisions self._tileObjects[i] =FlxTile(self,i,self._tileSize,self._tileSize,(i >= self.DrawIndex),collide) i+=1;
def __init__(self, X, Y, Width, Height, Sprites=None, Delay=-1, MinVelocityX=-100, MaxVelocityX=100, MinVelocityY=-100, MaxVelocityY=100, MinRotation=-360, MaxRotation=360, Gravity=500, Drag=0, Graphics=None, Quantity=0, Multiple=false, Parent=None): FlxCore.__init__(self) self.visible = false self.x = X self.y = Y self.width = Width self.height = Height self.minVelocity = FlxPoint(MinVelocityX, MinVelocityY) self.maxVelocity = FlxPoint(MaxVelocityX, MaxVelocityY) self._minRotation = MinRotation self._maxRotation = MaxRotation self._gravity = Gravity self._drag = Drag self._delay = Delay self._timer = 0 self._particle = 0 if (Graphics != None): self._sprites = FlxArray() for i in range(Quantity): if (Multiple): (self._sprites.add(FlxSprite(Graphics, 0, 0, true))).randomFrame() else: self._sprites.add(FlxSprite(Graphics)) for i in range(len(self._sprites)): if (Parent == None): FlxG.state.add(self._sprites[i]) else: Parent.add(self._sprites[i]) else: self._sprites = Sprites self.kill() if (self._delay > 0): self.reset()
def __init__(self,X, Y, Width, Height, Sprites=None, Delay=-1, MinVelocityX=-100, MaxVelocityX=100, MinVelocityY=-100, MaxVelocityY=100, MinRotation=-360, MaxRotation=360, Gravity=500, Drag=0, Graphics=None, Quantity=0, Multiple=false, Parent=None): FlxCore.__init__(self); self.visible = false; self.x = X; self.y = Y; self.width = Width; self.height = Height; self.minVelocity = FlxPoint(MinVelocityX,MinVelocityY); self.maxVelocity = FlxPoint(MaxVelocityX,MaxVelocityY); self._minRotation = MinRotation; self._maxRotation = MaxRotation; self._gravity = Gravity; self._drag = Drag; self._delay = Delay; self._timer=0 self._particle = 0; if(Graphics != None): self._sprites = FlxArray(); for i in range(Quantity): if(Multiple): (self._sprites.add( FlxSprite(Graphics,0,0,true))).randomFrame(); else: self._sprites.add( FlxSprite(Graphics)); for i in range(len(self._sprites)): if(Parent == None): FlxG.state.add(self._sprites[i]); else: Parent.add(self._sprites[i]); else: self._sprites = Sprites; self.kill(); if(self._delay > 0): self.reset();
def __init__(self): FlxCore.__init__(self) self._children = FlxArray()
def __init__(self): FlxCore.__init__(self) self._children = FlxArray();
class FlxSprite(FlxCore): LEFT= false; RIGHT = true; # #@desc If you changed the size of your sprite object to shrink the bounding box, you might need to offset the new bounding box from the top-left corner of the sprite # public var offset:Point; # public var self.velocity:Point; # public var aself.acceleration:Point; # #@desc This isn't self.drag exactly, more like deceleration that is only applied when aself.acceleration is not affecting the sprite # public var self.drag:Point; # public var maxself.velocity:Point; # #@desc WARNING: rotating sprites decreases rendering performance for this sprite by a factor of 10x! # public var self.angle:Number; # public var self.angularself.velocity:Number; # public var self.angularAself.acceleration:Number; # public var self.angularDrag:Number; # public var self.maxAngular:Number; # #@desc If you want to do Asteroids style stuff, check out self.thrust (instead of directly accessing the object's self.velocity or aself.acceleration) # public var self.thrust:Number; # public var maxself.thrust:Number; # public var health:Number; # #@desc self.scale doesn't currently affect collisions automatically, you will need to adjust the width, height and offset manually. WARNING: scaling sprites decreases rendering performance for this sprite by a factor of 10x! # public var self.scale:Point; # #@desc Whether the current animation has finished its first (or only) loop # public var finished:Boolean; # private var self._animations:FlxArray; # private var _flipped:uint; # protected var self._curAnim:FlxAnim; # protected var self._curFrame:uint; # private var self._frameTimer:Number; # private var _callback:Function; # private var self._facing:Boolean; # #helpers # private var self._bw:uint; # private var self._bh:uint; # private var _r:Rectself.angle; # private var self._p:Point; # private var self._pZero:Point; # public var pixels:BitmapData; # private var self._pixels:BitmapData; # private var self._alpha:Number; #@desc Constructor #@param Graphic The image you want to use #@param X The initial X position of the sprite #@param Y The initial Y position of the sprite #@param Animated Whether the Graphic parameter is a single sprite or a row of sprites #@param Reverse Whether you need this class to generate horizontally flipped versions of the animation frames #@param Width If you opt to NOT use an image and want to generate a colored block, or your sprite's frames are not square, you can specify a width here #@param Height If you opt to NOT use an image you can specify the height of the colored block here (ignored if Graphic is not null) #@param Color Specifies the color of the generated block (ignored if Graphic is not null) def __init__(self,Graphic=None,X=0,Y=0,Animated=false,Reverse=false,Width=0,Height=0,Color=0): if(Graphic != None): #image = pyglet.resource.image(Graphic) self.pixels = Graphic; pass else: self.pixels= pygame.image.load("data/logo.png") #pixels = FlxG.createBitmap(Width,Height,Color); FlxCore.__init__(self) #self.position=(X,FlxG.height-Y); #self.anchor=(0,0) #print dir(self.pixels) self.x = X; self.y = Y; if(Width == 0): if(Animated): Width = self.pixels.height; else: Width = self.pixels.width; self.width =Width self._bw = Width; self.height = self.pixels.height; self._bh = self.height; self.offset = FlxPoint(); self.velocity = FlxPoint(); self.acceleration = FlxPoint(); self.drag = FlxPoint(); self.maxVelocity = FlxPoint(10000,10000); self.angle = 0; self.angularVelocity = 0; self.angularAacceleration = 0; self.angularDrag = 0; self.maxAngular = 10000; self.thrust = 0; self.scale = FlxPoint(1,1); self.finished = false; self._facing = true; self._animations = FlxArray(); if(Reverse): #pass self._flipped = self.pixels.width>>1; else: self._flipped = 0; self._curAnim = None; self._curFrame = 0; self._frameTimer = 0; self._p = FlxPoint(self.x,self.y); self._pZero = FlxPoint(); self._r = FlxRect(0,0,self._bw,self._bh); #self._pixels = BitmapData(width,height); #print self._bw,self._bh #raw_input() self._pixels=self.pixels.get_region(0,0,self._bw,self._bh)#,self._pZero); self.health = 1; self._alpha = 1; self._callback = None; #@desc Called by game loop, handles animation and physics def update(self): self.last.x=self.x self.last.y=self.y #print "last",self,self.last.x,self.last.y FlxCore.update(self); if(not self.active): return; #animation if((self._curAnim != None) and (self._curAnim.delay > 0) and (self._curAnim.looped or not self.finished)): self._frameTimer += FlxG.elapsed; #print self._frameTimer,self._curAnim.delay,FlxG.elapsed #raw_input() if(self._frameTimer > self._curAnim.delay): self._frameTimer -= self._curAnim.delay; if(self._curFrame == len(self._curAnim.frames)-1): if(self._curAnim.looped): self._curFrame = 0; self.finished = true; else: self._curFrame+=1; self.calcFrame(); #print "curframe",self._curFrame #motion + physics self.angularVelocity = FlxG.computeVelocity(self.angularVelocity,self.angularAacceleration,self.angularDrag,self.maxAngular) self.angle += (self.angularVelocity)*FlxG.elapsed; self.thrustComponents=FlxPoint(); if(self.thrust != 0): self.thrustComponents = FlxG.rotatePoint(-self.thrust,0,0,0,self.angle); maxComponents = FlxG.rotatePoint(-maxself.thrust,0,0,0,self.angle); maxself.velocity.x = Math.abs(maxComponents.x); maxself.velocity.y = Math.abs(maxComponents.y); else: self.thrustComponents = self._pZero; self.velocity.x = FlxG.computeVelocity(self.velocity.x,self.acceleration.x+self.thrustComponents.x,self.drag.x,self.maxVelocity.x) self.x += (self.velocity.x)*FlxG.elapsed; self.velocity.y = FlxG.computeVelocity(self.velocity.y,self.acceleration.y+self.thrustComponents.y,self.drag.y,self.maxVelocity.y) self.y += (self.velocity.y)*FlxG.elapsed; #print "x,y",self,self.x,self.y #@desc Called by game loop, blits current frame of animation to the screen (and handles rotation) def render(self): if(not self.visible): return; self.getScreenXY(self._p); #ma todo # if((self.angle != 0) or (self.scale.x != 1) or (self.scale.y != 1)): # mtx = Matrix(); # mtx.translate(-(self._bw>>1),-(self._bh>>1)); # mtx.self.scale(self.scale.x,self.scale.y); # if(self.angle != 0):mtx.rotate(Math.PI * 2 * (self.angle / 360)); # mtx.translate(self._p.x+(self._bw>>1),self._p.y+(self._bh>>1)); # FlxG.buffer.draw(self._pixels,mtx); # return; #print dir(FlxG.buffer) #print dir(self._pixels) #print self._r,dir(self._r) r=FlxRect(self._p.x,self._p.y,self._r.width,self._r.height) #FlxG.buffer.blit(self._pixels,r); self._pixels.blit(self._p.x,self._p.y) #r=Rect(self._p.x,self._p.y,self._r.width,self._r.height) #FlxG.buffer.blit(self.pixels,r); #@desc Checks to see if a point in 2D space overlaps this FlxCore object #@param X The X coordinate of the point #@param Y The Y coordinate of the point #@param PerPixel Whether or not to use per pixel collision checking #@return Whether or not the point overlaps this object def overlapsPoint(self,X,Y,PerPixel = false): tx = self.x; ty = self.y; if((self.scrollFactor.x != 1) or (self.scrollFactor.y != 1)): tx -= Math.floor(FlxG.scroll.x*self.scrollFactor.x); ty -= Math.floor(FlxG.scroll.y*self.scrollFactor.y); if(PerPixel): return self._pixels.hitTest(Point(0,0),0xFF,Point(X-tx,Y-ty)); elif((X <= tx) or (X >= tx+self.width) or (Y <= ty) or (Y >= ty+self.height)): return false; return true; #@desc Called when this object collides with a FlxBlock on one of its sides #@return Whether you wish the FlxBlock to collide with it or not def hitWall(self): self.velocity.x = 0; return true; #@desc Called when this object collides with the top of a FlxBlock #@return Whether you wish the FlxBlock to collide with it or not def hitFloor(self): self.velocity.y = 0; return true; #@desc Called when this object collides with the bottom of a FlxBlock #@return Whether you wish the FlxBlock to collide with it or not def hitCeiling(self): self.velocity.y = 0; return true; #@desc Call this function to "damage" (or give health bonus) to this sprite #@param Damage How much health to take away (use a negative number to give a health bonus) def hurt(self,Damage): self.health -= Damage if(self.health<= 0): self.kill(); #@desc Called if/when this sprite is launched by a FlxEmitter def onEmit(self): pass #@desc Adds a animation to the sprite #@param Name What this animation should be called (e.g. "run") #@param Frames An array of numbers indicating what frames to play in what order (e.g. 1, 2, 3) #@param FrameRate The speed in frames per second that the animation should play at (e.g. 40 fps) #@param Looped Whether or not the animation is looped or just plays once def addAnimation(self,Name, Frames, FrameRate=30, Looped=true): self._animations.add(FlxAnim(Name,Frames,FrameRate,Looped)); #@desc Pass in a function to be called whenever this sprite's animation changes #@param AnimationCallback A function that has 3 parameters: a string name, a uint frame number, and a uint frame index def addAnimationCallback(self,AnimationCallback): self._callback = AnimationCallback; #@desc Plays an existing animation (e.g. "run") - if you call an animation that is already playing it will be ignored #@param AnimName The string name of the animation you want to play #@param Force Whether to force the animation to restart def play(self,AnimName,Force=false): if(not Force and (self._curAnim != None) and (AnimName == self._curAnim.name)): return; self._curFrame = 0; self._frameTimer = 0; for i in range( len(self._animations)): if(self._animations[i].name == AnimName): self.finished = false; self._curAnim = self._animations[i]; self.calcFrame(); return; #@desc Tell the sprite which way to face (you can just set 'facing' but this function also updates the animation instantly) #@param Direction True is Right, False is Left (see static const members RIGHT and LEFT) def setfacing(self,Direction): c = self._facing != Direction; self._facing = Direction; if(c): self.calcFrame(); #@desc Get the direction the sprite is facing #@return True means facing right, False means facing left (see static const members RIGHT and LEFT) def getfacing(self): return self._facing; #@desc Tell the sprite to change to a random frame of animation (useful for instantiating particles or other weird things) def randomFrame(self): self._pixels=self.pixels.get_region(Math.floor(Math.random()*(self.pixels.width/self._bw))*self._bw,0,self._bw,self._bh) #@desc Tell the sprite to change to a specific frame of animation (useful for instantiating particles) #@param Frame The frame you want to display def specificFrame(self,Frame): self._pixels=self.pixels.get_region(Frame*self._bw,0,self._bw,self._bh); #@desc Call this function to figure out the post-scrolling "screen" position of the object #@param P Takes a Flash Point object and assigns the post-scrolled X and Y values of this object to it def getScreenXY(self,P): P.x = Math.floor(self.x-self.offset.x)+Math.floor(FlxG.scroll.x*self.scrollFactor.x); P.y = Math.floor(self.y-self.offset.y)+Math.floor(FlxG.scroll.y*self.scrollFactor.y); #@desc Internal function to update the current animation frame def calcFrame(self): if(self._curAnim == None): self._pixels=self.pixels.get_region(self._r.x,self._r.y,self._r.width,self._r.height)#,self._pZero); else: rx = self._curAnim.frames[self._curFrame]*self._bw; if(not self._facing and (self._flipped > 0)): rx = (self._flipped<<1)-rx-self._bw; #print rx,self._bw,self._bh; #raw_input() self._pixels=self.pixels.get_region(rx,0,self._bw,self._bh) #if(self._alpha != 1): self._pixels.colorTransform(_r,ColorTransform(1,1,1,self._alpha)); if(self._callback != None): self._callback(self._curAnim.name,self._curFrame,self._curAnim.frames[self._curFrame]); #@desc The setter for alpha #@param Alpha The opacity value of the sprite (between 0 and 1) def setalpha(self,Alpha): if(Alpha > 1): Alpha = 1; if(Alpha < 0): Alpha = 0; self._alpha = Alpha; self.calcFrame(); #@desc The getter for alpha #@return The value of this sprite's opacity def getalpha(self): return self._alpha;
def __init__(self,Graphic=None,X=0,Y=0,Animated=false,Reverse=false,Width=0,Height=0,Color=0): if(Graphic != None): #image = pyglet.resource.image(Graphic) self.pixels = Graphic; pass else: self.pixels= pygame.image.load("data/logo.png") #pixels = FlxG.createBitmap(Width,Height,Color); FlxCore.__init__(self) #self.position=(X,FlxG.height-Y); #self.anchor=(0,0) #print dir(self.pixels) self.x = X; self.y = Y; if(Width == 0): if(Animated): Width = self.pixels.height; else: Width = self.pixels.width; self.width =Width self._bw = Width; self.height = self.pixels.height; self._bh = self.height; self.offset = FlxPoint(); self.velocity = FlxPoint(); self.acceleration = FlxPoint(); self.drag = FlxPoint(); self.maxVelocity = FlxPoint(10000,10000); self.angle = 0; self.angularVelocity = 0; self.angularAacceleration = 0; self.angularDrag = 0; self.maxAngular = 10000; self.thrust = 0; self.scale = FlxPoint(1,1); self.finished = false; self._facing = true; self._animations = FlxArray(); if(Reverse): #pass self._flipped = self.pixels.width>>1; else: self._flipped = 0; self._curAnim = None; self._curFrame = 0; self._frameTimer = 0; self._p = FlxPoint(self.x,self.y); self._pZero = FlxPoint(); self._r = FlxRect(0,0,self._bw,self._bh); #self._pixels = BitmapData(width,height); #print self._bw,self._bh #raw_input() self._pixels=self.pixels.get_region(0,0,self._bw,self._bh)#,self._pZero); self.health = 1; self._alpha = 1; self._callback = None;
class FlxEmitter(FlxCore): # public var minVelocity:Point; # public var maxVelocity:Point; # private var _minRotation; # private var _maxRotation; # private var _gravity; # private var _drag; # private var _delay; # private var _timer; # private var self._sprites:FlxArray; # private var _particle; #@desc Constructor #@param X The X position of the emitter #@param Y The Y position of the emitter #@param Width The width of the emitter (particles are emitted from a random position inside this box) #@param Height The height of the emitter #@param Sprites A pre-configured FlxArray of FlxSprite objects for the emitter to use (optional) #@param Delay A negative number defines the lifespan of the particles that are launched all at once. A positive number tells it how often to fire a particle. #@param MinVelocityX The minimum X velocity of the particles #@param MaxVelocityX The maximum X velocity of the particles (every particle will have a random X velocity between these values) #@param MinVelocityY The minimum Y velocity of the particles #@param MaxVelocityY The maximum Y velocity of the particles (every particle will have a random Y velocity between these values) #@param MinRotation The minimum angular velocity of the particles #@param MaxRotation The maximum angular velocity of the particles (you guessed it) #@param Gravity How much gravity should affect the particles #@param Drag Sets both the X and Y "Drag" or deceleration on the particles #@param Graphics If you opted to not pre-configure an array of FlxSprite objects, you can simply pass in a particle image or sprite sheet (ignored if you pass in an array) #@param Quantity The number of particles to generate when using the "create from image" option (ignored if you pass in an array) #@param Multiple Whether the image in the Graphics param is a single particle or a bunch of particles (if it's a bunch, they need to be square!) def __init__(self,X, Y, Width, Height, Sprites=None, Delay=-1, MinVelocityX=-100, MaxVelocityX=100, MinVelocityY=-100, MaxVelocityY=100, MinRotation=-360, MaxRotation=360, Gravity=500, Drag=0, Graphics=None, Quantity=0, Multiple=false, Parent=None): FlxCore.__init__(self); self.visible = false; self.x = X; self.y = Y; self.width = Width; self.height = Height; self.minVelocity = FlxPoint(MinVelocityX,MinVelocityY); self.maxVelocity = FlxPoint(MaxVelocityX,MaxVelocityY); self._minRotation = MinRotation; self._maxRotation = MaxRotation; self._gravity = Gravity; self._drag = Drag; self._delay = Delay; self._timer=0 self._particle = 0; if(Graphics != None): self._sprites = FlxArray(); for i in range(Quantity): if(Multiple): (self._sprites.add( FlxSprite(Graphics,0,0,true))).randomFrame(); else: self._sprites.add( FlxSprite(Graphics)); for i in range(len(self._sprites)): if(Parent == None): FlxG.state.add(self._sprites[i]); else: Parent.add(self._sprites[i]); else: self._sprites = Sprites; self.kill(); if(self._delay > 0): self.reset(); #@desc Called automatically by the game loop, decides when to launch particles and when to "die" def update(self): self._timer += FlxG.elapsed; if(self._delay < 0): if(self._timer > -self._delay) : self.kill(); return; if(not self._sprites[0].exists): for i in range(len(self._sprites)): self.emit(); return; while(self._timer > self._delay): self._timer -= self._delay; self.emit(); #@desc Call this function to reset the emitter (if you used a negative delay, calling this function "Explodes" the emitter again) def reset(self): self.active = true; self._timer = 0; self._particle = 0; #@desc This function can be used both internally and externally to emit the next particle def emit(self): s = self._sprites[self._particle]; s.exists = true; s.x = self.x - (s.width>>1); if(self.width != 0): s.x += Math.random()*self.width; s.y = self.y - (s.height>>1); if(self.height != 0): s.y += Math.random()*self.height; s.velocity.x = self.minVelocity.x; if(self.minVelocity.x != self.maxVelocity.x): s.velocity.x += Math.random()*(self.maxVelocity.x-self.minVelocity.x); s.velocity.y = self.minVelocity.y; if(self.minVelocity.y != self.maxVelocity.y): s.velocity.y += Math.random()*(self.maxVelocity.y-self.minVelocity.y); s.acceleration.y = self._gravity; s.angularVelocity = self._minRotation; if(self._minRotation != self._maxRotation): s.angularVelocity += Math.random()*(self._maxRotation-self._minRotation); if(s.angularVelocity != 0): s.angle = Math.random()*360-180; s.drag.x = self._drag; s.drag.y = self._drag; self._particle+=1 if(self._particle >= len(self._sprites)): self._particle = 0; s.onEmit(); #@desc Call this function to turn off all the particles and the emitter def kill(self): active = false; for i in range( len(self._sprites)): self._sprites[i].exists = false;
class FlxTilemap(FlxCore): #@desc Constructor #@param MapData A string of comma and line-return delineated indices indicating what order the tiles should go in #@param TileGraphic All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData #@param CollisionIndex The index of the first tile that should be treated as a hard surface #@param DrawIndex The index of the first tile that should actually be drawn def __init__(self,MapData, TileGraphic, CollisionIndex=1, DrawIndex=1): #image = pyglet.resource.image("data/logo.png") FlxCore.__init__(self); self.CollideIndex = CollisionIndex;self.DrawIndex = 1; self._ci = CollisionIndex; self.widthInTiles = 0; self.heightInTiles = 0; self._data = FlxArray(); #c; #cols:Array; rows = open(MapData).read().split("\n"); rows.reverse() rows=rows[2:] self.heightInTiles = len(rows); for r in range(self.heightInTiles): cols = rows[r].split(","); if(len(cols) <= 1): self.heightInTiles-=1; continue; if(self.widthInTiles == 0): self.widthInTiles = len(cols); for c in range(self.widthInTiles): self._data.append(int(cols[c])); self._pixels = TileGraphic self._rects = FlxArray(); self._p = FlxPoint(); self._tileSize =self._pixels.height; self.width = self.widthInTiles*self._tileSize; self.height = self.heightInTiles*self._tileSize; self.numTiles = self.widthInTiles*self.heightInTiles; for i in range(self.numTiles): if(self._data[i] >= DrawIndex): self._rects.append(FlxRect(self._tileSize*self._data[i],0,self._tileSize,self._tileSize)); else: self._rects.append(None); #self._block = FlxBlock(0,0,self._tileSize,self._tileSize,None); self._screenRows =int( Math.ceil(FlxG.height/self._tileSize)+1); if(self._screenRows > self.heightInTiles): self._screenRows = self.heightInTiles; self._screenCols = int(Math.ceil(FlxG.width/self._tileSize)+1); if(self._screenCols > self.widthInTiles): self._screenCols = self.widthInTiles; self._tileObjects = range(self._pixels.width/self._pixels.height) i=0 while(i < self._pixels.width/self._pixels.height): collide=FlxCore.NONE if(i>= self.CollideIndex): collide=self.allowCollisions self._tileObjects[i] =FlxTile(self,i,self._tileSize,self._tileSize,(i >= self.DrawIndex),collide) i+=1; #@desc Draws the tilemap def render(self): #NOTE: While this will only draw the tiles that are actually on screen, it will ALWAYS draw one screen's worth of tiles FlxCore.render(self) self.getScreenXY(self._p); #print self._p.x,self._p.y #self.position=(self._p.x,self._p.y) #raw_input() tx = Math.floor(-self._p.x/self._tileSize); ty = Math.floor(-self._p.y/self._tileSize); if(tx < 0): tx = 0; if(tx > self.widthInTiles-self._screenCols): tx = self.widthInTiles-self._screenCols; if(ty < 0): ty = 0; if(ty > self.heightInTiles-self._screenRows): ty = self.heightInTiles-self._screenRows; ri =int(ty*self.widthInTiles+tx); self._p.x += tx*self._tileSize; self._p.y += ty*self._tileSize; opx = self._p.x; for r in range(self._screenRows): cri = ri; for c in range(self._screenCols): #print self._rects[cri] #raw_input() if(self._rects[cri] != None): im=self._pixels.get_region(self._rects[cri].x,self._rects[cri].y,self._rects[cri].width,self._rects[cri].height)#.x,self._rects[cri].y, self._rects[cri].width,self._rects[cri].height) #tmp=Sprite(im) #tmp.position=(self._p.x,self._p.y) #print r,c,"tile",self._p.x,self._p.y #self.add(tmp) r=FlxRect(self._p.x,self._p.y,self._rects[cri].width,self._rects[cri].height) im.blit(self._p.x,self._p.y); cri+=1; self._p.x += self._tileSize; ri += self.widthInTiles; self._p.x = opx; self._p.y += self._tileSize; #@desc Collides a FlxSprite against the tilemap #@param Spr The FlxSprite you want to collide def old_collide(self,Spr): #print "map collide"#Spr.velocity.x ix =int(Math.floor((Spr.x - self.x)/self._tileSize)) iy =int(Math.floor((Spr.y - self.y)/self._tileSize)) for r in [iy-1,iy,iy+1]: if((r < 0) or (r >= self.heightInTiles)): continue; for c in [ix-1,ix,ix+1]: if((c < 0) or (c >= self.widthInTiles)): continue; at=(r)*self.widthInTiles+c #print "at=",at if( self._data[at] >= self._ci): self._block.x = self.x+c*self._tileSize; self._block.y = self.y+r*self._tileSize; self._block.collide(Spr); #print at,self._block.x,self._block.y return #old ix =int(Math.floor((Spr.x - self.x)/self._tileSize)) iy =int(Math.floor((Spr.y - self.y)/self._tileSize)) iw =int( Math.ceil(float(Spr.width)/self._tileSize)+1) ih =int(Math.ceil(float(Spr.height)/self._tileSize)+1) print "map collide",ih,iw print Spr.width,self._tileSize,Spr.x,Spr.y for r in range( ih): if((r < 0) or (r >= self.heightInTiles)): continue; for c in range(iw): if((c < 0) or (c >= self.widthInTiles)): continue; at=(iy+r)*self.widthInTiles+ix+c print "at=",at, if(at<len(self._data) and self._data[at] >= self._ci): self._block.x = self.x+(ix+c)*self._tileSize; self._block.y = self.y+(iy+r)*self._tileSize; self._block.collide(Spr); #print Spr.ySpr.y,Spr.velocity.y,"block",self._block.x,self._block.y,self._block.width,self._block.height #raw_input() # def collide(self,Spr): # self.overlapsWithCallback(Spr,FlxCore.separate) def setTileProperties(self,Tile,AllowCollisions=0x1111,Callback=None,CallbackFilter=None,Range=1): if(Range <= 0): Range = 1; i = Tile; l = Tile+Range; while(i < l): tile = self._tileObjects[i] i+=1 tile.allowCollisions = AllowCollisions; tile.callback = Callback; tile.filter = CallbackFilter; def overlapsArr(self,Array,callback): #print "overlapsArr" for i in range(len( Array)): c = Array[i]; #print dir(c) if(c.exists):#,c.visible self.overlapsWithCallback(c,callback) def collideArr(self,Array): for i in range(len( Array)): c = Array[i]; self.collide(c) def collide(self,Object): results = false; Position=None X = self.x; Y = self.y; if(Position != None): X = Position.x; Y = Position.y; #Figure out what tiles we need to check against selectionX = Math.floor((Object.x - X)/self._tileSize) selectionY = Math.floor((Object.y - Y)/self._tileSize) selectionWidth = selectionX + (Math.ceil(Object.width/self._tileSize)) + 1; selectionHeight = selectionY + Math.ceil(Object.height/self._tileSize) + 1; #Then bound these coordinates by the map edges if(selectionX < 0): selectionX = 0; if(selectionY < 0): selectionY = 0; if(selectionWidth > self.widthInTiles): selectionWidth = self.widthInTiles; if(selectionHeight > self.heightInTiles): selectionHeight = self.heightInTiles; #Then loop through this selection of tiles and call FlxObject.separate() accordingly rowStart = selectionY*self.widthInTiles; row = selectionY; overlapFound=false; deltaX = X - self.last.x; deltaY = Y - self.last.y; #print "selection=====" #print selectionX,selectionY,selectionWidth,selectionHeight while(row <= selectionHeight): column = selectionX; while(column <=selectionWidth): overlapFound = false; #print "at="+str(int(rowStart+column)) tile = self._tileObjects[self._data[int(rowStart+column)]]; #print "row,column",row,column,tile.allowCollisions #print "data="+str(self._data[int(rowStart+column)]) if(tile.allowCollisions): tile.x = X+column*self._tileSize; tile.y = Y+row*self._tileSize; tile.last.x = tile.x - deltaX; tile.last.y = tile.y - deltaY; #print "===========" #print tile.x,tile.y,self._tileSize #print Object.x,Object.y,Object.width,Object.height mycollide.collide(Object,tile) #raw_input() column+=1; rowStart += self.widthInTiles; row+=1; return results; def overlapsWithCallback(self,Object,Callback=None,FlipCallbackParams=false,Position=None): results = false; X = self.x; Y = self.y; if(Position != None): X = Position.x; Y = Position.y; #Figure out what tiles we need to check against selectionX = Math.floor((Object.x - X)/self._tileSize) selectionY = Math.floor((Object.y - Y)/self._tileSize) selectionWidth = selectionX + (Math.ceil(Object.width/self._tileSize)) + 1; selectionHeight = selectionY + Math.ceil(Object.height/self._tileSize) + 1; #Then bound these coordinates by the map edges if(selectionX < 0): selectionX = 0; if(selectionY < 0): selectionY = 0; if(selectionWidth > self.widthInTiles): selectionWidth = self.widthInTiles; if(selectionHeight > self.heightInTiles): selectionHeight = self.heightInTiles; #Then loop through this selection of tiles and call FlxObject.separate() accordingly rowStart = selectionY*self.widthInTiles; row = selectionY; overlapFound=false; deltaX = X - self.last.x; deltaY = Y - self.last.y; while(row < selectionHeight): column = selectionX; while(column < selectionWidth): #print "row,column",row,column overlapFound = false; tile = self._tileObjects[self._data[int(rowStart+column)]]; if(tile.allowCollisions): tile.x = X+column*self._tileSize; tile.y = Y+row*self._tileSize; tile.last.x = tile.x - deltaX; tile.last.y = tile.y - deltaY; if(Callback != None): if(FlipCallbackParams): overlapFound = Callback(Object,tile); else: overlapFound = Callback(tile,Object); else: overlapFound = (Object.x + Object.width > tile.x) and (Object.x < tile.x + tile.width) and (Object.y + Object.height > tile.y) and (Object.y < tile.y + tile.height); if(overlapFound): if((tile.callback != None) and ((tile.filter == None) or (Object is tile.filter))): tile.mapIndex = rowStart+column; tile.callback(tile,Object); results = true; elif((tile.callback != None) and ((tile.filter == None) or (Object is tile.filter))): tile.mapIndex = rowStart+column; tile.callback(tile,Object); column+=1; rowStart += self.widthInTiles; row+=1; return results;
class FlxTilemap(FlxCore): #@desc Constructor #@param MapData A string of comma and line-return delineated indices indicating what order the tiles should go in #@param TileGraphic All the tiles you want to use, arranged in a strip corresponding to the numbers in MapData #@param CollisionIndex The index of the first tile that should be treated as a hard surface #@param DrawIndex The index of the first tile that should actually be drawn def __init__(self, MapData, TileGraphic, CollisionIndex=1, DrawIndex=1): #image = pyglet.resource.image("data/logo.png") FlxCore.__init__(self) self.CollideIndex = CollisionIndex self.DrawIndex = 1 self._ci = CollisionIndex self.widthInTiles = 0 self.heightInTiles = 0 self._data = FlxArray() #c; #cols:Array; rows = open(MapData).read().split("\n") rows.reverse() rows = rows[2:] self.heightInTiles = len(rows) for r in range(self.heightInTiles): cols = rows[r].split(",") if (len(cols) <= 1): self.heightInTiles -= 1 continue if (self.widthInTiles == 0): self.widthInTiles = len(cols) for c in range(self.widthInTiles): self._data.append(int(cols[c])) self._pixels = TileGraphic self._rects = FlxArray() self._p = FlxPoint() self._tileSize = self._pixels.height self.width = self.widthInTiles * self._tileSize self.height = self.heightInTiles * self._tileSize self.numTiles = self.widthInTiles * self.heightInTiles for i in range(self.numTiles): if (self._data[i] >= DrawIndex): self._rects.append( FlxRect(self._tileSize * self._data[i], 0, self._tileSize, self._tileSize)) else: self._rects.append(None) #self._block = FlxBlock(0,0,self._tileSize,self._tileSize,None); self._screenRows = int(Math.ceil(FlxG.height / self._tileSize) + 1) if (self._screenRows > self.heightInTiles): self._screenRows = self.heightInTiles self._screenCols = int(Math.ceil(FlxG.width / self._tileSize) + 1) if (self._screenCols > self.widthInTiles): self._screenCols = self.widthInTiles self._tileObjects = range(self._pixels.width / self._pixels.height) i = 0 while (i < self._pixels.width / self._pixels.height): collide = FlxCore.NONE if (i >= self.CollideIndex): collide = self.allowCollisions self._tileObjects[i] = FlxTile(self, i, self._tileSize, self._tileSize, (i >= self.DrawIndex), collide) i += 1 #@desc Draws the tilemap def render(self): #NOTE: While this will only draw the tiles that are actually on screen, it will ALWAYS draw one screen's worth of tiles FlxCore.render(self) self.getScreenXY(self._p) #print self._p.x,self._p.y #self.position=(self._p.x,self._p.y) #raw_input() tx = Math.floor(-self._p.x / self._tileSize) ty = Math.floor(-self._p.y / self._tileSize) if (tx < 0): tx = 0 if (tx > self.widthInTiles - self._screenCols): tx = self.widthInTiles - self._screenCols if (ty < 0): ty = 0 if (ty > self.heightInTiles - self._screenRows): ty = self.heightInTiles - self._screenRows ri = int(ty * self.widthInTiles + tx) self._p.x += tx * self._tileSize self._p.y += ty * self._tileSize opx = self._p.x for r in range(self._screenRows): cri = ri for c in range(self._screenCols): #print self._rects[cri] #raw_input() if (self._rects[cri] != None): im = self._pixels.get_region( self._rects[cri].x, self._rects[cri].y, self._rects[cri].width, self._rects[cri].height ) #.x,self._rects[cri].y, self._rects[cri].width,self._rects[cri].height) #tmp=Sprite(im) #tmp.position=(self._p.x,self._p.y) #print r,c,"tile",self._p.x,self._p.y #self.add(tmp) r = FlxRect(self._p.x, self._p.y, self._rects[cri].width, self._rects[cri].height) im.blit(self._p.x, self._p.y) cri += 1 self._p.x += self._tileSize ri += self.widthInTiles self._p.x = opx self._p.y += self._tileSize #@desc Collides a FlxSprite against the tilemap #@param Spr The FlxSprite you want to collide def old_collide(self, Spr): #print "map collide"#Spr.velocity.x ix = int(Math.floor((Spr.x - self.x) / self._tileSize)) iy = int(Math.floor((Spr.y - self.y) / self._tileSize)) for r in [iy - 1, iy, iy + 1]: if ((r < 0) or (r >= self.heightInTiles)): continue for c in [ix - 1, ix, ix + 1]: if ((c < 0) or (c >= self.widthInTiles)): continue at = (r) * self.widthInTiles + c #print "at=",at if (self._data[at] >= self._ci): self._block.x = self.x + c * self._tileSize self._block.y = self.y + r * self._tileSize self._block.collide(Spr) #print at,self._block.x,self._block.y return #old ix = int(Math.floor((Spr.x - self.x) / self._tileSize)) iy = int(Math.floor((Spr.y - self.y) / self._tileSize)) iw = int(Math.ceil(float(Spr.width) / self._tileSize) + 1) ih = int(Math.ceil(float(Spr.height) / self._tileSize) + 1) print "map collide", ih, iw print Spr.width, self._tileSize, Spr.x, Spr.y for r in range(ih): if ((r < 0) or (r >= self.heightInTiles)): continue for c in range(iw): if ((c < 0) or (c >= self.widthInTiles)): continue at = (iy + r) * self.widthInTiles + ix + c print "at=", at, if (at < len(self._data) and self._data[at] >= self._ci): self._block.x = self.x + (ix + c) * self._tileSize self._block.y = self.y + (iy + r) * self._tileSize self._block.collide(Spr) #print Spr.ySpr.y,Spr.velocity.y,"block",self._block.x,self._block.y,self._block.width,self._block.height #raw_input() # def collide(self,Spr): # self.overlapsWithCallback(Spr,FlxCore.separate) def setTileProperties(self, Tile, AllowCollisions=0x1111, Callback=None, CallbackFilter=None, Range=1): if (Range <= 0): Range = 1 i = Tile l = Tile + Range while (i < l): tile = self._tileObjects[i] i += 1 tile.allowCollisions = AllowCollisions tile.callback = Callback tile.filter = CallbackFilter def overlapsArr(self, Array, callback): #print "overlapsArr" for i in range(len(Array)): c = Array[i] #print dir(c) if (c.exists): #,c.visible self.overlapsWithCallback(c, callback) def collideArr(self, Array): for i in range(len(Array)): c = Array[i] self.collide(c) def collide(self, Object): results = false Position = None X = self.x Y = self.y if (Position != None): X = Position.x Y = Position.y #Figure out what tiles we need to check against selectionX = Math.floor((Object.x - X) / self._tileSize) selectionY = Math.floor((Object.y - Y) / self._tileSize) selectionWidth = selectionX + (Math.ceil( Object.width / self._tileSize)) + 1 selectionHeight = selectionY + Math.ceil( Object.height / self._tileSize) + 1 #Then bound these coordinates by the map edges if (selectionX < 0): selectionX = 0 if (selectionY < 0): selectionY = 0 if (selectionWidth > self.widthInTiles): selectionWidth = self.widthInTiles if (selectionHeight > self.heightInTiles): selectionHeight = self.heightInTiles #Then loop through this selection of tiles and call FlxObject.separate() accordingly rowStart = selectionY * self.widthInTiles row = selectionY overlapFound = false deltaX = X - self.last.x deltaY = Y - self.last.y #print "selection=====" #print selectionX,selectionY,selectionWidth,selectionHeight while (row <= selectionHeight): column = selectionX while (column <= selectionWidth): overlapFound = false #print "at="+str(int(rowStart+column)) tile = self._tileObjects[self._data[int(rowStart + column)]] #print "row,column",row,column,tile.allowCollisions #print "data="+str(self._data[int(rowStart+column)]) if (tile.allowCollisions): tile.x = X + column * self._tileSize tile.y = Y + row * self._tileSize tile.last.x = tile.x - deltaX tile.last.y = tile.y - deltaY #print "===========" #print tile.x,tile.y,self._tileSize #print Object.x,Object.y,Object.width,Object.height mycollide.collide(Object, tile) #raw_input() column += 1 rowStart += self.widthInTiles row += 1 return results def overlapsWithCallback(self, Object, Callback=None, FlipCallbackParams=false, Position=None): results = false X = self.x Y = self.y if (Position != None): X = Position.x Y = Position.y #Figure out what tiles we need to check against selectionX = Math.floor((Object.x - X) / self._tileSize) selectionY = Math.floor((Object.y - Y) / self._tileSize) selectionWidth = selectionX + (Math.ceil( Object.width / self._tileSize)) + 1 selectionHeight = selectionY + Math.ceil( Object.height / self._tileSize) + 1 #Then bound these coordinates by the map edges if (selectionX < 0): selectionX = 0 if (selectionY < 0): selectionY = 0 if (selectionWidth > self.widthInTiles): selectionWidth = self.widthInTiles if (selectionHeight > self.heightInTiles): selectionHeight = self.heightInTiles #Then loop through this selection of tiles and call FlxObject.separate() accordingly rowStart = selectionY * self.widthInTiles row = selectionY overlapFound = false deltaX = X - self.last.x deltaY = Y - self.last.y while (row < selectionHeight): column = selectionX while (column < selectionWidth): #print "row,column",row,column overlapFound = false tile = self._tileObjects[self._data[int(rowStart + column)]] if (tile.allowCollisions): tile.x = X + column * self._tileSize tile.y = Y + row * self._tileSize tile.last.x = tile.x - deltaX tile.last.y = tile.y - deltaY if (Callback != None): if (FlipCallbackParams): overlapFound = Callback(Object, tile) else: overlapFound = Callback(tile, Object) else: overlapFound = (Object.x + Object.width > tile.x) and ( Object.x < tile.x + tile.width) and ( Object.y + Object.height > tile.y) and (Object.y < tile.y + tile.height) if (overlapFound): if ((tile.callback != None) and ((tile.filter == None) or (Object is tile.filter))): tile.mapIndex = rowStart + column tile.callback(tile, Object) results = true elif ((tile.callback != None) and ((tile.filter == None) or (Object is tile.filter))): tile.mapIndex = rowStart + column tile.callback(tile, Object) column += 1 rowStart += self.widthInTiles row += 1 return results
class FlxEmitter(FlxCore): # public var minVelocity:Point; # public var maxVelocity:Point; # private var _minRotation; # private var _maxRotation; # private var _gravity; # private var _drag; # private var _delay; # private var _timer; # private var self._sprites:FlxArray; # private var _particle; #@desc Constructor #@param X The X position of the emitter #@param Y The Y position of the emitter #@param Width The width of the emitter (particles are emitted from a random position inside this box) #@param Height The height of the emitter #@param Sprites A pre-configured FlxArray of FlxSprite objects for the emitter to use (optional) #@param Delay A negative number defines the lifespan of the particles that are launched all at once. A positive number tells it how often to fire a particle. #@param MinVelocityX The minimum X velocity of the particles #@param MaxVelocityX The maximum X velocity of the particles (every particle will have a random X velocity between these values) #@param MinVelocityY The minimum Y velocity of the particles #@param MaxVelocityY The maximum Y velocity of the particles (every particle will have a random Y velocity between these values) #@param MinRotation The minimum angular velocity of the particles #@param MaxRotation The maximum angular velocity of the particles (you guessed it) #@param Gravity How much gravity should affect the particles #@param Drag Sets both the X and Y "Drag" or deceleration on the particles #@param Graphics If you opted to not pre-configure an array of FlxSprite objects, you can simply pass in a particle image or sprite sheet (ignored if you pass in an array) #@param Quantity The number of particles to generate when using the "create from image" option (ignored if you pass in an array) #@param Multiple Whether the image in the Graphics param is a single particle or a bunch of particles (if it's a bunch, they need to be square!) def __init__(self, X, Y, Width, Height, Sprites=None, Delay=-1, MinVelocityX=-100, MaxVelocityX=100, MinVelocityY=-100, MaxVelocityY=100, MinRotation=-360, MaxRotation=360, Gravity=500, Drag=0, Graphics=None, Quantity=0, Multiple=false, Parent=None): FlxCore.__init__(self) self.visible = false self.x = X self.y = Y self.width = Width self.height = Height self.minVelocity = FlxPoint(MinVelocityX, MinVelocityY) self.maxVelocity = FlxPoint(MaxVelocityX, MaxVelocityY) self._minRotation = MinRotation self._maxRotation = MaxRotation self._gravity = Gravity self._drag = Drag self._delay = Delay self._timer = 0 self._particle = 0 if (Graphics != None): self._sprites = FlxArray() for i in range(Quantity): if (Multiple): (self._sprites.add(FlxSprite(Graphics, 0, 0, true))).randomFrame() else: self._sprites.add(FlxSprite(Graphics)) for i in range(len(self._sprites)): if (Parent == None): FlxG.state.add(self._sprites[i]) else: Parent.add(self._sprites[i]) else: self._sprites = Sprites self.kill() if (self._delay > 0): self.reset() #@desc Called automatically by the game loop, decides when to launch particles and when to "die" def update(self): self._timer += FlxG.elapsed if (self._delay < 0): if (self._timer > -self._delay): self.kill() return if (not self._sprites[0].exists): for i in range(len(self._sprites)): self.emit() return while (self._timer > self._delay): self._timer -= self._delay self.emit() #@desc Call this function to reset the emitter (if you used a negative delay, calling this function "Explodes" the emitter again) def reset(self): self.active = true self._timer = 0 self._particle = 0 #@desc This function can be used both internally and externally to emit the next particle def emit(self): s = self._sprites[self._particle] s.exists = true s.x = self.x - (s.width >> 1) if (self.width != 0): s.x += Math.random() * self.width s.y = self.y - (s.height >> 1) if (self.height != 0): s.y += Math.random() * self.height s.velocity.x = self.minVelocity.x if (self.minVelocity.x != self.maxVelocity.x): s.velocity.x += Math.random() * (self.maxVelocity.x - self.minVelocity.x) s.velocity.y = self.minVelocity.y if (self.minVelocity.y != self.maxVelocity.y): s.velocity.y += Math.random() * (self.maxVelocity.y - self.minVelocity.y) s.acceleration.y = self._gravity s.angularVelocity = self._minRotation if (self._minRotation != self._maxRotation): s.angularVelocity += Math.random() * (self._maxRotation - self._minRotation) if (s.angularVelocity != 0): s.angle = Math.random() * 360 - 180 s.drag.x = self._drag s.drag.y = self._drag self._particle += 1 if (self._particle >= len(self._sprites)): self._particle = 0 s.onEmit() #@desc Call this function to turn off all the particles and the emitter def kill(self): active = false for i in range(len(self._sprites)): self._sprites[i].exists = false
class FlxG: #@desc Represents the amount of time in seconds that passed since last frame elapsed = 0.0 #@desc A reference or pointer to the current FlxFlxG.state object being used by the game state = None width = 0 height = 0 level = 0 levels = FlxArray() score = 0 scores = FlxArray() #@desc These are the constants for use with the Pressed and Releases functions LEFT = 0 #@desc These are the constants for use with the Pressed and Releases functions RIGHT = 1 #@desc These are the constants for use with the Pressed and Releases functions UP = 2 #@desc These are the constants for use with the Pressed and Releases functions DOWN = 3 #@desc These are the constants for use with the Pressed and Releases functions A = 4 #@desc These are the constants for use with the Pressed and Releases functions B = 5 #@desc These are the constants for use with the Pressed and Releases functions MOUSE = 6 #@desc A shortcut way of checking if a particular key is pressed kUp = false #@desc A shortcut way of checking if a particular key is pressed kDown = false #@desc A shortcut way of checking if a particular key is pressed kLeft = false #@desc A shortcut way of checking if a particular key is pressed kRight = false #@desc A shortcut way of checking if a particular key is pressed kA = false #@desc A shortcut way of checking if a particular key is pressed kB = false #@desc A shortcut way of checking if a particular key is pressed kMouse = false #@desc The current game coordinates of the mouse pointer (not necessarily the screen coordinates) # mouse=FlxPoint(); _keys = [] _oldKeys = [] # #audio # _muted; # _music:Sound; _musicChannel = None _musicPosition = None # _volume; # _musicVolume; # _masterVolume; # #Ccmera system variables followTarget = None followLead = FlxPoint() followLerp = 1 followMin = FlxPoint() followMax = FlxPoint() _scrollTarget = FlxPoint() # #graphics stuff scroll = FlxPoint() # buffer:BitmapData; _cache = {} # #function reflectors # _quake; # _flash; # _fade; # _switchFlxG.state; # _log; # _setCursor; #@desc Resets the key register and shortcut booleans to "off" @staticmethod def resetKeys(): kUp = kDown = kLeft = kRight = kA = kB = kMouse = false for i in range(len(FlxG._keys)): FlxG._keys[i] = 0 #@desc Check to see if this key is pressed #@param Key One of the key constants listed above (e.g. LEFT or A) #@return Whether the key is pressed @staticmethod def pressed(Key): return FlxG._keys[Key] > 0 #@desc Check to see if this key was JUST pressed #@param Key One of the key constants listed above (e.g. LEFT or A) #@return Whether the key was just pressed @staticmethod def justPressed(Key): return FlxG._keys[Key] == 2 #@desc Check to see if this key is NOT pressed #@param Key One of the key constants listed above (e.g. LEFT or A) #@return Whether the key is not pressed @staticmethod def justReleased(Key): return FlxG._keys[Key] == -1 #@desc Set up and autoplay a music track #@param Music The sound file you want to loop in the background #@param Volume How loud the sound should be, from 0 to 1 #@param Autoplay Whether to automatically start the music or not (defaults to true) @staticmethod def setMusic(Music, Volume=1, Autoplay=true): FlxG.stopMusic() FlxG._music = Music FlxG._musicVolume = Volume if (Autoplay): FlxG.playMusic() #@desc Plays a sound effect once #@param SoundEffect The sound you want to play #@param Volume How loud to play it (0 to 1) @staticmethod def play(SoundEffect, Volume=1): SoundEffect().play( 0, 0, SoundTransform(Volume * _muted * _volume * _masterVolume)) #@desc Plays or resumes the music file set up using setMusic() @staticmethod def playMusic(): if (FlxG._musicPosition < 0): return if (FlxG._musicPosition == 0): if (FlxG._musicChannel == None): FlxG._musicChannel = _music.play( 0, 9999, SoundTransform(_muted * _volume * _musicVolume * _masterVolume)) else: FlxG._musicChannel = _music.play( FlxG._musicPosition, 0, SoundTransform(_muted * _volume * _musicVolume * _masterVolume)) FlxG._musicChannel.addEventListener(Event.SOUND_COMPLETE, loopMusic) FlxG._musicPosition = 0 #@desc An internal helper function used to help Flash resume playing a looped music track @staticmethod def loopMusic(event=None): if (FlxG._musicChannel == None): return FlxG._musicChannel.removeEventListener(Event.SOUND_COMPLETE, loopMusic) FlxG._musicChannel = None playMusic() #@desc Pauses the current music track @staticmethod def pauseMusic(): if (FlxG._musicChannel == None): FlxG._musicPosition = -1 return FlxG._musicPosition = FlxG._musicChannel.position FlxG._musicChannel.stop() while (FlxG._musicPosition >= _music.length): FlxG._musicPosition -= _music.length FlxG._musicChannel = None #@desc Stops the current music track @staticmethod def stopMusic(): FlxG._musicPosition = 0 if (FlxG._musicChannel <> None): FlxG._musicChannel.stop() FlxG._musicChannel = None #@desc Mutes the sound #@param SoundOff Whether the sound should be off or on @staticmethod def setMute(SoundOff): if (SoundOff): _muted = 0 else: _muted = 1 adjustMusicVolume() #@desc Check to see if the game is muted #@return Whether the game is muted @staticmethod def getMute(): if (_muted == 0): return true return false #@desc Change the volume of the game #@param Volume A number from 0 to 1 @staticmethod def setVolume(Volume): _volume = Volume adjustMusicVolume() #@desc Find out how load the game is currently #@param A number from 0 to 1 @staticmethod def getVolume(): return _volume #@desc Change the volume of just the music #@param Volume A number from 0 to 1 @staticmethod def setMusicVolume(Volume): _musicVolume = Volume adjustMusicVolume() #@desc Find out how loud the music is #@return A number from 0 to 1 @staticmethod def getMusicVolume(): return _musicVolume #@desc An internal function that adjust the volume levels and the music channel after a change @staticmethod def adjustMusicVolume(): if (_muted < 0): _muted = 0 elif (_muted > 1): _muted = 1 if (_volume < 0): _volume = 0 elif (_volume > 1): _volume = 1 if (_musicVolume < 0): _musicVolume = 0 elif (_musicVolume > 1): _musicVolume = 1 if (_masterVolume < 0): _masterVolume = 0 elif (_masterVolume > 1): _masterVolume = 1 if (FlxG._musicChannel <> None): FlxG._musicChannel.soundTransform = SoundTransform( _muted * _volume * _musicVolume * _masterVolume) #@desc Generates a BitmapData object (basically a colored square :P) and caches it #@param FlxG.width How wide the square should be #@param FlxG.height How high the square should be #@param Color What color the square should be #@return This object is used during the sprite blitting process @staticmethod def createBitmap(width, height, Color): key = str(width) + "x" + str(height) + ":" + str(Color) if (FlxG._cache.get(key) == None): FlxG._cache[key] = BitmapData(width, height, true, Color) return FlxG._cache[key] #@desc Loads a bitmap from a file, caches it, and generates a horizontally flipped version if necessary #@param Graphic The image file that you want to load #@param Reverse Whether to generate a flipped version @staticmethod def addBitmap(Graphic, Reverse=false): needReverse = false key = str(Graphic) print Graphic if (FlxG._cache.get(key) == None): FlxG._cache[key] = Graphic().bitmapData if (Reverse): needReverse = true pixels = FlxG._cache[key] if (not needReverse and Reverse and (pixels.width == (Graphic).bitmapData.width)): needReverse = true if (needReverse): newPixels = BitmapData(pixels.width << 1, pixels.height, true, 0x00000000) newPixels.draw(pixels) mtx = Matrix() mtx.scale(-1, 1) mtx.translate(newPixels.width, 0) newPixels.draw(pixels, mtx) pixels = newPixels return pixels #@desc Rotates a point in 2D space around another point by the given angle #@param X The X coordinate of the point you want to rotate #@param Y The Y coordinate of the point you want to rotate #@param PivotX The X coordinate of the point you want to rotate around #@param PivotY The Y coordinate of the point you want to rotate around #@param Angle Rotate the point by this many degrees #@return A Flash Point object containing the coordinates of the rotated point @staticmethod def rotatePoint(X, Y, PivotX, PivotY, Angle): radians = -Angle / 180 * math.PI dx = X - PivotX dy = PivotY - Y return Point( PivotX + math.cos(radians) * dx - math.sin(radians) * dy, PivotY - (math.sin(radians) * dx + math.cos(radians) * dy)) #@desc Calculates the angle between a point and the origin (0,0) #@param X The X coordinate of the point #@param Y The Y coordinate of the point #@return The angle in degrees @staticmethod def getAngle(X, Y): return math.atan2(Y, X) * 180 / math.PI #@desc Tells the camera subsystem what FlxCore object to follow #@param Target The object to follow #@param Lerp How much lag the camera should have (can help smooth out the camera movement) @staticmethod def follow(Target, Lerp=1): FlxG.followTarget = Target FlxG.followLerp = Lerp FlxG._scrollTarget.x = (FlxG.width >> 1) - FlxG.followTarget.x - ( FlxG.followTarget.width >> 1) FlxG.scroll.x = FlxG._scrollTarget.x FlxG._scrollTarget.y = (FlxG.height >> 1) - FlxG.followTarget.y - ( FlxG.followTarget.height >> 1) FlxG.scroll.y = FlxG._scrollTarget.y #@desc Specify an additional camera component - the velocity-based "lead", or amount the camera should track in front of a sprite #@param LeadX Percentage of X velocity to add to the camera's motion #@param LeadY Percentage of Y velocity to add to the camera's motion @staticmethod def followAdjust(LeadX=0, LeadY=0): FlxG.followLead = FlxPoint(LeadX, LeadY) #@desc Specify an additional camera component - the boundaries of the level or where the camera is allowed to move #@param MinX The smallest X value of your level (usually 0) #@param MinY The smallest Y value of your level (usually 0) #@param MaxX The largest X value of your level (usually the level FlxG.width) #@param MaxY The largest Y value of your level (usually the level FlxG.height) @staticmethod def followBounds(MinX=0, MinY=0, MaxX=0, MaxY=0): FlxG.followMin = FlxPoint(-MinX, -MinY) FlxG.followMax = FlxPoint(-MaxX + FlxG.width, -MaxY + FlxG.height) if (FlxG.followMax.x > FlxG.followMin.x): FlxG.followMax.x = FlxG.followMin.x if (FlxG.followMax.y > FlxG.followMin.y): FlxG.followMax.y = FlxG.followMin.y #@desc A fairly stupid tween-like function that takes a starting velocity and some other factors and returns an altered velocity #@param Velocity Any component of velocity (e.g. 20) #@param Acceleration Rate at which the velocity is changing #@param Drag Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set #@param Max An absolute value cap for the velocity @staticmethod def computeVelocity(Velocity, Acceleration=0, Drag=0, Max=10000): if (Acceleration <> 0): Velocity += Acceleration * FlxG.elapsed elif (Drag <> 0): d = Drag * FlxG.elapsed if (Velocity - d > 0): Velocity -= d elif (Velocity + d < 0): Velocity += d else: Velocity = 0 if ((Velocity <> 0) and (Max <> 10000)): if (Velocity > Max): Velocity = Max elif (Velocity < -Max): Velocity = -Max return Velocity #@desc Checks to see if a FlxCore overlaps any of the FlxCores in the array, and calls a function when they do #@param Array An array of FlxCore objects #@param Core A FlxCore object #@param Collide A function that takes two sprites as parameters (first the one from Array, then Sprite) @staticmethod def overlapArray(Array, Core, Collide): if ((Core == None) or not Core.exists or Core.dead): return for i in range(len(Array)): c = Array[i] if ((c == Core) or (c == None) or not c.exists or c.dead): continue if (c.overlaps(Core)): Collide(c, Core) #@desc Checks to see if any FlxCore in Array1 overlaps any FlxCore in Array2, and calls Collide when they do #@param Array1 An array of FlxCore objects #@param Array2 Another array of FlxCore objects #@param Collide A function that takes two FlxCore objects as parameters (first the one from Array1, then the one from Array2) @staticmethod def overlapArrays(Array1, Array2, Collide): if (Array1 == Array2): for i in range(len(Array1)): core1 = Array1[i] if ((core1 == None) or not core1.exists or core1.dead): continue j = i + 1 while (j < Array2.length): core2 = Array2[j] if ((core2 == None) or not core2.exists or core2.dead): continue if (core1.overlaps(core2)): Collide(core1, core2) j += 1 else: for i in range(len(Array1)): core1 = Array1[i] if ((core1 == None) or not core1.exists or core1.dead): continue for j in range(len(Array2)): core2 = Array2[j] if ((core1 == core2) or (core2 == None) or not core2.exists or core2.dead): continue if (core1.overlaps(core2)): Collide(core1, core2) #@desc Collides a FlxSprite against the FlxCores in the array #@param Array An array of FlxCore objects #@param Sprite A FlxSprite object @staticmethod def collideArray(Cores, Sprite): #print "collideArray" if ((Sprite == None) or not Sprite.exists or Sprite.dead): return for i in range(len(Cores)): core = Cores[i] if ((core == Sprite) or (core == None) or not core.exists or core.dead): continue core.collide(Sprite) #@desc Collides an array of FlxSprites against a FlxCore object #@param Sprites An array of FlxSprites #@param Core A FlxCore object @staticmethod def collideArray2(Core, Sprites): if ((Core == None) or not Core.exists or Core.dead): return for i in range(len(Sprites)): sprite = Sprites[i] if ((Core == sprite) or (sprite == None) or (not sprite.exists) or sprite.dead): continue Core.collide(sprite) #@desc Collides the array of FlxSprites against the array of FlxCores #@param Cores An array of FlxCore objects #@param Sprites An array of FlxSprite objects @staticmethod def collideArrays(Cores, Sprites): if (Cores == Sprites): for i in range(len(Cores)): core = Cores[i] if ((core == None) or not core.exists or core.dead): continue j = i + 1 while (j < Sprites.length): sprite = Sprites[j] if ((sprite == None) or not sprite.exists or sprite.dead): continue core.collide(sprite) j += 1 else: for i in range(len(Cores)): core = Cores[i] if ((core == None) or not core.exists or core.dead): continue for j in range(len(Sprites)): sprite = Sprites[j] if ((core == sprite) or (sprite == None) or not sprite.exists or sprite.dead): continue core.collide(sprite) #@desc Switch from one FlxFlxG.state to another #@param FlxG.state The class name of the FlxG.state you want (e.g. PlayFlxG.state) @staticmethod def switchState(state): FlxG._switchState(state) #@desc Log data to the developer console #@param Data The data (in string format) that you wanted to write to the console @staticmethod def log(Data): FlxG._log(Data) #@desc Shake the screen #@param Intensity Percentage of screen size representing the maximum distance that the screen can move during the 'quake' #@param Duration The length in seconds that the "quake" should last @staticmethod def quake(Intensity, Duration=0.5): pass #FlxG._quake(Intensity,Duration) #@desc Temporarily fill the screen with a certain color, then fade it out #@param Color The color you want to use #@param Duration How long it takes for the flash to fade #@param FlashComplete A function you want to run when the flash finishes #@param Force Force the effect to reset @staticmethod def flash(Color, Duration=1, FlashComplete=None, Force=false): pass #FlxG._flash(Color,Duration,FlashComplete,Force); #@desc Fade the screen out to this color #@param Color The color you want to use #@param Duration How long it should take to fade the screen out #@param FadeComplete A function you want to run when the fade finishes #@param Force Force the effect to reset @staticmethod def fade(Color, Duration=1, FadeComplete=None, Force=false): pass #_fade(Color,Duration,FadeComplete,Force) #@desc Set the mouse cursor to some graphic file #@param CursorGraphic The image you want to use for the cursor @staticmethod def setCursor(CursorGraphic): _setCursor(CursorGraphic) #@desc Switch to a different web page @staticmethod def openURL(URL): navigateToURL(URLRequest(URL)) #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def setGameData(w, h, Switchstate=None, Log=None, Quake=None, Flash=None, Fade=None, SetCursor=None): FlxG._cache = {} FlxG.width = w FlxG.height = h _muted = 1.0 _volume = 1.0 _musicVolume = 1.0 _masterVolume = 0.5 FlxG._musicPosition = -1 mouse = FlxPoint() FlxG._switchState = Switchstate FlxG._log = Log _quake = Quake _flash = Flash _fade = Fade _setCursor = SetCursor FlxG.unfollow() FlxG._keys = [] FlxG._oldKeys = [] for i in range(7): FlxG._keys.append(0) FlxG._oldKeys.append(0) FlxG.levels = FlxArray() FlxG.scores = FlxArray() level = 0 score = 0 #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def setMasterVolume(Volume): FlxG._masterVolume = Volume FlxG.adjustMusicVolume() #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def getMasterVolume(): return FlxG._masterVolume #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def doFollow(): from FlxSprite import FlxSprite if (FlxG.followTarget <> None): if (FlxG.followTarget.exists and not FlxG.followTarget.dead): FlxG._scrollTarget.x = ( FlxG.width >> 1) - FlxG.followTarget.x - ( FlxG.followTarget.width >> 1) FlxG._scrollTarget.y = ( FlxG.height >> 1) - FlxG.followTarget.y - ( FlxG.followTarget.height >> 1) if ((FlxG.followLead <> None) and (type(FlxG.followTarget) == FlxSprite)): FlxG._scrollTarget.x -= ( FlxG.followTarget).velocity.x * FlxG.followLead.x FlxG._scrollTarget.y -= ( FlxG.followTarget).velocity.y * FlxG.followLead.y FlxG.scroll.x += (FlxG._scrollTarget.x - FlxG.scroll.x) * FlxG.followLerp * FlxG.elapsed FlxG.scroll.y += (FlxG._scrollTarget.y - FlxG.scroll.y) * FlxG.followLerp * FlxG.elapsed if (FlxG.followMin <> None): if (FlxG.scroll.x > FlxG.followMin.x): FlxG.scroll.x = FlxG.followMin.x if (FlxG.scroll.y > FlxG.followMin.y): FlxG.scroll.y = FlxG.followMin.y if (FlxG.followMax <> None): if (FlxG.scroll.x < FlxG.followMax.x): FlxG.scroll.x = FlxG.followMax.x if (FlxG.scroll.y < FlxG.followMax.y): FlxG.scroll.y = FlxG.followMax.y #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def unfollow(): FlxG.followTarget = None FlxG.followLead = None FlxG.followLerp = 1 FlxG.followMin = None FlxG.followMax = None FlxG.scroll = FlxPoint() FlxG._scrollTarget = FlxPoint() #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def pressKey(k): if (FlxG._keys[k] > 0): FlxG._keys[k] = 1 else: FlxG._keys[k] = 2 #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def releaseKey(k): if (FlxG._keys[k] > 0): FlxG._keys[k] = -1 else: FlxG._keys[k] = 0 #@desc This function is only used by the FlxGame class to do important internal management stuff @staticmethod def updateKeys(): for i in range(7): if ((FlxG._oldKeys[i] == -1) and (FlxG._keys[i] == -1)): FlxG._keys[i] = 0 elif ((FlxG._oldKeys[i] == 2) and (FlxG._keys[i] == 2)): FlxG._keys[i] = 1 FlxG._oldKeys[i] = FlxG._keys[i]