''' 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()" 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. Create the world variables mouseX and mouseY. 8. In the handleMouseClick method, set these to the mouse position, then call the script "handleMouseClick()". 9 (Optional). Set the ambientLightColor world variable to "no color" to have white cells instead of grey. ''' # 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 * # misc from edu.cmu.cs.stage3.alice.authoringtool import * from edu.cmu.cs.stage3.alice.authoringtool.util import * def main(screen): global screenObj screenObj = screen # set dimension constants _size = world.camera.renderTarget.getAWTComponent().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 grid for x in xrange(int(dims.GRID_WIDTH / dims.CELL_WIDTH)): for y in xrange(int(dims.HEIGHT / dims.CELL_WIDTH)): changeCell(x, y, OFF) 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 ### CONSTANTS dims = Generic() ### FUNCTIONS # images images = {} def makeImage(name, w, h): ''' adds an (empty BufferedImage, its Graphics2D) tuple to images ''' 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 ''' texture = TextureMap() texture.propertyChanged(PropertyEvent(texture.image, image)) object.propertyChanged(PropertyEvent(object._diffuseColorMap, 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) TOGGLE = 0 ON = 1 OFF = 2 def changeCell(gridX, gridY, setting = TOGGLE, isCurGrid = true): 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 getImage(name).getRGB(int(x + dims.CELL_WIDTH / 2), int(y + dims.CELL_WIDTH / 2)) == Color.BLACK.getRGB(): # it's on g2d.setPaint(Color.WHITE) else: g2d.setPaint(Color.BLACK) g2d.draw(rect) def updateGrid(): ''' blit current grid to main image, then update it as the texture ''' g2d = getModifiable('main') g2d.drawImage(getImage(getCurGridName()), None, 0, 0) setTexture(screenObj, getImage('main')) # mouse def handleMouseClick(): changeCell(int(mouseX.getValue() / dims.CELL_WIDTH), int(mouseY.getValue() / dims.CELL_WIDTH)) updateGrid() # misc def onScreen(obj): world.bool = camera.canSee(obj, false)