Simulator experiments

Thanks @adekto. Find out there’s already PICO8 palette definition ready to use.

#include "pokitto.h"
#include "math.h"
Pokitto::Core game;

//110x88
const int S=16;
const int S2=S/2;
int cx,cy=0;

void pir(int x,int y,int w,int h,int cx,int cy)
{
  game.display.color=C_WHITE;
  game.display.fillTriangle(x,y,w/2+cx,h/2+cy,x+w,y);
  game.display.color=C_LIGHTGRAY;
  game.display.fillTriangle(x+w,y,w/2+cx,h/2+cy,x+w,y+h);
  game.display.color=C_BLUE;
  game.display.fillTriangle(x,y,w/2+cx,h/2+cy,x,y+h);
  game.display.color=C_DARKBLUE;
  game.display.fillTriangle(x,y+h,w/2+cx,h/2+cy,x+w,y+h);
}

int main () {
//Load pico 8 palette
game.display.load565Palette(def565palette);
//Start game
game.begin();
while (game.isRunning()) {
    if (game.update()) {

        for (int x=0;x<game.display.width;x+=S)
        {
            for (int y=0;y<game.display.height;y+=S)
            {
                cx=S2*sin(game.frameCount/300.0*(1+x+y));
                cy=S2*cos(game.frameCount/300.0*(1+x+y));
                pir(x,y,S,S,x+cx,y+cy);
            }
        }
    }
}
return 1;
}

2 Likes

you have to include your image its prety trippy

#include "pokitto.h"
Pokitto::Core game;
const unsigned short pallet[]={
0xf800, 0xf80c, 0xf81c, 0xd01f,
0x681f, 0x101f, 0x1ff, 0x5bf,
0x7fe, 0x7f3, 0x7e6, 0x17e0,
0x77e0, 0xe7e0, 0xfea0, 0xfae0,
};
int main () {
game.begin();

game.display.load565Palette(pallet);
while (game.isRunning()) {
    if (game.update()) {
        game.display.rotatePalette(1);
        game.display.drawBitmap(0,0,sprite);
    }
}
return 1;
}
5 Likes

Is there a way to export gif directly from simulator?

Yes there is. I will write instructions for you all after 2 hours when I get back home (at a car show)

1 Like

That is so damn cool.

  1. #define SCREENCAPTURE 1 in POKITO_SIM\PokitoSimulator.h
  2. Create a Folder in c:\screencap
  3. Copy ffmpeg.exe there
  4. Run Pokitto Sim
  5. Close the Sim and hit Y in the console

You have an output.mp4 in c:\screencap

2 Likes

Thanks! You figured it out!

1 Like

Thank you @jonne to point out, the solution was already there.
Now I’m making some test to export also animated gif format, but the frame rate seems not being respected.
Cheers

Can someone have a look at this? I can’t seem to create/load a palette, nor can I get the palette to rotate.
What step am I missing here?

#include "pokitto.h"

Pokitto::Core game;

unsigned short pal[256];
char buff[220*174];

int PntClr(int x, int y){
	return buff[x+game.display.width*y];
}
void Dot (int x, int y, int c){
    // create a buffer for the screen image
	buff[x+game.display.width*y]=c;
}

int RandMinMax(int min, int max){
    return rand() % max + min;
}

int Adjust (int xa, int ya, int x, int y, int xb, int yb){
	if(PntClr(x, y) != 0) return 0;
	int q = abs(xa - xb) + abs(ya - yb);
	int v = (PntClr(xa, ya) + PntClr(xb, yb)) / 2 + (RandMinMax(0,q*10)) / 10;
	if (v < 1) v = 1;
	if (v > 255) v = 255;
	Dot(x, y, v);
	return 1;
}

void SubDivide (int x1, int y1, int x2, int y2){
	if ((x2 - x1 < 2) && (y2 - y1 < 2)) return;
	int x = (x1 + x2) / 2;
	int y = (y1 + y2) / 2;
	Adjust(x1, y1, x, y1, x2, y1);
	Adjust(x1, y2, x, y2, x2, y2);
	Adjust(x2, y1, x2, y, x2, y2);
	Adjust(x1, y1, x1, y, x1, y2);
	if(PntClr(x, y) == 0)	{
		int v = PntClr(x1, y1) + PntClr(x2, y1) + PntClr(x2, y2);
		v = v + PntClr(x1, y2) + PntClr(x1, y) + PntClr(x, y1);
		v = v + PntClr(x2, y) + PntClr(x, y2);
		v = v / 8;
		Dot(x, y, v);
	}
	SubDivide(x1, y1, x, y);
	SubDivide(x, y, x2, y2);
	SubDivide(x, y1, x2, y);
	SubDivide(x1, y, x, y2);
}

