Skip to content

Instantly share code, notes, and snippets.

@ultimateprogramer
Last active January 14, 2020 19:16
Show Gist options
  • Select an option

  • Save ultimateprogramer/3eef65108fdad9c48a3f5d26e80e5a89 to your computer and use it in GitHub Desktop.

Select an option

Save ultimateprogramer/3eef65108fdad9c48a3f5d26e80e5a89 to your computer and use it in GitHub Desktop.
Useful ct.js Code Snippets

Move an object a specific direction

  • Speed of 3
  • Direction - Downwards
  • Set a timer for bullets
  • Sets explicitly the object type as string
/**
 * OnCreate - Move an object a specific direction and set a "Type"
 */
this.speed = 3;
this.direction = 270;

this.bulletTimer = 60;
this.ctype = 'Hostile';

Collission that reduces life

  • Detect to see if it has hit object 'ObjectType'
  • Reduces life
/**
 * Hit to reduce life - put this "On Step" for a type
 */
if (ct.place.meet(this, this.x, this.y, 'ObjectType')) {
    if (ct.room.lives < 3) {
        ct.room.lives++;
        this.kill = true;
    }
}

Spawn a bullet after a period of time

  • Reduce time on each frame in the On Step call
  • Create a new bullet when time is up
  • Re-initiate the timer a-fresh
/**
 * Spawn a Bullet after a specific period of time. Put this "On Step" (enemy)
 */
this.bulletTimer -= ct.delta;
if (this.bulletTimer <= 0) {
    // Reset timer
    this.bulletTimer = 180;
    // Create a Laser
    ct.types.copy('Laser_Red', this.x, this.y + 32);
}

Break an asteroid into smaller pieces

  • If it collides with the Laser_Blue
  • Kill the bullet
  • Kill the main object
  • Spawn new sub-objects
/**
 * Break an asteroid into 2 pieces after it gets hit by a bullet. Put "On Step"
 */
var collided = ct.place.meet(this, this.x, this.y, 'Laser_Blue');
if (collided) {
    // Kill the bullet
    collided.kill = true;
    // Kill the main object
    this.kill = true;

    // Create new Mini Asteroids
    ct.types.copy('Asteroid_Medium', this.x, this.y);
    ct.types.copy('Asteroid_Medium', this.x, this.y);
    
    // Increase Game Score
    ct.room.score += 25;
}

Move an object a specific direction depending on what key was pressed

  • The Action's multiplier is set as -1 or +1 in the settings
  • Make the move
/**
 * Move X direction or Y direction depending on which key is pressed.
 * 
 * The Multiplier is what sets MoveX or MoveY by +1 or -1.
 * 
 * Put this "On Step"
 */
this.x += 8 * ct.delta * ct.actions.MoveX.value; // Move by X axis
this.y += 8 * ct.delta * ct.actions.MoveY.value; // Move by Y axis

Movement up or down for a Bullet

/**
 * Bullet moves upwards. "On Create"
 */
this.speed = 18;
this.direction = 90;

/**
 * Move a bullet downwards. This bullet rotates as it moves
 */

// On Create
this.speed = 8;
this.direction = 270;

this.rotation = ct.random.deg();

this.ctype = 'Hostile';

// On Step
if (this.y > ct.height + 40) {
    this.kill = true;
}

this.move();

this.rotation += 10 * ct.delta;

Spawn a meteor and enemy plane at specific regular intervals

/**
 * Spawn a Meteor or Space Ship at Random Intervals - In a Room's code - "On Step"
 */
this.asteroidTimer -= ct.delta;
if (this.asteroidTimer <= 0) {
    this.asteroidTimer = ct.random.range(20, 200);
    ct.types.copy(ct.random.dice('Asteroid_Big', 'Asteroid_Medium'), ct.random(ct.viewWidth), -100);
}

this.enemyTimer -= ct.delta;
if (this.enemyTimer <= 0) {
    this.enemyTimer = ct.random.range(180, 400);
    ct.types.copy('EnemyShip', ct.random(ct.viewWidth), -100);
}

Put a scrolling core & Lives Label in the screen

  • On Create code for a Room
  • Draw code for a Room
