Skip to: Site menu | Main content


Welcome to PSP-Programming.com, a place for developers to get together.

Welcome to the forums. Here you can find other user tutorials as well as homebrew releases and the source code repository. You can also ask for help with your code here and post your own homebrew!

PSP-Programming.com Forums
March 12, 2010, 09:30:16 AM *
Welcome, Guest. Please login or register.
Did you miss your activation email?

Login with username, password and session length

News: Welcome to PSP-Programming.com
Home Help Search Shop Login Register
Digg This!
Pages: [1] 2
Print
Author Topic: [Tutorial] Full Game Part 2 - Movement & Animation  (Read 11164 times)
Insert_Witty_Name
Global Moderator
Hero Member
*

Karma: +148/-17
Offline Offline

Posts: 1602
1141.66 points

View Inventory
Send Money to Insert_Witty_Name

View Profile WWW
« on: June 04, 2006, 10:04:10 PM »

Part 1 can be found here.

http://www.psp-programming.com/dev-forum/viewtopic.php?t=359

In this next step we will create our game environment, implement movement and create our character animation.

Open up your main.c from part 1, at the top where your includes are find this section of code:

Code:
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include "graphics.h"


Add an extra line so it reads:

Code:
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include "graphics.h"
#include "game.h"


Find this section of code:

Code:
       else if (OnDifficultyMenu == 1)
        {
         //HERE'S WHERE WE WOULD START THE ACTUAL GAME
        }


And change it to:

Code:
       else if (OnDifficultyMenu == 1)
        {
         //Start The Game
         Game();
         OnStartGameMenu = 1;
        }


All we've done is added the code which will enable us to call our Game() function which will hold all the code for our actual game.

The line:
Code:
        OnStartGameMenu = 1;


Just simply resets our menu so that it reverts to the 'Start Game' part when we return from the game.

Your new main.c should now look like this:

Code:
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include "graphics.h"
#include "game.h"

PSP_MODULE_INFO("Game Tutorial Part 1: Menu", 0, 1, 1);

#define RGB(r, g, b) ((r)|((g)<<8)|((b)<<16))

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common) {
          sceKernelExitGame();
          return 0;
}

/* Callback thread */
int CallbackThread(SceSize args, void *argp) {
          int cbid;

          cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
          sceKernelRegisterExitCallback(cbid);

          sceKernelSleepThreadCB();

          return 0;
}

/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void) {
          int thid = 0;

          thid = sceKernelCreateThread("update_thread", CallbackThread, 0x11, 0xFA0, 0, 0);
          if(thid >= 0) {
                    sceKernelStartThread(thid, 0, 0);
          }

          return thid;
}

//GLOBAL VARIABLES
int DifficultySetting = 1;

int main(void) {
    SetupCallbacks();
    initGraphics();

    SceCtrlData pad, lastpad;

    sceCtrlReadBufferPositive(&lastpad, 1);
   
    Image* Background;
    Background = loadImage("./Images/Background.png");

    Color EasyColor = RGB(0, 0, 0);
    Color MediumColor = RGB(0, 0, 0);
    Color HardColor = RGB(0, 0, 0);
   
    int OnStartGameMenu = 1;
    int OnDifficultyMenu = 0;
    extern int DifficultySetting;

    while(1) {
      sceCtrlReadBufferPositive(&pad, 1);

      if(pad.Buttons != lastpad.Buttons) {
      lastpad = pad;

      if(pad.Buttons & PSP_CTRL_CROSS)
      {
        if (OnStartGameMenu == 1)
           {
           OnStartGameMenu = 0;
           OnDifficultyMenu = 1;
           DifficultySetting = 1;
           }
        else if (OnDifficultyMenu == 1)
        {
         //Start The Game
         Game();
         OnStartGameMenu = 1;
        }
      }

      if(pad.Buttons & PSP_CTRL_CIRCLE)
      {
        if (OnDifficultyMenu == 1)
           {
           OnStartGameMenu = 1;
           OnDifficultyMenu = 0;
           }
      }


      if(pad.Buttons & PSP_CTRL_UP)
      {
        if (OnDifficultyMenu == 1)
           {
           DifficultySetting--;
           if (DifficultySetting < 1)
           DifficultySetting = 1;
           }
      }

      if(pad.Buttons & PSP_CTRL_DOWN)
      {
       if (OnDifficultyMenu == 1)
           {
           DifficultySetting++;
           if (DifficultySetting > 3)
           DifficultySetting = 3;
           }
      }

    }

    blitAlphaImageToScreen(0, 0 , 480, 272, Background, 0, 0);

    if (OnStartGameMenu == 1)
    {
    printTextScreen(170, 140, "Start Game", RGB(191, 0, 0));
    }
   
    else if (OnDifficultyMenu == 1)
    {
      if (DifficultySetting == 1)
      {
       EasyColor = RGB(191, 0, 0);
       MediumColor = RGB(0, 0, 0);
       HardColor = RGB(0, 0, 0);
      }
      else if (DifficultySetting == 2)
      {
       EasyColor = RGB(0, 0, 0);
       MediumColor = RGB(191, 0, 0);
       HardColor = RGB(0, 0, 0);
      }
      else if (DifficultySetting == 3)
      {
       EasyColor = RGB(0, 0, 0);
       MediumColor = RGB(0, 0, 0);
       HardColor = RGB(191, 0, 0);
      }

    printTextScreen(170, 140, "Easy", EasyColor);
    printTextScreen(170, 150, "Medium", MediumColor);
    printTextScreen(170, 160, "Hard", HardColor);
    }

    sceDisplayWaitVblankStart();
    flipScreen();

    }
    sceKernelSleepThread();
    return 0;
}