void make_plasma(void){
	int i=0;
	for(i=0; i<game.display.width*game.display.height; i++)	{
		buff[i]=0;
	}
	srand(1890462285);
	Dot(0, 0, RandMinMax(0,255) + 1);
	Dot(game.display.width-1, 0, RandMinMax(0,255) + 1);
	Dot(game.display.width-1, game.display.height-1, RandMinMax(0,255) + 1);
	Dot(0, game.display.height-1, RandMinMax(0,255) + 1);
	SubDivide(0, 0, game.display.width-1, game.display.height-1);
}

void make_pal(void){
	int a,s,r,g,b;
	for(a=0; a<=63; a++){
		s = 0; 	r = a; 		g = 63-a;	b = 0;		pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 64; r = 63-a;	g = 0;		b = a; 		pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 128; r = 0;	 	g = 0;		b = 63-a;	pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 192; r = 0;		g = a;		b = 0;	 	pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
	}
    game.display.load565Palette(&pal[0]);
}

int main(){
	game.begin();
	game.display.setColorDepth(8); // is this needed in the simulator?
	game.display.width = 220; // full size
	game.display.height = 174;
	game.setFrameRate(30); // doesn't matter what this is, speed isn't an issue with this demo
	make_pal();
    make_plasma();

	while (game.isRunning()) {
        game.display.rotatePalette(1);
        for(int y=0; y<game.display.height; y++){
            for(int x=0; x<game.display.width; x++){
                game.display.directPixel(x,y,buff[x+220*y]);
            }
        }
	}
	return 1;
}
1 Like

as far as i understand the pallet array will only be using the first 16 colors
also try game.display.load565Palette(pal);

I’m still trying to figure this stuff out myself, but these are my observations:

  1. As far as I know, in the current version of the emulator, only the fast mode (110 by 88) is guaranteed to work.

  2. It looks like the display.directPixel function writes a pixel to the screen without going through the pixel logic. Use display.drawPixel instead.

  3. It appears that you need the " if (game.update()) { " check if you are doing graphics updates.

This version appears to work (but it is very green…)

#include "pokitto.h"
Pokitto::Core game;
unsigned short pal[256];
char buff[220*174];
int PntClr(int x, int y){
	return buff[x+game.display.width*y];
}
void Dot (int x, int y, int c){
    // create a buffer for the screen image
	buff[x+game.display.width*y]=c;
}
int RandMinMax(int min, int max){
    return rand() % max + min;
}
int Adjust (int xa, int ya, int x, int y, int xb, int yb){
	if(PntClr(x, y) != 0) return 0;
	int q = abs(xa - xb) + abs(ya - yb);
	int v = (PntClr(xa, ya) + PntClr(xb, yb)) / 2 + (RandMinMax(0,q*10)) / 10;
	if (v < 1) v = 1;
	if (v > 255) v = 255;
	Dot(x, y, v);
	return 1;
}
void SubDivide (int x1, int y1, int x2, int y2){
	if ((x2 - x1 < 2) && (y2 - y1 < 2)) return;
	int x = (x1 + x2) / 2;
	int y = (y1 + y2) / 2;
	Adjust(x1, y1, x, y1, x2, y1);
	Adjust(x1, y2, x, y2, x2, y2);
	Adjust(x2, y1, x2, y, x2, y2);
	Adjust(x1, y1, x1, y, x1, y2);
	if(PntClr(x, y) == 0)	{
		int v = PntClr(x1, y1) + PntClr(x2, y1) + PntClr(x2, y2);
		v = v + PntClr(x1, y2) + PntClr(x1, y) + PntClr(x, y1);
		v = v + PntClr(x2, y) + PntClr(x, y2);
		v = v / 8;
		Dot(x, y, v);
	}
	SubDivide(x1, y1, x, y);
	SubDivide(x, y, x2, y2);
	SubDivide(x, y1, x2, y);
	SubDivide(x1, y, x, y2);
}
void make_plasma(void){
	int i=0;
	for(i=0; i<game.display.width*game.display.height; i++)	{
		buff[i]=0;
	}
	srand(1890462285);
	Dot(0, 0, RandMinMax(0,255) + 1);
	Dot(game.display.width-1, 0, RandMinMax(0,255) + 1);
	Dot(game.display.width-1, game.display.height-1, RandMinMax(0,255) + 1);
	Dot(0, game.display.height-1, RandMinMax(0,255) + 1);
	SubDivide(0, 0, game.display.width-1, game.display.height-1);
}
void make_pal(void){
	int a,s,r,g,b;
	for(a=0; a<=63; a++){
		s = 0; 	r = a; 		g = 63-a;	b = 0;		pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 64; r = 63-a;	g = 0;		b = a; 		pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 128; r = 0;	 	g = 0;		b = 63-a;	pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 192; r = 0;		g = a;		b = 0;	 	pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
	}
    game.display.load565Palette(&pal[0]);
}
int main(){
	game.begin();
	game.display.setColorDepth(8); // is this needed in the simulator?
	game.display.width = 110; // full size
	game.display.height = 88;
	game.setFrameRate(30); // doesn't matter what this is, speed isn't an issue with this demo
	make_pal();
    make_plasma();
    while (game.isRunning()) {
            if (game.update()) {
    game.display.rotatePalette(1);
    for(int y=0; y<game.display.height; y++){
        for(int x=0; x<game.display.width; x++){
            //game.display.directPixel(x,y,buff[x+220*y]);
            game.display.drawPixel(x,y,buff[x+110*y]);
        }
    }
            }
}
return 1;
}

