• Hey Guest! Ever feel like entering a Game Jam, but the time limit is always too much pressure? We get it... You lead a hectic life and dedicating 3 whole days to make a game just doesn't work for you! So, why not enter the GMC SLOW JAM? Take your time! Kick back and make your game over 4 months! Interested? Then just click here!

Melee attack on tile collisions

boy656

Member
Whenever i follow shauns spalding's tutorial for melee attacks with heartbeast's tile code already implemented, my character goes incredibly slow, and only very briefly shows the jump sprite without jumping at all.

here is my code.

ObjectIdle:

Create:

/// @description Movement variables
velocity_ = [0, 16];
gravity_ = 1.5;
jump_speed_ = 38;
max_velocity_ = [12, 42];
acceleration_ = 6.1;
// Get the tilemap id
var layer_id = layer_get_id("Collision");
collision_tile_map_id_ = layer_tilemap_get_id(layer_id);
state = PLAYERSTATE.FREE;
hitByAttack = ds_list_create();
enum PLAYERSTATE
{
FREE,
ATTACK_SLASH,
ATTACK_COMBO
}

Step:

/// @description Movement logic
// Get the input
var key_right, key_left, key_jump, input_x, on_ground;
key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_jump = keyboard_check_pressed(ord("Z"));
keyAttack = keyboard_check_pressed(ord("X"));
input_x = keyboard_check(vk_right) - keyboard_check(vk_left);
switch (state)
{
case PLAYERSTATE.FREE: PlayerState_Free(); break;
case PLAYERSTATE.ATTACK_SLASH: PlayerState_Attack_Slash(); break;
case PLAYERSTATE.ATTACK_COMBO: PlayerState_Attack_Combo(); break;
}

Clean Up:

ds_list_destroy(hitByAttack);

Scripts:

move_and_contact_tiles:

///@param tile_map_id
///@param tile_size
///@param velocity_array
var tile_map_id = argument0;
var tile_size = argument1;
var velocity = argument2;
// For the velocity array
var vector2_x = 0;
var vector2_y = 1;
// Move horizontally
x += velocity[vector2_x];
// Right collisions
if velocity[vector2_x] > 0 {
var tile_right = tile_collide_at_points(tile_map_id, [bbox_right-1, bbox_top], [bbox_right-1, bbox_bottom-1]);
if tile_right {
x = bbox_right & ~(tile_size-1);
x -= bbox_right-x;
velocity[@ vector2_x] = 0;
}
} else {
var tile_left = tile_collide_at_points(tile_map_id, [bbox_left, bbox_top], [bbox_left, bbox_bottom-1]);
if tile_left {
x = bbox_left & ~(tile_size-1);
x += tile_size+x-bbox_left;
velocity[@ vector2_x] = 0;
}
}
// Move vertically
y += velocity[vector2_y];
// Vertical collisions
if velocity[vector2_y] > 0 {
var tile_bottom = tile_collide_at_points(tile_map_id, [bbox_left, bbox_bottom-1], [bbox_right-1, bbox_bottom-1]);
if tile_bottom {
y = bbox_bottom & ~(tile_size-1);
y -= bbox_bottom-y;
velocity[@ vector2_y] = 0;
}
} else {
var tile_top = tile_collide_at_points(tile_map_id, [bbox_left, bbox_top], [bbox_right-1, bbox_top]);
if tile_top {
y = bbox_top & ~(tile_size-1);
y += tile_size+y-bbox_top;
velocity[@ vector2_y] = 0;
}
}

tile_collide_at_points:

///@param tile_map_id
///@param point_arrays...
var tile_map_id = argument[0];
// Found variable
var found = false;
// for the point arrays
var vector2_x = 0;
var vector2_y = 1;
// Loop through the points and check for a tile
for (var i=1; i<argument_count; i++) {
var point = argument;
found = found || tilemap_get_at_pixel(tile_map_id, point[vector2_x], point[vector2_y]);
}
// return found
return found;

