[Demo]Sketchi


#1

Since i already had a pixel moving around my screen i added a frame to it:

Sketchi.bin (56.3 KB)

A-button increases the speed
B-button clears the screen

edit, updated using tips from Pharap. Added a gamecondition to display title, as in the Lost game.

#include "Pokitto.h"
#include "Background.h"
#include "Title.h"

enum class GameState //This sets up a class that limits the possibilities to the items in it.
{
TitleScreen,
Gameplay,
};



// Create an instance of Pokitto::Core
Pokitto::Core pokitto;

//declare variables
int step = 1;
int positionX = 15;
int positionY = 15;
GameState gameState = GameState::TitleScreen; //sets the gamestate to start in the titlescreen ?

const int screenW = Pokitto::Display::getWidth() - 1;//the width of the screen - 1
const int screenH = Pokitto::Display::getHeight() - 1;//the Height of the screen - 1

// Predeclare functions so they can be called as required, create them so they can be called later
void updateTitleScreen(void);
void drawTitleScreen(void);

void updateGameplay(void);
void drawGameplay(void);

int main(void)
{
pokitto.begin();
// When 1 does not clear the screen, hence the pixel leaves a track
pokitto.display.persistence = 1;
pokitto.display.load565Palette(Etch_pal);
//Set the grey colour of the frame as invisible
pokitto.display.setInvisibleColor(0);
//set frame rate to 40 instead of the default 20
pokitto.setFrameRate(40);

while(pokitto.isRunning())
{
	if(pokitto.update())
	{
		// Update logic
		switch(gameState)
		{
			case GameState::TitleScreen: updateTitleScreen(); break;
			case GameState::Gameplay: updateGameplay(); break;
		}
		// Drawing logic
		switch(gameState)
		{
			case GameState::TitleScreen: drawTitleScreen(); break;
			case GameState::Gameplay: drawGameplay(); break;
		}
	}
}
}





void updateTitleScreen(void)
{

//to update the titlescreen, like movement or something ?

}






void drawTitleScreen(void)
{
// Your titlescreen code here

pokitto.display.drawBitmap(0,0,Etch_title);//Title

// Move to gameplay when A is pressed
if (pokitto.buttons.repeat(BTN_A, 0))
{
    pokitto.display.clear();//clear the display so the title screen disappears, since the persistence was set to 1
	gameState = GameState::Gameplay; //set the gamestate to gameplay
}

}






void updateGameplay()
{
// Input handling
if (pokitto.buttons.repeat(BTN_LEFT, 0))
{
    // Don't go below zero
    if(positionX >= step)
    positionX = positionX - step; //or positionX -=step; // better get used to this..
    else
    positionX = 0;
}

if (pokitto.buttons.repeat(BTN_RIGHT, 0))
{
	const int difference = screenW - positionX;//e.g. 220 - 100 = 120
	if(difference >= step)//120 is larger then step so execute next line
		positionX = positionX + step;//i like the readability of this better.
	else
		positionX = screenW;
}

if (pokitto.buttons.repeat(BTN_UP, 0))
{
	// Don't go below zero
	if(positionY >= step)
		positionY = positionY - step;
	else
		positionY = 0;
}

if (pokitto.buttons.repeat(BTN_DOWN, 0))
{
	const int difference = screenH - positionY;
	if(difference >= step)
		positionY = positionY + step;
	else
		positionY = screenH;
}

// Pressing the A button increases the speed by increasing the step value
if (pokitto.buttons.repeat(BTN_A, 0))
{
	if(step == 1) //if A button pressed check if step equals 1, if yes change it to 5
		step = 5;
}
	else
    {
    step = 1;
    }




// Brackets are not needed with 1 line being executed when the if is true
if (pokitto.buttons.repeat(BTN_B, 0))
	pokitto.display.clear();

}







void drawGameplay(void)
{
// Background first, everything else is drawn on top of that
pokitto.display.drawBitmap(0, 0, Etch);
pokitto.display.setColor(2);

// Draw the pixel
pokitto.display.drawPixel(positionX, positionY);
}



Learning to talk to Pokitto
#2