Catsfolly

1 Like

I hacked the palette logic to limit it to the first 16 colors.

Here is the modified version:

#include "pokitto.h"
Pokitto::Core game;
unsigned short pal[256];
char buff[220*174];
int PntClr(int x, int y){
	return buff[x+game.display.width*y];
}
void Dot (int x, int y, int c){
    // create a buffer for the screen image
	buff[x+game.display.width*y]=c;
}
int RandMinMax(int min, int max){
    return rand() % max + min;
}
int Adjust (int xa, int ya, int x, int y, int xb, int yb){
	if(PntClr(x, y) != 0) return 0;
	int q = abs(xa - xb) + abs(ya - yb);
	int v = (PntClr(xa, ya) + PntClr(xb, yb)) / 2 + (RandMinMax(0,q*10)) / 10;
	if (v < 1) v = 1;
	if (v > 255) v = 255;
	Dot(x, y, v);
	return 1;
}
void SubDivide (int x1, int y1, int x2, int y2){
	if ((x2 - x1 < 2) && (y2 - y1 < 2)) return;
	int x = (x1 + x2) / 2;
	int y = (y1 + y2) / 2;
	Adjust(x1, y1, x, y1, x2, y1);
	Adjust(x1, y2, x, y2, x2, y2);
	Adjust(x2, y1, x2, y, x2, y2);
	Adjust(x1, y1, x1, y, x1, y2);
	if(PntClr(x, y) == 0)	{
		int v = PntClr(x1, y1) + PntClr(x2, y1) + PntClr(x2, y2);
		v = v + PntClr(x1, y2) + PntClr(x1, y) + PntClr(x, y1);
		v = v + PntClr(x2, y) + PntClr(x, y2);
		v = v / 8;
		Dot(x, y, v);
	}
	SubDivide(x1, y1, x, y);
	SubDivide(x, y, x2, y2);
	SubDivide(x, y1, x2, y);
	SubDivide(x1, y, x, y2);
}
void make_plasma(void){
	int i=0;
	for(i=0; i<game.display.width*game.display.height; i++)	{
		buff[i]=0;
	}
	srand(1890462285);
	Dot(0, 0, RandMinMax(0,255) + 1);
	Dot(game.display.width-1, 0, RandMinMax(0,255) + 1);
	Dot(game.display.width-1, game.display.height-1, RandMinMax(0,255) + 1);
	Dot(0, game.display.height-1, RandMinMax(0,255) + 1);
	SubDivide(0, 0, game.display.width-1, game.display.height-1);
}
void make_pal(void){
	int a,s,r,g,b;
	for(a=0; a<=3; a++){
		s = 0; 	r = a * 3; 		g = 48-(a * 3);	b = 0;		pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 4; r = 48-(a * 3);	g = 0;		b = (a * 3); 	pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 8; r = 0;	 	g = 0;		b = 48-(s * 3);	    pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
		s = 12; r = 0;		g = (a * 3);		b = 0;	 	pal[a+s] = game.display.RGBto565(r*4,g*4,b*4);
	}
    game.display.load565Palette(&pal[0]);
}
int main(){
	game.begin();
	game.display.setColorDepth(8); // is this needed in the simulator?
	game.display.width = 110; // full size
	game.display.height = 88;
	game.setFrameRate(30); // doesn't matter what this is, speed isn't an issue with this demo
	make_pal();
    make_plasma();
    while (game.isRunning()) {
            if (game.update()) {
    game.display.rotatePalette(1);
    for(int y=0; y<game.display.height; y++){
        for(int x=0; x<game.display.width; x++){
            //game.display.directPixel(x,y,buff[x+220*y]);
            game.display.drawPixel(x,y,buff[x+110*y]);
        }
    }
            }
}
return 1;
}

