Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Please read the forum rules before posting.



Check if you are posting in the correct category.



The Off Topic section is not meant for discussing Cookie Clicker.

Making clickables for fun and profit.

ShylightShylight Moderator, Friendly, Helpful, Flagger Posts: 6,452 Mod
So, in case if you didn't know, in the new beta Orteil completely rewrote the way Golden Cookies and Deer work. Aside from much cleaner code, it means that anyone can make a clickable or two without having to hack into the code (as long as you don't want to have an effect like Cookie Storm — that is governed by a different function entirely, since you can't actually have several Golden Cookies spawning at once naturally). So, in this handy tutorial, we'll look at how to make a Kappa shimmer (that's what stuff like this is called nowadays apparently).



So, first things first. Let's talk about what shimmers are. Before they were a collection of disjointed functions, now each is a JSON object contained in Game.shimmerTypes. So, let's talk about what this object has to include for a shimmer to work. That's few functions that are called by the game:

Game.shimmerTypes['kappa'] = { //declaring that our shimmer is called kappa reset:function(){}, //used on reset to clear the persistent variables like progress through Cookie Chain and what cookie effect was chosen last. initFunc:function(me){}, //describes how your shimmer will look and how long it will last updateFunc:function(me){}, //describes how your shimmer will act on screen — i.e. pulasting like GC or prancing like a deer popFunc:function(me){}, //what will happen when your shimmer is popped missFunc:function(me){}, //what will happen if you don't click it in time spawnConditions:function(){}, //in case if you don't want shimmers to spawn under certain conditions spawnsOnTimer:true, //if you want shimmer to be spawned on timer. Otherwise set to false. That would render next three functions unnecessary. getTimeMod:function(m){}, //not strictly necessary, but useful if you want spawning time to be affected by some conditions getMinTime:function(){}, //sets minimal spawning time getMaxTime:function(){}, //sets maximal spawning time spawned:0, //used to track whether there is one of those on screen at the moment time:0, //how long have the game was waiting since the last shimmer disappeared minTime:0, //minimal spawning time maxTime:0, //maximal spawning time

You probably noticed that many functions have "me" as an argument. That allows those functions to interact with variables that we also set up in that declaration. So, shall we look at them a bit closer? Kappa has nothing to reset, so I'll just provide the code for GC as an example in case if you need it:

reset:function() { this.chain=0; this.totalFromChain=0; this.last=''; },

I don't think there's much to comment on here — simply cleaning stuff up. So let's look at something interesting: the initialization.
initFunc:function(me) { if (!this.spawned && Game.chimeType==1 && Game.ascensionMode!=1) PlaySound('snd/chime.mp3'); //set image. Thankfully we can use imgur and stuff. var bgPic='http://i.imgur.com/PYzpcjR.png'; var picX=0;var picY=0; //if your image is a sprite sheet, you can set coordinates for the image if (Game.PARTY) //any amount of conditions may apply to the way things look { //here I check whether the game is in party mode and var n = Math.random() //make several random checks to decide what the shimmer switch (true) //will look like in the party mode { case (n<=0.05): picX=5; //as you might imagine, my image was sprite sheet and I break; //do that by simply adjusting picX variable case (n<=0.2875): picX=4; break; case (n<=0.525): picX=3; break; case (n<=0.7625): picX=2; break; default: picX=1; break; } } //Here we have the load of various CSS options applied to the shimmer. First four lines decide //where exactly it will spawn. Width and height of the shimmer are decided afterwards. //Next two lines set the way it looks. Don't forget to adjust numbers after picX and picY //to match your width and height. Of course, you're free to adjust anything. me.x=Math.floor(Math.random()*Math.max(0,(Game.bounds.right-300)-Game.bounds.left-128)+Game.bounds.left+64)-64; me.y=Math.floor(Math.random()*Math.max(0,Game.bounds.bottom-Game.bounds.top-128)+Game.bounds.top+64)-64; me.l.style.left=me.x+'px'; me.l.style.top=me.y+'px'; me.l.style.width='128px'; me.l.style.height='128px'; me.l.style.backgroundImage='url('+bgPic+')'; me.l.style.backgroundPosition=(-picX*128)+'px '+(-picY*128)+'px'; me.l.style.opacity='0'; me.l.style.display='block'; me.life=1;//the shimmer's current progression through its lifespan (in frames) if (Game.PARTY) {me.dur=2} else {me.dur=26};//duration; the shimmer's lifespan in seconds before it despawns me.life=Math.ceil(Game.fps*me.dur); //remember that life variable we defined before? That's where we actually set it. me.force=''; me.sizeMult=1; },

Next comes update function. It's pretty complicated and mostly contains maths. So I didn't really touch it. Maybe someone with more mathematic minds would have more success in altering stuff like that. If you want to act it like a deer, there's an example in the game code.
updateFunc:function(me) { var curve=1-Math.pow((me.life/(Game.fps*me.dur))*2-1,4); me.l.style.opacity=curve; //this line makes each golden cookie pulse in a unique way me.l.style.transform='rotate('+(Math.sin(me.id*0.69)*24+Math.sin(Game.T*(0.35+Math.sin(me.id*0.97)*0.15)+me.id/*+Math.sin(Game.T*0.07)*2+2*/)*(3+Math.sin(me.id*0.36)*2))+'deg) scale('+(me.sizeMult*(1+Math.sin(me.id*0.53)*0.2)*curve*(1+(0.06+Math.sin(me.id*0.41)*0.05)*(Math.sin(Game.T*(0.25+Math.sin(me.id*0.73)*0.15)+me.id))))+')'; me.life--; //make sure it's lifetime is counting down. Don't want for it to sit around forever. Unless, of course, you do. if (me.life<=0) {this.missFunc(me);me.die();} //This one is important. It actually removes the shimmer after its time has run its course },
Pop function… Anything can happen in that. Want to spawn all them wrinklers? You can do that. Want to inverse your CpS for 30 minutes? Can do.
popFunc:function(me) { //I just check if the game is in party mode, clear it if it is and set it if it isn't. var popup = '' if (Game.PARTY) { Game.PARTY = false Game.l.style.filter=''; Game.l.style.webkitFilter=''; Game.l.style.transform=''; popup="Calm your tits" } else { Game.PARTY = true popup="Party time!" } Game.Popup(popup,me.x+me.l.offsetWidth/2,me.y); //this spawns the neat popup. You can do some neat stuff with that rather than just pass simple strings here me.die(); },
Miss function only comes into play if something has to happen when a player has missed your wonderful shimmer. Punish them if you wish. Here's a GC as an example if you're interested once more.
missFunc:function(me) { if (this.chain>0 && this.totalFromChain>0) { Game.Popup('Cookie chain broken.<div style="font-size:65%;">You made '+Beautify(this.totalFromChain)+' cookies.</div>',me.x+me.l.offsetWidth/2,me.y); this.chain=0;this.totalFromChain=0; } if (me.spawnLead) Game.missedGoldenClicks++; },
SparklebuttimagePurplesmart

Comments

  • ShylightShylight Moderator, Friendly, Helpful, Flagger Posts: 6,452 Mod
    edited April 2016
    Spawn conditions… You might want things to spawn only under certain conditions. "return true" should suffice otherwise. Another GC example.
    spawnConditions:function() { if (!Game.Has('Golden switch [off]')) return true; else return false; },
    And, finally, timers. Nothing much to say about them. Don't forget that Game.fps is one second. So multiply timers accordingly. I just use that to ensure that stuff is spawning constantly in the Party mode.
    getTimeMod:function(m) { if (Game.PARTY) {return 0} else {return Math.ceil(Game.fps*60*m)}; }, getMinTime:function() { var m=5; return this.getTimeMod(m); }, getMaxTime:function() { var m=15; return this.getTimeMod(m); },

    That's all that is necessary to start tweaking stuff on your own if you're into that. Or just copy the code to have your own kappa party.
    Game.shimmerTypes['kappa'] = { reset:function(){}, initFunc:function(me) { if (!this.spawned && Game.chimeType==1 && Game.ascensionMode!=1) PlaySound('snd/chime.mp3'); //set image var bgPic='http://i.imgur.com/PYzpcjR.png'; var picX=0;var picY=0; if (Game.PARTY) { var n = Math.random() switch (true) { case (n<=0.05): picX=5; break; case (n<=0.2875): picX=4; break; case (n<=0.525): picX=3; break; case (n<=0.7625): picX=2; break; default: picX=1; break; } } me.x=Math.floor(Math.random()*Math.max(0,(Game.bounds.right-300)-Game.bounds.left-128)+Game.bounds.left+64)-64; me.y=Math.floor(Math.random()*Math.max(0,Game.bounds.bottom-Game.bounds.top-128)+Game.bounds.top+64)-64; me.l.style.left=me.x+'px'; me.l.style.top=me.y+'px'; me.l.style.width='128px'; me.l.style.height='128px'; me.l.style.backgroundImage='url('+bgPic+')'; me.l.style.backgroundPosition=(-picX*128)+'px '+(-picY*128)+'px'; me.l.style.opacity='0'; me.l.style.display='block'; me.life=1;//the cookie's current progression through its lifespan (in frames) if (Game.PARTY) {me.dur=2} else {me.dur=26};//duration; the cookie's lifespan in seconds before it despawns me.life=Math.ceil(Game.fps*me.dur); me.force=''; me.sizeMult=1; }, updateFunc:function(me) { var curve=1-Math.pow((me.life/(Game.fps*me.dur))*2-1,4); me.l.style.opacity=curve; //this line makes each golden cookie pulse in a unique way me.l.style.transform='rotate('+(Math.sin(me.id*0.69)*24+Math.sin(Game.T*(0.35+Math.sin(me.id*0.97)*0.15)+me.id/*+Math.sin(Game.T*0.07)*2+2*/)*(3+Math.sin(me.id*0.36)*2))+'deg) scale('+(me.sizeMult*(1+Math.sin(me.id*0.53)*0.2)*curve*(1+(0.06+Math.sin(me.id*0.41)*0.05)*(Math.sin(Game.T*(0.25+Math.sin(me.id*0.73)*0.15)+me.id))))+')'; me.life--; if (me.life<=0) {this.missFunc(me);me.die();} }, popFunc:function(me) { if (Game.PARTY) { Game.PARTY = false Game.l.style.filter=''; Game.l.style.webkitFilter=''; Game.l.style.transform=''; } else { Game.PARTY = true } me.die(); }, missFunc:function(me){}, spawnsOnTimer:true, spawnConditions:function() { return true }, spawned:0, time:0, minTime:0, maxTime:0, getTimeMod:function(m) { if (Game.PARTY) {return 0} else {return Math.ceil(Game.fps*60*m)}; }, getMinTime:function() { var m=5; return this.getTimeMod(m); }, getMaxTime:function() { var m=15; return this.getTimeMod(m); }, }
    SparklebuttimagePurplesmart
  • TrevinMacielTrevinMaciel Member Posts: 1,017
    So, how do can I make a custom building?
    "Dude, I'm pretty sure you can't just quote yourself." "After this game is finished we will celebrate... by starting a "Count to 25,000 starting from 10,000" thread!" -Brainstorm
    "You're gonna have a bad time." -Running In Reverse "http://i.imgur.com/2jStH32.png" -Cookie
Sign In or Register to comment.