# Need help to develop KSboy (Kerbal Space Program 8-bits)

(Pharap) #8

Dammit Jim, I’m a programmer, not a rocket scientist.

Sketch uses 10684 bytes (37%) of program storage space. Maximum is 28672 bytes.
Global variables use 1323 bytes (51%) of dynamic memory, leaving 1237 bytes for local variables. Maximum is 2560 bytes.

I don’t doubt that a trimmed down version of KSP would be possible, but it would still take a lot of know-how and effort.

#9

Shorthand is there’s points where gravity cancels out and an object in those points will stay puy unlike a normal orbit that decays.

Ksp works off of sphere of influences. So if your within x away from a body that’s all that exists basicly as far as physics calculations.

Which really burns down to just calculating the orbits using your velocity and position. I said 2d but really a 2d overlook would just be a 1 dimensional calculating with a clockwise or counter clockwise direction applied. 1 planet should be too hard but adding an orbiting moon would definitely add a lot of complexity.

I think your fixed points library would also be necessary since plants are spherical and more importantly orbits follow an elipse. I don’t see how else you could do those calculations.

Aerodynamics could be boiled down pretty easy too. A switchcase for drag based on altitude wouldn’t be too complex.

Velocity = Velocity - gravity factor - aerodrag + engine acceleration.

(Pharap) #10

Sounds like KSP may have chosen to do that for optimisation reasons.

Checking for object interractions often ends up being an `O(N^2)` check unless you’re prepared to do space partitioning of some description (e.g. binary space partitioning or octrees).

#11

Ok thank you very much

#12

i am trying to do at first a start page:

(Stephane C) #13

Ok… and what kind of help do you need? Is there something you want to add that you don’t know to do it?
Don’t take it bad but usually things like title screen are better be worked on later (even though it’s the first thing we see).

You maybe should start by trying to work on the mechanism of the game first to see if it’s possible for you to create it on the Arduboy, it would be sad to see a lot of your time wasted on a beautiful title screen and graphics if the game can’t be done right?

But if you really want to start with the title screen like you mention, please be more specific about the help that you need. Saying that you are trying to make a start screen doesn’t tell us much (at least me).

Do you need help with the graphics for that screen?
Do you need to know how to make it so that when you press a button it goes in-game?
Do you need to know how to animate something on that screen?
Etc…

Also, having a look at the @filmote HERE and @crait 's HERE tutorials in this forum might help you a lot and more often then not your answers will be there.

Also, you can have a look at the sources of other games to see how others are doing things, i learned a lot that way (not that i am good now, but i know a lot more and i understand things better).

#14

My problem is when i turn on the arduboy the screen don’t display anything but at line 26 :

arduboy.drawBitmap(50,50, Start, 64, 128, BLACK);