Catsfolly

2 Likes

Really cool stuff!!!

snaking experiment, single button , not real interaction
trying to fiddle with some delta time like stuff

#include "pokitto.h"
#include "math.h"
struct{
    float x;
    float y;
    float r;
    Uint16 speed;
    bool direction;
}snake;
short trail[16][2];
Pokitto::Core game;
int main () {
game.begin();
snake.x = 55;
snake.y = 44;
snake.r = 5;
snake.direction = true;
snake.speed = 300;
float camX = -snake.x;
float camY = -snake.y;
float t = 0.1;
int dt;
int elapse;
while (game.isRunning()) {
    if(game.buttons.pressed(BTN_A)) snake.direction = !snake.direction;
    if (game.update()) {

        dt = game.getTime()-elapse;
        elapse = game.getTime();

        if(snake.direction) t+=((float)dt)/snake.speed ;
        else t-=((float)dt)/snake.speed ;
        snake.x += cos(t)*snake.r;
        snake.y += sin(t)*snake.r;

        //game.display.print();
        camX = -snake.x +55;
        camY = -snake.y +44;
        game.display.fillCircle(snake.x+camX,snake.y+camY,2);
        trail[15][0] = snake.x;
        trail[15][1] = snake.y;
        for(int i =0; i<15; i++){
            trail[i][0] = trail[i+1][0];
            trail[i][1] = trail[i+1][1];
            game.display.fillCircle(trail[i][0]+camX ,trail[i][1]+camY,i/3);
        }
        for(int x =0; x<15; x++){
             for(int y =0; y<15; y++){
                    game.display.drawRect(x*16+camX,y*16+camY,x,y);
             }
        }
    }

}

return 1;
}
2 Likes

Quick test with particles:

#include "pokitto.h"
#include "math.h"
Pokitto::Core game;

//110x88
unsigned char xp=55;
signed char xo=0;
unsigned char yp=80;

unsigned char partIndx=0;
struct Particle {
   float x;
   float y;
   float dx;
   float dy;
   float life=9999;
} ;
const unsigned MAX_PART=200;
static Particle particles[MAX_PART];

static unsigned char PAL_FILE[5]={C_YELLOW,C_ORANGE,C_RED,C_BROWN,C_DARKGRAY};

void addParticle(unsigned char x,unsigned char y)
{
    particles[partIndx].x=x;
    particles[partIndx].y=y;
    particles[partIndx].dx=random(-100,100)/300.0;
    particles[partIndx].dy=random(-100,-80)/80.0;
    particles[partIndx].life=0;
    partIndx++;
    if (partIndx>MAX_PART) {partIndx=0;}
}

void renderParticles()
{
    for (int i=0;i<MAX_PART;i++)
        {
            if(particles[i].life<50)
            {
                particles[i].life++;
                game.display.color=PAL_FILE[(int)particles[i].life/10];

                particles[i].x+=particles[i].dx;
                particles[i].y+=particles[i].dy;

                float radius= particles[i].life/10;
                game.display.fillCircle(particles[i].x,particles[i].y,radius);
                if(particles[i].life>10){
                    game.display.color=C_BLACK;
                    game.display.drawCircle(particles[i].x,particles[i].y,radius);
                }
            }
        }
}

int main () {
game.begin();
game.display.load565Palette(def565palette);
while (game.isRunning()) {
    if (game.update()) {

        if (game.upBtn()) {yp-=2;}
        if (game.downBtn()) {yp+=2;}
        if (game.rightBtn()) {xp+=2;}
        if (game.leftBtn()) {xp-=2;}

        //Particles
        renderParticles();

        //Cursor
        game.display.color=C_RED;
        xo=-15*sin(game.frameCount/10.0);
        addParticle(xp+xo,yp);
        addParticle(xp+xo,yp);
        addParticle(xp+xo,yp);
        game.display.drawCircle((xp+xo),yp,2);

        //Cross
        game.display.drawLine(xp-1,yp,xp+1,yp);
        game.display.drawLine(xp,yp-1,xp,yp+1);
    }
}
return 1;
}