The cleanest way to do that simply without using a class system is (in my opinion) to use scoped enumerations (enum class and a switch statement).

I did a quick reshuffle of your code.
I made a few other changes, some cosmetic, some functionally important.
The cosmetic changes are mostly personal preference.
(I find allman brace style much easier to read than other brace styles, I genuinely struggle to read styles that put the opening brace on the end of the line.)

#include "Pokitto.h"
#include "Background.h"

enum class GameState
{
  TitleScreen,
  Gameplay,
};

// Create an instance of Pokitto::Core
Pokitto::Core pokitto;

int step = 1;
int positionX = 15;
int positionY = 15;
GameState gameState = GameState::TitleScreen;

const int screenW = Pokitto::Display::getWidth() - 1;//the width of the screen - 1
const int screenH = Pokitto::Display::getHeight() - 1;//the Height of the screen - 1

// Predeclare functions so they can be called as required
void updateTitleScreen(void);
void drawTitleScreen(void);

void updateGameplay(void);
void drawGameplay(void);

int main(void)
{
	pokitto.begin();
	// When 1 does not clear the screen, hence the pixel leaves a track
	pokitto.display.persistence = 1;

	pokitto.display.load565Palette(Etch_pal);
	// Set the grey colour of the frame is invisible
	pokitto.display.setInvisibleColor(0);

	pokitto.setFrameRate(40);

	while(pokitto.isRunning())
	{
		if(pokitto.update())
		{
			// Update logic
			switch(gameState)
			{
				case GameState::TitleScreen: updateTitleScreen(); break;
				case GameState::Gameplay: updateGameplay(); break;
			}
			// Drawing logic
			switch(gameState)
			{
				case GameState::TitleScreen: drawTitleScreen(); break;
				case GameState::Gameplay: drawGameplay(); break;
			}
		}
	}
}

void updateTitleScreen(void)
{
	// Your titlescreen code here

	// Move to gameplay when A is pressed
	if (pokitto.buttons.repeat(BTN_A, 0))
	{
		gameState = GameState::Gameplay;
	}
}

void drawTitleScreen(void)
{

}

void updateGameplay()
{
	// Input handling
	if (pokitto.buttons.repeat(BTN_LEFT, 0))
	{
		// Don't go below zero
		if(positionX >= step)
			positionX -= step;
		else
			positionX = 0;
	}

	if (pokitto.buttons.repeat(BTN_RIGHT, 0))
	{
		const int difference = screenW - positionX;
		if(difference >= step)
			positionX += step;
		else
			positionX = screenW;
	}

	if (pokitto.buttons.repeat(BTN_UP, 0))
	{
		// Don't go below zero
		if(positionY >= step)
			positionY -= step;
		else
			positionX = 0;
	}

	if (pokitto.buttons.repeat(BTN_DOWN, 0))
	{
		const int difference = screenH - positionY;
		if(difference >= step)
			positionY += step;
		else
			positionY = screenH;
	}

	// Pressing the A button increases the speed by increasing the step value
	if (pokitto.buttons.repeat(BTN_A, 0))
	{
		if(step == 1)
			step = 5;
		else
			step = 1;
	}

	// Brackets are not needed with 1 line being executed when the if is true
	if (pokitto.buttons.repeat(BTN_B, 0))
		pokitto.display.clear();
}

void drawGameplay(void)
{
	// Background first, everything else is drawn on top of that
	pokitto.display.drawBitmap(0, 0, Etch);
	pokitto.display.setColor(2);

	// Draw the pixel
	pokitto.display.drawPixel(positionX, positionY);
}

If you have any questions don’t hesitate to ask.
I didn’t actually check if this compiles or runs, so let me know if there’s an error or something doesn’t work.
(Generally it takes me more effort to check than it does to make the code changes.)


#3

Thank you, i will have a good look this evening.


#4

Just tried to compile it, got some errors.

GameState wasnt named the same everywhere so that was easy to fix.
Pokitto::Display.getWidth() is not allowed, so i changed it back to a fixed number.

And then there is this:

