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

8 years ago by fulvio

I am developing a main menu for my game.

The kind of parallax scrolling functionality I'm after occurs on the following title screen and level select screen for the following game:

https://www.youtube.com/watch?v=AVWXUb5SMvc

Notice how the background layer is parallax scrolling while you're on the main menu and the level select screen? I was wondering whether someone has had experience developing something like this with Impact?

The only way I can think of at the moment is spawning an entity with a gravityFactor of 0 that has an acceleration on the x-axis within the init() method?

The only problem is that once the level reaches the end it'll stop scrolling as far as I know. I haven't tried to implement as I was hoping to give this a shot when I'm at home. It's just something that's been in my mind for a while now.

I would have to figure out a way to repeat the background once it reaches the end of the map.

Any help would be greatly appreciated in regards to implementing this the proper way.

UPDATE:

Now that I think of it, I might give something like this a go in my main.js / update() method:

update: function () {
    if (this.mainmenu) {
        this.backgroundMaps[0].scroll.x -= 200 * ig.system.tick;
    }
    this.update();
}

UPDATE 2:

Okay, this didn't seem to yield any results. I think I may be missing some further code to get this working.

8 years ago by mimik

How about making a layered lvl.
with repeating backgrounds inside the level editor?
Check the repeat box in westmeister.
Then just scroll then screen.
Setting the depth differently on the layers will produce a parallax

8 years ago by fulvio

I tried the following with no avail:

(NOTE: parallax.png is 248x248 pixels).

GameTitle = ig.Game.extend({
    parallax: new ig.Image('media/background/parallax.png'),
    font: new ig.Font('media/fonts/04b03.font.png'),
    clearColor: '#0d0c0b',
    init: function() {
        ig.input.bind(ig.KEY.SPACE, 'start');

        ig.system.clear(this.clearColor);

        this.font.draw('Press space to play.', 80, 140, ig.Font.ALIGN.CENTER);

        var map = new ig.BackgroundMap(248, [[1]], this.parallax);
        map.repeat = true;
        this.backgroundMaps.push(map);
    },
    draw: function() {
        this.update();
    },
    update: function() {
        if (ig.input.pressed('start')) {
            ig.system.setGame(MyGame);
            return;
        }

        this.backgroundMaps[0].scroll.x += 50 * ig.system.tick;

        this.parent();
    }
});

I just see the font text with a black background.

8 years ago by jerev

Briefly looking over your code I can see this problem:

    draw: function() {
        this.update();
    },

Note, your font draw will also disappear the first time the draw() method is called by the gameloop. So put that draw in the draw() method.

   draw: function() {
      this.parent();
      this.font.draw('Press space to play.', 80, 140, ig.Font.ALIGN.CENTER);
   },

you also don't need to call
ig.system.clear(this.clearColor);

That's done by the game class draw method.

Also note scrolling won't work, as the draw method of the game class will override the scroll.x/y

8 years ago by fulvio

@jerev: Yes, I noticed these silly issues just now. My mistake.

Even if I completely remove the draw() method however, I still don't see the background appear or scroll at all.

8 years ago by jerev

I wrote a simple plugin that can be used for horizontal scrolling parallaxes.
I'll later extend it so it can do vertical ones too.

Get it here: https://dl.dropbox.com/u/43009917/impact/plugins/parallax.js
Place it in lib/plugins/ and require it.

Example Usage:

MyGame = ig.Game.extend({    

    parallax: null,
 
    init: function() {
        ...
        this.parallax = new Parallax();

        // Add one or more layers, bottom to top.
        // p.add(pathtoimage, settings)
        //      settings: 
        //          distance defines the speed it'll be scrolling at relative to the others.
        //          y is the actual y location the screen.
        // Using a negative distance will allow to scroll one layer left, 
        //  the other right for example.
        this.parallax.add('res/par-2.png', {distance: 5, y: 0});
        this.parallax.add('res/par-1.png', {distance: 2, y: 0});
        ...
    },

    ...

    update: function() {
        ...
        // Do the movement, based on a speed
        this.parallax.move(50); //speed
        ...
    },

    draw: function() {
        ...
        // Draw the parallax.
        this.parallax.draw();
        ...
    },

    ...

});

// Preload the images. IMPORTANT
new ig.Image('res/par-2.png'); 
new ig.Image('res/par-1.png');
ig.main( ....... );

And here's the plugin embedded, if I'd ever delete the dropbox version:

/*  jerev - 10/2012 - parallax.js

Be sure to require plugins.parallax, and place this file in lib/plugins/

Parallax usage
    p = new Parallax();
    p.add('path/to/image.ext', {distance: 1, y: 0})
    p.add('path/to/other/image.ext', {distance: 5, y: 0})

    p.move(speed);

    p.draw();

Please note: you need to preload the images, you can do this before you call ig.main()
    new ig.Image('path/to/image.ext');
    new ig.Image('path/to/other/image.ext');
    ig.main(..);

 */
ig.module(
    'plugins.parallax'
)
.requires(
    'impact.image'
)
.defines(function(){
Parallax = ig.Class.extend({
    layers: [],
    screen: {x: 0, y: 0},

    init: function(settings) {
        ig.merge(this, settings);
    },

    add: function(path, settings) {
        var layer = new ParallaxLayer(path, settings);
        this.layers.push(layer);
    },

    move: function(x) {
        this.screen.x += (x * ig.system.tick);
    },

    draw: function() {
        for(var i=0; i < this.layers.length; i++) {
            var layer = this.layers[i];

            var x = -((this.screen.x / layer.distance)%layer.w);
            if (this.screen.x <= 0) x = x - layer.w;
            layer.x = x;

            while (layer.x < ig.system.width) {
                layer.draw(); 
                layer.x += layer.w;     
            }
            layer.x = x;
        }
    }
});

ParallaxLayer = ig.Class.extend({
    distance: 0,

    x: 0, y: 0,
    w: 0, h: 0,

    img: null,

    init: function(path, settings) {
        if (settings && settings.distance == 0) settings.distance = 1;

        this.img = new ig.Image(path);
        this.w = this.img.width;
        this.h = this.img.height;

        ig.merge(this, settings);
    },

    draw: function() {
        this.img.draw(this.x, this.y);
    }
})
});

8 years ago by fulvio

@jerev: Thank you very much kind sir. You, rock!

8 years ago by fulvio

@jerev: The plugin is working great so far!

8 years ago by jerev

Quote from fulvio
@jerev: The plugin is working great so far!


That's nice to hear, if you face any problems, I'll look into them ;-)
And when I find some time, i'll extend it, and make it nicer, because I'm not happy about the current preload method.

7 years ago by fulvio

@jerev: Any idea how to make the parallax backgrounds appear behind entities and tiles? At the moment the backgrounds always appear above everything.

Even setting the zIndex for the ParallaxLayer() doesn't work.

7 years ago by Rybar

@fulvio, override draw in main.js like so:

draw: function() {
		//not calling parent here so we can make sure background draws first
		this.myParralaxThingie.draw();   

		//Draw the rest
		for(var i = 0; i < this.entities.length; i++) {
			this.entities[i].draw();
		};
		
		
		// Add your own drawing code here


	}

7 years ago by DaveVoyles

Do you know if there is a way to only draw the parallax images one time?

As it stands, it repeats the image over and over in the background, which is not always what I want.

Other than that, the plugin works great!
Page 1 of 1
« first « previous next › last »