1. Arne Babenhauserheide
  2. fungus


fungus / fungus_water.py

#!/usr/bin/env python
# -*- coding: utf-8 -*-
# encoding: utf-8

"""Fungus collisions :) 


#### Call the correct fungus_game when called from the command line or clicked in a GUI ####

if __name__ == "__main__": 
    # Call this Scene via fungus_game
    from fungus_core import call_this_scene
    # pass the commandline args
    from sys import argv
    call_this_scene(__file__, argv)

#### Imports ####

from fungus_scene import BaseScene

### Things needed for the scene

IMAGE_BLOB = "water.png"

### The Scene itself. 

class Scene(BaseScene): 
    """A dummy scene - mostly just the Scene API."""
    def __init__(self, core, *args, **kwds): 
        """Initialize the scene with a core object for basic functions."""
        ## Get the necessary attributes for any scene. 
        # This gets the 'visible', 'colliding' and 'overlay' lists 
        # as well as the scene switch 'switch_to_scene' 
        # which can be assigned a scene to switch to. 
        super(Scene, self).__init__(core, *args, **kwds)
        ## Tests - not necessary for every scene. 
	# add a batch for faster drawing
	self.batch = self.core.batch()
        # Add a blob. 
        self.blob = self.core.sprite(IMAGE_BLOB, x=0, y=208,
                                     update_func=self.blob_update, batch=self.batch)

        # and give it some random velocity
	from random import random
	self.random = random
	self.blob.dy = 3*random()
	self.blob.dx = 3*random()
	# also we want to be able to spawn blobs
	self.spawns = []
	# make the batch visible

    def stay_on_screen(self, x, y, dx, dy, width, height): 
        """Keep a blob inside the screen borders."""
        if y < 0:
	    # don't bump back with full velocity
	    dy *= -0.99
	    y += 1
	elif y + height > self.core.win.height: 
	    dy *= -1
	    y -= 1
        if x < 0: 
	    dx *= -1
	    x += 1
	elif x + width > self.core.win.width:
	    dx *= -1
	    x -= 1

        return x, y, dx, dy

    def adhere_gravity(self, x, y, dx, dy): 
	"""Gravity pulls them down."""
	dy -= 0.5
	return x, y, dx, dy

    def blob_update(self, x, y, dx, dy): 
        """Move the blob and calculate collisions."""
        # If we "deeptouch" (closer than quarter width) another blob, we exchange 90% of the velocity
        colliding_spawns = [s for s in self.spawns if not s.x == x and (s.x - x)**2 < (0.25*s.width)**2 and (s.y - y)**2 < (0.25*s.height)**2]
        for spawn in colliding_spawns: 
		# first exchange velocity
                _dx = spawn.dx*0.9
                _dy = spawn.dy*0.9
                spawn.dx *= 0.1
                spawn.dy *= 0.1
                spawn.dx += dx*0.9
                spawn.dy += dy*0.9
                dx = 0.1*dx + _dx
                dy = 0.1*dy + _dy
		## then avoid collisions
		x += 0.5*(x - spawn.x)
		y += 0.5*(y - spawn.y)
	# stay inside the screen borders
        x, y, dx, dy = self.stay_on_screen(x, y, dx, dy, self.blob.width, self.blob.height)
	# and adhere gravity
	x, y, dx, dy = self.adhere_gravity(x, y, dx, dy)
	# and move one step to avoid constant collisions
	#x += dx
	#y += dy
        return x, y, dx, dy
    def update(self): 
        """Update the stats of all scene objects. 

Don't blit them, though. That's done by the Game itself.

To show something, add it to the self.visible list. 
To add a collider, add it to the self.colliding list. 
To add an overlay sprite, add it to the self.overlay list. 
	for spawn in self.spawns: 
        # create one spawn every frame, but at most 50
	if not self.spawns[20:]:
		blob = self.core.sprite(IMAGE_BLOB, x=0, y=200,
					update_func=self.blob_update, batch=self.batch)
		from random import random
		blob.dx = 5 + random()
		blob.dy = 5 + random()
		blob.x += blob.dx
		blob.y += blob.dy
		blob.scale = 4.0
		del blob