Impact

This forum is read only and just serves as an archive. If you have any questions, please post them on github.com/phoboslab/impact

1 decade ago by quidmonkey

Hey All-

I created a new Canvas-Native Fonts Plugin along with a new FontManager plugin that replaces my popular NotificationManager plugin.

Enjoy, and I appreciate your feedback.

UPDATE

Updated plugin to v1.1. Changelog:

- Added .alpha property
- Added logic to prevent the canvas context .font property from being set each .draw() for optimization
- Updated .getWidth() and Font.getWidth() to make the font parameter optional and added optimization test
- Removed text parameter from constructor
- Changed .baseline from 'middle' to 'top' to match ImpactJS's style of an object's origin being the top-left corner


Most notable is the change to updating the context .font property only when necessary. Thanks to Graphikos, we did some initial testing comparing canvas-native fonts vs. ig.Font and found our results all over the place. After some research, I found that setting the context .font property to be a bottleneck. While I could find no explanation why this is, my guess is because each time it's set, it loads in the new font in preparation for drawing. If anyone else has done some benchmarking, I'm all ears.

1 decade ago by stahlmanDesign

Can you provide some working examples?

I finally got it working but I don't understand everything.

Here's the code I used by taking the basic template from Impact 1.20 and adding your font plugin and font manager:

ig.module( 
	'game.main' 
)
.requires(
	'impact.game',
	'plugins.font',
	'plugins.font-manager'
)
.defines(function(){

MyGame = ig.Game.extend({
	
	font: null,
	fm: null,
	
	init: function() {
		// Initialize your game here; bind keys etc.
		
		fm = new FontManager();
		font = new Font('40px Garamond', 'Hello World' );
		fm.add( 3.3, font );
		fm.spawn( 2.7 );
	},
	
	update: function() {
		// Update all entities and backgroundMaps
		this.parent();
		// Add your own, additional update code here
		fm.update();
	},
	
	draw: function() {
		// Draw all entities and backgroundMaps
		this.parent();
		
		fm.draw( );
		
		// Add your own drawing code here
		var x = ig.system.width/2,
			y = ig.system.height/2;
				
	}
});


// Start the Game with 60fps, a resolution of 320x240, scaled
// up by a factor of 2
ig.main( '#canvas', MyGame, 60, 320, 240, 2 );

});

It seems that this would require the font being installed in the system, right? Or does this work with web fonts, such as Google web fonts?

1 decade ago by quidmonkey

I don't see why you couldn't use web fonts, provided they're readily loaded. From the canvas spec:

Font names must be interpreted in the context of the font style source node's stylesheets when the font is to be used; any fonts embedded using @font-face that are visible to that element must therefore be available once they are loaded. (If a reference font is used before it is fully loaded, or if the font style source node does not have that font in scope at the time the font is to be used, then it must be treated as if it was an unknown font, falling back to another as described by the relevant CSS specifications.)


Here's an example:

ig.module( 
	'game.main' 
)
.requires(
	'impact.game',
	'impact.font',

	'plugins.font'
)
.defines(function(){

FontTest = ig.Game.extend({
	
	fireFont: new Font( '20px Garamond' ),		//animated font
	font: new Font( '20px Garamond' ),			//basic font

	init: function(){
		ig.input.bind( ig.KEY.SPACE, 'prompt' );

		//add array of colors to font to animate through
		this.fireFont.colors = ['#FF0000', '#FF6600', '#FFFF00', '#FFFFFF' ];
	},

	draw: function() {
		ig.system.clear( this.clearColor );

		var x = ig.system.width / 2 - this.font.getWidth() / 2,
			y = ig.system.height / 2,
			offset = this.font.size * 1.5;
		
		//draw font with various parameters
		this.font.draw( 'Hello World', x, y - offset  ); //left align, white coloring
		this.font.draw( 'Hello World', x, y, 'right' );  //white coloring
		this.font.draw( 'Hello World', x, y + offset, 'center', '#FF0000' );

		//draw animated font
		this.fireFont.draw( 'Hello World', x, y + offset * 2, 'center' );
	},

	update: function(){
		//if space is pressed, allow user to enter new font type
		if( ig.input.pressed( 'prompt' ) ){
			this.font.font = prompt( 'Enter New Font Type:', this.font.font ) || this.font.font;
			this.fireFont.font = this.font.font;
		}

		//animate through font colors
		this.fireFont.update();
	}
});

ig.main( '#canvas', FontTest, 60, 320, 240, 2 );

});

1 decade ago by lazer

Edit: fillText doesn't seem to support line breaks, so I've put together a makeshift workaround. Details and code here, maybe someone will find it useful.

Awesome plugin, thank you.

1 decade ago by lazer

