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 glhg

Hi there,

After few tests, I figured out that video as texture wasn't supported yet.
I've tried something like:
context.drawImage(video,0,0), with a proper loaded video.
The output error is -[EJBindingVideo texture]: unrecognized selector sent to instance 0x8e54a50

Did anyone already worked on a video Texture solution? Is there any ? I'm actually not a C coder, so I can't really figure out what such kind of feature really means in term of binding ...

If anybody has an advice, I would really appreciate that.
Thank you

1 decade ago by stillen

This can be adjusted to suit your needs:
https://github.com/stillenklipse/impactjs.video-entity

I made a test case for a game where the player was a TV and played video. I used a different player entity for each "channel" the TV could have on it while it played.

This creates a video player then draws the frame into the entity. It's ugly, but should get you started.


/***
	This lets you place a mp4 into an entity and display in in Weltmeister for scalling and placement.
	There is a callback for video ending, such as load the next level and use this as simple level cut scene
	This can be extented to also be a moveable player on the game as well
	This doesn't test for video types or checks for abilty to play, as I was only targeting webkit browsers, so mp4 would be fine.
***/

ig.module(
	'game.entities.video'
)
.requires(
	'impact.entity'
)
.defines(function(){
	EntityVideo = ig.Entity.extend({
		_wmDrawBox: true,
		_wmBoxColor: 'rgba(255, 100, 0, 0.7)',
		size: {x: 90, y: 90},
		pos:{x:0, y:0},
		videoSrc:'media/video.mp4',
		videoControls:true,
		videoScaling:'aspect-fill',// 'fill','none',
		videoStartFrame:0,
		video: null,
		videoDisplay:'none', // css values, display none to hide
		videoId:'v',// for multiple videos
		maxVel:{x:20, y:20},
		init: function( x, y, settings ) {
			var video = document.createElement('video');
			var parent = this;
			video.src = this.videoSrc;
			video.id=this.videoId;
			video.style.display=this.videoDisplay;
			video.addEventListener('canplaythrough', function(){
			    video.scalingMode = this.videoScaling;
			    video.play();
			    video.currentTime=this.videoStartFrame;
			    video.addEventListener('ended', function(){
			    	parent.videoEnded();
				}, false);
			}, false);
			document.body.appendChild(video);
			this.video = video;
			this.parent( x, y, settings );
		},
		videoEnded:function(){
			// loops, could load next level.
			this.video.play();
			//this.kill();
		},
		kill:function(){
			// We should destroy the video object and remove when done as well to clean up resources
			var id = this.videoId;
			var vidDelete= document.getElementById(id);
			vidDelete.parentNode.removeChild(vidDelete);
			this.parent();
		},
		draw: function() {
			var ctx = ig.system.context;
			var s = ig.system.scale;
			var x = this.pos.x * s - ig.game.screen.x * s;
			var y = this.pos.y * s - ig.game.screen.y * s;
			var sizeX = this.size.x * s;
			var sizeY = this.size.y * s;
			ctx.save();
			ctx.drawImage(this.video, x, y, sizeX, sizeY );
			ctx.restore();
			this.parent();
	    },
		update: function(){
			if(ig.input.state('left')){
				this.pos.x = this.pos.x - 6;	
			}
			if(ig.input.state('right')){
				this.pos.x = this.pos.x + 6;	
			}
			if(ig.input.state('up')){
				this.pos.y = this.pos.y - 6;	
			}
			if(ig.input.state('down')){
				this.pos.y = this.pos.y + 6;	
			}
			if(ig.input.state('z')){
				this.size.x = this.size.x +5;
				this.size.y = this.size.y +5;
			}
			if(ig.input.state('x')){
				this.size.x = this.size.x -5;
				this.size.y = this.size.y -5;
			}



			this.parent();
		}
	});
});

1 decade ago by glhg

Thank you for your proposition. I've had already seen it on GitHub, tried to implement it without IMPACT, only within EJECTA itself. -> no success.

I do something like this:

video = document.createElement( 'video' );
video.src = "videos/sintel.mp4";
video.addEventListener('canplaythrough', function(){
                       video.scalingMode = 'aspect-fill';
                       video.play();
                       video.currentTime=0;
                       animate();
                       }, false);



var draw = function(){
   //ctx.drawImage(video,0,0);
    var s = 4;
    var x = 0;
    var y = 0;
    var sizeX = this.size.x * s;
    var sizeY = this.size.y * s;
    ctx.save();
    ctx.drawImage(this.video, x, y, sizeX, sizeY );
    ctx.restore();
}

function animate() {
    
    // ctx.clearRect(0, 0, canvas.width, canvas.height);
    // cloth.update();
	//cloth.draw();
    //background.render();
    draw();
    requestAnimationFrame( animate );
}

1 decade ago by stillen

Have you tried giving the video an ID and then grabbing the video by id instead of this? In just quickly looking over the example, I could see this.video being undefined.

Thats why in my example I give the video an ID to reference.

1 decade ago by glhg

Yep, I've tried that...
Actually it was wrong to call this.video, but calling just video instead brings me to the following error:

2013-09-21 15:54:56.907 Ejecta[535:907] JS: [object Video]
2013-09-21 15:54:56.909 Ejecta[535:907] -[EJBindingVideo texture]: unrecognized selector sent to instance 0x1d52d720
2013-09-21 15:54:56.910 Ejecta[535:907] * Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[EJBindingVideo texture]: unrecognized selector sent to instance 0x1d52d720'
Page 1 of 1
« first « previous next › last »