Warning: Scoped enumeration types are a C++11 feature in “main.cpp”, Line: 4, Col: 2

It seems that mbed doesnt support this C++ 11 feature “out of the box” ?

edit: looks like it

edit2 :

I tried Embitz, but that has the same problem, even after setting it to C++11, i am going to try it like in the Lost game.

int main () {
    game.begin();


    while (game.isRunning()) {
        if(gameConditon == 0){
            oldTime = game.getTime();
            titlegame();
        }
        if(gameConditon == 1){
            playgame();
        }
        if(gameConditon == 2){
            endgame();
        }



            //game.display.print(0,0,game.getTime()/1000);
            //game.display.print(20,0,vbullet.size());

    }
return 1;
}

#5

Sorry, I just realised that’s supposed to be Pokitto::Display::getWidth().

Ah dammit, I didn’t realise you were using mbed.
You’ll have to use regular enums if you’re using mbed because they’re behind the times and still haven’t got C++11 support sorted.
(We’ve had C++14 and C++17 since then, and it’s not long until C++20 arrives, so they’re really getting behind.)


Give me a moment to clean it up and test on EmBitz and I’ll get back to you.


Fixed. The only remaining issue was a typo.
(I put state instead of gameState).
I updated the original, but I’ll post it here too:

#include "Pokitto.h"
#include "Background.h"

enum class GameState
{
  TitleScreen,
  Gameplay,
};

// Create an instance of Pokitto::Core
Pokitto::Core pokitto;

int step = 1;
int positionX = 15;
int positionY = 15;
GameState gameState = GameState::TitleScreen;

const int screenW = Pokitto::Display::getWidth() - 1;//the width of the screen - 1
const int screenH = Pokitto::Display::getHeight() - 1;//the Height of the screen - 1

// Predeclare functions so they can be called as required
void updateTitleScreen(void);
void drawTitleScreen(void);

void updateGameplay(void);
void drawGameplay(void);

int main(void)
{
	pokitto.begin();
	// When 1 does not clear the screen, hence the pixel leaves a track
	pokitto.display.persistence = 1;

	pokitto.display.load565Palette(Etch_pal);
	// Set the grey colour of the frame is invisible
	pokitto.display.setInvisibleColor(0);

	pokitto.setFrameRate(40);

	while(pokitto.isRunning())
	{
		if(pokitto.update())
		{
			// Update logic
			switch(gameState)
			{
				case GameState::TitleScreen: updateTitleScreen(); break;
				case GameState::Gameplay: updateGameplay(); break;
			}
			// Drawing logic
			switch(gameState)
			{
				case GameState::TitleScreen: drawTitleScreen(); break;
				case GameState::Gameplay: drawGameplay(); break;
			}
		}
	}
}

void updateTitleScreen(void)
{
	// Your titlescreen code here

	// Move to gameplay when A is pressed
	if (pokitto.buttons.repeat(BTN_A, 0))
	{
		gameState = GameState::Gameplay;
	}
}

void drawTitleScreen(void)
{

}

void updateGameplay()
{
	// Input handling
	if (pokitto.buttons.repeat(BTN_LEFT, 0))
	{
		// Don't go below zero
		if(positionX >= step)
			positionX -= step;
		else
			positionX = 0;
	}

	if (pokitto.buttons.repeat(BTN_RIGHT, 0))
	{
		const int difference = screenW - positionX;
		if(difference >= step)
			positionX += step;
		else
			positionX = screenW;
	}

	if (pokitto.buttons.repeat(BTN_UP, 0))
	{
		// Don't go below zero
		if(positionY >= step)
			positionY -= step;
		else
			positionX = 0;
	}

	if (pokitto.buttons.repeat(BTN_DOWN, 0))
	{
		const int difference = screenH - positionY;
		if(difference >= step)
			positionY += step;
		else
			positionY = screenH;
	}

	// Pressing the A button increases the speed by increasing the step value
	if (pokitto.buttons.repeat(BTN_A, 0))
	{
		if(step == 1)
			step = 5;
		else
			step = 1;
	}

	// Brackets are not needed with 1 line being executed when the if is true
	if (pokitto.buttons.repeat(BTN_B, 0))
		pokitto.display.clear();
}

