Monkuar Posted January 24, 2015 Share Posted January 24, 2015 (edited) In PHP? Let's say I'm going off of: width x height So this is 2x1 2x1 2 blocks across, 1 block height. How do I check this against other blocks in php to see if the 2x1 will overlap another set of dimensions dynamically? Am I over thinking this? Edited January 24, 2015 by Monkuar Quote Link to comment Share on other sites More sharing options...
CroNiX Posted January 24, 2015 Share Posted January 24, 2015 Maybe array_intersect()? Quote Link to comment Share on other sites More sharing options...
requinix Posted January 25, 2015 Share Posted January 25, 2015 Doesn't it depend on the positioning of the two blocks? Quote Link to comment Share on other sites More sharing options...
Monkuar Posted January 25, 2015 Author Share Posted January 25, 2015 (edited) Doesn't it depend on the positioning of the two blocks? Yeah, that's the problem I faced. I had to scratch this project and just go back to my original inventory system: I really want to do the inventory system like Path of Exile or Diablo 2's/3's. But the problem is. I cannot get the positions of the other items when moving the main item. (Well, I could, but I cannot do it dynamically) I added a field in my rpg_items table called slot_size and for the belt it was 2x1 (2 WIDTH, 1 HEIGHT), and slot position = 1. Then, I used explode to check the width and height of all the users inventory items But... the image is spanning across 2 blocks. So I just don't know how to read the image, so a user cannot put a item in slot position 2. But then, what if the item they are moving is 3x2? or 1x5? Too much algorithm / math involved that I could never really understand. What if the belt was 2x5? 2width and 5 blocks high? How do I check serverside if a user was putting an item on the XX slot? 5 blocks down would be in row 5, and slot number whatever. Just too much shit going on and I cannot do it. I'm sorry guys, failed you but this was too much. I am either wrong on the design process, or my knowledge is the bottleneck. I'm using interactJS to drag and drop though. So if anyone crafts this up, I'll pay around 50$. But other then that, I'm happy with my regular 1 slot moving inventory system.. well not really. I would really love a D2/Path of Exile feel... but too complicated atm. Time is Gold. Edited January 25, 2015 by Monkuar Quote Link to comment Share on other sites More sharing options...
Solution mac_gyver Posted January 25, 2015 Solution Share Posted January 25, 2015 the program logic would be - // origin is top, left - 1,1 (x,y) // define grid size $max_x = 5; // across $max_y = 4; // down // create empty grid - $x = range(1,$max_x); $y = range(1,$max_y); $grid = array(); foreach($x as $xx){ foreach($y as $yy){ $grid[$xx][$yy] = 0; } } // for any requested x,y position, determine if the $item can be placed starting at that position in the grid // inputs - $x,$y - requested position // $item - item definition array(id, width, height) // $grid - the grid holding existing items // processing - test starting at the requested position if the item fits within the grid boundary and that all the corresponding cells are empty // return - 1 if the item can be placed at the requested position, 2 if out of bounds, 3 if overlap another item define('POS_OK',1); define('POS_OUTOFBOUNDS',2); define('POS_OVERLAP',3); function test_pos($x,$y,$item,$grid){ $w = $x + $item['w'] - 1; // highest width $h = $y + $item['h'] - 1; // highest height // check if out of bounds if(!isset($grid[$x]) || !isset($grid[1][$y]) || !isset($grid[$w]) || !isset($grid[1][$h])){ return POS_OUTOFBOUNDS; } // check if overlap for($xx = $x; $xx <= $w; $xx++){ for($yy = $y; $yy <= $h; $yy++){ if($grid[$xx][$yy] != 0){ return POS_OVERLAP; } } } return POS_OK; } // example usage - $item = array('id'=>123,'w'=>2,'h'=>1); // define a 'test' item $grid[5][4] = 456; // put an item in the grid (value is the item's id, 0 = empty, not used as an id value) var_dump(test_pos(3,4,$item,$grid)); Quote Link to comment Share on other sites More sharing options...
Monkuar Posted January 25, 2015 Author Share Posted January 25, 2015 (edited) the program logic would be - // origin is top, left - 1,1 (x,y) // define grid size $max_x = 5; // across $max_y = 4; // down // create empty grid - $x = range(1,$max_x); $y = range(1,$max_y); $grid = array(); foreach($x as $xx){ foreach($y as $yy){ $grid[$xx][$yy] = 0; } } // for any requested x,y position, determine if the $item can be placed starting at that position in the grid // inputs - $x,$y - requested position // $item - item definition array(id, width, height) // $grid - the grid holding existing items // processing - test starting at the requested position if the item fits within the grid boundary and that all the corresponding cells are empty // return - 1 if the item can be placed at the requested position, 2 if out of bounds, 3 if overlap another item define('POS_OK',1); define('POS_OUTOFBOUNDS',2); define('POS_OVERLAP',3); function test_pos($x,$y,$item,$grid){ $w = $x + $item['w'] - 1; // highest width $h = $y + $item['h'] - 1; // highest height // check if out of bounds if(!isset($grid[$x]) || !isset($grid[1][$y]) || !isset($grid[$w]) || !isset($grid[1][$h])){ return POS_OUTOFBOUNDS; } // check if overlap for($xx = $x; $xx <= $w; $xx++){ for($yy = $y; $yy <= $h; $yy++){ if($grid[$xx][$yy] != 0){ return POS_OVERLAP; } } } return POS_OK; } // example usage - $item = array('id'=>123,'w'=>2,'h'=>1); // define a 'test' item $grid[5][4] = 456; // put an item in the grid (value is the item's id, 0 = empty, not used as an id value) var_dump(test_pos(3,4,$item,$grid)); This might be a Godsend, but requinex pm'd me with some guidelines and an overhow on how to do it. I'm going to try to spend all today figuring this out on my own instead of just copying your code. I feel like I would be cheating myself, and that's not right. I will spend all day today, and if nothing prevails I'll use this as a startup. Marked as best answer, thank you mac. Requinex told me it should be 0,0 as top left. Now you're saying it should be 1,1. Life is confusing lol, haha. I need to get away from the house and just do this I know I can Edited January 25, 2015 by Monkuar Quote Link to comment Share on other sites More sharing options...
Monkuar Posted January 25, 2015 Author Share Posted January 25, 2015 (edited) the program logic would be - // origin is top, left - 1,1 (x,y) // define grid size $max_x = 5; // across $max_y = 4; // down // create empty grid - $x = range(1,$max_x); $y = range(1,$max_y); $grid = array(); foreach($x as $xx){ foreach($y as $yy){ $grid[$xx][$yy] = 0; } } // for any requested x,y position, determine if the $item can be placed starting at that position in the grid // inputs - $x,$y - requested position // $item - item definition array(id, width, height) // $grid - the grid holding existing items // processing - test starting at the requested position if the item fits within the grid boundary and that all the corresponding cells are empty // return - 1 if the item can be placed at the requested position, 2 if out of bounds, 3 if overlap another item define('POS_OK',1); define('POS_OUTOFBOUNDS',2); define('POS_OVERLAP',3); function test_pos($x,$y,$item,$grid){ $w = $x + $item['w'] - 1; // highest width $h = $y + $item['h'] - 1; // highest height // check if out of bounds if(!isset($grid[$x]) || !isset($grid[1][$y]) || !isset($grid[$w]) || !isset($grid[1][$h])){ return POS_OUTOFBOUNDS; } // check if overlap for($xx = $x; $xx <= $w; $xx++){ for($yy = $y; $yy <= $h; $yy++){ if($grid[$xx][$yy] != 0){ return POS_OVERLAP; } } } return POS_OK; } // example usage - $item = array('id'=>123,'w'=>2,'h'=>1); // define a 'test' item $grid[5][4] = 456; // put an item in the grid (value is the item's id, 0 = empty, not used as an id value) var_dump(test_pos(3,4,$item,$grid)); Okay. I found an issue in the code: // example usage - $item = array('id'=>5,'w'=>5,'h'=>5); // define a 'test' item $grid[1][2] = 5; // put an item in the grid (value is the item's id, 0 = empty, not used as an id value) var_dump(test_pos(1,3,$item,$grid));This returns 1 (String OK) which it shouldn't.Because if you have an item at location 1,2 and the item id is 5. The WIDTH of that item is 5 ('w'=>5). So 1,3 should be overlapping. 1,4 too, 1,5, 1,6, and 1,7. 1,8 is a free spot (But then it would be outof bounds). Also: I added this to display the grid: foreach ($grid as $widthbox => $heightbox){ // Grid layout: foreach($heightbox as $heightgrid => $item){ $counter++; if ($item['id'] == $i){ // Trying to display the item based on it's width and height values ( How many boxes to take up! ?? ) // We have a match. $i = $item['id']; $w = $item['w']; $h = $item['h']; echo '<div class="InventoryTest" title="'.$counter.'"> '.$item.'</div>'; }else{ echo '<div class="InventoryTest" title="'.$counter.'"> '.$item.'</div>'; } } }The problem is, if a item's width is 5 boxes, I cannot seem to make it a 'block' and take up those corresponding 5 blocks horizontally. css for everything is: <style> .fadeIn{animation-name:fadeIn;-webkit-animation-name:fadeIn;animation-duration:.7s;-webkit-animation-duration:.7s;animation-timing-function:ease-in-out;-webkit-animation-timing-function:ease-in-out;visibility:visible!important}@keyframes fadeIn{0%{transform:scale(0);opacity:0}60%{transform:scale(1.1)}100%{transform:scale(1);opacity:1}}@-webkit-keyframes fadeIn{0%{-webkit-transform:scale(0);opacity:0}60%{-webkit-transform:scale(1.1)}100%{-webkit-transform:scale(1);opacity:1}} .InventoryTest{ border:1px solid #D3D3D3;border-bottom:0;width:24px;height:24px;float:left;padding:3px;border-right:0; } .itemdrag{position:relative;z-index:1} .InventoryTest:nth-child(9n+9){ border-right:1px solid #D3D3D3 } .InventoryTest:nth-last-child(-n+9){ border-bottom:1px solid #D3D3D3; } .itemdrag{position:relative;z-index:1} </style> <?php error_reporting(E_WARNING); // origin is top, left - 1,1 (x,y) // define grid size $max_x = 9; // across $max_y = 9; // down // create empty grid - $x = range(1,$max_x); $y = range(1,$max_y); $grid = array(); foreach($x as $xx){ foreach($y as $yy){ $grid[$xx][$yy] = 0; } } // for any requested x,y position, determine if the $item can be placed starting at that position in the grid // inputs - $x,$y - requested position // $item - item definition array(id, width, height) // $grid - the grid holding existing items // processing - test starting at the requested position if the item fits within the grid boundary and that all the corresponding cells are empty // return - 1 if the item can be placed at the requested position, 2 if out of bounds, 3 if overlap another item define('POS_OK', 'OK'); define('POS_OUTOFBOUNDS', 'OUT OF BOUNDS'); define('POS_OVERLAP', 'OVERLAP'); function test_pos($x,$y,$item,$grid){ $w = $x + $item['w'] - 1; // highest width $h = $y + $item['h'] - 1; // highest height // check if out of bounds if(!isset($grid[$x]) || !isset($grid[1][$y]) || !isset($grid[$w]) || !isset($grid[1][$h])){ return POS_OUTOFBOUNDS; } // check if overlap for($xx = $x; $xx <= $w; $xx++){ for($yy = $y; $yy <= $h; $yy++){ if($grid[$xx][$yy] != 0){ return POS_OVERLAP; } } } return POS_OK; } // example usage - $item = array('id'=>5,'w'=>5,'h'=>5); // define a 'test' item $grid[1][1] = 5; // put an item in the grid (value is the item's id, 0 = empty, not used as an id value) var_dump(test_pos(1,3,$item,$grid)); ?> <div style="width:310px" id="InventoryContainer" onmouseleave="qs('#InventoryContainer').style.cursor='default'"> <?php foreach ($grid as $widthbox => $heightbox){ // Grid layout: foreach($heightbox as $heightgrid => $item){ $counter++; if ($item['id'] == $i){ // Trying to display the item based on it's width and height values ( How many boxes to take up! ?? ) // We have a match. $i = $item['id']; $w = $item['w']; $h = $item['h']; echo '<div class="InventoryTest" title="'.$counter.'"> '.$item.'</div>'; }else{ echo '<div class="InventoryTest" title="'.$counter.'"> '.$item.'</div>'; } } } ?> </div> Edited January 25, 2015 by Monkuar Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted January 25, 2015 Share Posted January 25, 2015 your test case has no overlap. the existing item in the grid is at x=1,y=2 and has w=1,h=1. the item you are testing by calling the function starts at x=1,y=3 and goes to x=5,y=7. y=3 (the lowest y position of item being tested) is greater than y=2 (the y position of the item already in the grid) and there is no overlap. Quote Link to comment Share on other sites More sharing options...
Monkuar Posted January 25, 2015 Author Share Posted January 25, 2015 (edited) your test case has no overlap. the existing item in the grid is at x=1,y=2 and has w=1,h=1. the item you are testing by calling the function starts at x=1,y=3 and goes to x=5,y=7. y=3 (the lowest y position of item being tested) is greater than y=2 (the y position of the item already in the grid) and there is no overlap. Isn't the item identified in the array though? $item = array('id'=>5,'w'=>5,'h'=>5); // define a 'test' item $grid[1][2] = 5; // put an item in the grid (value is the item's id, 0 = empty, not used as an id value) var_dump(test_pos(1,3,$item,$grid)); Yeah, the existing item in the grid is x=1, y=2, but it's defined in the $item=array with width=5, h=5. not w=1, h=1. Where did u get w=1, h=1 from? Edited January 25, 2015 by Monkuar Quote Link to comment Share on other sites More sharing options...
kicken Posted January 25, 2015 Share Posted January 25, 2015 The function doesn't look at the width/height of existing items, it just checks if something has been assigned to that slot. Either you'd have to change the function to take into account the width/height of items already in the grid (ie, store the entire item info, not just the id) or you'd have to fill every space that an item takes up with it's ID number (ie $grid[1 - 6][2 - 7] = 5). Quote Link to comment Share on other sites More sharing options...
mac_gyver Posted January 26, 2015 Share Posted January 26, 2015 the $grid in this example code, since is shows what blocks are occupied, would need an entry for every block that's occupied by an item, which is why the id of the instance of an item is what's stored. at some point, for the simplest test_pos() code, the items stored in the grid would need to be expanded and occupy all the blocks they, well occupy. Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.