/**
 * Put in a Score & Lives Label in a Room
 */
// On Create
this.asteroidTimer = 20;
this.enemyTimer = 180;

this.score = 0;
this.scoreLabel = new PIXI.Text('Score: ' + this.score, ct.styles.get('ScoreText'));
this.addChild(this.scoreLabel);
this.scoreLabel.x = 30;
this.scoreLabel.y = 30;

this.lives = 3;
this.livesLabel = new PIXI.Text('Lives: ' + this.lives, ct.styles.get('LivesText'));
this.addChild(this.livesLabel);
this.livesLabel.x = ct.width - 200;
this.livesLabel.y = 30;

// Draw
this.scoreLabel.text = 'Score: ' + this.score;
this.livesLabel.text = 'Lives: ' + this.lives;

Robot Speed, Jump Speed & Animation Speed

/**
 * Create a Robot and assign it Jump Speed & Gravity, as well as Animation Speed
 * 
 * Change Animations according to activity
 */
// On Create
this.jumpSpeed = -10;
this.gravity = 0.5;

this.animationSpeed = 0.2;

// On Step
if (this.hspd !== 0) {
    // The Robot is moving
    if (this.tex !== 'Robot_Walking') {
        // Change the texture (/ animation) to "Robot_Walking"
        this.tex = 'Robot_Walking';
        // Play animation. You use .stop() to stop animation
        this.play();
    }
    if (this.hspd > 0) {
        this.scale.x = 1;
    } else {
        this.scale.x = -1;
    }
} else {
    // Don't move horizontally if no input
    this.tex = 'Robot_Idle';
}

Complete On Step code for a Robot on Platformer

this.speed = 4 * ct.delta; // Max horizontal speed

// Check for a collision with a deadly object with Collision Group "Deadly"
if (ct.place.occupied(this, this.x, this.y, 'Deadly')) {
    this.x = this.savedX;
    this.y = this.savedY;
    this.hspd = 0;
    this.vspd = 0;
    ct.room.lives --;
    if (ct.room.lives <= 0) {
        ct.rooms.switch(ct.room.name);
    }
    return;
}

// Check to see if Left or Right is pressed
if (ct.actions.MoveLeft.down) {
    this.hspd = -this.speed;
} else if (ct.actions.MoveRight.down) {
    this.hspd = this.speed; 
} else {
    this.hspd = 0;
}

// Change the animation type to Walking or Idle based on movement speed
if (this.hspd !== 0) {
    if (this.tex !== 'Robot_Walking') {
        this.tex = 'Robot_Walking';
        this.play();
    }
    if (this.hspd > 0) {
        this.scale.x = 1;
    } else {
        this.scale.x = -1;
    }
} else {
    // Don't move horizontally if no input
    this.tex = 'Robot_Idle';
}

// If there is ground underneath the Robot…
if (ct.place.occupied(this, this.x, this.y + 1, 'Solid')) {
    // …and the W key or the spacebar is down…
    if (ct.actions.Jump.down) {
        // …then jump!
        this.vspd = this.jumpSpeed;
    } else {
        // Reset our vspd. We don't want to be buried underground!
        this.vspd = 0;
    }
} else {
    // If there is no ground  
    this.vspd += this.gravity * ct.delta;
    // Set jumping animation!
    this.tex = 'Robot_Jump';
}

// Move by horizontal axis, pixel by pixel
for (var i = 0; i < Math.abs(this.hspd); i++) {
    if (ct.place.free(this, this.x + Math.sign(this.hspd), this.y, 'Solid')) {
        this.x += Math.sign(this.hspd);
    } else {
        break;
    }
}
// Do the same for vertical speed
for (var i = 0; i < Math.abs(this.vspd); i++) {
    if (ct.place.free(this, this.x, this.y + Math.sign(this.vspd), 'Solid')) {
        this.y += Math.sign(this.vspd);
    } else {
        break;
    }
}

Movable Lives Widget (as a Type)

/**
 * Implement a moving widget for "lives"
 */

// On Create
this.text = new PIXI.Text(ct.room.lives, ct.styles.get('HeartCounter'));
this.text.x = -32;
this.text.anchor.y = 0.5;
this.text.anchor.x = 1;

