Yann's Forum Posts

  • 1\ System condition doesn't pick (unless it's a foreach, a pick nth instance, or a pick random instance)

    2\ You use a global variable to carry the direction, thus applying the same value for everyone

    Things could be waaaaaay simplier:

    +Enemy: Is on-screen
      -> Enemy: set a to ceil(((angle(self.x,self.y,player.x,player.y)+360)/45)-0.5)%8
      -> Enemy: set animation to "direction_"&a
      +System: Every 3 seconds
      +System: For each Enemy
        -> Enemy: Spawn Ts on layer 4 at image point "shoot1"
        -> Ts: set bullet angle to Enemy.a*45 degrees
        -> Audio: Play Explosion1 no looping (tag:"")

    These few line should replace your "AI_AimAtAngles" and "AI_ShootWhileonScreen" groups

    Note that you'll have to create an instance variable named 'a' type number for your enemies

    And also rename your animations:

    • right -> direction_0
    • rightdown45 -> direction_1
    • down -> direction_2
    • .. etc (respect the clockwise rotation)
  • A good way to learn how to use array might be to start with one dimensional array.

    A one 1D-array is just like a simple indexed list.

    Array are usefull because they provide a unique name (the name of the array) for more than one value.

    Classical variables (instance, global, local, etc) don't, it's always one name <-> one value.

    Using one name for many values helps to lessen the number of variable.

    Imagine a list of enemy. With variable you'd have to do stuff like:

    global variable enemy1 = "wolf"
    global variable enemy2 = "bear"
    global variable enemy3 = "cactus" // why not?
    etc

    There's no advantage and many drawback to this method

    I'd use Array like this

    +On Start of layout
      -> enemy set size to (3,1,1)
      -> enemy.At(0) = "wolf"
      -> enemy.At(1) = "bear"
      -> enemy.At(2) = "cactus"

    (note that array are 0-based)

    This way you can do stuff like

    +On Start of layout
      -> Text: set Text to "There are "&enemy.width&" types of enemy in this area:"&newline
      +for each X element 
        -> Text append "  -"&enemy.CurValue&newline

    Note that:

    • using foreach X element is the same as doing:+for "" from 0 to enemy.width-1

    -> Text append " -"&enemy.At(loopindex)&newline

    - using enemy.CurValue is the same as using enemy.At(enemy.CurX)

    Once you're used to work with 1D array, you can begin to use 2D arrays. For instance you could store the area index in X index and use the Y indexing for the list of enemies.

    Like

    +On Start of layout
      -> enemy set size to (2,3,1)
      -> enemy.At(0,0) = "wolf"
      -> enemy.At(0,1) = "bear"
      -> enemy.At(0,2) = "cactus"
      -> enemy.At(1,0) = "pony"
      -> enemy.At(1,1) = "jar jar binks"
      -> enemy.At(1,2) = "your stepmother"

    And you could go really far with this idea if you want to even store the name of the area and some characteristics.

    There you can do it by organising your array such as the 2 first Y indexes are for these data and the rest is for the list of enemies

    +On Start of layout
      -> enemy set size to (2,5,1)
      -> enemy.At(0,0) = "The Shire" //name of the area
      -> enemy.At(0,1) = "mostly cloudy" // type of weather
      -> enemy.At(0,2) = "wolf"
      -> enemy.At(0,3) = "bear"
      -> enemy.At(0,4) = "cactus"
      -> enemy.At(1,0) = "DreamLand" //name of the area
      -> enemy.At(1,1) = "sunny"  // type of weather
      -> enemy.At(1,2) = "pony"
      -> enemy.At(1,3) = "jar jar binks"
      -> enemy.At(1,4) = "your stepmother"

    Or you could build a 3D array to split things up a bit more

    +On Start of layout
      -> enemy set size to (2,2,3)
      -> enemy.At(0,0,0) = "The Shire" //name of the area
      -> enemy.At(0,0,1) = "mostly cloudy" // type of weather
      -> enemy.At(0,1,0) = "wolf"
      -> enemy.At(0,1,1) = "bear"
      -> enemy.At(0,1,2) = "cactus"
      -> enemy.At(1,0,0) = "DreamLand" //name of the area
      -> enemy.At(1,0,1) = "sunny"  // type of weather
      -> enemy.At(1,1,0) = "pony"
      -> enemy.At(1,1,1) = "jar jar binks"
      -> enemy.At(1,1,2) = "your stepmother"

    (overkill isn't it?)

    Anyway in the end the most important thing to consider when using array is how you'll organize it.

    And also, I never set so much data by end. I always end up putting all that in a string and parsing it (via tokenat and tokencount)

    But that's another story (:

  • jbadams

    There's one, if the object isn't global, the variables are reset on start of layout. There is a "reset all global variables" but that's an all or nothing function. I like to keep some data (like score or current level) but reset some other (like enemy counter or some) and even have some different initial values for the same variable in different layouts (like base strength of ennemies or stuff like that)

    Also the object is accessible from other event sheets yes, and that's fine, but it's not accessible in a layout where you didn't put the object. Which make the variable holder object truely 'by layout'. So you will just have to be carefull with included event sheet that uses these variables not to include them in event sheets of layout that doesn't have the object.

  • Well just one thing then, I wouldn't use a sprite. Almost any object can have variables, but sprite are drawn objects that you must place, so you could potentially delete it by mistake, and it would just be another object to put somewhere on the side of your layout.

    Then I would just use a non world object like array, dictionnary, or anything else that can hold instance variables. You can always call it vars (:

  • kittiewan

    smoke doesn't move faster, smoke is just feet (if you have a running character) or wheels (if it's a vehicle) that creates local air movements and that makes dust fly up... So the faster you go, the more dust smoke you would produce, but the dust doesn't move that much, it just goes up and then fall on the ground.

    There's not that much dust going horizontally unless there's a strong friction (like a car stuck in the sand or something like that)

  • I believe in english that's called a trail

    trail2.capx (you can play with randomness values if you want.

  • Joe7

    Yeah you can do that but unless you are super clean and keep track of which index of the array corresponds to which value, it's a pain (:

    I always prefer some properly named variables.

    Well now... With the Dictionnary plugin maybe... If you're organised such as initializing all the variable you'll use in one place in your event sheet. 'Cause you won't have a list of keys the same way you have a list of global/local variables =)

  • Basically, once the path is generated, the list of coordinate to go through is stored in an array you can query via getCtXPathList(n) and getCtYPathList(n), n is just the index of the cells listed. It goes from 0 (starting cell) to the the number of cell to travel-1 (the last cell).

    But it's just coordinates, if you simply read the array and change the position of the sprite accordingly, you will have a stepped movement.

    Lerp(a,b,t) = a + (b-a) * t

    so basically if t evolve from 0 to 1 you get a nice interpolation from a to b.

    Here I use lerp() to go from index n (a) to index n+1 (b) in the array.

    The global variable iteration simply count time since the start of the interpolation.

    t = iteration-floor(iteration) means that I only keep the decimal part.

    t = 5.2 - floor(5.2) = 5.2-5 = 0.2

    So for example, if you are at iteration = 5.5 seconds

    You will get something like

    Lerp(getCtXPathList(4),getCtXPathList(5),0.5)

    Which means you'll be halfway between the X coordinate at n=4 and n=5.

    Which also means that if you choose the cut corner option, you'll go faster in diagonal than in orthogonal movements.

    This formula can be enhanced by taking into account the distance. But it should be handle at the 'iteration' incrementation. With something like

    set length to distance(getCtXPathList(max(0,floor(iteration)-1)),getCtYPathList(max(0,floor(iteration)-1)),getCtXPathList(floor(iteration)),getCtYPathList(floor(iteration)))
    set iteration to (length > 0) ? dt*Speed/length : 0[/code:27m508yq]
    
    Well, as there was still some mistake in my capx, I updated it with these new formula and some comments.
    And I added a debug text you can set to visible to see how some of the values evolve.
    
    [url=https://app.box.com/s/zo7vfwjpnz4j6g80rajp]kyat-PF.capx[/url]
  • Nah, no real alternative, I usually use global variable for that.

    I already suggested 'Layout Variables' last November but, now that I think about it, it would rather be 'Event Sheet Variables' since each layout can share the same event sheet.

    Or some kind of 'static local variable' if it's the right term. Local variable that doesn't get reinitialized.

    Anyway, that's Ashley 's call (:

  • the first animation frame is just empty, and the nine sprites are already created and positionned (snap feature helps for that)

    Every 'next' seconds I just set the current sprite to frame 0 (empty) and randomly pick one sprite amongst the eight other sprites and set its animation frame to a random integer between 1 and 20.

  • the first animation frame is just empty, and the nine sprites are already created and positionned (snap feature helps for that)

    Every 'next' seconds I just set the current sprite to frame 0 (empty) and randomly pick one sprite amongst the eight other sprites and set its animation frame to a random integer between 1 and 20.

  • it can be as easy as this

    random9sprites.capx

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Building graphically is often heavier on the cpu because you have to handle many object instead of simple numbers in an array.

    I did a cave generator some months ago, starting by covering the screen with sprites and mining with 'miner' sprites... it was waaaay slower than the array solution I built afterward.

    Anyway here is the thing

    mazeBackTrack.capx

  • Cubemaze uses the Recursive Backtrack algo (:

    For a capx hmmm I don't have a basic one right now... Shouldn't be too hard though

  • Oh I see the resize function does a cropping unless I choose stretch (as it was a noise texture I didn't notice).

    But nonetheless, It's still kinda weird to keep the old big collision poly. Maybe it would be better to add another option that says "scale/trim/don't modify the collision polygon accordingly".

    I think for most case I would scale it. But it would at least make people aware of what the resize will do.

    As we don't see collision polygons by default we might miss the consequence of a resize and come across unexpected bugs.