from flash.display import Sprite from flash.display import StageAlign, StageScaleMode from flash.events import Event, KeyboardEvent from flash.text import TextField from flash.utils import getTimer from flash.geom import Matrix from flash.display import GradientType, SpreadMethod from game import Frame, Keys from layout import TopLevel, Widget from layout import State, Layout class Ball(Sprite): def __init__(self, field): self.field = field self.graphics.beginFill(0xFF0000) self.graphics.drawCircle(-field.BALLRADIUS/2, -field.BALLRADIUS/2, field.BALLRADIUS) self.graphics.endFill() self.cacheAsBitmap = True self.radius = field.BALLRADIUS def initposition(self): self.pos_x = self.field.TOTALWIDTH/2 self.pos_y = self.field.TOTALHEIGHT/2 self.speed_x = 0 self.speed_y = 200 def start(self): self.initposition() Frame.attach(self.frame) def stop(self): Frame.detach(self.frame) self.speed_x = 0 self.speed_y = 0 def frame(self, delta): sx = self.speed_x*delta sy = self.speed_y*delta nx = self.pos_x + sx ny = self.pos_y + sy if nx < self.radius: self.pos_x = -nx + 2*self.radius self.speed_x = -self.speed_x self.speed_x *= 0.75 elif nx > self.field.TOTALWIDTH - self.radius: self.pos_x = self.field.TOTALWIDTH*2 - 2*self.radius - nx self.speed_x = -self.speed_x self.speed_x *= 0.75 else: self.pos_x = nx if ny < self.radius: self.pos_y = -ny + 2*self.radius self.speed_y = -self.speed_y elif ny > self.field.TOTALHEIGHT: self.initposition() else: self.pos_y = ny self.x = Math.round(self.pos_x) self.y = Math.round(self.pos_y) class Racket(Sprite): def __init__(self, field): self.racket_width = 80 self.field = field self.pos = 0.5 def draw(self): field = self.field self.x = Math.round((field.TOTALWIDTH - self.racket_width)*self.pos) self.y = field.TOTALHEIGHT - field.BRICKHEIGHT - field.PADDING m = Matrix() m.createGradientBox(self.racket_width, field.BRICKHEIGHT, 0, -self.racket_width/4, -field.BRICKHEIGHT/4) self.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0x808080], #colors [1.0, 1.0], #alphas [0, 255], #ratios m, # transform matrix SpreadMethod.PAD) self.graphics.drawRoundRect(0, 0, self.racket_width, field.BRICKHEIGHT, field.BRICKHEIGHT, field.BRICKHEIGHT) self.graphics.endFill() m.createGradientBox(self.racket_width*3, field.BRICKHEIGHT*3, 0, -self.racket_width/4, -field.BRICKHEIGHT/4) self.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, 0x808080], #colors [1.0, 1.0], #alphas [0, 255], #ratios m, # transform matrix SpreadMethod.PAD) self.graphics.drawRoundRect(field.LINEWIDTH, field.LINEWIDTH, self.racket_width - field.LINEWIDTH*2, field.BRICKHEIGHT - field.LINEWIDTH*2, field.BRICKHEIGHT - field.LINEWIDTH, field.BRICKHEIGHT - field.LINEWIDTH) self.graphics.endFill() self.cacheAsBitmap = True def start(self): Frame.attach(self.frame) Keys.register(Keys.LEFT, 'racket_left') Keys.register(Keys.RIGHT, 'racket_right') def stop(self): Frame.detach(self.frame) def frame(self, delta): if delta: if Keys.keys.racket_left: self.speed -= delta elif Keys.keys.racket_right: self.speed += delta else: if Math.abs(self.speed) > 0.01: self.speed *= Math.pow(0.01, delta) else: self.speed = 0 if self.speed: self.pos += self.speed*delta if self.pos < 0: self.pos = 0 elif self.pos > 1: self.pos = 1 self.x = Math.round((self.field.TOTALWIDTH-self.racket_width)*self.pos) class Brick(Sprite): def __init__(self, field, brickdef): m = Matrix() fullw = field.BRICKWIDTH fullh = field.BRICKHEIGHT m.createGradientBox(fullw, fullh, 0, -fullw/4, -fullh/4) self.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, brickdef.color], #colors [1.0, 1.0], #alphas [0, 255], #ratios m, # transform matrix SpreadMethod.PAD) self.graphics.drawRoundRect(0, 0, fullw, fullh, field.ROUND) self.graphics.endFill() m.createGradientBox(fullw*3, fullh*3, 0, -fullw/4, -fullh/4) self.graphics.beginGradientFill(GradientType.RADIAL, [0xFFFFFF, brickdef.color], #colors [1.0, 1.0], #alphas [0, 255], #ratios m, # transform matrix SpreadMethod.PAD) self.graphics.drawRoundRect(field.LINEWIDTH, field.LINEWIDTH, field.BRICKWIDTH-field.LINEWIDTH*2, field.BRICKHEIGHT-field.LINEWIDTH*2, field.ROUND-field.LINEWIDTH) self.graphics.endFill() self.cacheAsBitmap = True def hit(self): # die on first hit return True class BrickDef: def __init__(self, color): self.color = color class Level: def __init__(self, bricks, levelset): self.bricks = bricks self.levelset = levelset def populate(self, field): lines = {} y = 0 for line in values(self.levelset.split('\n')): x = 0 for i in range(line.length): c = line.charAt(i) if ' \n\t\r'.indexOf(c) >= 0: continue if c == '.': pass elif self.bricks[c]: b = Brick(field, self.bricks[c]) field.add_brick(x, y, b) x += 1 if x: y += 1 level1 = Level({ 'r': BrickDef(0xFF0000), 'g': BrickDef(0x00FF00), 'b': BrickDef(0x0000FF), }, """ rrrrggggggrrrr ggggbbbbbbgggg rrrrbbbbbbrrrr ggggbbbbbbgggg rrrrggggggrrrr """) class Field(Widget): def __init__(self, level, name, states): super().__init__(name, states) self.init_const() self.ball = Ball(self) self.racket = Racket(self) self.bricks = {} self.drawn = False level1.populate(self) self.addChild(self.ball) self.addChild(self.racket) def start(self): self.racket.start() self.ball.start() Frame.attach(self.frame) def stop(self): Frame.detach(self.frame) self.ball.stop() self.racket.stop() def frame(self, delta): test = self.ball.hitTestObject if test(self.racket): self.ball.speed_y = -self.ball.speed_y if self.racket.speed: self.ball.speed_x += self.racket.speed*5 bx = (self.ball.x - self.PADDING) bax = Math.floor((bx - self.BALLRADIUS) / self.BRICKWIDTH) bbx = Math.floor((bx + self.BALLRADIUS) / self.BRICKWIDTH) by = (self.ball.y - self.PADDING) bay = Math.floor((by - self.BALLRADIUS) / self.BRICKHEIGHT) bby = Math.floor((by + self.BALLRADIUS) / self.BRICKHEIGHT) for bkey in values([ bax + ',' + bay, bax + ',' + bby, bbx + ',' + bay, bby + ',' + bby, ]): b = self.bricks[bkey] if not b: continue if test(b) and b.hit(): del self.bricks[bkey] self.removeChild(b) def init_const(self): self.BALLRADIUS = 10 self.PADDING = 20 self.BRICKWIDTH = 40 self.BRICKHEIGHT = 20 self.ROUND = 10 self.LINEWIDTH = 3 def add_brick(self, x, y, brick): self.bricks[x + ',' + y] = brick brick.x = self.PADDING+self.BRICKWIDTH*x brick.y = self.PADDING+self.BRICKHEIGHT*y self.addChild(brick) def draw(self, width, height): self.TOTALWIDTH = width self.TOTALHEIGHT = height if not self.drawn: self._draw() self.drawn = True self.racket.draw() def _draw(self): self.graphics.lineStyle(2, 0x000000) self.graphics.drawRoundRect(0, 0, self.TOTALWIDTH, self.TOTALHEIGHT, self.ROUND, self.ROUND) @package('arkanoid') class Main(TopLevel): def __init__(self): Frame.start(self, True) Keys.start(self.stage) self.layout = Layout([ Field(level1, 'field', { 'normal': State.parse( 'normal:(0,0)-(1,1)*(0.5,0.5)[560,400]'), }), ]) super().__init__() self.layout.mapping.field.start()