this.addChild(this.text);

// Draw
this.x = ct.room.x + ct.viewWidth - 24;
this.y = ct.room.y + 24;

this.text.text = ct.room.lives;

Moving between Rooms (stages of a game)

/**
 * Move between rooms / stages
 */

// Room - "On Create"
this.nextRoom = 'Level_02';

// Type - Object that invokes next level move through collission. "On Step"
if (ct.room.nextRoom) {
    // Do we collide with the Robot?
    if (ct.place.meet(this, this.x, this.y, 'Robot')) {
        // Switch to the next room
        ct.rooms.switch(ct.room.nextRoom);
        // You can use ct.rooms.switch(ct.room.name); to restart the current level
    }
}

Get all objects of a specific type

  • Script sample below gets all objects of the type "Bonus"
  • It then kills these objects
for (var bonus of ct.types.list['Bonus']) {
    bonus.kill = true;
}

// Can also be done as so:
for (var bonus of ct.types.list.Bonus) {
    bonus.kill = true;
}

Follow a specific object and make it the center of the viewport (camera)

  • Place this code, e.g, to your hero's OnCreate code
var room = ct.room;
room.follow = this;

// Follow the hero so it is always at the center of the screen
room.borderX = room.viewWidth / 2;
room.borderY = room.viewHeight / 2;

Handling collisions over Tilemaps

  • When setting up tiles we setup the depth through the properties of the tileset in the room editor.
  • We need to use this depth to check for collisions with tiles.

The following example allows a Robot character to jump over tiles on the platform:

// On create

this.vspd = 0;
this.hspd = 3;
ct.room.follow = this;
this.gravity = 1;
this.jumpSpeed = -25;

// On step
this.vspd += (this.gravity * ct.delta);

for(var y = 0; y < Math.abs(this.vspd); y++) {
    if(!ct.place.tile(this, this.x, this.y + Math.sign(this.vspd), -10)) {
        this.y += Math.sign(this.vspd);
    } else {
        if(ct.actions.Space.down) {
            this.vspd = this.jumpSpeed;
        } else {
            break;
        }
    }
}

for(var x = 0; x < Math.abs(this.hspd); x++) {
    if(!ct.place.tile(this, this.x + Math.sign(this.hspd), this.y, -10)) {
        this.x += Math.sign(this.hspd);
    } else {
        this.scale.x = this.scale.x * -1;
        this.hspd = this.hspd * -1;
    }
}

Drawing icons in a room to display lives left

  • Draws 3 ships in the On Create event for full lives on the corner of the screen
  • When lives reduce, it does so on the Draw event

Room Create:

// On Create
// Draw small ship icons in a top-right corner
for (var i = 0; i < 3; i++) {
    var icon = new PIXI.Sprite(ct.res.getTexture('PlayerShip_Blue', 0));
    icon.x = ct.width - 32 - i*48;
    icon.y = 32;
    icon.scale.x = icon.scale.y = 0.3;
    icon.depth = 100;
    this.addChild(icon);
    this.shipIcons.push(icon);
}

Room Draw:

// Draw
this.scoreLabel.text = 'Score: ' + this.score;

if (ct.types.list.Player_Blue.length) {
    for (var i = 0; i < 3; i++) {
        this.shipIcons[i].visible = ct.types.list.Player_Blue[0].lives > i;
    }
}

Using skeletal animations

  • Import the dragonbones skeletal animation in textures (skeletal animation section)
  • Code the Type as so:
// onCreate for a type
this.skel = ct.res.makeSkeleton('Astronaut'); // Astronaut is a Skeletal Animation in Textures
this.skel.animation.play('Stand');
this.addChild(this.skel);

this.skel.on(dragonBones.EventObject.FRAME_EVENT, event => {
    if (event.name === 'Shoot') {
        const bullet = ct.types.copy('BlueBall', this.x + this.scale.x * 460, this.y - 640);
        bullet.direction = this.scale.x > 0?  0 : 180;
    }
});

// onDraw for a type
this.skel.animation.play('Run');
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment