GameSalad

Coins !

SocksSocks London, UK.Posts: 12,711Member

Another asset I made but never used, Gold and Silver coins, might be useful for someone.

The attached GS project contains the full quality PNGs of both Gold and Silver coins.

EDIT: Extra fat Boss Coin ! (GameSalad Project / PNGs in post bellow)

EDIT: Added Black Death Coin.

Comments

  • monkeyboy+simianmonkeyboy simian Posts: 465Member, PRO

    They look great @Socks.. I don't understand how you made them use the different images to create the animation though. Could you please explain? Also, I'm curious as to which program you used to create them?

  • SocksSocks London, UK.Posts: 12,711Member
    edited June 25

    @monkeyboy simian said:
    I don't understand how you made them use the different images to create the animation though. Could you please explain?

    Sure, what is it you want explaining, I'm not sure, do you want to know how the equation works ?

    @monkeyboy simian said:
    Also, I'm curious as to which program you used to create them?

    I used Cinema4D, but you could do this in absolutely any 3D program, it's simply a circle extruded (or a cylinder squashed flat) with a bump map (drawn in Photoshop) applied.

    Blender could probably do a better job (and Blender is free) with its new Principled shader which is really good at metal textures.

  • SocksSocks London, UK.Posts: 12,711Member

    Extra fat Boss Coin !

    (full quality PNG images in the GameSalad project attached)

  • IceboxIcebox Posts: 1,413Member, PRO
    edited June 25

    Is there a quick option to export png sequence in cinema4d ? I used blender but i just get stuck when trying to export a transparent png sequence. The lighting gets messed up and its a bit difficult to adjust the camera . ( btw Tony the spider in a coin animation would be epic :p )

    Edit: thanks for sharing , might use them later on

  • SocksSocks London, UK.Posts: 12,711Member

    @Icebox said:
    Is there a quick option to export png sequence in cinema4d ?

    I'm not sure what you mean by 'quick' can you be more specific ?

    You can render to just about any format in most pieces of software, from a PNG sequence to a ProRess422 Quicktime . . . (and a hundred other formats).

    @Icebox said:
    I used blender but i just get stuck when trying to export a transparent png sequence. The lighting gets messed up and its a bit difficult to adjust the camera .

    I'm not that familiar with Blender yet, but seeing as it keeps on getting more and more powerful and is absolutely free (whereas C4D can cost up to $3k!) I'm tempted to switch.

    @Icebox said:
    ( btw Tony the spider in a coin animation would be epic :p )

    Tony's opinion is that video games are below him, he sees himself more as a stage actor.

  • IceboxIcebox Posts: 1,413Member, PRO

    @Socks said:
    I'm not sure what you mean by 'quick' can you be more specific ?

    I mean after making the animation in the software is there a button to export "transparent png sequence" ? Cause I watched tutorials on blender and i saw that they export png sequence but it had a solid background color, they take the png files to photoshop and remove the background color to make it transparent.

  • SocksSocks London, UK.Posts: 12,711Member

    @Icebox said:
    I mean after making the animation in the software is there a button to export "transparent png sequence" ?

    Sure, just hit the render button and make sure you have the alpha channel switched on.

    @Icebox said:
    Cause I watched tutorials on blender and i saw that they export png sequence but it had a solid background color, they take the png files to photoshop and remove the background color to make it transparent.

    What the . . . ! Lol :D Seriously that's madness. In blender you do much the same, just export a RGBA file (for example PNGs) and make sure the background is transparent.

    Even if you couldn't output an alpha channel in Blender (which would be really weird for a 3D program), you would simply generate your own alpha channel, take everything in your scene and make it solid white, make your background solid black, render it out and you have a perfect alpha channel / matte, no need to cut stuff out in Photoshop.

  • SocksSocks London, UK.Posts: 12,711Member

    Black Death Coin . . .

  • monkeyboy+simianmonkeyboy simian Posts: 465Member, PRO

    @Socks.. Thanks for the tip about how to make the coins.. Re the animation.. yeah, I don't understand how the equation works. I don't see any reference to the individual coin images. i.e.: GoldCoin_5 etc. I'm guessing all of that stuff in the expression editor with floor (???) in it is making it happen... I just don't understand how it happens without actually referencing the image file names. The expression editor is to me a mysterious thing.

  • jamie_cjamie_c ImagineLabs.rocks Posts: 5,314Member, BASIC
  • SocksSocks London, UK.Posts: 12,711Member
    edited June 26

    @monkeyboy simian said:
    I just don't understand how it happens without actually referencing the image file names.

    It is referencing the image file names ! Here's the expression:

    "GoldCoin_"..floor(( self.Time*60)+ self.R )%40

    The images are called:

    GoldCoin_0
    GoldCoin_1
    GoldCoin_2
    GoldCoin_3
    GoldCoin_4 . . . . etc

    So, of course, we want our Constrain behaviour to produce a result that goes . . .

    GoldCoin_0
    GoldCoin_1
    GoldCoin_2
    GoldCoin_3
    GoldCoin_4 . . . . etc

    . . . . . . . . . . .

    The first thing to establish is that a Constrain behaviour is basically the same as a Change Attribute behaviour . . . . but while a Change Attribute changes an attribute when it's triggered (for example when a condition is met for a rule that the Change Attribute is inside of) . . . a Constrain behaviour will instead change an attribute on every 'frame' of your game (every 'frame' of your game's code).

    So in other words a Constrain behaviour (when triggered) will change an attribute 60 times a second, because GameSalad games run at 60 'frames' a second.

    . . . . . . . . . . .

    Ok, back to the expression:

    "GoldCoin_"..floor(( self.Time*60)+ self.R )%40

    The first part "GoldCoin_" unsurprisingly gives us this:

    GoldCoin_

    The next part, the two dots (..) are used as 'expression glue' (technical term) to glue the first part (GoldCoin_) to the number that will be produced by the next part.

    Now working from inside the brackets outwards . . . we have 'self.time', self.time is simply a clock that all actors have, it counts up from 0, so we have a constantly rising value.

    This is a 'real' number, so rather than giving us a whole number like 1, 2, 3 or 4 it gives us decimal numbers, so if we were to display self.time after 3.962 seconds it will gives us 3.962 . . . but we want whole numbers, because our animation sequence uses whole numbers (GoldCoin_0 . . . GoldCoin_1 . . .GoldCoin_2 . . . etc).

    So, we use the mathmatical function called floor to round the number down to the nearest whole number.

    floor (2.769) would give us 2
    floor (1.9) would give us 1
    floor (87) would give us 87
    floor (87.89283111) would give us 87

    . . . you get the idea.

    If the function to round a number down is called 'floor' you can probably guess what the function to round a number up is called . . . yup, 'ceiling' (which is called 'ceil' in GameSalad).

    Ok, so far we have:

    "GoldCoin_"..floor(self.time)

    . . .which is giving us this:

    GoldCoin_0
    GoldCoin_1
    GoldCoin_3
    GoldCoin_4
    GoldCoin_5

    . . . sorta looks like the right thing, looks like the image sequence . . . . but . . . seeing as self.time is counting up in seconds our image changes only once every second . . . .so we need to speed up the self.time part.

    This is where we add the *60 bit of the expression:

    "GoldCoin_"..floor(self.Time*60)

    Now self.time is counting up 60 times as fast ! Producing our needed sequence at 60fps.

    But obviously when it gets to the last frame it will just continue counting up (as the actor's clock just runs on forever) . . . . and if you only have - for example - 40 frames, then when it gets passed that number the expression will tell the actor to display an image that doesn't exist (the result is a blank/white actor)

    GoldCoin_38
    GoldCoin_39
    GoldCoin_40 < < < !
    GoldCoin_41 < < < !
    GoldCoin_42 < < < !

    So we want to 'loop' the numbers so that they count up to 40 and then start again at 1, this is done with the modulus math function (the '%40' bit on the end)

    "GoldCoin_"..floor(self.Time*60)%40

    This is saying 'when the number on the left of the '%' sign reaches the number on the right of the '%' sign, then reset the number on the left to 0.

    (technically this is a crap explantion, @tatiang has more correct technical explanation of what it's really doing).

    So we now have:

    "GoldCoin_"..floor(self.Time*60)%40

    This expression now produces this . . .

    GoldCoin_0
    GoldCoin_1
    GoldCoin_2
    GoldCoin_3
    GoldCoin_4
    GoldCoin_5
    GoldCoin_6
    GoldCoin_7
    GoldCoin_8
    GoldCoin_9
    GoldCoin_10
    GoldCoin_11
    GoldCoin_12
    GoldCoin_13
    GoldCoin_14
    GoldCoin_15
    GoldCoin_16
    GoldCoin_17
    GoldCoin_18
    GoldCoin_19
    GoldCoin_20
    GoldCoin_21
    GoldCoin_22
    GoldCoin_23
    GoldCoin_24
    GoldCoin_25
    GoldCoin_26
    GoldCoin_27
    GoldCoin_28
    GoldCoin_29
    GoldCoin_30
    GoldCoin_31
    GoldCoin_32
    GoldCoin_33
    GoldCoin_34
    GoldCoin_35
    GoldCoin_36
    GoldCoin_37
    GoldCoin_38
    GoldCoin_39
    GoldCoin_0
    GoldCoin_1
    GoldCoin_2
    GoldCoin_3
    GoldCoin_4
    GoldCoin_5
    GoldCoin_6
    GoldCoin_7
    GoldCoin_8
    GoldCoin_9
    GoldCoin_10
    GoldCoin_11
    GoldCoin_12
    GoldCoin_13
    GoldCoin_14
    GoldCoin_15
    GoldCoin_16
    GoldCoin_17
    GoldCoin_18
    GoldCoin_19
    GoldCoin_20
    GoldCoin_21
    GoldCoin_22
    GoldCoin_23
    GoldCoin_24
    GoldCoin_25
    GoldCoin_26
    GoldCoin_27
    GoldCoin_28
    GoldCoin_29
    GoldCoin_30
    GoldCoin_31
    GoldCoin_32
    GoldCoin_33
    GoldCoin_34
    GoldCoin_35
    GoldCoin_36
    GoldCoin_37
    GoldCoin_38
    GoldCoin_39
    GoldCoin_0
    GoldCoin_1
    GoldCoin_2
    GoldCoin_3 . . . . . . etc etc

    . . . . . . . . . . . . .

    I then added in a random starting frame (the 'self.R' bit) so the coins are not spinning in sync. I simply generated a random number called 'R' - Change R to random(1,40) - and added it into the expression.

    "GoldCoin_"..floor(( self.Time*60)+ self.R )%40

    *actually I didn't need to include R within the 'floor' brackets like I do above as I made R an integer so it doesn't need to be rounded down (as it's got no decimal places).

    So I'm going to slightly simplify the expression to make it clearer:

    "GoldCoin_"..floor(self.Time*60)+self.R %40

    Ok, so we have the first part which is the name.

    This is glued (..) to a number produced by the second part.

    The second part says 'take the value of the actor's built in clock, speed it up by x60, then round this ever-changing number down to the nearest whole number, then add our random number to this . . . and finally make sure it all never goes above 40, if it does then just reset it to 0.

    Hope that makes sense.

  • monkeyboy+simianmonkeyboy simian Posts: 465Member, PRO

    Wow. My brain just melted. I think I'm getting it. The "GoldCoin_" is calling for the the next number to be given to it due to the expression? That's why the individual file names aren't listed.. they're being called? This stuff is amazing... and full on. Thanks @Socks – I've got a LOT to learn, still.

  • SocksSocks London, UK.Posts: 12,711Member

    @monkeyboy simian said:
    Wow. My brain just melted. I think I'm getting it. The "GoldCoin_" is calling for the next number to be given to it due to the expression? That's why the individual file names aren't listed.. they're being called?

    Yes, the expression is firing once every 'frame' (that's a code frame, it doesn't refer to an animation frame, don't confuse the two!) . . . in GameSalad that's once every 1/60th of a second.

    GameSalad looks at the lowest actor in the lowest layer of your project, it scans the code you've placed in that actor from the top to the bottom, it then jumps up in the layer stack to the next actor, and scans the code you've placed in that actor from the top to the bottom . . . it continues to do this until it's worked it's way right to the last actor right at the top of your layers.

    This takes 1/60th of a second.

    Once it has gathered all that information, where each actor should be, what is being touched on the screen, what actors are touching each other, what should happen when they do, what attributes need changing and to what value . . . (etc etc) . . . once it's got all that info and has sorted out what goes where . . . it then draws the frame, that is to say it generates a frame for your iPad (etc) to display for that 1/60th of a second.

    Then it scans the code for the next frame, again starting with the bottom most actor, and it scans the code you have placed in that actor from top to bottom, then up to the next actor . . . . etc etc

    . . . . . . .

    So a Constrain is telling GameSalad to do whatever you've written in it on every frame of the above process, every time your code is scanned (once every 1/60th of a second) when the code scan gets to the Constrain, GS will check out the equation and see what value the constrain is generating . . . and as we are using self.time every time GS checks out the Constrain (once every scan / every 1/60th of second) the value would have moved on a little, so it takes that number glues it on the end of "GoldCoin_" and at the end of the code cycle displays that image, and of course on the next code cycle the value of self.time would have moved on a little more . . . . etc etc.

    tl;dr use the Animation behaviour instead :p :)

  • IceboxIcebox Posts: 1,413Member, PRO
    edited June 27

    I read somewhere earlier that "%" is not supported in javascript , so this might cause an issue once we move to the html5 web tool. its better to use mod() to avoid trouble later on, you never know .

    @Socks Why would you use this method instead of an animate behaviour? whats the difference ?

  • BigDaveBigDave Posts: 2,232Member, PRO
    edited June 27

    i wish I would get my gold coin back soon. They send it to test the % of purity. It say 900/1000 meaning its 90% gold should be some good extra money to buy food and pay rent and stuff..

    weird real life info. Nice coins!

  • SocksSocks London, UK.Posts: 12,711Member
    edited June 27

    @Icebox said:
    I read somewhere earlier that "%" is not supported in javascript , so this might cause an issue once we move to an html5 web tool. its better to use mod() to avoid trouble later on, you never know .

    Yeah, that was mentioned by GS years ago (literally years), that mod() was more supported / more compatible than %X, but the %X was never removed so it continues to get used, it's also tempting to just throw %X at the end of a value, rather than the few extra seconds of thinking required to correctly arrange your stuff inside the brackets (#lazy!) . . . if it ever becomes an issue like you say it's an easy fix to do.

    If you needed to and were really clever I'm pretty sure you could write a little script to scan your GS project's XML files and replace %X with mod() in the correct way, it's not something I could do, but I've seen some clever stuff like that from people like @Armelline, and Darren from Deep Blue Apps was a genius with that sort of thing.

    @Icebox said:
    @Socks Why would you use this method instead of an animate behaviour? whats the difference ?

    Well, again laziness :) I'm basically a very lazy person.

    If you have the following set up . . . .

    Actor with: Constrain self.image to "name_"..(frameNumber/fps)%loop

    . . . . it becomes very easy to look-after / handle your animated image sequences.

    So imagine you've dragged a 360 frame sequence in called GoldCoin, you also have one called 'GoldCoin_Darker' and one called 'GoldCoin_Star' (and a few others) . . . if you want to change the animation from GoldCoin to one of the other versions, there's no need to open the Actor, highlight all the frames in the Animation behaviour and delete them, open the Image Pane, scroll down to where the coin frames start, drag until you have all 360 images selected . . . uh ! hold on ! I've just selected a few images from the previous sequence too, ok, let's deselect just those, which key is it again, option or command . . damn! just let go and lost my selection, let's try that again . . . and then drag them to the Animation behaviour . . . instead you just type '_Darker' on the end of the name, hit play, damn! it looks crap, double click the actor, type '_Star' at the end to try the Star version instead, hit play . . . etc.

    That's one of the things I like the most, not having to sift through hundreds of images, just dealing with them by typing their name into the expression, job done. In fact once I drag large image sequences into GS I never need to even look at them again, there's no need to, no need to scroll around the window looking for what I need.

    And if I decide to swap out a 360 frame sequence called "GoldCoin" for a new 180 frame sequence called "NewCoinB", again it's as simple as swapping . .

    "GoldCoin"..(frameNumber/fps)%360

    . . . for . . .

    "NewCoinB"..(frameNumber/fps)%180

    . . . without ever having to venture into the Image pane to wrestle with hundreds of images.

    . . . . . . . . . . . .

    And the second reason is enormous flexibility, well laziness again and flexibility.

    "Why would you use this method" . . I wouldn't ! Being lazy it was quick and simple to just throw 'self.time' in there, it's a lazy person's trick, a quick way of getting a rising value. But if I were doing it properly I would use a slightly different form of the same approach, which is . . .

    "name"..floor(cAngle)%loop

    Ok, in this version I would have a separate controller actor to define the frame number - just a simple blank actor, hidden off-screen or invisible or with dimensions x0, y0 (basically with no size) . . etc.

    This controller actor rotates CCW (numbers rising), a simple Rotate behaviour will do the trick. That's all the controller needs.

    The animation gets its frame number from the controller's angle ('cAngle').

    example: "FlyingBat"..floor(controller'sRotation)%32

    This is where the flexibility comes in . . .

    Want your frames to play at 42fps, simply set the controller to rotate at 42°/sec.

    Want your frames to play at 60fps (the Animate behaviour only goes up to 30fps), simply set the controller to rotate at 60°/sec

    Want your your frames to play at 120fps(!!), simple, set the controller to rotate at 120°/sec, and your animation will play at 60fps, but skip every other frame (which will effectively mean your animation is whizzing along at 120fps) - without you needing to do any extra coding.

    Ok, so we can go a lot faster than the Animate behaviour if we need, and we can even play the animations - effectively - faster than GS's code cycle if we want.

    Want your animation to play backwards, just open up the controller and click on the CW button (instead of the CCW) button - or set the speed to a negative value - and your animation is playing backwards.

    Want a fast rewind effect, stick it on -500°/sec.

    Want your animation to play, but gradually slow to a stop ? Just add a little Angular drag to the controller actor.

    Want your animation to smoothly play forwards and backs and forwards and backwards (and so on), just stick a sine wave into the controller's Rotate speed.

    Or maybe you want the speed of your sequence to change randomly over time, to give it some life, every few seconds change the rotation speed a little with a timer (really simple rules) or have it modulate over time with a sine wave that never goes into the negative (for example 20*sin(X)+60 . . .etc).

    Want to be able to pause your animation ? (let's use a simple mouse button down example), stick the controller's Rotate behaviour into the otherwise section of a mouse button down Rule, job done! (How long would that take to set up using the Animate behaviour, needing to restart the animation when the button is released from the correct frame number ?)

    Want to play exactly to frame number 32, and when the mouse button is down rewind to frame 16, and when it's released play back to frame 32 ?

    Rule- when mouse is down
    --Rotate to angle 16
    Otherwise
    --Rotate to angle 32

    . . . and so on and so on, you can see that when you use the "name_"..(cAngle) approach, and frame numbers become simply the angle of a controller, once difficult animation tasks become really really straightforward . . . once you start to think of the controller actor as a kind of jog wheel for playing your image sequence you'll feel very restricted with the limitations of the Animate behaviour, no speeds above 30, fixed direction, unable to change speed or direction at run time . . . etc etc

    I could go on and on (and I have :smile: ), want your image sequence to get faster and faster and faster as time goes on, simply throw self.time into the Rotate behaviour's speed field, job done . . . .etc etc.

  • IceboxIcebox Posts: 1,413Member, PRO

    Wow .. this method is great and really useful , thanks for taking the time to explain it !

  • SocksSocks London, UK.Posts: 12,711Member
    edited June 27

    Small Fast & Plain (no numbers or symbols) - Full quality PNG image sequence attached below (the full quality PNGs don't have the crappy dithering on the edges like the GIFs do).

  • monkeyboy+simianmonkeyboy simian Posts: 465Member, PRO

    wow.. this stuff is hurting my brain. I think I'll be referring back to this thread in future.. Thanks @Socks..

Sign In or Register to comment.