PlayerState_Free:

var key_right, key_left, key_jump, input_x, on_ground;
key_right = keyboard_check(vk_right);
key_left = keyboard_check(vk_left);
key_jump = keyboard_check_pressed(ord("Z"));
keyAttack = keyboard_check_pressed(ord("X"));
input_x = keyboard_check(vk_right) - keyboard_check(vk_left);
velocity_ = [0, 16];
gravity_ = 1.5;
jump_speed_ = 38;
max_velocity_ = [62, 42];
acceleration_ = 6.1;
// Vector variables
var vector2_x = 0;
var vector2_y = 1;
// Horizontal movement
velocity_[vector2_x] = clamp(velocity_[vector2_x]+input_x, -max_velocity_[vector2_x], max_velocity_[vector2_x]);
// Friction
if input_x == 0 {
velocity_[vector2_x] = lerp(velocity_[vector2_x], 0, .2);
}
// Gravity
velocity_[vector2_y] += gravity_;
// Move and contact tiles
move_and_contact_tiles(collision_tile_map_id_, 64, velocity_);
// Jumping
on_ground = tile_collide_at_points(collision_tile_map_id_, [bbox_left, bbox_bottom], [bbox_right-1, bbox_bottom]);
if (input_x != 0)
{
// Set sprite if you're on the ground
if (on_ground)
{
sprite_index = spriteRun;
}
// Face right or left
image_xscale = input_x;
}
else
{
// Set sprite if you're on the ground
if (on_ground)
{
sprite_index = sprite0;
}
// Slow down
}
// Jump
if (key_jump && on_ground)
{
sprite_index = sprite2;
velocity_[vector2_y] = -jump_speed_;
}
// Gravity
if (!on_ground)
{
// Set your sprite if you're falling
if (vspd > 0)
{
sprite_index = sprite2;
}
}
if (keyAttack) state = PLAYERSTATE.ATTACK_SLASH

PlayerState_Attack_Slash:

max_velocity_ = 0;
gravity_ = 0;
if (sprite_index != spriteAttack)
{
sprite_index = spriteAttack;
image_index = 0;
ds_list_clear(hitByAttack);

}
mask_index = spriteHB;
var hitByAttackNow = ds_list_create();
var hits = instance_place_list(x,y,objectKoopa,hitByAttackNow,false)
if (hits > 0)
{
for (var i = 0; i < hits; i++)
{
var hitID = hitByAttackNow[| i];
if (ds_list_find_index(hitByAttack,hitID) == -1)
{
ds_list_add(hitByAttack,hitID);
with (hitID)
{
hp = -1;
}
}
}
}
ds_list_destroy(hitByAttackNow);
mask_index = objectIdle;
if (animation_end())
{
sprite_index = objectIdle;
state = PLAYERSTATE.FREE;
}

Animation_end:

var _sprite=sprite_index;
var _image=image_index;
if(argument_count > 0) _sprite=argument[0];
if(argument_count > 1) _image=argument[1];
var _type=sprite_get_speed_type(sprite_index);
var _spd=sprite_get_speed(sprite_index)*image_speed;
if(_type == spritespeed_framespersecond)
_spd = _spd/room_speed;
if(argument_count > 2) _spd=argument[2];
return _image+_spd >= sprite_get_number(_sprite);
 

TheouAegis

Member
input_x = keyboard_check(vk_right) - keyboard_check(vk_left);

That's just key_right-key_left. Don't run keyboard checks twice needlessly.

Why are you doing your keyboard check in the step event and in the scripts as well? Either do it in the scripts or do it in the step event. Actually, why are you even duplicating any code in your script?

Code:
with (hitID)
{
hp = -1;
}
This should be hp-=1;


I'm not sure about this bright changing thing. I don't see, or at least I don't notice, anywhere in your code where you change the Sprite to anything that's not jump related without first checking for a ground.

Edit: I accidentally hit post. I'm still looking at your code. LOL
 
Last edited:
Top