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; } }