為能在 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