I say to display start so my start page
And…
it does’nt work :’(

(Boti Kis) #15

Took a brief look at your code.
The `loop()` function is a bit messy and I suggest to clean it up.
There is a `for-loop` at line 28 which don’t make any sense to me and is the root of your problem.

``````void loop() {
arduboy.clear();
arduboy.drawBitmap(50,50, Start, 64, 128, BLACK);

if(arduboy.pressed(A_BUTTON))
{
// Do stuff
}

arduboy.display();
}
``````

I believe that there is something wrong with your `drawBitmap()` since I don’t think that the image is 64 in width and 128 in height.

I also don’t understand what you want to happen after line 28. If you want some help on that, please be more specific. As @Vampirics already suggested, I also recommend you to first go through the tutorials of @filmote and @crait before you start to make your own game.

(Stephane C) #16

I kinda understand what you are trying to do, but not sure you are doing it the best way.
You want to make it so that the ship(player) launches after we press A…

For starter…

@Botisaurus is right about your Start bitmap, it sure isn’t 64 x 128 so that must be wrong, if you enter the wrong dimension there, it will always display garbage or parts of things that are in memory.

Another thing, i am pretty sure you may have mixed what is BLACK and what is WHITE ( or maybe you wanted the background white? but looking at the image you posted it’s all inverted.

In your code you are also inverting X and Y, playerx should be the coordinate for when the player moves horizontally, and playery vertically. your code is still working, but it’s weird to see playery as the X coordinate.

(Holmes) #17

I WILL BE SOON! Also still working on the latest tutorial!

(Pharap) #18

To point out some of the specific problems

`arduboy.clear()` clears the screen.

In your code you’re drawing `Start` and then clearing the screen, so that sprite will be erased before it’s shown.

It also means that in this case:

``````    if(var > 10){
arduboy.drawBitmap(97,15, base2, 32, 32, BLACK);

arduboy.clear();
}
``````

You’re drawing a sprite and then immediately erasing it.

Secondly the loop @Botisaurus hinted at:

``````for (int i=0; i <= 150; i++){
``````

Seems to not really serve a purpose.

A better approach

From reading this code I think where you’re going wrong is in your approach to the code.
You’re trying to tell it what you want it to do all at once in a single function.

Games generally don’t work like that.
Nearly every modern game consists of an update-render loop in which the code:

2. Updates the game state (physics, ai, general logic)
3. Renders the graphics

These are generally kept distinct and not mixed (i.e. not moving the character and then drawing the character’s sprite immediately after).

The key bit of information that I think you’re missing is the concept of a state machine and how to get your game to be in different states and change state.

For example:

``````#include <Arduboy2.h>

// You'll probably want to replace this with a separate image of the rocket
// and the actual title when you know how
const uint8_t TitleScreenImage[] PROGMEM =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xFC, 0xFF, 0xC3, 0xFF, 0xFC, 0xE0, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xC0, 0xC0, 0xC0, 0xC0, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xC0, 0xE0, 0x60, 0x60, 0x60, 0x60, 0xC0, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE0, 0xE0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x83, 0x07, 0x0C, 0x0C, 0x0C, 0x0C, 0x98, 0xF8, 0xF0, 0x00, 0x00, 0x03, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x00, 0xE0, 0xE6, 0x33, 0x33, 0x33, 0xB7, 0xFE, 0xFC, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0x06, 0x03, 0x03, 0x03, 0x00, 0x03, 0xFF, 0xFF, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x3F, 0xFF, 0x00, 0xE0, 0xFC, 0x3F, 0x1F, 0x3F, 0x3F, 0xFF, 0x3F, 0x3F, 0x1F, 0x3F, 0xFC, 0xE0, 0x00, 0xFF, 0x3F, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x01, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x01, 0x03, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x0F, 0x3F, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xFC, 0x44, 0x44, 0x7C, 0x30, 0x00, 0x7C, 0x04, 0x04, 0x00, 0x7C, 0x54, 0x54, 0x5C, 0x00, 0x00, 0x5C, 0x54, 0x74, 0x00, 0x00, 0x5C, 0x54, 0x74, 0x00, 0x00, 0x00, 0x7C, 0x82, 0x01, 0x7D, 0x15, 0x7D, 0x01, 0x82, 0x7C, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00, 0x00, 0x00
};

const unsigned char PlayerImage[] PROGMEM  =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0xc0, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x80, 0xc0, 0xc0, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xff, 0xff, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xe1, 0xf1, 0xf9, 0xf9, 0xdd, 0xd, 0x86, 0x80, 0x80, 0x00, 0x3, 0x7, 0xc, 0xc, 0x1c, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0xff, 0xff, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x3f, 0x7f, 0x7f, 0xef, 0xc3, 0x87, 0x7, 0x7, 0x3, 0x00, 0x00, 0x00, 0x00, 0x2, 0x6, 0xe, 0xe, 0xe, 0xe, 0xf, 0xf, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xe, 0xa, 0x1, 0x00, 0x00, 0x00,
};

// This is a scoped enumeration (often called an 'enum class')
// Don't worry too much about how this works,
// just see how it's used
enum class GameState : uint8_t
{
TitleScreen,
Gameplay,
};

Arduboy2 arduboy = Arduboy2();
GameState gameState = GameState::TitleScreen;

// int16_t is the same as int on the Arduboy,
// but int isn't the same size on all platforms,
// while int16_t is
uint16_t playerX = 0;
uint16_t playerY = 0;

// The 'void' in the brackets means 'this function takes no arguments'
// If you don't know what functions and arguments are,
// you need to read more tutorials - they're crucial to writing manageable games
void setup(void)
{
arduboy.begin();
}

void loop(void)
{
// This stops the Arduboy trying to draw before it's ready
if(!arduboy.nextFrame())
return;

// This updates the button state
arduboy.pollButtons();

// Do different things depending on the current game state
switch(gameState)
{
case GameState::TitleScreen:
updateTitleScreen();
break;
case GameState::Gameplay:
updateGameplay();
break;
}

// This clears the screen
arduboy.clear();

// Do different things depending on the current game state
switch(gameState)
{
case GameState::TitleScreen:
renderTitleScreen();
break;
case GameState::Gameplay:
renderGameplay();
break;
}

// This displays the screen
arduboy.display();
}

void updateTitleScreen(void)
{
// If A is pressed, move to Gameplay state
if(arduboy.justPressed(A_BUTTON))
{
gameState = GameState::Gameplay;
}
}

void updateGameplay(void)
{
// If left is pressed, move the player left
if(arduboy.pressed(LEFT_BUTTON))
{
--playerX;
}

if(arduboy.pressed(RIGHT_BUTTON))
{
++playerX;
}

// I'll let you fill in the equivalent for Y
}

void renderTitleScreen(void)
{
// You don't need to specify the colour, it defaults to 'BLACK',
// which means 'draw the image normally'
// Using 'WHITE' inverts the image
arduboy.drawBitmap(0, 0, TitleScreenImage, 128, 64);
}

void renderGameplay(void)
{
// Draw the player at the player position
arduboy.drawBitmap(playerX, playerY, PlayerImage, 32, 32);
}
``````

(Gist available here.)

Feel free to ask questions, I’m probably doing at least half a dozen things in that code that you haven’t encountered before.

Some other tips

Avoid `delay`.
It delays all the code, which includes drawing and input, so your game can end up feeling unresponsive.

(Also, never be afraid to ask questions, most programmers love discussing code and explaining how it works because code is cool.)

(Specific questions are more likely to get good answers though, vague or general questions are hard to answer.)

(Simon) #19

Nothing like a little heckling to get you worked up!.

#21

Thank you so much @Pharap i just updated my code with your own and…
Start work

(Pharap) #22

Don’t forget to make sure you at least partly understand how it works,
enough to adapt it without it breaking even if you don’t yet fully understand what’s going on.

(Simon) #24

What did you use to generate the image?

BTW arduboy.drawBitmap(0, 0, Start, 127, 63); - the last two parameters are size and width. Is yours supposed to be 128 and 64?

#25

yes it was that
now im trying to insert clouds

#26

A little idea of what i want
Ksp 8bits
And
8bit song

#27

I’d recommend trying to brake the game up into parts. Maybe start with a moon lander game and then add a builder screen to modify the lander.

After that you can add more locations by changing the acceleration of gravity.

(Pharap) #28

It’s better to focus on gameplay before you go thinking about music and art.
You might not even have space for music by the end.

Otherwise you’re going to end up with fancy graphics and music, but no gameplay.

#29

I have a problem i am trying to set an height value but numbers aren’t in the right angle
ps:i placed another code in github, it is the work in progress code with bugs, the problem is in the test code