Пример #1
0
    def init(self):
        Scene.init(self)
        self._game_over = False
        self._router = None
        self._total_tp = 0
        self._total_tp_reached = 0
        self._data_collected = 0
        self._data_leaked = 0
        self._total_kills = 0
        self._score = 0
        self._show_once = set()
        self._time = 0

        self._alerts = SortedList()

        self._current_alert = 1

        self._bases = []
        self._target_points= set()
        self._projectiles = set()
        self._enemies = set()

        self._vpw, self._vph = getViewportSize()

        self._sprites = SpriteManager()
        self._text_writer = Writer(self._sprites)


        self._map = Map("map2")

        pos = self._map.getPlayerInitialPosition()

        self._player = Player(self._map, pos + (0,0,1))

        self._camera = Camera(self._player, self._map)

        self._particles = ParticleController()

        self._router = RouterBatchProcessor(Router(self._map, pos, 65))

        self.placeInitialLocations()

        self._time_z = 0

        self._new_spawn  = float("Inf")

        self._lock_sprite = self._sprites.newSprite("lock.png",alpha=1.0,centered=True)
        self._sprites.setSpriteAlpha(self._lock_sprite,0)


        self._texts = {
            "collected":[-1,(20,20),lambda:"Data collected: %s%%"%int(100*self._data_collected)],
            "leaked":[-1,(20,50),lambda:"Data leaked: %s%%"%int(100*(self._data_leaked / self._data_collected) if self._total_tp_reached else 0)],
            "kills":[-1,(500,50),lambda:"Kills: %s"%self._total_kills],
            "score":[-1,(500,20),lambda:"SCORE %s"%self._score]
        }

        for i in xrange(10):
            # expiry time, location, writer_id
            self._alerts.append((float("Inf"),0,0))

        self.updateText(*self._texts.keys())


        #pygame.image.save(self._sprites._textures[0]._surface,"tiles.png")




        self.addAlert(self._time+8000, "*Use the arrow keys to move around\n<ENTER> for shooting and <SPACE> for jumping", color=(0,255,0), once="keys")
