Python-Course

Brython << Previous Next >> GCS

Ggame

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

App

sprite

Sprite

event

KeyEvent, MouseEvent

asset

ImageAsset, TextAsset, CircleAsset, RectangleAsset
PolygonAsset, LineAsset, EllipseAsset
Frame, Color, LineStyle

sound

SoundAsset, Sound


Brython << Previous Next >> GCS