- '''
- 1. Create an image in paint or something with aspect ratio 4:3.
- 2. Make a billboard with it using: File > Make Billboard... in Alice.
- 3. Move and resize it so it covers the whole screen.
- 4. Place the script "main(<billboard name>)" in world.my_first_method. If the name starts with a number, place an underscore before it.
- 5. Create a new world method, handleMouseClick
- 6. Create a "When mouse is clicked on" event with the billboard and world.handleMouseClick
- 7. In the handleMouseClick method, call the script "handleMouseClick()".
- 8 (Optional). Set the ambientLightColor world variable to "no color" to have white cells instead of grey.
- '''
- # apparently nested functions can't see outside variables without this, silly jython
- from __future__ import nested_scopes
- # core classes
- from edu.cmu.cs.stage3.alice.core import *
- from edu.cmu.cs.stage3.alice.core.event import *
- from edu.cmu.cs.stage3.alice.core.response import *
- from edu.cmu.cs.stage3.alice.core.property import *
- from edu.cmu.cs.stage3.alice.core.question import *
- # constants
- from edu.cmu.cs.stage3.alice.core.Direction import *
- from edu.cmu.cs.stage3.alice.core.style.TraditionalAnimationStyle import *
- # image
- from java.awt import *
- from java.awt.image import *
- from java.awt.geom import *
- # for profiling
- import time
- # misc
- from edu.cmu.cs.stage3.alice.authoringtool import *
- from edu.cmu.cs.stage3.alice.authoringtool.util import *
- def main(screen):
- global screenObj
- global screenComponent
- screenObj = screen
- screenComponent = world.camera.renderTarget.getAWTComponent()
- # set dimension constants
- _size = screenComponent.getSize()
- dims.WIDTH = _size.width
- dims.HEIGHT = _size.height
- # make a square grid
- dims.GRID_WIDTH = dims.HEIGHT
- # get as close to 20 px per cell as possible, is a float
- dims.CELL_WIDTH = dims.GRID_WIDTH / round(dims.GRID_WIDTH / 20)
- dims.MENU_WIDTH = dims.WIDTH - dims.GRID_WIDTH
- # store images
- makeImage('main', dims.WIDTH, dims.HEIGHT)
- makeGrids()
- makeImage('menu', dims.MENU_WIDTH, dims.HEIGHT)
- # initialize grids
- for gridX in xrange(int(dims.GRID_WIDTH / dims.CELL_WIDTH)):
- for gridY in xrange(int(dims.HEIGHT / dims.CELL_WIDTH)):
- changeCell(gridX, gridY, OFF)
- changeCell(gridX, gridY, OFF, false)
- updateGrid()
- ### CLASSES
- class Generic: # TODO: find a better way to have dicts that work with . instead of []
- pass
- ### VARIABLES
- # the Billboard object that represents the screen
- screenObj = None
- # the actual Component of the screen
- screenComponent = None
- ### CONSTANTS
- dims = Generic()
- ### FUNCTIONS
- # images
- images = {}
- def makeImage(name, w, h):
- '''
- adds an (empty BufferedImage, its Graphics2D) tuple to images if doesn't already exist
- '''
- if name not in images.keys():
- image = AuthoringTool.getHack().getJAliceFrame().getGraphicsConfiguration().createCompatibleImage(w, h)
- modifiable = image.createGraphics()
- images[name] = (image, modifiable)
- def getImage(name):
- return images[name][0]
- def getModifiable(name):
- return images[name][1]
- # textures
- def setTexture(object, image):
- '''
- takes java.awt.Image, makes it texture of object
- 0 - 0.001
- '''
- texture = TextureMap()
- texture.propertyChanged(PropertyEvent(texture.image, image))
- object.propertyChanged(PropertyEvent(object._diffuseColorMap, texture))
- del texture
- def getTextureImage(object):
- '''
- returns java.awt.Image
- '''
- return object.diffuseColorMap.image
- # grid
- def makeGrids():
- makeImage('grid0', dims.GRID_WIDTH, dims.HEIGHT)
- makeImage('grid1', dims.GRID_WIDTH, dims.HEIGHT)
- getModifiable('grid0').setStroke(BasicStroke(1))
- curGrid = 0
- def getCurGridName():
- return 'grid' + str(curGrid)
- def getOtherGridName():
- return 'grid' + str(1 - curGrid)
- def switchGrids():
- global curGrid
- curGrid = 1 - curGrid
- def isOn(gridX, gridY, isCurGrid = true):
- '''
- 0.0000333 over 10000 runs
- '''
- if isCurGrid:
- name = getCurGridName()
- else:
- name = getOtherGridName()
- x, y = gridX * dims.CELL_WIDTH, gridY * dims.CELL_WIDTH
- return getImage(name).getRGB(int(x + dims.CELL_WIDTH / 2), int(y + dims.CELL_WIDTH / 2)) == Color.BLACK.getRGB()
- TOGGLE = 0
- ON = 1
- OFF = 2
- def changeCell(gridX, gridY, setting = TOGGLE, isCurGrid = true):
- '''
- 0 - 0.001, 0.000071 over 10000 runs
- '''
- if isCurGrid:
- name = getCurGridName()
- else:
- name = getOtherGridName()
- x, y = gridX * dims.CELL_WIDTH, gridY * dims.CELL_WIDTH
- rect = Rectangle2D.Double(x, y, dims.CELL_WIDTH, dims.CELL_WIDTH)
- g2d = getModifiable(name)
- if setting == ON:
- g2d.setPaint(Color.BLACK)
- elif setting == OFF:
- g2d.setPaint(Color.WHITE)
- else:
- if isOn(gridX, gridY, isCurGrid):
- # it's on
- g2d.setPaint(Color.WHITE)
- else:
- g2d.setPaint(Color.BLACK)
- g2d.fill(rect)
- g2d.setPaint(Color.BLACK)
- g2d.draw(rect)
- def updateGrid():
- '''
- blit current grid to main image, then update it as the texture
- 0.001 - 0.002
- '''
- g2d = getModifiable('main')
- g2d.drawImage(getImage(getCurGridName()), None, 0, 0)
- setTexture(screenObj, getImage('main'))
- def runOneStep():
- start = time.time()
- gridW = int(dims.GRID_WIDTH / dims.CELL_WIDTH)
- gridH = int(dims.HEIGHT / dims.CELL_WIDTH)
- pxArray = getImage(getCurGridName()).getRaster().getDataBuffer().getData()
- def _isOn(gridX, gridY):
- x, y = gridX * dims.CELL_WIDTH, gridY * dims.CELL_WIDTH
- return pxArray[int(x + dims.CELL_WIDTH / 2) + int(y + dims.CELL_WIDTH / 2) * dims.GRID_WIDTH] == Color.BLACK.getRGB()
- for gridX in xrange(gridW):
- for gridY in xrange(gridH):
- count = 0
- curIsOn = _isOn(gridX, gridY)
- if curIsOn:
- for offX in xrange(-1, 2):
- for offY in xrange(-1, 2):
- if offX or offY:
- if _isOn((gridX + offX) % gridW, (gridY + offY) % gridH):
- count += 1
- if count == 4:
- break
- if count == 4:
- break
- if count <= 1 or count == 4:
- changeCell(gridX, gridY, OFF, false)
- else:
- changeCell(gridX, gridY, ON, false)
- else:
- for offX in xrange(-1, 2):
- for offY in xrange(-1, 2):
- if offX or offY:
- if _isOn((gridX + offX) % gridW, (gridY + offY) % gridH):
- count += 1
- if count == 4:
- break
- if count == 4:
- break
- if count == 3:
- changeCell(gridX, gridY, ON, false)
- else:
- changeCell(gridX, gridY, OFF, false)
- switchGrids()
- updateGrid()
- del pxArray
- print time.time() - start
- # mouse
- def handleMouseClick():
- pos = screenComponent.getMousePosition()
- changeCell(int(pos.x / dims.CELL_WIDTH), int(pos.y / dims.CELL_WIDTH))
- updateGrid()
- # misc
- def onScreen(obj):
- world.bool = camera.canSee(obj, false)
Untitled
Posted by Anonymous on Wed 15th Dec 2010 13:59
raw | new post
Submit a correction or amendment below (click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.