Пример #2
0
class MainScene(Scene):

    def __init__(self):
        Scene.__init__(self)


    def init(self):
        Scene.init(self)
        self._game_over = False
        self._router = None
        self._total_tp = 0
        self._total_tp_reached = 0
        self._data_collected = 0
        self._data_leaked = 0
        self._total_kills = 0
        self._score = 0
        self._show_once = set()
        self._time = 0

        self._alerts = SortedList()

        self._current_alert = 1

        self._bases = []
        self._target_points= set()
        self._projectiles = set()
        self._enemies = set()

        self._vpw, self._vph = getViewportSize()

        self._sprites = SpriteManager()
        self._text_writer = Writer(self._sprites)


        self._map = Map("map2")

        pos = self._map.getPlayerInitialPosition()

        self._player = Player(self._map, pos + (0,0,1))

        self._camera = Camera(self._player, self._map)

        self._particles = ParticleController()

        self._router = RouterBatchProcessor(Router(self._map, pos, 65))

        self.placeInitialLocations()

        self._time_z = 0

        self._new_spawn  = float("Inf")

        self._lock_sprite = self._sprites.newSprite("lock.png",alpha=1.0,centered=True)
        self._sprites.setSpriteAlpha(self._lock_sprite,0)


        self._texts = {
            "collected":[-1,(20,20),lambda:"Data collected: %s%%"%int(100*self._data_collected)],
            "leaked":[-1,(20,50),lambda:"Data leaked: %s%%"%int(100*(self._data_leaked / self._data_collected) if self._total_tp_reached else 0)],
            "kills":[-1,(500,50),lambda:"Kills: %s"%self._total_kills],
            "score":[-1,(500,20),lambda:"SCORE %s"%self._score]
        }

        for i in xrange(10):
            # expiry time, location, writer_id
            self._alerts.append((float("Inf"),0,0))

        self.updateText(*self._texts.keys())


        #pygame.image.save(self._sprites._textures[0]._surface,"tiles.png")




        self.addAlert(self._time+8000, "*Use the arrow keys to move around\n<ENTER> for shooting and <SPACE> for jumping", color=(0,255,0), once="keys")


    def updateText(self, *which):
        for w in which:
            v = self._texts[w]
            id,pos,fn = v
            if id == -1:
                self._text_writer.setFont(10)
                self._text_writer.setColor(255,255,255,200)
                id = self._text_writer.addText(pos,fn())
                v[0] = id
            else:
                self._text_writer.changeText(id, fn())


    def getAlertPos(self, i):
        return (20, i*17+90)


    def addAlert(self, keep_until, text, color=(255,255,255), once=None):

        if once is not None:
            if once in self._show_once:
                return

            self._show_once.add(once)

        if "\n" in text:
            for line in text.split("\n"):
                self.addAlert(keep_until, line, color)
            return

        if self._alerts[0][0]>0: # take an empty slot
            p = self._alerts.pop(-1)
        else: # or an alert which is closest to disappear
            p = self._alerts.pop(0)

        id = p[2]
        if id == 0:
            self._text_writer.setFont(6)
            self._text_writer.setColor(*color)
            id = self._text_writer.addText((0,0),text)
        else:
            self._text_writer.changeText(id,text,pos=(0,0), color=color)

        self._alerts.add((keep_until,self._current_alert,id)) # insert the text
        self._current_alert += 1

        self.reorderAlerts()


    def reorderAlerts(self):
        # now, reorganize the list, sorted by alert number
        i = 0
        for l in sorted(self._alerts, key=lambda a:a[1]): # sort by location
            expiry, slot, writer = l
            if expiry == 0 or writer==0: # not active
                continue
            self._text_writer.moveText(writer, self.getAlertPos(i))
            i+=1


    def updateAlerts(self, time):
        changed = False
        while True:
            expiry, slot, writer = self._alerts[0]
            if expiry == 0 or expiry > time:
                break
            p = self._alerts.pop(0)
            self._text_writer.setTextAlpha(p[2],0.0)
            self._alerts.add((float("Inf"),1000,p[2]))
            changed = True

        if changed:
            self.reorderAlerts()



    def gameOver(self):
        self._game_over = True
        c = T.translation_matrix((self._vpw/2, self._vph/2,-0.1))
        self._game_over_sprite = self._sprites.newSprite("gameover.png",centered=True, xform=c)

    def gameWin(self):
        self._game_over = True
        c = T.translation_matrix((self._vpw/2, self._vph/2,-0.1))
        self._game_over_sprite = self._sprites.newSprite("finished.png",centered=True, xform=c)


    def getMap(self):
        return self._map


    def getParticleManager(self):
        return self._particles


    def placeInitialLocations(self):
        self._total_tp = 0

        for pos in self._map.getResourcePositions("base"):
            self.placeBase(pos)

        for pos in self._map.getResourcePositions("target_point"):
            self.placeTargetPoints(pos)

        for pos in self._map.getResourcePositions("enemy_base"):
            self.placeEnemyBase(pos)


    def placeTargetPoints(self, pos):
        self._total_tp += 1
        self._total_tp_reached = 0
        self._target_points.add(TargetPoint(self, pos+(0,0,1)))




    def placeBase(self, pos):


        pg = ParticleGenerator("billboard","particle5.png")
        pg.setEasing(0.2,0.2,0.0,0.5,2.0)
        pg.setBrightness(0.5)
        pg.setMode("LOOP")
        pg.setPosition(pos + (0,0,3))
        self._particles.manageGenerator(pg)


        #pg = ParticleGenerator("billboard","particle2.png")
        #pg.setMode("LOOP")
        #pg.setPosition(pos)
        #self._particles.manageGenerator(pg)

        self._bases.append(Base(pos, pg))




    def placeEnemyBase(self, pos):
        pass



    def newEnemy(self):
        pos = random.choice(self._map.getResourcePositions("enemy_source"))
        tgt = random.choice(self._bases).getPosition()
        m = Enemy(self, pos, tgt, self._router)
        self._enemies.add(m)


    def enemyReachedBase(self, e):
        if e.closing():
            return
        e.close()
        self._data_leaked += (self._data_collected-self._data_leaked) *random.random()*0.2
        self.updateText("leaked")


        self.addAlert(self._time+3000, "*Enemies are stealing your data!", color=(255,128,0))
        self.addAlert(self._time+8000, "*If 50% of your collected data gets leeched, you lose", color=(0,255,0), once="lose")
        if self._data_leaked >0  and (self._data_leaked > self._data_collected * 0.5):
            if not self._game_over:
                self.gameOver()


        #pygame.image.save(self._sprites._textures[0]._surface,"tiles.png")


    def reachedTargetPoint(self, tp):
        if tp.closing():
            return
        tp.close()
        self._total_tp_reached += 1
        self._data_collected = float(self._total_tp_reached)/self._total_tp
        self._score += 500
        self.updateText("collected","score","leaked")
        self.addAlert(self._time+8000, "*Follow all the beacons to collect the data", color=(0,255,0), once="beacons")
        #pygame.image.save(self._sprites._textures[0]._surface,"tiles.png")

        if self._total_tp_reached == self._total_tp:
            self.gameWin()

        # first leecher is spawned after data is collected
        if self._total_tp_reached == 1:
            self._new_spawn = self._time + 5000


    def updateEntities(self, time, *entity_list):
        for el in entity_list:
            p = []
            for e in el:
                r = e.update(time)
                if not r:
                    p.append(e)
            el.difference_update(p)



    def advance(self, screen, time, inp):
        if self._time_z == 0:
            self._time_z = time
            return

        time -= self._time_z  # relative time to the beginning of the game

        self._time = time

        self._modelview_m = self._camera.getMatrix()

        self.freezeLight()

        #self._modelview_m = lookAtMtx(N.array((300,300,300),dtype="f"),N.array(self._player.getPosition(),dtype="f"), (0,0,1))

        # pre-render update -------

        self._player.update(time)

        self._camera.update(time)

        self._particles.update(time)

        for e in self._bases: e.update(time)

        self.updateEntities(time,
                self._target_points,
                self._projectiles,
                self._enemies
            )

        # check collisions -------

        #for e in self._projectiles:
        #    collisions = e.getCollisions()
        #    for c in collisions:
        #        if c in self._enemies:
        #            c.destroy()
        #            e.explode()



        for e in self._enemies:
            if e.targetReached():
                self.enemyReachedBase(e)
            else:
                self._player.checkLock(e)
                for p in self._projectiles:
                    if p.collidesWith(e):
                        self._total_kills += 1
                        p.explode()
                        e.explode()
                        self._score += 100
                        self.updateText("kills", "score")



        if not self._game_over:
            p = self._player
            nearby = p.getCloseEntities()
            for n in nearby:
                if isinstance(n,TargetPoint):
                    if p.collidesWith(n):
                        self.reachedTargetPoint(n)

        #  draw -------

        self._map.draw(self)
        self._player.draw(self)

        for e in self._bases: e.draw(self)
        for e in self._target_points: e.draw(self)
        for e in self._projectiles: e.draw(self)
        for e in self._enemies: e.draw(self)


        glDepthMask(False)
        glBlendFunc(GL_SRC_ALPHA, GL_ONE)
        glEnable(GL_BLEND)

        self._particles.draw(self) # very last thing to draw
        for e in self._target_points: e.drawBeacon(self)

        glDisable(GL_BLEND)
        glDepthMask(True)

        # UI ------
        self.updateAlerts(time)

        locking = False
        if not self._game_over:
            lock_pos = self._player.getLockPosition()
            if lock_pos is not None:
                proj = mmult(self._perspective_m, self._modelview_m, N.array((lock_pos[0], lock_pos[1], lock_pos[2], 1), dtype = "f"))

                if proj[3] > 0:
                    px = ((proj[0] / proj[3]) +1.0)* self._vpw*0.5
                    py = (1.0 - (proj[1] / proj[3]))* self._vph*0.5
                    if px > 0 and px < self._vpw and py >0 and py < self._vph:
                        self._sprites.setSpriteTransform(self._lock_sprite, T.translation_matrix((px,py,0)))
                        self._sprites.setSpriteAlpha(self._lock_sprite, 0.5)
                        locking = True
        if not locking:
            self._sprites.setSpriteAlpha(self._lock_sprite, 0.0)

        self.resetModelview()
        self.setOrthoMode()

        self._sprites.draw(self)

        self.setPerspectiveMode()
        # process input ------

        if not self._game_over:

            if (inp.wantJump()):
                self._player.jump()

            if (inp.wantShoot()):
                m = self._player.getMissile(self)
                self._projectiles.add(m)

            self._player.advance(inp.fwdMotion()*0.00001)
            self._player.alterHeading(inp.rotMotion()*0.01)

        # misc world advance ------

        self._router.dispatch()

        if time > self._new_spawn:
            self.newEnemy()
            self.addAlert(time+3000,"*New leecher approaching",(200,200,0))

            self._new_spawn = time+ random.randint(20000,50000)


    def destroy(self):
        if self._router:
            self._router.finish()
        self._router = None


    def __del__(self):
        try:
            # in case "destroy" wasn't called.
            # do this at least
            if self._router:
                self._router.finish()
            self._router = None
        except:
            pass