void drawGameplay(void)
{
	// Background first, everything else is drawn on top of that
	pokitto.display.drawBitmap(0, 0, Etch);
	pokitto.display.setColor(2);

	// Draw the pixel
	pokitto.display.drawPixel(positionX, positionY);
}

All these years and I still slip up on the little things like getting a variable name wrong :P.

If you can’t be bothered to get C++11 going, you should be able to replace enum class with enum and remove all the GameState::.
I’d recommend using C++11 on EmBitz though, C++11 was a major language upgrade.


#6

I tried to set the 11 version in embitz, but this only accepted the enum class. The rest of the names were still in error (everything with :: in it)

Do i have to set/change more then the compiler settings?

I will add a picture of what i mean tonight currently on phone.


#7

That’s definitely something else causing the problem.

I actually checked the code compiled on EmBitz.
I had to comment out the 3 lines related to Background.h because I didn’t have that file, but otherwise everything compiled.

Are you modifying the hello world example or just adding new files?
If you didn’t modify the hello world example and haven’t set up a new build target then your problem is probably to do with the project set up.


#8

@Rakkachi : the error must be in your project setup. I took the basic HelloWorld and replaced the main.cpp code with your code. Compiled without issues for me.

Code used:

#include “Pokitto.h”
//#include “Background.h”

enum class GameState
{
TitleScreen,
Gameplay,
};

// Create an instance of Pokitto::Core
Pokitto::Core pokitto;

int step = 1;
int positionX = 15;
int positionY = 15;
GameState gameState = GameState::TitleScreen;

const int screenW = Pokitto::Display::getWidth() - 1;//the width of the screen - 1
const int screenH = Pokitto::Display::getHeight() - 1;//the Height of the screen - 1

// Predeclare functions so they can be called as required
void updateTitleScreen(void);
void drawTitleScreen(void);

void updateGameplay(void);
void drawGameplay(void);

int main(void)
{
pokitto.begin();
// When 1 does not clear the screen, hence the pixel leaves a track
pokitto.display.persistence = 1;

//pokitto.display.load565Palette(Etch_pal);
// Set the grey colour of the frame is invisible
pokitto.display.setInvisibleColor(0);

pokitto.setFrameRate(40);

while(pokitto.isRunning())
{
if(pokitto.update())
{
// Update logic
switch(gameState)
{
case GameState::TitleScreen: updateTitleScreen(); break;
case GameState::Gameplay: updateGameplay(); break;
}
// Drawing logic
switch(gameState)
{
case GameState::TitleScreen: drawTitleScreen(); break;
case GameState::Gameplay: drawGameplay(); break;
}
}
}
}

void updateTitleScreen(void)
{
// Your titlescreen code here

// Move to gameplay when A is pressed
if (pokitto.buttons.repeat(BTN_A, 0))
{
gameState = GameState::Gameplay;
}
}

void drawTitleScreen(void)
{

}

void updateGameplay()
{
// Input handling
if (pokitto.buttons.repeat(BTN_LEFT, 0))
{
// Don’t go below zero
if(positionX >= step)
positionX -= step;
else
positionX = 0;
}

if (pokitto.buttons.repeat(BTN_RIGHT, 0))
{
const int difference = screenW - positionX;
if(difference >= step)
positionX += step;
else
positionX = screenW;
}

if (pokitto.buttons.repeat(BTN_UP, 0))
{
// Don’t go below zero
if(positionY >= step)
positionY -= step;
else
positionX = 0;
}

if (pokitto.buttons.repeat(BTN_DOWN, 0))
{
const int difference = screenH - positionY;
if(difference >= step)
positionY += step;
else
positionY = screenH;
}

// Pressing the A button increases the speed by increasing the step value
if (pokitto.buttons.repeat(BTN_A, 0))
{
if(step == 1)
step = 5;
else
step = 1;
}

// Brackets are not needed with 1 line being executed when the if is true
if (pokitto.buttons.repeat(BTN_B, 0))
pokitto.display.clear();
}

