Jump to content

Check the position of x, y-1


Mat-eria
 Share

Recommended Posts

Any object which has a position x, y. Is there a way to force the object to check the position of x, y-1 and if cleared to go. This check should be carried out until the object is alive.
Or, as an option, even lower when the object dies forwards the event to the upper ...
Maybe someone tell me how to implement it ...

Link to comment
Share on other sites

No one can help ?! Currently using function

checkCorrectPos: function (_flag) {
    var flag = _flag || 'default';

    switch (flag){
        case 1:
                var rowDown = this.generalR + 1;

                if(rowDown > 9 ){
                    return;
                }

                if (me.lettersGrid[rowDown][this.generalC].flag === 'none') {
                    me.lettersGrid[rowDown][this.generalC].setFlag('yes');
                    me.lettersGrid[this.generalR][this.generalC].setFlag('none');
                    this.y = me.lettersGrid[rowDown][this.generalC].y;
                    this.generalR = rowDown;
                    return;
                }
            break;
        default:
            if (me.lettersGrid[this.generalR][this.generalC].flag === 'none') {

                me.lettersGrid[this.generalR][this.generalC].setFlag('yes');
                return true;
            } else {
                return false;
            }
            break;
    }

},

me.game.time.events.loop is called, but it still does not work correctly because if the removed object 2 in a single column, then y -2 also becomes three, but drops only one is in them ...

Link to comment
Share on other sites

I didn't answer because I'm not sure what you're trying to do. Can you provide more information about the game and what problem you're trying to solve? When you write "Any object which has a position x, y. Is there a way to force the object to check the position of x, y-1 and if cleared to go" that's not quite a problem description, but a description of the answer you want. I'm trying to make sure your problem is solved. ( =

Link to comment
Share on other sites

18 minutes ago, drhayes said:

I didn't answer because I'm not sure what you're trying to do. Can you provide more information about the game and what problem you're trying to solve? When you write "Any object which has a position x, y. Is there a way to force the object to check the position of x, y-1 and if cleared to go" that's not quite a problem description, but a description of the answer you want. I'm trying to make sure your problem is solved. ( =

It is very difficult to express their thoughts in English, I hope you understand.

In my game the player needs to find words on the size of the field is 10 * 10. When a player finds a word, the letters used are removed from the field, and those letters that were supremely should take their place (the letters are moved only in the column).

Now it is implemented as it was written supreme (but it does not work properly).Through events realized I could not get ...

Link to comment
Share on other sites

I think you'd maybe want to do something like the following:

You have a grid of letters that represents your game state (for brevity lets just assume an array of arrays to make your 2d grid),

var state = [
  [ 'a', 'f', 'k' ],
  [ 'b', 'g', 'l' ],
  [ 'c', 'h', 'm' ],
  [ 'd', 'i', 'n' ],
  [ 'e', 'j', 'o' ], 
]

This is a 3x5 grid, but you'd probably render this on the screen as a 5x3 grid (i.e. rotated). 

At some point in time your user does something which changes (mutates) this game state. Let's assume they select the letters 'g', 'h' and 'i' (I'm guessing it is a word matching game so imagine that `ghi` is a word, actually according to wiktionary it is a word in a couple of languages, including English, live and learn). So, your user selects the letters and they disappear from the grid.

Your transient state becomes:

var state = [
  [ 'a', 'f', 'k' ],
  [ 'b',      'l' ],
  [ 'c',      'm' ],
  [ 'd',      'n' ],
  [ 'e', 'j', 'o' ], 
]

I've maintained spaces for clarity, and I say transient because this state is going to be very short lived, it might not exist at all in this form.

Your next game state is going to push new characters into those arrays so that each array now contains the necessary 3 characters again. Your code to determine this is simple:

for each array, if it contains less than 3 characters then push new characters on to it until its length equals 3.

for each array
  if 
    ( array length is less than 3 )
  then 
    push new characters on to array until its length equals 3
next array

If random letters are pushed on (I'll use capitals for emphasis) then your next game state is going to look something like the following:

var state = [
  [ 'a', 'f', 'k' ],
  [ 'X', 'b', 'l' ],
  [ 'Y', 'c', 'm' ],
  [ 'Z', 'd', 'n' ],
  [ 'e', 'j', 'o' ], 
]

This is your logic. If I understand your problem well enough you dont need to worry about checking if a space is free or not, you simply splice from or add to an array based on its length. This is easier to reason about and simpler computations.

The 2nd part of solving this problem is that your UI probably does not update atomically, i.e. you probably want to animate from one state to another. This is (should be) a separate concern from the logic that drives state changes in your application.

I hope that makes sense, and that it helps solve your problem, I tried to make my English as clear as possible.

 

Link to comment
Share on other sites

Not exactly, but you thought I submitted how to explain more precisely.
There are a grid of 10x10 it looks

me.lettersGrid = [
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null]
];

This is the field of play. At the very beginning of the game at the same time on the field falls 30 letters uniformly fill the bottom line looks like this

me.lettersGrid = [
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [w, t, g, i, a, r, x, z, o, i],
    [s, i, d, p, e, h, l, a, a, s],
    [a, v, d, a, b, l, p, o, q, x]
];

then every 5 seconds 1 more letter appended to the field. Looks like that

me.lettersGrid = [
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, k, null, null, null, null, null, null, null],
    [w, t, g, i, a, r, x, z, o, i],
    [s, i, d, p, e, h, l, a, a, s],
    [a, v, d, a, b, l, p, o, q, x]
];

