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 bitmapshades

I wrote this plugin for a quest icon that works like quest icons in MMO games where the icon moves with the NPC then moves to the next NPC in the quest chain. Ttrying to refine it so that I can make it portable for different quests. Maybe someone on these boards can see if there's a way to do that?

ig.module(
	'game.entities.questicon'
)
.requires(
	'impact.entity'
)
.defines(function(){
EntityQuesticon = ig.Entity.extend({
	animSheet: new ig.AnimationSheet( 'media/quest-sprite.png', 30, 30 ),
	size: {x: 30, y: 30},
	offset: {x: 0, y: 0},
        amount: 1,
	
        type: ig.Entity.TYPE.NONE,
	checkAgainst: ig.Entity.TYPE.A, // Check against friendly
        collides: ig.Entity.COLLIDES.NEVER,

        init: function( x, y, settings ) {
                this.parent( x, y, settings );
		
		// Add the animations
		this.addAnim('idle', 1, [8]);
                this.addAnim('fadein', 0.2, [1, 2, 3, 4, 5, 6, 7, 8]);
		this.addAnim('fadeout', 0.2, [8, 7, 6, 5, 4, 3, 2, 1]);
		//this.timer = new ig.Timer(10);
        },
	
	update: function() {
		var target;
		// if mission accepted
		switch(ig.game.mission.stage){
				case(10):
					this.pos.x = -99;
					this.pos.y = -99;
					break;
				case(20):
					this.kill();
					break;
				case(30):
					this.kill();
					break;
				case(40):
					this.kill();
					break;
		}
		switch(ig.game.state){
			case('play'):
				// if entity exists move with target position
				target = ig.game.getEntityByName('Miss Robbins');
				if(target && ig.game.mission.stage < 10){
					this.pos.x = target.pos.x;
					this.pos.y = target.pos.y - 30;
				}
				target = ig.game.getEntityByName('Lieutenant Biggs');
				if(target && ig.game.mission.stage < 20){
					this.pos.x = target.pos.x;
					this.pos.y = target.pos.y - 30;
				}
				this.currentAnim = this.anims.idle;
				break;
			default:
				break;
			}
		
		this.parent();
	},

});
});

1 decade ago by onion

I'm interested in this because I'm creating a similar game to you with quests. I'm stuck at the stage of how best to manage all the quest dialogue, without putting it all in the code!

1 decade ago by bitmapshades

Hey there you might be interested to know I've made that code much lighter and more portable in a different entity class. I originally wanted to leverage the targets properties in WM but doing it this way means you can define your arrays of mission objectives without having to micromanage it in the level editor.

Let me know how this works for you. Simply calling this.track(target) should enable you to track any mission target at different stages.

ig.module(
	'game.entities.marker'
)
.requires(
	'impact.entity'
)
.defines(function(){
EntityMarker = ig.Entity.extend({
	animSheet: new ig.AnimationSheet( 'media/marker2.png', 40, 40),
	size: {x: 40, y: 40},
	m0Targets: ['Miss Robbins', 'Lieutenant Biggs', 'shooting range'],
	//m1Targets: ['hq', 'level1start', 'level1exit'],
	targets: [],

	type: ig.Entity.TYPE.NONE,
	checkAgainst: ig.Entity.TYPE.NONE,
	collides: ig.Entity.COLLIDES.NEVER,

	init: function( x, y, settings ) {
		this.parent( x, y, settings );
		this.addAnim('idle', 1, [0]);
    },

	track: function(other){
		if(other){
			this.pos.x = other.pos.x;
			this.pos.y = other.pos.y;
		}
		else{
			console.error('entity does not exist in this level');
		}
	},

	update: function() {
		// If Mission completed
		if(ig.game.mission.stage >= 40){
			this.kill();
		}
		this.currentAnim = this.anims.idle;
		var target;

		// Tutorial
		if(ig.game.mission.id == 0){
			this.targets = this.m0Targets;
		}

		// if target exists during gameplay move with target
		if(ig.game.state == 'play'){
			switch(ig.game.mission.stage){
				case(0):
					target = ig.game.getEntityByName(this.targets[0]);
					this.track(target);
					break;
				case(10):
					target = ig.game.getEntityByName(this.targets[1]);
					this.track(target);
					break;
				case(20):
					target = ig.game.getEntityByName(this.targets[2]);
					this.track(target);
					break;
				case(30):
					target = ig.game.getEntityByName(this.targets[1]);
					this.track(target);
					break;
			}
		}
		this.parent();
	},

});
});

