Example: main.pwn
1// This PAWN script is generated by WOWCube SDK project wizard23#define G2D45#pragma warning disable 2036#pragma warning disable 2137#pragma warning disable 22989// Includes10// -----------------------------11#include "wowcore.inc"12#include "topology.inc"13#include "graphics.inc"14#include "fixed.inc"15#include "motion_sensor.inc"16#include "math.inc"17#include "log.inc"18#include "string.inc"19#include "random.inc"2021// Application defines22// -----------------------------23#define DISPLAY_CENTER_X 12024#define DISPLAY_CENTER_Y 1202526#define SCREEN_WIDTH 24027#define SCREEN_HEIGHT 2402829#define NUM_MAGNETS 430#define PARTICLES_PER_MAGNET 1531#define MAGNETIC_FORCE_THRESHOLD 3003233// Application constants34// ------------------------------35new const Colors[.white, .black, .red, .green, .blue, .marsh] =36[37 0xFFFFFFFF,38 0xFF000000,39 0xFFFF0000,40 0xFF00FF00,41 0xFF0000FF,42 0xFF161D2443];4445// Global variables and constants46// ----------------------------4748//array of attractors ("magnets")49new Fixed:magnets[NUM_MAGNETS][Fixed:.x,Fixed:.y,Fixed:.size,Fixed:.orbit];50new numMagnets = 0;51new magnetsShift = 0;5253//array of particles54new Fixed:particles[NUM_MAGNETS*PARTICLES_PER_MAGNET][Fixed:.x,Fixed:.y,Fixed:.shx,Fixed:.shy,Fixed:.angle,Fixed:.size,Fixed:.speed,Fixed:.force,.magnet,Fixed:.orbit];55new numParticles = 0;565758// WOWCube application callbacks59// -----------------------------6061//Applicaton initialization callback. Called once when CUB application starts62public ON_Init(id, size, const pkt[])63{64 LOG_i("\n");65 LOG_i("*** WOWCube SDK Example \"Simple Shapes - Circles\" ***\n\n");6667 //create 4 attractors68 createMagnet(40,40);69 createMagnet(50,180);70 createMagnet(150,80);71 createMagnet(120,120);7273 LOG_i("Done.\n");74}7576//Saved application state data load callback. Gets called in response to loadState() function call77public ON_Load(id, size, const pkt[])78{79}8081//Main run loop callback. Gets called recurrently by the CUB application as frequent as application code allows.82public ON_Tick()83{84}8586//This callback is gets called immediately after ON_Tick(). Use it for calling your rendering code.87public ON_Render()88{89 for(new screenNumber = 0; screenNumber<3; screenNumber++)90 {91 GFX_setRenderTarget(screenNumber);92 GFX_clear(Colors.marsh);9394 //Render particles95 renderParticles();9697 GFX_render();98 }99}100101//The "physics" callback. Gets called recurrently with 30ms resolution.102public ON_PhysicsTick()103{104 //Slowly change positions of attractors105 moveMagnets();106}107108//The "inner network" callback. Gets called when WOWCube module receives a data packet from other module109public ON_Packet(type, size, const pkt[])110{111}112113//The cube topology change callback. Gets called when cube is twisted and its topological desctiption has been changed114public ON_Twist(twist[TOPOLOGY_TWIST_INFO])115{116 if (SELF_ID == 0)117 {118 }119 else120 {121 }122}123124//Device shake detection callback.125public ON_Shake(const count)126{127}128129//Screen tap callback.130public ON_Tap(const count, const display, const bool:opposite)131{132 if (SELF_ID == 0)133 {134 }135 else136 {137 }138}139140//Application quit callback.141public ON_Quit()142{143 //144 //Save game data here145 //146}147148// Functions149//----------------150151//Returns the squared length of a distance vector between two points152distanceSquared(Fixed:x1,Fixed:y1,Fixed:x2,Fixed:y2)153{154 return (x2-x1)*(x2-x1)+(y2-y1)*(y2-y1);155}156157//Initializes particle arrays for given attractor158createParticles(Fixed:x,Fixed:y, magnet)159{160 for(new i=0;i<PARTICLES_PER_MAGNET;i++)161 {162 new Fixed:r1 = fixed(RND_randomize(0,100))/100.0;163 new Fixed:r2 = fixed(RND_randomize(0,100))/100.0;164165 particles[numParticles].x = x;166 particles[numParticles].y = y;167 particles[numParticles].shx = x;168 particles[numParticles].shy = y;169170 particles[numParticles].angle = 0;171 particles[numParticles].size = 0+r1*6.5;172 particles[numParticles].speed = (0.001 + ((particles[numParticles].size+1)/40.0)*0.015);173 particles[numParticles].force = 0.98 - r2*0.15;174 particles[numParticles].orbit = 1.0;175176 particles[numParticles].magnet = magnet;177178 numParticles++;179 }180}181182//Creates an attractor at given coordinates183createMagnet(Fixed:x,Fixed:y)184{185 if(numMagnets<NUM_MAGNETS)186 {187 magnets[numMagnets].x = x;188 magnets[numMagnets].y = y;189 magnets[numMagnets].orbit = 100.0;190 magnets[numMagnets].size = 1.0;191192 createParticles(x,y,numMagnets);193194 numMagnets++;195 }196}197198//Animates attractor positions199moveMagnets()200{201 new Fixed:fSin = fixed(FixedSin( magnetsShift))/256.0;202203 for(new i=0;i<numMagnets;i++)204 {205 magnets[i].x+=fixed(FixedSin( magnetsShift*(i+1)))/512.0;206 }207 magnetsShift++;208 if(magnetsShift>360) magnetsShift=0;209}210211//Handles particle system and renders particles with circles212renderParticles()213{214 new position[GFX_POINT];215216 for(new i=0;i<numParticles;i++)217 {218 new Fixed:currentDistance = -1;219 new Fixed:closestDistance = -1;220 new closestMagnet = -1;221222 // Attraction force vector223 new force[Fixed:.x,Fixed:.y];224 force.x = 0;225 force.y = 0;226227 // Figure out the most influential attractor for a particle and calculate attraction force228 for(new j=0;j<numMagnets;j++)229 {230 currentDistance = distanceSquared(particles[i].x,particles[i].y,magnets[j].x,magnets[j].y) - magnets[j].orbit*magnets[j].orbit;231232 if(particles[i].magnet!=j)233 {234 new Fixed:fx = magnets[j].x - particles[i].x;235236 if( fx > -MAGNETIC_FORCE_THRESHOLD && fx < MAGNETIC_FORCE_THRESHOLD )237 {238 force.x += fx / MAGNETIC_FORCE_THRESHOLD;239 }240241 new Fixed:fy = magnets[j].y - particles[i].y;242 if( fy > -MAGNETIC_FORCE_THRESHOLD && fy < MAGNETIC_FORCE_THRESHOLD )243 {244 force.y += fy / MAGNETIC_FORCE_THRESHOLD;245 }246247 }248249 if( closestMagnet == -1 || currentDistance < closestDistance )250 {251 closestDistance = currentDistance;252 closestMagnet = j;253 }254255 }256257 if( particles[i].magnet == -1 || particles[i].magnet != closestMagnet )258 {259 particles[i].magnet = closestMagnet;260 }261262 // Spin the particle263 particles[i].angle += particles[i].speed*0.5;264265 // Translate the particle towards the magnet position266 particles[i].shx += ( (magnets[closestMagnet].x+(force.x*4)) - particles[i].shx) * particles[i].speed*0.5;267 particles[i].shy += ( (magnets[closestMagnet].y+(force.y*4)) - particles[i].shy) * particles[i].speed*0.5;268269 new Fixed:fSin = fixed(FixedSin(i+particles[i].angle))/256.0;270 new Fixed:fCos = fixed(FixedCos(i+particles[i].angle))/256.0;271272 // Apply integral change to the particle's position273 particles[i].x = particles[i].shx + fSin * (particles[i].orbit*particles[i].force);274 particles[i].y = particles[i].shy + fCos * (particles[i].orbit*particles[i].force);275276 // Slowly inherit the cloest magnets orbit277 particles[i].orbit += ( magnets[closestMagnet].orbit - particles[i].orbit )* 0.1;278279 // Change particle color280 new color = fint(255.0/(particles[i].size+1));281282 // Draw particle283284 position.x = fint(particles[i].x);285 position.y = fint(particles[i].y);286287 GFX_drawSolidCircle(position, fint(particles[i].size)*3, GFX_fromARGB8888(255,color, color*0.8, color*0.9));288 }289}