Possible Phaser target?
Monkey Targets Forums/HTML5/Possible Phaser target?
| ||
. |
| ||
I am trying to create a target to be able to use Phaser as a monkey target. I can get most of it working but the biggest problem is passing function as parameters for functions (if that makes any sense). Does any one have an idea how I can use an alternative solution for that? I already have running the only limit so far is passing functions as parameters which is a big deal. really a show stopper. This is [a/ phaser.io]phaser[/a] |
| ||
Hmmm? I don't know what Phaser is, but why would you need to pass a function as parameter? Is it a requirement in the Phaser SDK? What language does it use? If its C++ - this is an example I use on my DX9 target: LRESULT CALLBACK WindowProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) { } And then in the structure used by the CreateWindow call, this is how its filled: // fill in the struct with the needed information wc.lpfnWndProc = WindowProc; <--- name of the function // register the window class RegisterClassEx(&wc); |
| ||
Sorry, I just assumed since this was an html5 section it would be obvious to assume it would unquestionably be Javascript. this phaser. It is a Javascript/Html5 game library/engine. This is the javascript code for a demo: var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { // You can fill the preloader with as many assets as your game requires // Here we are loading an image. The first parameter is the unique // string by which we'll identify the image later in our code. // The second parameter is the URL of the image (relative) game.load.image('phaser', 'assets/sprites/phaser.png'); } var sprite; function create() { // To make the sprite move we need to enable Arcade Physics game.physics.startSystem(Phaser.Physics.ARCADE); sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'phaser'); sprite.anchor.set(0.5); // And enable the Sprite to have a physics body: game.physics.arcade.enable(sprite); } function update () { // If the sprite is > 8px away from the pointer then let's move to it if (game.physics.arcade.distanceToPointer(sprite, game.input.activePointer) > 8) { // Make the object seek to the active pointer (mouse or touch). game.physics.arcade.moveToPointer(sprite, 300); } else { // Otherwise turn off velocity because we're close enough to the pointer sprite.body.velocity.set(0); } } function render () { game.debug.inputInfo(32, 32); } and this is the monkey code I have working: Import legend Function Main:Int() New Game Return 1 End Function Class Game Extends App Field game:Phaser Method New() game = CreateGame(800,600,Phaser.AUTO,"touch") End Method Method OnPreload() ' You can fill the preloader with as many assets as your game requires ' Here we are loading an image. The first parameter is the unique ' string by which we'll identify the image later in our code. ' The second parameter is the URL of the image (relative) game.load.Image("phaser", "data/phaser.png"); End Method Method OnCreate() ' To make the sprite move we need to enable Arcade Physics game.physics.StartSystem(Physics.ARCADE); sprite = game.add.Sprite(game.world.centerX, game.world.centerY, "phaser"); sprite.anchor.Set(0.5); ' And enable the Sprite to have a physics body: game.physics.arcade.Enable(sprite); End Field sprite:Sprite Method OnUpdate() ' If the sprite is > 8px away from the pointer Then let's move to it If (game.physics.arcade.DistanceToPointer(sprite, game.input.activePointer) > 8) ' Make the Object seek To the active pointer (mouse Or touch). game.physics.arcade.MoveToPointer(sprite, 300); Else ' Otherwise turn off velocity because we're close enough to the pointer sprite.body.velocity.Set(0); End End Method OnRender() game.debug.InputInfo(32, 32); End Method End Class and it works exactly as in this demo: http://phaser.io/examples/v2/basics/04-image-follow-input it can not run this code because of the function name as parameter: var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { game.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', 37, 45, 18); } var sprites; var rip = 0; function create() { sprites = game.add.group(); game.time.events.loop(50, createSprite, this); } function createSprite() { var mummy = sprites.create(0, game.world.randomY, 'mummy'); mummy.animations.add('walk'); mummy.play('walk', 10, true); } function update() { sprites.setAll('x', 10, true, true, 1); sprites.forEach(checkSprite, this, true); } function checkSprite(sprite) { try { if (sprite.x > game.width) { rip++; sprites.remove(sprite, true); } } catch (e) { console.log(sprite); } } function render() { game.debug.text("Group size: " + sprites.total, 32, 32); game.debug.text("Destroyed: " + rip, 32, 64); } all I am doing is opening the javascript code to Monkey-X. I can just about do everything that does not require passing functions to other functions as parameters. Phaser uses functions for event controls and its exactly where the problem is. I won't be able to continue unless I figure out how to do a work around. I am not sure if all of the base languages for monkey allow this but if that is the case my only other solution would be if Mark was to add that property to Monkey. |
| ||
Yeah, if you want proper call-backs/delegates/function-pointers, then you'll have some problems with Monkey (In Monkey, we just use interfaces for this). To do something like this, you'll need to create your own module which handles this kind of thing in native code, then share common variables or classes with Monkey (Basically, what Mojo does). That being said, you could technically make a custom target based on the standard HTML5 one. This looks like it would be annoying when dealing with external code, as you'd probably need to create some kind of generic wrapper system. Monkey doesn't support passing functions as arguments, so you'd need to either use interfaces, or use generics with a few hacks. The far better option is to port the entire thing to Monkey, though. Monkey has WebGL support, and most of what can be done in JavaScript can be easily plugged-into, or accessed from Monkey ('dom' module, for example). That's a pretty big project, though. Plus, it would still need some refactoring to work well. I'm not a JavaScript expert, I've messed with it before, but nothing major. I suppose technically, the compiler could have language-specific setups like this, but I doubt Mark would be okay with it. Other than using the "mangled" names the compiler produces, I can't really see a way around this. Maybe with an interface being sent into external code? Not sure if interfaces can work like that with Monkey. So, besides being a nice API, is there a reason you want to use Phaser with Monkey? It's not like your code would be portable anyway. Maybe you like the way Monkey looks? Unless you're going to put the effort into a port, or possibly make a custom target/module, you can't really do much with it. I vote for porting it, but that would take a bit of effort. |
| ||
. |
| ||
besides being a nice API, is there a reason you want to use Phaser with Monkey? It's just a nerdy project I wanted to tackle. I kind of liked the idea of it being able to run on desktop and smart devices with out any modifications. It's a reach and flexible library. besides at the rate I was going it was going to be a quick and easy conversion. Yea, I don't know if I want to tackle converting the whole library to monkey. Might be a nice library to convert though. Beside they are already working on a new version which according to them its a complete rewrite and not going to be compatible with previous versions. I might tackle editing the compiler. Although I have not messed with compilers before, It might be a good challenge for me. Thanks IO. |
| ||
For simple callbacks: 1. Write a "wrapper" function or method, substituting the Function object type parameter with a string parameter. Use the object's built-in associative array to access the relevant method via the string. 2. Include the wrapper function/method in your Monkey Extern declarations. 3. Call the wrapper function/method as necessary, placing the desired callback in a string. The name should match exactly the Javascript equivalent. Example ------------- cbtest.js //Javascript object: function MyObj() { this.action = null; this.doAction = function(pAction){this.action=pAction; this.action();}; this.doThis = function() {alert("This!");}; this.doThat = function() {alert("That!");}; } //Wrapper method for Monkey's benefit: MyObj.prototype.doActionFromStr = function (strAction) { this.doAction(this[strAction]); } -- test.monkey Strict Import "cbtest.js" Import mojo Extern Class TMyObj = "MyObj" Method DoActionFromStr:Void(strAction:String) = "doActionFromStr" End Public Function Main:Int() New MyApp Return 0 End Class MyApp Extends App Field obj:TMyObj Method OnCreate:Int() obj = New TMyObj() SetUpdateRate 60 Return 0 End Method OnUpdate:Int() If MouseHit(MOUSE_LEFT) 'Use the wrapper method. '(Put the desired callback method in quotes). obj.DoActionFromStr("doThis") Else If MouseHit(MOUSE_RIGHT) obj.DoActionFromStr("doThat") Endif Endif Return 0 End Method OnRender:Int() Cls 0, 0, 0 DrawText "Left-click for THIS action. Right-click for THAT action", 10, 10 Return 0 End End |
| ||
Thanks Impixi. I'll try that. Very much appreciated. |
| ||
Although my above explanation only helps if you want to switch between existing Javascript functions. Such functionality *within* Monkey is a whole different problem (eg function pointers, callbacks, etc, in actual Monkey code.) For my three.js wrapper, I cloned and modified mojo's HTML5 module. Also coded a more Monkey-friendly underlying application framework. You might need to do something similar for your Phaser project. An extract: function ThreeApp() { //TODO: Check validity of all created objects before use... this.monkeyCanvas = document.getElementById("GameCanvas"); var glContext = initWebGL(this.monkeyCanvas); this.renderer = new THREE.WebGLRenderer(glContext); this.renderer.setSize(this.monkeyCanvas.width, this.monkeyCanvas.height); this.scene = null; this.camera = null; this.GetWidth = function(){return this.monkeyCanvas.width;}; this.GetHeight = function(){return this.monkeyCanvas.height;}; this.GetRenderer = function(){return this.renderer;}; this.SetScene = function (scene) {this.scene = scene;}; this.SetCamera = function (camera) {this.camera = camera;}; this.OnRender = function() { requestAnimationFrame(this.OnRender.bind(this)); if ((this.scene!=null) && (this.camera!=null)) { this.renderer.render(this.scene, this.camera); } }; this.OnRender(); } _ In Monkey, I just create a new ThreeApp and set my camera and scene objects accordingly. (And work within my modified Mojo HTML framework OnCreate and OnUpdate methods. OnRender is not used in my case.) _ |
| ||
I pretty much redid the the mojo module including all of the relevant brl files and I based it on the Html5 target. even though I am using the OnCreate OnUpdate, and OnRender, they don't work the same way. I am trying to make the target as close as possible to the original Phaser module. The onRender is mostly for debugging. I haven't tried your example yet, it seems as it might be the solution for what I need to do. I'll try tomorrow. Going to sleep now. Thanks Again. |