1 decade ago by vincentpiel

Try to make your code data driven to ease design choices.
remove entirely any game data from the entity, and have them provided in the parameters :

   // list of levels where the target will change. last level means kill entity.
   targetChangeLevels: null,  // required in init settings. Expl : [0,5,10]
    // list of target names. should be one item shorter than change levels, since last is kill.
    newTargetsNames: null,  // required in init settings  Expl : ['bob', 'dragon1']
    // what do we do if we don't find an entity ? 
    stopTrackingIfDead : true, // can be set in init settings, default to true.
    
    // public member containing current target name or null if no target ?? or target lost ?? .
    targetName : null,
    
    // returns the current entity nammed targetName. If no entity is found and this.stopTrackingIfDead, then
    // we stop searching by setting this.targetName to null.
    getTarget : function( targetName)
    {
        if (!targetName) return null;
        var targetEntity = ig.game.getEntityByName(targetName);
        // should we keep on searching it if dead ??
        if ((this.stopTrackingIfDead == true) && (!targetEntity)) this.targetName=null;  
        return targetEntity;
    },

    // checks the settings
    init: function( x, y, settings ) {
    this.parent( x, y, settings );
    this.addAnim('idle', 1, [0]);
    if (!settings.newTargetsNames) throw ('missing setting : newTargetsNames');
    if (!settings.targetChangeLevels) throw ('missing setting : targetChangeLevels');
    // just to avoid bugs...
    if ( this.newTargetsNames.length != this.targetChangeLevels.length -1 ) throw ('number of targets and target change level not matching');
     }, // init end

// trackCurrent : called in update if game state is 'play', to track moving targets.
trackCurrent: function(){
    if (!this.targetName) return;
    var trackedEntity = this.getTarget(this.targetName);
    if(trackedEntity){
        this.pos.x = trackedEntity.pos.x;
        this.pos.y = trackedEntity.pos.y;
        // OOOOORRRRRR  this.pos = trackedEntity.pos, only once... ???
    }
},

lastStage:-1,
update : function()
{
    this.currentAnim = this.anims.idle;
    if (ig.game.state == 'play'){
        // level change ? we might have a target change.
        if (ig.game.mission.stage != this.lastStage)
        {  this.lastStage = ig.game.mission.stage;
            var isNewTarget = this.targetChangeLevels.indexOf(ig.game.stage);
            // reached last mission ?
            if (isNewTarget == this.newTargets.length-1)  { this.kill();  return }
            // reached a new target ?  --> track it.
            if (isNewTarget>=0)
            {
                this.targetName= this.newTargetsNames[isNewTarget];
            }
         }
        }
        // if we play, we track
        this.trackCurrent();
    }
    this.parent();
},

// RQ : YOU SHOULD NOT DRAW IF NO ENTITY TRACKED, so :
draw : function()
{
    if (!this.targetName) return;
    this.parent();
},


And you provide the game data while creating the entity :
here i give an example with two difficulty modes.

//... somewhere in your game...
    targetChangeLevels :  [0,10,20,25,31,40],
    newTargetsNames: ['Dr Death', 'Lieutenant Biggs', 'Master Chang','oo','pp'],
    newTargetsNamesEasy : ['M. Candy', 'daddy sugar', ' smily face', 'blah', 'blah''],
    currentTargetNames : null,

    // ... in the init() of your game
    this.currentTargetNames = (this.mode.easy)?this.newTargetsNamesEasy : this.newTargetsNames  ;

    this.spawnEntity(EntityMarker , x, y ,
        { targetChangeLevels : this.targetChangeLevels,
            newTargetsNames : this.currentTargetNames } );

And one last remark, but i am very long allready, is that you
should handle when the size of all entities are not the same.
(... or not :-)

1 decade ago by bitmapshades

Thank you Vincent that's very good advice and its given me much food for thought. I'm trying my best to separate hard coded strings from implementation but my brain goes a bit haywire when I try to comprehend structures that don't yet exist unless I've named or placed them in the editor.
Page 1 of 1
« first « previous next › last »