External Exam Download Resources Web Applications Games Recycle Bin

tilemaps with non square sprites | gml



objPlayer and sprites

Attempting with non-square sprites using this spritesheet: dude32x32.png:





mask and moving platform setup



Include code from same moving platform object objMovingPlatform → Create and objMovingPlatform → Step as previous tutorial example.



objPlayer Create

grid_size = 32;
move_speed = 8;
jump_speed = 16;
grav = 0.75; //gravity (manual)
v_speed = 0; //vertical speed (manual)
dx = 0; //destination x
dy = 0; //destination y
t1 = 0; //corner 1 we are checking (either top-left/right / bottom-left/right)
t2 = 0; //corner 2 we are checking for collision (will depend which way we are going)

default_vplatform_check_px = 1;
current_vplatform_check_px = default_vplatform_check_px;
jumping = false;

// tile map info
var layer_id = layer_get_id("Mask");
tilemask = layer_tilemap_get_id(layer_id);

// sprite bbox info
sprite_bbox_left = sprite_get_bbox_left(sprite_index) - sprite_get_xoffset(sprite_index);
sprite_bbox_right = sprite_get_bbox_right(sprite_index) - sprite_get_xoffset(sprite_index);
sprite_bbox_bottom = sprite_get_bbox_bottom(sprite_index) - sprite_get_yoffset(sprite_index);
sprite_bbox_top = sprite_get_bbox_top(sprite_index) - sprite_get_yoffset(sprite_index);

objPlayer Step

// check bottom left and right corners of bounding box for a tile ...
t1 = tilemap_get_at_pixel(tilemask, bbox_left, bbox_bottom + 1) & tile_index_mask;
t2 = tilemap_get_at_pixel(tilemask, bbox_right, bbox_bottom + 1) & tile_index_mask;

// ... and if there is a tile:
if (t1 != 0 || t2 != 0) {
    // ... then i am on the ground:
    jumping = false;
    
    // ... which means i can jump:
    if (keyboard_check(vk_up)) {
        v_speed = -jump_speed;
        jumping = true;
    }
}

// calculate x-axis destination:
dx = move_speed * (keyboard_check(vk_right) - (keyboard_check(vk_left)));

// calculate y-axis destination:
dy = v_speed;
v_speed += grav;

// still OR moving:
if (dx == 0) sprite_index = sprStill else sprite_index = sprRun;

// falling OR jumping:
if (dy > 1 or dy < -1) or jumping sprite_index = sprJump;

// left OR right:
if (dx < 0) image_xscale = -1 else if (dx > 0) image_xscale = 1;

// --=============================================--
// --=====-- VERTICAL PLATFORM CALCULATION --=====--
var v_platform = instance_place(x,y+dy,objMovingPlatform);
if v_platform == noone { 
    // perhaps there is a platform, but we may already be moved to where we should be:
    v_platform = instance_place(x,y+current_vplatform_check_px,objMovingPlatform);
}

// if there is a v platform (in either case), AND i'm not jumping up through platform:
if v_platform != noone && !(dy < 0) {
    jumping = false;
    v_speed = 0; //stop moving vertically - we will control y with platform
    current_vplatform_check_px = v_platform.move_speed + 1; //relative from my y
    if v_platform.going == "up" {
        y = ((v_platform.y - v_platform.move_speed) - sprite_bbox_bottom) - 1; //plant feet 1px above platform
    } else {
        y = ((v_platform.y + v_platform.move_speed) - sprite_bbox_bottom) - 1;	
    }
    if keyboard_check(vk_up) { 
        v_speed = -jump_speed; 
        jumping = true; 
    } //allow jump off platform
}
// --=============================================--
else {
    // apply regular y-axis destination to this object:
    y += dy;
    // reset back to default - some platforms may have a different v speed:
    current_vplatform_check_px = default_vplatform_check_px;
}

// if i'm moving down:
if (dy > 0) {
    // is there a tile or no tile at bottom left or bottom right corner:
    t1 = tilemap_get_at_pixel(tilemask, bbox_left, bbox_bottom) & tile_index_mask;
    t2 = tilemap_get_at_pixel(tilemask, bbox_right, bbox_bottom) & tile_index_mask;
    
    // if there is a tile at bottom left or bottom right corner:
    if (t1 != 0 || t2 != 0) {
        // snap the y value of this object to the grid size we are using:
        y = ((bbox_bottom & ~ (grid_size-1)) - 1) - sprite_bbox_bottom;
        v_speed = 0;
    }   
} else { // check top left and right corners:
    t1 = tilemap_get_at_pixel(tilemask, bbox_left, bbox_top) & tile_index_mask;
    t2 = tilemap_get_at_pixel(tilemask, bbox_right, bbox_top) & tile_index_mask;
    // if blocked up, snap y value to previous non-blocked tile area:
    if (t1 != 0 || t2 != 0) {
        y = ((bbox_top + grid_size) & ~ (grid_size-1)) - sprite_bbox_top;
        v_speed = 0;
    }
}

// apply x-axis destination to this object:
x += dx;

// if i'm moving RIGHT:
if (dx > 0) { 
    // is there a tile or no tile at TOP RIGHT or BOTTOM RIGHT:
    var t1 = tilemap_get_at_pixel(tilemask, bbox_right, bbox_top) & tile_index_mask;
    var t2 = tilemap_get_at_pixel(tilemask, bbox_right, bbox_bottom) & tile_index_mask;
    // if blocked RIGHT, snap x to 1 non-blocked tile area LEFT:
    if (t1 != 0 || t2 != 0) {
        x = ((bbox_right & ~ (grid_size-1)) - 1) - sprite_bbox_right;
    }   
} 

// otherwise if i'm moving LEFT (so not moving RIGHT):
else if (dx < 0) {
    // is there a tile or no tile at TOP LEFT or BOTTOM LEFT:
    var t1 = tilemap_get_at_pixel(tilemask, bbox_left, bbox_top) & tile_index_mask;
    var t2 = tilemap_get_at_pixel(tilemask, bbox_left, bbox_bottom) & tile_index_mask;
    // if blocked LEFT, snap x to 1 non-blocked tile area RIGHT:
    if (t1 != 0 || t2 != 0) {
        x = ((bbox_left + (grid_size-1)) & ~ (grid_size-1)) - sprite_bbox_left;
    }
}