Save and close your main.c file.

Create a new file named game.h, this will be the header file for our game which we have already included in our main.c (#include "game.h").

Header files contain declarations to functions and variables and have a .h extension.

Code:
#ifndef __GAME__
#define __GAME__

extern void Game();

#endif



We are just defining our Game() function here - note the extern again, this is because our actual Game() function will be held in a different file (game.c).

Because we only want to define our function once we use the #ifndef command. Basically the above code translates to: if __GAME__ is not defined, then define __GAME__ and the Game() function. This is just a precaution in case you #include this header file in more than 1 other file.

Save and close game.h

Create a new file name game.c. First we'll add our includes:

Code:
#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include "graphics.h"


If you're not sure why we're including these, please refer to Part 1 of the tutorial.

We only have one declare in game.c, the same as is in main.c:
Code:
#define RGB(r, g, b) ((r)|((g)<<8)|((b)<<16))


Again, refer to Part 1 if you are unsure what this does.

Let's start our Game() function:

Code:

void Game()
{


And add some variables:

Code:

 SceCtrlData pad;
 int BlinkyPosX = 170;
 int BlinkTimer = 0;
 Color White = RGB(255, 255, 255);


pad will hold our controls variable, BlinkyPosX will be the X position of our character, BlinkTimer will be a timer which we'll get to later on in this tutorial and finally White is the color white.

Let's add some new images:

Code:

 Image* BlinkyImages[6];
 BlinkyImages[0] = loadImage("./Images/Idle.png");
 BlinkyImages[1] = loadImage("./Images/IdleBlink.png");
 BlinkyImages[2] = loadImage("./Images/Left.png");
 BlinkyImages[3] = loadImage("./Images/LeftBlink.png");
 BlinkyImages[4] = loadImage("./Images/Right.png");
 BlinkyImages[5] = loadImage("./Images/RightBlink.png");


We are declaring an array of images (6) which will hold all our images for Blinky, then loading the various images into the array. Note how we declared 6 images and they range from [0] to [5] NOT [1] to [6].

Code:

int FrameCounter = 0;


Finally, we declare an integer named FrameCounter and set it to 0. FrameCounter will hold the number of the current image we will display for Blinky ie. The 'X' in BlinkyImages[X]. So FrameCounter will always be populated with a number from 0-5, same as our image array. Setting it to 0 will allow us to display BlinkyImages[0] later in our code by using BlinkyImages[FrameCounter].

Onto our loop.

Code:

 while(1)
 {


You should know what this does, starts our loop in which we will read controls, blit images etc.

Code:

 sceCtrlReadBufferPositive(&pad, 1);

 FrameCounter = 0;
 BlinkTimer++;


We are taking a reading of the controls and putting the result in the pad variable, setting FrameCounter to 0 (Idle) and incrementing the BlinkTimer.

We set FrameCounter to 0 because if we don't receive any input from the controls we want to display the idle image and we have to check for this within the loop each iteration.

BlinkTimer++ just adds 1 to the current value stored in BlinkTimer.

Note how we don't have a lastpad repeat check for the controls in this file like we did in main.c. That's because we want the controls to repeat - if we hold left we want our character to keep moving left.

Onto reading the controls:

Code:

 if (pad.Buttons & PSP_CTRL_START)
      {
      break;
      }


If start is pressed we want to break out of our loop and end the Game() function, thus returning us to the 'Start Game' menu. This is just a temporary thing for this tutorial as a way of getting us back to the menus.

Code:

 if (pad.Buttons & PSP_CTRL_LEFT)
      {
      BlinkyPosX -= 2;
      FrameCounter = 2;
      }


If left button is being pressed, we subtract 2 from the current BlinkyPosX variable, which will make Blinky move toward the left. We then set the FrameCounter variable to 2 - if you look back up at where we loaded our Blinky image array you will see that BlinkyImages[2] is in fact Left.png.

We then do a similar thing for right:

Code:

 if (pad.Buttons & PSP_CTRL_RIGHT)
      {
      BlinkyPosX += 2;
      FrameCounter = 4;
      }


This time we add 2 to the BlinkyPosX variable, moving Blinky toward the right and then set FrameCounter to 4. BlinkyImages[4] is Right.png.

Code:

 if (BlinkTimer > 200)
    {
     FrameCounter++;
    }


Ok, so after 200 iterations of the loop we want Blinky to blink. If you look at the image array again, you will see that the blinking versions of each image are +1 to the non-blinking versions. ie. idle is BlinkyImages[0], idle   with a blink is BlinkyImages[1], so we just add one to our FrameCounter variable.

Now we need a check to cancel the blinking animation, and reset the image back to the non-blinking version:

Code:

 if (BlinkTimer > 220)
    {
    BlinkTimer = 0;
    }


We reset the BlinkTimer variable to 0, so it has another 200 iterations of the loop before we blink again.

Code:

 if (BlinkyPosX < 0)
    {
      BlinkyPosX = 0;
    }
 else if (BlinkyPosX > (480 - 106))
    {
     BlinkyPosX = (480 - 106);
    }


The above code keeps Blinky on our screen. The first check just makes sure that BlinkyPosX is never lower than 0, otherwise Blinky would disappear off the left side of the screen if we went too far left.

The second check make sure Blinky doesn't go off the right side of the screen. Our Blinky images are 106 pixels wide, the PSP screen is 480 pixels wide, so we simply subtract one from the other. I've left the calculations involved in to illustrate this, but you could simply put 374 (which is what 480-106 equals) instead.

Code:

 fillScreenRect(White, 0, 0, 480, 272);


We draw a rectangle the full size of the screen and make it white - this will be our 'background' of sorts.

Code:

 blitAlphaImageToScreen(0, 0, 106, 72, BlinkyImages[FrameCounter], BlinkyPosX, 170);


This might look a bit different than what you're normally used to. We're blitting the image BlinkyImages[FrameCounter] (where FrameCounter is a value from 0 to 5) to the screen at our BlinkyPosX X position and Y position 170. The Blinky images are all 106x72 so we can hard code those values in.

I hope you can see now why we alter the BlinkyPosX variable and the FrameCounter variable.

Let's finish it up:
Code:

 sceDisplayWaitVblankStart();
 flipScreen();
 }
}


Waiting for our vertical blank and then flipping the off-screen to the screen.

Your full code for game.c should look like this:
Code:

#include <pspkernel.h>
#include <pspdisplay.h>
#include <pspctrl.h>
#include "graphics.h"

#define RGB(r, g, b) ((r)|((g)<<8)|((b)<<16))

void Game()
{
 SceCtrlData pad;
 int BlinkyPosX = 170;
 int BlinkTimer = 0;
 Color White = RGB(255, 255, 255);

 Image* BlinkyImages[6];
 BlinkyImages[0] = loadImage("./Images/Idle.png");
 BlinkyImages[1] = loadImage("./Images/IdleBlink.png");
 BlinkyImages[2] = loadImage("./Images/Left.png");
 BlinkyImages[3] = loadImage("./Images/LeftBlink.png");
 BlinkyImages[4] = loadImage("./Images/Right.png");
 BlinkyImages[5] = loadImage("./Images/RightBlink.png");

 int FrameCounter = 0;

 while(1)
 {
 sceCtrlReadBufferPositive(&pad, 1);

 FrameCounter = 0;
 BlinkTimer++;

 if (pad.Buttons & PSP_CTRL_START)
      {
      break;
      }
     
 if (pad.Buttons & PSP_CTRL_LEFT)
      {
      BlinkyPosX -= 2;
      FrameCounter = 2;
      }

 if (pad.Buttons & PSP_CTRL_RIGHT)
      {
      BlinkyPosX += 2;
      FrameCounter = 4;
      }

 if (BlinkTimer > 200)
    {
     FrameCounter++;
    }

 if (BlinkTimer > 220)
    {
    BlinkTimer = 0;
    }

 if (BlinkyPosX < 0)
    {
      BlinkyPosX = 0;
    }
 else if (BlinkyPosX > (480 - 106))
    {
     BlinkyPosX = (480 - 106);
    }

 fillScreenRect(White, 0, 0, 480, 272);
 blitAlphaImageToScreen(0, 0, 106, 72, BlinkyImages[FrameCounter], BlinkyPosX, 170);

 sceDisplayWaitVblankStart();
 flipScreen();
 }
}



Now, the makefile for this will be slightly different to the original one, as we have to compile our game.c as well as the main.c:

Code:

TARGET = GameTutorial2
OBJS = main.o graphics.o framebuffer.o game.o

CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBDIR =
LIBS = -lpspgu -lpng -lz -lm
LDFLAGS =

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Game Tutorial Part 2

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


All we've done (apart from change the PSP_EBOOT_TITLE and TARGET) is add game.o to the end of the OBJS line. If there were more C files incorporated into this project, we would add them too.

Files for this tutorial can be found here:

http://www.psp-programming.com/animate/GameTutorial2.rar

The archive contains everything you need apart from the main.c, game.c, game.h and makefile.

Don't forget to copy the 'Images' folder to the 'GameTutorial2' folder (without the %).

Part 3 will finish our game off and will implement the actual gameplay, collision detection and scoring.
Logged

Coder formerly known as:

Check out my homebrew & C tutorials at http://insomniac.0x89.org
Last updated 6th Oct 06 - Tutorial 2 added.


Insert_Witty_Name
Global Moderator
Hero Member
*

Karma: +148/-17
Offline Offline

Posts: 1602
1141.66 points

View Inventory
Send Money to Insert_Witty_Name

View Profile WWW
« Reply #1 on: June 04, 2006, 10:23:13 PM »

A few screenshots.




Logged

Coder formerly known as:

Check out my homebrew & C tutorials at http://insomniac.0x89.org
Last updated 6th Oct 06 - Tutorial 2 added.
harleyg
Give miinaturvat Points!
Hero Member
*****

Karma: +11/-14
Offline Offline

Posts: 715
462.95 points

View Inventory
Send Money to harleyg


View Profile
« Reply #2 on: June 04, 2006, 10:27:46 PM »

Once again, nice work!
Logged
whazilla
Sr. Member
****

Karma: +2/-8
Offline Offline

Posts: 377
1793.33 points

View Inventory
Send Money to whazilla


View Profile
« Reply #3 on: June 05, 2006, 01:12:17 AM »

blinky Wink
Logged
faati
Full Member
***

Karma: +0/-1
Offline Offline

Posts: 152
0.00 points

View Inventory
Send Money to faati


View Profile
« Reply #4 on: June 05, 2006, 07:03:34 AM »

I'll take a look later  Very Happy
Logged

stalin
CCCP - Crazy Communist C Programmer
Jr. Member
**

Karma: +0/-1
Offline Offline

Posts: 53
1620.46 points

View Inventory
Send Money to stalin


View Profile
« Reply #5 on: June 05, 2006, 03:22:43 PM »

i don't think you have been given the praise you deserve Insomniac.

i happen to know a bit about programming C/C   from PC i am brand new to the psp programming scene and these tutorials are giving me a great idea of the subtle differences
Logged
Insert_Witty_Name
Global Moderator
Hero Member
*

Karma: +148/-17
Offline Offline

Posts: 1602
1141.66 points

View Inventory
Send Money to Insert_Witty_Name

View Profile WWW
« Reply #6 on: June 05, 2006, 03:36:45 PM »

Thanks for the kind words Stalin  Very Happy
Logged

Coder formerly known as:

Check out my homebrew & C tutorials at http://insomniac.0x89.org
Last updated 6th Oct 06 - Tutorial 2 added.
soccerpmn
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 33
0.00 points

View Inventory
Send Money to soccerpmn

View Profile WWW
« Reply #7 on: June 16, 2006, 01:44:59 PM »

Do you know how to do state saves?  Like be able to pause in the middle of gameplay and go to a menu, then return to the gameplay in the same conditions that it was in?
Logged

harleyg
Give miinaturvat Points!
Hero Member
*****

Karma: +11/-14
Offline Offline

Posts: 715
462.95 points

View Inventory
Send Money to harleyg


View Profile
« Reply #8 on: June 16, 2006, 03:59:22 PM »

Think thats just the case of stopping everything...

However exiting the game and then starting it exactly how it was left is another kettle of fish...
Logged
soccerpmn
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 33
0.00 points

View Inventory
Send Money to soccerpmn

View Profile WWW
« Reply #9 on: June 16, 2006, 05:11:11 PM »

Well I'm working on something involving lots of text, on various 'screens', that will probably be changed back and forth rather quickly and has to be scrollable.  I'm thinking of using text to image or whatever that function is, then make scrolling just move the actual image up and down...
Logged

stalin
CCCP - Crazy Communist C Programmer
Jr. Member
**

Karma: +0/-1
Offline Offline

Posts: 53
1620.46 points

View Inventory
Send Money to stalin


View Profile
« Reply #10 on: June 16, 2006, 06:05:28 PM »

when can we begin to expect part 3? im really looking forward to it
Logged
Insert_Witty_Name
Global Moderator
Hero Member
*

Karma: +148/-17
Offline Offline

Posts: 1602
1141.66 points

View Inventory
Send Money to Insert_Witty_Name

View Profile WWW
« Reply #11 on: June 17, 2006, 12:23:57 AM »

Quote from: "stalin"
when can we begin to expect part 3? im really looking forward to it


Not sure to be honest, I'm shying away from using the graphics.c stuff myself -- but I'll try and get part 3 up Sunday night.
Logged

Coder formerly known as:

Check out my homebrew & C tutorials at http://insomniac.0x89.org
Last updated 6th Oct 06 - Tutorial 2 added.
soccerpmn
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 33
0.00 points

View Inventory
Send Money to soccerpmn

View Profile WWW
« Reply #12 on: June 17, 2006, 06:15:01 PM »

What is this finished game going to be like?  I could try creating the finishing touches and send them to you, and we could discuss, collaborate, improve, tutorialize, etc.  Laughing
Logged

kenchin
Newbie
*

Karma: +0/-0
Offline Offline

Posts: 14
372.29 points

View Inventory
Send Money to kenchin

Developing as a Progrmmer


View Profile WWW
« Reply #13 on: December 01, 2006, 11:00:26 AM »

I really appreciate it , I'v been looking for a tut or diy psp game so that i could grasp the concept behind it's funtions.
as i am currently learning c , c++, opengl this helps a hell of a lot. I hope that i could use some of the functions in this tut for my future work. here's on of my demo's to show what i have learned . it will improve as i improve,tnx.

http://www.megaupload.com/?d=QHGME44P
Logged
emcp
Jr. Member
**

Karma: +1/-12
Offline Offline

Posts: 52
3142.80 points

View Inventory
Send Money to emcp

View Profile
« Reply #14 on: February 26, 2007, 12:14:25 PM »

great cant wait for part 3 seriously cant wait RELEASE RELEASE RELEASE  Very Happy

anyway in part 3 or 4 could you also tell us how to make the player stay in the middle and the map move or for the player to move a bit but also make the map move something like the Pokemon game Very Happy please

also i edited the player to go up and down and for the analog to control it

BTW can you use collision map in c++ and are they slow like in lua also what is the maximum size of pic you can display on screen

THANKS ALOT
 Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy Very Happy
« Last Edit: February 26, 2007, 01:10:59 PM by emcp » Logged
Pages: [1] 2
Print
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC Valid XHTML 1.0! Valid CSS!
Page created in 0.508 seconds with 36 queries.
Sister Sites: Guitar Hero 4   BrokeniTouch.com