void drawGameplay(void)
{
// Background first, everything else is drawn on top of that
//pokitto.display.drawBitmap(0, 0, Etch);
pokitto.display.setColor(2);

// Draw the pixel
pokitto.display.drawPixel(positionX, positionY);
}


#9

ok, i will check my settings tonight. Is the setup as described on the forum still accurate?.


#10

If in doubt:

  • Nuke your copy of PokittoLib
  • Grab a fresh version from the master branch
  • Open it in EmBitz
  • Select HelloWorld as a build target
  • Open hello.cpp
  • Replace the contents of hello.cpp with the code @jonne posted*

* Which is the same as what I posted before, but with all the parts that need to be commented out, commented out.


Or, if you’re feeling brave:


#11

I made the new setup in Embitz, i can compile and run all examples and the simple Noughts and crossed from Pharap.

The code as Jonne put it up here does compile, no problem. But the game doesnt work as it should.
I suspect because of the lines that where commented out.

So i will run trough it and see what i can learn and fix it.
So please no hints this time :smile: i want to understand the code as it is now.

Many thanks for the assist @Pharap and @jonne


#12

Glad to hear that. That means my tutorial was nice and clear (hopefully).

Yeah, you never supplied your Background.h file.
As a result we needed to comment out references to stuff declared in Background.h to get the code to compile without that file.

If it compiled without Background.h then it should compile with Background.h added back in.
If C++11 wasn’t turned on you’d have got errors about the enum class.

Ok, no hints unless you ask, but I will say that if you get stuck, look to en.cppreference.com/w/cpp, or perhaps something from my cpp resource list.


#13

I went trought the code @Pharap and I understand what is going on.

Did raise some points tho:

  • GameState gameState = GameState::TitleScreen; Why is this named twice ?
  • There is a updateTitle and a DrawTitle, do I understand correctly that I could make something move in the Title screen?
  • Why the extra check if the Step == 1 ? this seems redundant.
  • Why write this positionX +=step; instead of positionX = positionX + step; ? I am aware of this normally being used but i cant find a good reason to do so. Googling even confirms that most modern compilers output exactly the same regardless of what i type. I dont mind typing a little more if this increases the readabilty (for me).
 #include "Pokitto.h"
 #include "Background.h"
 #include "Title.h"

enum class GameState //This sets up a class that limits the possibilities to the items in it.
{
TitleScreen,
Gameplay,
};



// Create an instance of Pokitto::Core
Pokitto::Core pokitto;

//declare variables
int step = 1;
int positionX = 15;
int positionY = 15;
GameState gameState = GameState::TitleScreen; //sets the gamestate to start in the titlescreen ?

const int screenW = Pokitto::Display::getWidth() - 1;//the width of the screen - 1
const int screenH = Pokitto::Display::getHeight() - 1;//the Height of the screen - 1

// Predeclare functions so they can be called as required, create them so they can be called later
void updateTitleScreen(void);
void drawTitleScreen(void);

void updateGameplay(void);
void drawGameplay(void);

int main(void)
{
pokitto.begin();
// When 1 does not clear the screen, hence the pixel leaves a track
pokitto.display.persistence = 1;
pokitto.display.load565Palette(Etch_pal);
//Set the grey colour of the frame as invisible
pokitto.display.setInvisibleColor(0);
//set frame rate to 40 instead of the default 20
pokitto.setFrameRate(40);

while(pokitto.isRunning())
{
	if(pokitto.update())
	{
		// Update logic
		switch(gameState)
		{
			case GameState::TitleScreen: updateTitleScreen(); break;
			case GameState::Gameplay: updateGameplay(); break;
		}
		// Drawing logic
		switch(gameState)
		{
			case GameState::TitleScreen: drawTitleScreen(); break;
			case GameState::Gameplay: drawGameplay(); break;
		}
	}
}
}





void updateTitleScreen(void)
{

//to update the titlescreen, like movement or something ?

}