5 Likes

Excellent work! Note to self: add particles to lib.

back again with a little bit of broken code…

It will run fine in the simulator as it is, but if you uncomment the second part of the draw routine it will crash.

It’s supposed to be this - https://www.khanacademy.org/computer-programming/Metaballs!/6209526669246464

#include "pokitto.h"
Pokitto::Core game;

int width=110;
int height=88;

int PX_SIZE = 3;
int PY_SIZE = PX_SIZE;
int SUM_THRESHOLD = 10;
const int NUM_CIRCLES = 8;

struct circle{
    int x;
    int y;
    int r;
    int vx;
    int vy;
};
static circle c[NUM_CIRCLES];

int RandMinMax(int min, int max){
    return rand() % max + min;
}

void draw_circles(){

    for (int i = 0; i < NUM_CIRCLES; i++) {

        c[i].x += c[i].vx;
        c[i].y += c[i].vy;

        if (c[i].x - c[i].r < 0) {
            c[i].vx = +abs(c[i].vx);
        }
        if (c[i].x + c[i].r > width) {
            c[i].vx = -abs(c[i].vx);
        }
        if (c[i].y - c[i].r < 0) {
            c[i].vy = +abs(c[i].vy);
        }
        if (c[i].y + c[i].r > height) {
            c[i].vy = -abs(c[i].vy);
        }

        game.display.color = i;
        game.display.drawCircle(c[i].x,c[i].y,c[i].r);

    }

/*
    for (int x = 0; x < width; x += PX_SIZE) {
        for (int y = 0; y < height; y += PY_SIZE) {
            int sum = 0;
            int closestD2 = 9999999;
            int closestColor = 0;
            for (int i = 0; i < NUM_CIRCLES; i++) {
                int dx = x - c[i].x;
                int dy = y - c[i].y;
                int d2 = dx * dx + dy * dy;
                sum += c[i].r * c[i].r / d2;

                if (d2 < closestD2) {
                    closestD2 = d2;
                    closestColor = 1;//[c.red, c.green, c.blue];
                }
            }
            if (sum > SUM_THRESHOLD) {
                game.display.color = closestColor;
                game.display.fillRectangle(x, y, PX_SIZE, PY_SIZE);
            }
        }
    }
*/

}

int main(){

    srand(game.getTime());
    for (int i = 0; i < NUM_CIRCLES; i++) {
        c[i].x = RandMinMax(0,width);
        c[i].y = RandMinMax(0,height);
        c[i].r = RandMinMax(5, 10);
        c[i].vx = RandMinMax(-2,2);
        c[i].vy = RandMinMax(-2,2);
    }



	game.begin();
	game.display.width = width; // full size
	game.display.height = height;
    game.setFrameRate(60);
    game.display.load565Palette(def565palette);

	while (game.isRunning()) {
        if (game.update()) {
            //game.display.drawPixel(x,y,pixel/16);
            draw_circles();
        }
}
return 1;
}

I think you are dividing by zero.

If you replace the line:

sum += c[i].r * c[i].r / d2;

with:

if (d2 != 0) sum += c[i].r * c[i].r / d2;

then it stops the crashing. But the result is not pretty.
The code is summing up fractional items, which doesn’t work well with integers.

Catsfolly

Spinal -

This version kinda works!

I multiplied the fractional things by 16 to make them integers.
And I got rid of the color zero circle by adding 1 to the circle index.