the player finds the word bear. These letters (b,e,a,r) are deleted,

me.lettersGrid = [
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, k, null, null, null, null, null, null, null],
    [w, t, g, i, null, null, x, z, o, i],
    [s, i, d, p, null, h, l, a, a, s],
    [a, v, d, a, null, l, p, o, q, x]
];

and the letter 't' should take place 'b'

me.lettersGrid = [
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [w, t, g, i, null, null, x, z, o, i],
    [s, i, d, p, null, h, l, a, a, s],
    [a, v, d, a, k, l, p, o, q, x]
];
Link to comment
Share on other sites

 My function makes it so

me.lettersGrid = [
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [null, null, null, null, null, null, null, null, null, null],
    [w, t, g, i, k, null, x, z, o, i],
    [s, i, d, p, null, h, l, a, a, s],
    [a, v, d, a, null, l, p, o, q, x]
];
Link to comment
Share on other sites

You are over complicating something by trying to model how you see it visually.

I'll try to explain a bit more.

Anti-pattern

In your current situation you are looking for an answer that checks every item in your 2d grid, each item must then check the space directly beneath it (in a separate array) and then move if that space is clear. The check for this is simple:

// Pseudo-code
movement = true
while ( movement )
  movement = false
  for each item in grid
    get [ x, y ] location of item
    check [ x, y + 1 ]
    if empty then
      [ x, y + 1 ] = [ x, y ]
      [ x, y ] = null
      movement = true
    endif
  next item
endwhile

This becomes trickier than the implementation above suggests, particularly in JS (accessing items in arrays in JS might not work how you expect) but with a bit of effort that solution would work. However, you would have to check every item in the entire grid and you would have to keep track of any movements and stop the algorithm when there no movements are left to make, that is what the movement variable and while loop do. This is extremely expensive and extremely wasteful.

You might be able to improve that a little by working backwards from the bottom and only moving items from above when the current item is empty, but you'd still have to do it per column and access lots of different arrays for each column.

Better Pattern

A better pattern is simply to rotate the array when you render it.

So, your array data structure remains the same but checking for insertions/deletions becomes easier.

When a user matches a word you simply `splice` those letters out of whichever array/row they are in. Don't replace them with null, simply remove them. Then check each row to see if it has the correct number of items in it. If it does not then add enough items on to the front/back of the array (front or back depends on how you rotate the model when you render it) so that it contains the correct number of items.

Splice is not that cheap in JS but this way you are drastically reducing the number of operations you are performing, for a start, in your example only 2 of the rows have changes, so when you are performing 10 checks against array.length, and you are adding some items to only 2 of the rows, if you only just push/unshift then you add 3 items to 1 row ( b, e, a ) and 1 item to another row ( r ), for a total of 14 operations.

In the naive solution above you are moving `k` down 3 spaces (to replace b, e, a) but since you must check every item in for adjacent spaces you are performing at least 10 * 10 * 3 checks, and even then you must also check the space 'below' so you can double that to 600 (and I'm still not sure, it might be more).

For an added bonus the JIT compiler can optimise this method a little, but I dont think it can do too much to optimise loads and loads of array lookups.

To rotate the array when you render you would do something trivial like:

var bigArray = [
  [ 'b', 'e' ],
  [ 'a', 'r' ]
]

for ( var y = 0; y < 2; y++ ) {
  for( var x = 0; x < 2; x++ ) {
    var item = bigArray[ x, y ]

    // Notice x and y are reversed here, this changes the render order,]
    // a very cheap rotation
    // multiply by 40 to assume that each rendered item is 40x40
    drawItemAt( y * 40, x * 40 )
  }
}

 Then resultant render would look like:

 
 b a
 e r

 

There are a load of things you can do to optimise that, for a start, an array of arrays is about the least efficient 2d grid representation going.

 

 

Link to comment
Share on other sites

 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...