void drawTitleScreen(void)
{
// Your titlescreen code here

pokitto.display.drawBitmap(0,0,Etch_title);//Title

// Move to gameplay when A is pressed
if (pokitto.buttons.repeat(BTN_A, 0))
{
    pokitto.display.clear();//clear the display so the title screen disappears, since the persistence was set to 1
	gameState = GameState::Gameplay; //set the gamestate to gameplay
}

}






void updateGameplay()
{
// Input handling
if (pokitto.buttons.repeat(BTN_LEFT, 0))
{
    // Don't go below zero
    if(positionX >= step)
    positionX = positionX - step;
    else
    positionX = 0;
}

if (pokitto.buttons.repeat(BTN_RIGHT, 0))
{
	const int difference = screenW - positionX;//e.g. 220 - 100 = 120
	if(difference >= step)//120 is larger then step so execute next line
		positionX = positionX + step;//i like the readability of this better. 
	else
		positionX = screenW;
}

if (pokitto.buttons.repeat(BTN_UP, 0))
{
	// Don't go below zero
	if(positionY >= step)
		positionY = positionY - step;
	else
		positionY = 0;
}

if (pokitto.buttons.repeat(BTN_DOWN, 0))
{
	const int difference = screenH - positionY;
	if(difference >= step)
		positionY = positionY + step;
	else
		positionY = screenH;
}

// Pressing the A button increases the speed by increasing the step value
if (pokitto.buttons.repeat(BTN_A, 0))
{
	//if(step == 1) //why would i check if step equals 1 ?
		step = 5;
}
	else
    {
    step = 1;
    }




// Brackets are not needed with 1 line being executed when the if is true
if (pokitto.buttons.repeat(BTN_B, 0))
	pokitto.display.clear();

}







void drawGameplay(void)
{
// Background first, everything else is drawn on top of that
pokitto.display.drawBitmap(0, 0, Etch);
pokitto.display.setColor(2);

// Draw the pixel
pokitto.display.drawPixel(positionX, positionY);
}

#14

enum classes are ‘scoped enumerations’.
The values are scoped to the specific enum.

Using ‘unscoped enumerations’ (commonly called ‘plain enums’), this would be an error:

enum Colour { Red, Green, Blue }; 
enum Feeling { Excited, Moddy, Blue };

Because the Blue defined by Colour and the Blue defined by Feeling both end up in the same scope, which causes a name conflict.

But by making them scoped enumerations:

enum class Colour { Red, Green, Blue }; 
enum class Feeling { Excited, Moddy, Blue };

There’s no longer a conflict because the Blue in Colour has to be accessed as Colour::Blue and the Blue in Feeling has to be accessed as Feeling::Blue. Every scoped enumeration has its own scope to prevent interfering with each other, just like the functions and variables of a class are inside the class’s scope to avoid conflicting with names in other scopes.

(See also, this comment.)

Yes, you could make stuff move to animate the title screen.
Or you could have an options menu or something.

If you’re wondering why I split it, generally it’s best to keep updating the logic separate from the rendering.
If you split them up then it’s harder for bugs from one to bleed into the other and it’s easier to predict the state when you come to draw if you’ve handled all the updating before the drawing.

Not sure I understand. If you mean here:

if(step == 1)
	step = 5;
else
	step = 1;

Then the check isn’t redundant.
If step is 1 then it changes step to 5, otherwise (e.g. step is 5) it changes step to 1.

Mainly because it’s shorter, partly because most people find it more readable.

Also it sometimes helps to reduce errors.
With a case of positionX = positionX + step; it’s possible to change one name and forget to change the other, e.g. positionY = positionX + step;

Compound operators are much more common than the longer approach.
Technically it’s possible to make them not the same when defining custom types (though it’s unlikely anyone ever would).

You can stick to the long way if you want, but you’d do well to get used to the compound assignment operators, they’re used quite a lot.


If you think GameState gameState = GameState::TitleScreen; is repetative, you can write:

auto gameState = GameState::TitleScreen;

auto is a C++11 feature that infers the type of the expression on the right. But be careful that you actually know the type of the expression on the right, sometimes it’s not what you think.
For example auto x = 1.0; is double, not float.
To be float it would have to be auto x = 1.0f;.