View difference between Paste ID: bY4NhxQM and fYN34fXv
SHOW: | | - or go back to the newest paste.
1
// ********* Create ***************//
2
bbox = new tile_bbox(mask_index); // Instance of the struct below
3
4
// ********* How to call it when moving (step event or something) *************** //
5
bbox.move_collide(id, x, y, _vx, _vy);  // _vx and _vy are whatever your movement speeds are
6
7
8
// ********* The struct ******************************//
9
function tile_bbox(_mask) constructor
10
{
11
	/* Performs tile collision independent from object's bbox.
12
	 * Since we can use a separate mask here from the objects, that allows
13
	 * the object to use a different shaped mask for hit detection and not
14
	 * need a whole other "hurtbox" object.
15
	 * 
16
	 * Plus this is actually faster and requires less round/floor/ceil nonsense
17
	 * to fix some internal junk.
18
	 *
19
	 * Note the "& 1" checks for odd numbered tiles as "solid", pretty usefull 
20
	 * if you want waist high walls that cause movement collision but can be 
21
	 * shot over with a gun or something.
22
	 */
23
24
	#macro TILE_SOLID 1
25
	#macro TILE_ONE_WAY 2
26
	#macro TILE_SIZE 16
27
	#macro TILE_SIZE_M1 15
28
	
29
	#macro COLLIDE_VER_UP 1
30
	#macro COLLIDE_VER_DOWN -1
31
	#macro COLLIDE_VER_NONE 0
32
	#macro COLLIDE_HOR_RIGHT 1
33
	#macro COLLIDE_HOR_LEFT -1
34
	#macro COLLIDE_HOR_NONE 0
35
	
36
	var _w = sprite_get_width(_mask), 
37
		_h = sprite_get_height(_mask),
38
		_y_count = ceil(_h / TILE_SIZE),
39
		_x_count = ceil(_w / TILE_SIZE);
40
		
41
	mask_sprite = _mask;
42
	
43
	cmap   = global.layer_collision;  
44
	// or layer_tilemap_get_id(layer_get_id("collision_map")); 
45
	// Remember the id could change between rooms
46
	
47
	left   = -sprite_get_xoffset(_mask);
48
	right  = _w - sprite_get_xoffset(_mask);
49
	top    = -sprite_get_yoffset(_mask);
50
	bottom = _h - sprite_get_yoffset(_mask);
51
	
52
	hor_count     = _y_count + 1;
53
	hor_increment = (_h - 1) / _y_count;
54
	ver_count     = _x_count + 1;
55
	ver_increment = (_w - 1) / _x_count;
56
	
57
	on_horizontal = 0; // Useful for wall jumps
58
	on_vertical = 0; // Can be used to set on_ground
59
	on_one_way_platform = false;
60
				
61
	function move_collide(_this, _x, _y, _vx, _vy)
62
	{
63
		_x += _vx;
64
		if (_vx > 0) _x = collide_right(_x, _y);
65
		else if (_vx < 0) _x = collide_left(_x, _y);
66
		else on_horizontal = COLLIDE_HOR_NONE;
67
68
		_y += _vy;
69
		if (_vy > 0) _y = collide_bottom(_x, _y, _vy);
70
		else if (_vy < 0) _y = collide_top(_x, _y);
71
		else 
72
		{
73
			on_vertical = COLLIDE_VER_NONE;
74
			on_one_way_platform = false;
75
		}
76
		
77
		_this.x = _x;
78
		_this.y = _y;
79
	}			
80
				
81
	function collide_right(_x, _y)
82
	{
83
		var _right = _x + right;
84
		_y = round(_y + top);
85
		for (var _i = 0; _i < hor_count; _i++)
86
		{
87
			if ((tilemap_get_at_pixel(cmap, _right, _y) & tile_index_mask) & 1)
88
			{
89
				on_horizontal = COLLIDE_HOR_RIGHT;
90
				return (_right &~ TILE_SIZE_M1) - right;
91
			}
92
			_y += hor_increment;
93
		}
94
		on_horizontal = COLLIDE_HOR_NONE;
95
		return _x;
96
	}
97
	
98
	function collide_left(_x, _y)
99
	{
100
		var _left = _x + left;
101
		_y = round(_y + top);
102
		for (var _i = 0; _i < hor_count; _i++)
103
		{
104
			if ((tilemap_get_at_pixel(cmap, _left, _y) & tile_index_mask) & 1) 
105
			{
106
				on_horizontal = COLLIDE_HOR_LEFT;
107
				return (_left &~ TILE_SIZE_M1) + TILE_SIZE - left;
108
			}
109
			_y += hor_increment;
110
		}
111
		on_horizontal = COLLIDE_HOR_NONE;
112
		return _x;
113
	}
114
	
115
	function collide_top(_x, _y)
116
	{
117
		on_one_way_platform = false;
118
		var _top = _y + top;
119
		_x = round(_x + left);
120
		for (var _i = 0; _i < ver_count; _i++)
121
		{
122
			if ((tilemap_get_at_pixel(cmap, _x, _top) & tile_index_mask) & 1)
123
			{
124
				on_vertical = COLLIDE_VER_UP;
125
				return (_top &~ TILE_SIZE_M1) + TILE_SIZE - top;
126
			}
127
			_x += ver_increment;
128
		}
129
		on_vertical = COLLIDE_VER_NONE;
130
		return _y;
131
	}
132
	
133
	function collide_bottom(_x, _y, _vy)
134
	{
135
		// A bit different to account for one-way platforms
136
		
137
		var _bottom = _y + bottom,
138
			_tile_top = _bottom &~ TILE_SIZE_M1,
139
			_above_one_way = (_bottom - _vy) <= _tile_top;
140
			
141
		_x = round(_x + left);
142
		for (var _i = 0; _i < ver_count; _i++)
143
		{
144
			var _tile_index = tilemap_get_at_pixel(cmap, _x, _bottom) & tile_index_mask,
145
				_on_one_way_platform = (_above_one_way && _tile_index == TILE_ONE_WAY);
146
			
147
			if (_tile_index & 1 || _on_one_way_platform)
148
			{
149
				on_vertical = COLLIDE_VER_DOWN;
150
				on_one_way_platform = _on_one_way_platform;
151
				return _tile_top - bottom;
152
			}
153
			_x += ver_increment;
154
		}
155
		on_vertical = COLLIDE_VER_NONE;
156
		return _y;
157
	}
158
	
159
	function draw_mask(_x, _y)
160
	{
161
		draw_sprite(mask_sprite, 0, _x, _y);
162
	}
163
	
164
}