#include "pokitto.h"
Pokitto::Core game;
int width=110;
int height=88;
int PX_SIZE = 3;
int PY_SIZE = PX_SIZE;
int SUM_THRESHOLD = 10;
const int NUM_CIRCLES = 8;
struct circle{
    int x;
    int y;
    int r;
    int vx;
    int vy;
};
static circle c[NUM_CIRCLES];
int RandMinMax(int min, int max){
    return rand() % max + min;
}
void draw_circles(){
    for (int i = 0; i < NUM_CIRCLES; i++) {

    c[i].x += c[i].vx;
    c[i].y += c[i].vy;

    if (c[i].x - c[i].r < 0) {
        c[i].vx = +abs(c[i].vx);
    }
    if (c[i].x + c[i].r > width) {
        c[i].vx = -abs(c[i].vx);
    }
    if (c[i].y - c[i].r < 0) {
        c[i].vy = +abs(c[i].vy);
    }
    if (c[i].y + c[i].r > height) {
        c[i].vy = -abs(c[i].vy);
    }

    game.display.color = i+1;
    game.display.drawCircle(c[i].x,c[i].y,c[i].r);

}
// was commented out
    for (int x = 0; x < width; x += PX_SIZE) {
        for (int y = 0; y < height; y += PY_SIZE) {
            int sum = 0;
            int closestD2 = 32767;
            int closestColor = 0;
            for (int i = 0; i < NUM_CIRCLES; i++) {
                int dx = x - c[i].x;
                int dy = y - c[i].y;
                int d2 = dx * dx + dy * dy;
                if (d2 != 0) sum += ((c[i].r * c[i].r) * 16) / d2;
                if (d2 < closestD2) {
                closestD2 = d2;
                closestColor = i+1;//[c.red, c.green, c.blue];
            }
        }
        if (sum > SUM_THRESHOLD) {
            game.display.color = closestColor;
            game.display.fillRectangle(x, y, PX_SIZE, PY_SIZE);
        }
    }
}
// end commented out
}
int main(){
    srand(game.getTime());
for (int i = 0; i < NUM_CIRCLES; i++) {
    c[i].x = RandMinMax(0,width);
    c[i].y = RandMinMax(0,height);
    c[i].r = RandMinMax(5, 10);
    c[i].vx = RandMinMax(-2,2);
    c[i].vy = RandMinMax(-2,2);
}



game.begin();
game.display.width = width; // full size
game.display.height = height;
game.setFrameRate(60);
game.display.load565Palette(def565palette);

while (game.isRunning()) {
    if (game.update()) {
        //game.display.drawPixel(x,y,pixel/16);
        draw_circles();
    }
}
return 1;
}

Nice effect!

Catsfolly

Smoothed it a little…

#include "pokitto.h"
Pokitto::Core game;
int width=110;
int height=88;

int PX_SIZE = 1;
int PY_SIZE = PX_SIZE;
int SUM_THRESHOLD = 64;
const int NUM_CIRCLES = 6;
struct circle{
    int x;
    int y;
    int r;
    int vx;
    int vy;
};
static circle c[NUM_CIRCLES];
int RandMinMax(int min, int max){
    return rand() % max + min;
}
void draw_circles(){
    for (int i = 0; i < NUM_CIRCLES; i++) {

    c[i].x += c[i].vx;
    c[i].y += c[i].vy;

    if (c[i].x - c[i].r < 0) {
        c[i].vx = +abs(c[i].vx);
    }
    if (c[i].x + c[i].r > width) {
        c[i].vx = -abs(c[i].vx);
    }
    if (c[i].y - c[i].r < 0) {
        c[i].vy = +abs(c[i].vy);
    }
    if (c[i].y + c[i].r > height) {
        c[i].vy = -abs(c[i].vy);
    }

    game.display.color = i+1;
    game.display.drawCircle(c[i].x,c[i].y,c[i].r);

}
// was commented out
    for (int x = 0; x < width; x += PX_SIZE) {
        for (int y = 0; y < height; y += PY_SIZE) {
            int sum = 0;
            int closestD2 = 32767;
            int closestColor = 0;
            for (int i = 0; i < NUM_CIRCLES; i++) {
                int dx = x - c[i].x;
                int dy = y - c[i].y;
                int d2 = dx * dx + dy * dy;
                if (d2 != 0) sum += ((c[i].r * c[i].r) * 64) / d2;
                if (d2 < closestD2) {
                closestD2 = d2;
                closestColor = i+1;//[c.red, c.green, c.blue];
            }
        }
        if (sum > SUM_THRESHOLD) {
            game.display.color = closestColor;
            game.display.fillRectangle(x, y, PX_SIZE, PY_SIZE);
        }
    }
}
// end commented out
}
int main(){
    srand(game.getTime());
for (int i = 0; i < NUM_CIRCLES; i++) {
    c[i].x = RandMinMax(0,width);
    c[i].y = RandMinMax(0,height);
    c[i].r = RandMinMax(5, 15);
    c[i].vx = RandMinMax(-2,2);
    c[i].vy = RandMinMax(-2,2);
}



game.begin();
game.display.width = width; // full size
game.display.height = height;
game.setFrameRate(60);
game.display.load565Palette(def565palette);

while (game.isRunning()) {
    if (game.update()) {
        //game.display.drawPixel(x,y,pixel/16);
        draw_circles();
    }
}
return 1;
}
1 Like