為能在 canvas 模式下正確執行, 必須採用下列 sysdeps.py
def module_exists(module_name): try: __import__(module_name) except ImportError: return False else: return True if module_exists('browser') and module_exists('javascript'): from browser import window, document, load from javascript import JSObject, JSConstructor # pixi 與 buzz 模組, 改為在頁面載入時導入 major = window.__BRYTHON__.implementation[0] minor = window.__BRYTHON__.implementation[1] # brython 新版與 Javascript 程式庫結合運用方法 if major == 3 and minor >= 3 or major > 3: GFX = window.PIXI GFX_Rectangle = GFX.Rectangle.new GFX_Texture = GFX.Texture.new GFX_Texture_fromImage = GFX.Texture.fromImage.new GFX_Sprite = GFX.Sprite.new GFX_Graphics = GFX.Graphics.new() GFX_Text = GFX.Text.new GFX_NewStage = GFX.Container.new SND = window.buzz SND_Sound = SND.sound.new else: # 舊版 Brython 呼叫 Javascript 物件方法 GFX = JSObject(window.PIXI) GFX_Rectangle = JSConstructor(GFX.Rectangle) GFX_Texture = JSConstructor(GFX.Texture) GFX_Texture_fromImage = JSConstructor(GFX.Texture.fromImage) GFX_Sprite = JSConstructor(GFX.Sprite) GFX_Graphics = JSConstructor(GFX.Graphics)() GFX_Text = JSConstructor(GFX.Text) GFX_NewStage = JSConstructor(GFX.Container) SND = JSObject(window.buzz) SND_Sound = JSConstructor(SND.sound) GFX_DetectRenderer = GFX.autoDetectRenderer class GFX_Window(object): def __init__(self, width, height, onclose): canvas = window.document.getElementById('ggame-canvas') if canvas: ''' # 原始 Ggame 使用方法, 無法使用, 改為下列方式運用. self._w = window window.bsUI.graphicsmode() options = {'transparent':True, 'antialias':True, 'view':canvas} attachpoint = window.document.getElementById('graphics-column') w, h = attachpoint.clientWidth, attachpoint.clientHeight ''' self._w =window w, h = self._w.innerWidth, self._w.innerHeight options = {'transparent':True, 'antialias':True, 'view':canvas} attachpoint = window.document.getElementById('graphics-column') else: #self._w = window.open("", "") # 在頁面直接執行時, 不另開視窗頁面 self._w =window w, h = self._w.innerWidth * 0.9, self._w.innerHeight * 0.9 options = {'transparent':True, 'antialias':True} attachpoint = self._w.document.body GFX.utils._saidHello = True; # ugly hack to block pixi banner self._stage = GFX_NewStage() self.width = width if width != 0 else int(w) self.height = height if height != 0 else int(h) self._renderer = GFX.autoDetectRenderer(self.width, self.height, options) attachpoint.appendChild(self._renderer.view) self._w.onunload = onclose def bind(self, evtspec, callback): self._w.document.body.unbind(evtspec) # in case already bound self._w.document.body.bind(evtspec, callback) def unbind(self, evtspec): self._w.document.body.unbind(evtspec) def add(self, obj): self._stage.addChild(obj) def remove(self, obj): self._stage.removeChild(obj) def animate(self, stepcallback): self._renderer.render(self._stage) self._w.requestAnimationFrame(stepcallback) def destroy(self): SND.all().stop() self._stage.destroy() elif module_exists('pygame'): try: from ggame.pygamedeps import * except ImportError: from pygamedeps import * else: try: from ggame.headlessdeps import * except ImportError: from headlessdeps import *
在 CMSimfly 頁面執行方式:
# Ggame from ggame import App, ImageAsset, Sprite, MouseEvent from random import random, randint from browser import document as doc from browser import html import math # 建立內定名稱為 "ggame-canvas" 的 canvas 標註 canvas = html.CANVAS(width = 600, height = 400) canvas.id = "ggame-canvas" brython_div = doc["brython_div"] brython_div <= canvas # 建立名稱為 graphics-column 且 1x1 大小的 div 標註 graphics_column = html.DIV(width = 1, height = 1) graphics_column.id = "graphics-column" brython_div <= graphics_column class Bunny(Sprite): asset = ImageAsset("./.../../images/bunny.png") def __init__(self, position): super().__init__(Bunny.asset, position) # register mouse events App.listenMouseEvent(MouseEvent.mousedown, self.mousedown) App.listenMouseEvent(MouseEvent.mouseup, self.mouseup) App.listenMouseEvent(MouseEvent.mousemove, self.mousemove) self.dragging = True def step(self): # Every now and then a bunny hops... if random() < 0.01: self.x += randint(-20,20) self.y += randint(-20,20) def mousedown(self, event): # capture any mouse down within 50 pixels self.deltax = event.x - (self.x + self.width//2) self.deltay = event.y - (self.y + self.height//2) if abs(self.deltax) < 50 and abs(self.deltay) < 50: self.dragging = True # only drag one bunny at a time - consume the event event.consumed = True def mousemove(self, event): if self.dragging: self.x = event.x - self.deltax - self.width//2 self.y = event.y - self.deltay - self.height//2 event.consumed = True def mouseup(self, event): if self.dragging: self.dragging = False event.consumed = True class DemoApp(App): def __init__(self): super().__init__() for i in range(5): Bunny((randint(50, 600), randint(50, 400))) def step(self): # Override step to perform action on each frame update for bunny in self.spritelist: bunny.step() # Create the app app = DemoApp() # Run the app app.run()
GFX = window.PIXI
GFX_Rectangle = GFX.Rectangle.new
GFX_Texture = GFX.Texture.new
GFX_Texture_fromImage = GFX.Texture.fromImage.new
GFX_Sprite = GFX.Sprite.new
GFX_Graphics = GFX.Graphics.new()
GFX_Text = GFX.Text.new
GFX_NewStage = GFX.Container.new
SND = window.buzz
SND_Sound = SND.sound.new
class GFX_Window(object):
def __init__(self, width, height, onclose):
App
Sprite
KeyEvent, MouseEvent
ImageAsset, TextAsset, CircleAsset, RectangleAsset
PolygonAsset, LineAsset, EllipseAsset
Frame, Color, LineStyle
SoundAsset, Sound