Ahh more font problems :( I don't even know if quidmonkey still checks this thread, but if anyone sees this, has anyone had the problem with specified font colors being ignored? Eg this:

this.HUDfont.draw( ig.game.player.waterLeft, 47, 18, 'center', '#000000' );

Draws the actual text as it should, but the color setting is completely ignored (I also tried inputting an RGBA value). The font is the default white.

1 decade ago by quidmonkey

I tried to replicate this, but could not. Could you post a code sample?

For those interested, my plugin has been updated to v1.1.

1 decade ago by lazer

Thanks, quidmonkey. Upgrading the plugin solved the color issue for me, but now I can't seem to make the font manager work (it was before). Here's how I'm triggering it:

in main.js init:
this.fm = new FontManager();

in main.js update:
this.fm.update();

In main.js draw:
this.fm.draw();

Putting the following anywhere does not display anything:

			this.fm.spawn(0, '40px Lucida Console', 'test', 100, 100);

To be exact I was using this for dialogue and the exact way this was working before has been:

    // Triggered when each level is loaded
    setDialogue: function() {
    	switch (this.memoryNum) {
    		case 1: 	
    			this.dialogueArr = 
    				[{text:"Destroy the EVIL CUBES OF DOOM.~Quench the fire with icy water and stuff~and melt the ice with your kickass~flame-thrower.", x: 3, y: 380, color: '#2d8f00', align: 'left', lifespan: 6},
    				{text: "But...everything is in grayscale", x: 317, y: 400,  align: 'right', color: '#ffffff', lifespan: 4},
    				{text: "All is not as it appears.", x: 3, y: 400, align: 'left', color: '#2d8f00', lifespan: 4}];
    			break;
    		}
    	this.triggerDialogue();
    },
    
    // The function that actually spawns the dialogue on the screen. 
    triggerDialogue: function() {
    	var currentLine = this.dialogueArr[0];
    	var lines = currentLine.text.split('~');
		var settings = {align: currentLine.align, color: currentLine.color};
		for (var i = 0; i < lines.length; i++) {
			console.log('triggering dialogue');
			var currentText = lines[i];
			ig.game.fm.spawn(currentLine.lifespan, '11px Lucida Console', currentText, currentLine.x, currentLine.y,  settings);
			currentLine.y += 12;
			ig.game.dialoguetimeout = currentLine.lifespan;

		} 
		// Remove this first dialogue piece from the array,
		// making the subsequent dialogue piece spawn next
		this.dialogueArr.shift();
    },


But that no longer displays like it was previously, nor does the test snippet above.

Edit: Sorry, my forum formatting was getting screwed so I had to remove some of the code hash tags to make it look semi ok :S

1 decade ago by quidmonkey

I changed the Font constructor so that text is no longer required. Thus, a .spawn() looks like this:
this.fm.spawn( 0, '40px Lucida Console', 100, 100, { text: 'test' } );

1 decade ago by lazer

Ah great, that works, thanks! But now the color isn't working as it was for this before, using this:

##
ig.game.fm.spawn(currentLine.lifespan, '11px Lucida Console', currentLine.x, currentLine.y, {align: currentLine.align, color: currentLine.color, text: currentText});
##

No matter what hex code I put in as a test, the text is always white. Spawning text without the font manager (as in the HUDfont.draw example I mentioned above) does display the color, but this does not no matter how I try to format it. I'm obviously doing something wrong on my end, I just can't figure out what. Like I said, alignment and the actual text are now ok.

1 decade ago by lazer

Also sorry to bombard you, but the other thing I noticed is if the value of something you're printing out is 0, nothing is drawn. Eg I'm drawing my score. When the score gets to 1, it starts being displayed, but until then it's not showing anything. I hacked this really horribly by just putting '0' in the text attribute in font.js which "fixed" it, but I'm sure this isn't a good way to do it, I just had to put something in quick.

1 decade ago by quidmonkey

The color property is .colors vs. .color. And make sure .colors is an Array.

1 decade ago by quidmonkey

Convert the score to a string before feeding it to .draw():
this.font.draw( score.toString() );

The issue here is that Javascript interprets 0 as false in any logic statement.

1 decade ago by lazer

Perfect, thank you!

1 decade ago by jul

Thanks for this my game is in Japanese and this was a life saver!

Has anyone tried if this works with iOSImpact? Or how to go about to make it work?

1 decade ago by quidmonkey

Unfortunately, I have no experience with iOSImpact. My guess is that it does not. iOSImpact is designed to support the Impact api only, so direct canvas calls are unsupported.

1 decade ago by riceje7

does this plugin provide some form of text formatting? specifically a word-wrap feature?
Page 1 of 1
« first « previous next › last »