SlideShare uma empresa Scribd logo
1 de 10
Baixar para ler offline
Pong
One of the first games. Tennis for Two and Space War were earlier, but they didn't have a score.
This is the first game and where possible, simplifications will be made. The goal is to develop game
construction principles that can be scaled. Rather than jump to what is the best solution, the code starts
off simple and will be improved on.
Focus on controls, core mechanic, playfield, design, and programming.

Objectives
   ● developing a plan: features, iterations, refactoring, scaling
   ● setting up a 3D camera
   ● drawing the court, paddles, ball in 3D
   ● setting up a 2D camera and drawing the heads up display in 2D
   ● handling player input: keyboard and joystick
   ● collisions with the playfield, reflections
   ● collisions with paddles, point versus rectangle
   ● dynamically created objects, pointers, clean coding
   ● game controller class follows the singleton pattern
   ● recording and playing sounds

Introduction
These are the notes that go along with the presentation.
There are lots of game development concepts to learn from even the simplest game. And pong is a
simple game. This development doesn't attempt to re-create a fun version of pong.

Development Plan: 1000 Features
The agile practice of creating a list of features you want in your game seems to work best. Write out a
list and give each feature an unique rank from 1000 to 0 -- 1000 being the most important to your
game. Generally devote more time and energy to the higher ranking features.
The feature list should include only things that can be seen, heard, felt, or otherwise tested by playing
the game and not include work under the hood.
       basic court, ball, paddles are drawn
   •
       ball collisions with the walls
   •
       input from keyboard
   •
       input from joysticks
   •
       ball collisions with the player paddles
   •
score displayed
   •
       game waits for start button, plays, ends
   •
       ball speeds up, English on the ball
   •

This list is meant to get the big things out on the table and also give you ideas for a development plan.

Development Plan: Iteration
Take a step back and think about the development process and your goals.
Game development lends itself well to an iterative approach. Build something small and work to
improve it in steps. Consistent forward progress depends on choosing the size and direction of your
iterative steps.
Games are built by combining a number of individual technologies. The set of technologies you must
pull together depend on the game, the engine, and the development environment.
Iteration steps should be small and able to be completed in one sitting. In the beginning of a project,
find steps that result in visual changes. Start by getting the main game objects drawn.
       a hello world window
   •
       overhead camera and drawing the court
   •
       draw the ball
   •
       draw the paddles
   •

Next, do one step with all the different tech your game needs. The goal is to write code that can be
improved on. The first part of a project focuses on a kind of breadth-first development. Keep your
steps small -- aim for something you will complete in one sitting.
       player input and connect it to the paddles
   •
       collisions of the ball with the court
   •
       collisions of the ball with the player paddles
   •
       playing of a sound
   •
       2D heads up display of score
   •

It's important not to wait too long before tackling this next stage. Setup your game to run in an attract
mode loop, play the game, and exit without any memory leaks.
       write a game controller that manages state transitions including the following
   •
       display a title screen
   •
       wait for start button to start the game
   •
       start and play the game until someone wins
   •
       display the game over screen
   •
       testing for clean, balanced coding
   •
       loop until the player exits
   •
       exit without any memory leaks
   •

After the first pass of your game elements and technology is completed, you will likely have some
messy code. Now is a good time to look at the overall structure of your game and decide if you can
improve it. Also, look at each system, improving the names usually leads to better code.
improve the structure
     •
         improve the names, define and follow a coherent approach
     •

Now, focus on the game itself. Iterate on the elements that stick out the most. Eventually, your focus
will change and instead of fixing things that are problems, you'll be improving things and looking for
ways to make things more interesting.
         find the worst thing, iterate on it until it's not the worst thing
     •
         find things that you can make better
     •

Realize that you will never run out of things to work on, but you will run out of time.

Developing a Plan: Refactoring
Plan on refactoring your code from the start. Rather than work to write perfect code, write good code
that can be refactored. This means that you should write code that with distinct names. Set yourself up
to be able to search and rename sections of code. Also, write code that groups a feature together.
Refactor the sections when they get too big or the logic starts getting tangled or they clearly belong in
their own function.
It seems that most code is refactored two or three times during a project. However, don't be over
anxious to refactor code, you should wait to refactor until the old code becomes unbearable.

The Game Loop
The beginning of the game controller class. Independent update and draw. Keep features orthogonal.

Class pointers and references
Pointers are an important part of game programming. Get used to using them.

Common Identifier Space
Start all of your identifiers at one. Reserve zero for defaults and uninitialized tests. Define one set of
identifiers. Use these for game ids, return codes, other uses.
enum {
   // int, unique ids for any use in the game
   // rather than have ids all over the place
   GAMEID_TMP=1, // reserved
   GAMEID_GAME, // game instance

     // game modes
     GAMEID_MODE_ATTRACT,
     GAMEID_MODE_GAME,

     // return codes
     GAMEID_BALL_REFLECT,
     GAMEID_BALL_OFFLEFT,
     GAMEID_BALL_OFFRIGHT,
};
Function construction
Initialize. Body. Finalize and exit. One return.
Initialization section must initialize all the objects. Design your objects so zeroing them initializes
them.
Return negative values for errors.
int function()
{
   int r;

    /////////////
    // initialize

    ///////
    // body

   r=0; // normal exit code, success
BAIL:
   /////////////////////
   // finalize, clean up

   return r;
} // function()

Free what you allocate
Clean up after yourself. Write your final code so that it is path independent. If non-zero, free and zero.

Public Classes
Projects go through a few phases. In the beginning, setup your code for flexibility. The beginning of a
project is marked by changes in direction and structure. One way to facilitate this is with classes with
all the elements marked public. Once you understand the problem space and your solution, you will
refactor your code to move fields into the private or protected. Until then, it will only slow you down.
Protecting fields becomes important when you scale your project up and add programmers. Be sure to
set aside time for this step.
Feature based accessors, not straight-to-vars. Peter Bennett.

Allocating and Freeing Objects
In C, memory allocated and freed with the malloc() and free() functions and objects must be setup by
the programmer. In C++, the new operator calls malloc() to allocate memory and calls the constructor
function to setup the object. Likewise, the delete operator calls the destructor function to cleanup the
object and then calls free() to release the memory.
Memory is one of your primary resources. Game objects are defined by classes and take up memory
when they are created.
QE Base Classes
Derive from qe base classes so all the allocations run through the engine. Objects derived from qe base
classes zero their memory when allocated.
Derive from qeUpdateBase for objects that are managed by the game engine. Normally, you will
override the update() and draw() functions with your own code.
Derive from qe for simple, non-managed objects.

Bracketing Resources
Bullet-proof your resource allocation and freeing. Build a structure that guarantees that you free all the
resources you allocate. This is accomplished with a 3-part structure: initialization, use, and
finalization.
The initialization is code that is guaranteed to run early in the game, and finalization code is guaranteed
to run before you exit. Initialization code should simply zero all resource fields. The finalization code,
which is also guaranteed to run, checks resource fields, frees any non-zero resource, and then zeros that
field. There must be only one owner of each resource and one initialization and finalization section of
code for each resource field.
The code that runs in-between the initialization and finalization must follow the simple rules to test the
resource field before each use and set the field if the resource is successfully created. This structure
allows you to bracket your resource usage and provides the necessary structure to write code that
guarantees balanced resource usage.
       initialization (guaranteed): zeros
   •
       finalization (guaranteed): tests, frees & zeros
   •
       usage: tests, allocates & sets, uses
   •

Game Controller Class
This class manages the game.
Load all the initial content including images and sounds.
Modes should be avoided because they promote structural discontinuity and ultimately complicate your
program greatly. However, modes do make prototyping easier and novice programmers should use
modes until a modeless structure resolves itself.
Start off in attract mode. When the start button is pressed, drop into game mode.
Attract mode waits for the start button and then drops into game mode. Display the last scores.
Game mode runs the game until the game is over. Then drops back into attract mode.

Matrices
A matrix is a set of numbers that define any combination of movements, rotations, and scaling of
objects in a 3D world. The matrices used here are 12 element matrices. The first 3 entries are the X,
Y, and Z positions. The next 9 entries define a simple rotation and scaling matrix. Taken together, the
12 elements are all you need for most game operations and qe provides a set of functions to operate on
the raw 12 element array of floats.
Simple 3D Camera
For now, it's best to use the code and experiment with it as you go.
Cameras are a software metaphor implemented with matrices. The camera matrix transforms objects
from world space into camera space. In other words, it treats the camera as the center of the world, and
moves and rotates everything in the world in front of the camera. In OpenGL, this matrix is called the
MODELVIEW matrix.
There are two matrices in OpenGL. You can think of the MODELVIEW matrix as the way you
position the camera, and the PROJECTION matrix as the camera's lens.
OpenGL's PROJECTION matrix transforms objects from camera space into clip coordinates. The
perspective division (divide by z) then transforms clip coordinates into normalized device coordinates.
These coordinates are then mapped through the viewport into a window.

BRK(), Code to Continue
This macro expands to into an interrupt call that breaks the program execution and 'wakes up' the
debugger at that point. If the debugger is not running, the macro has no effect. Write your code to
detect errors and continue running. Players don't want to see a dialog box asking them if they want to
send an error report to Microsoft. Even in extreme cases, do your best to continue running.
That said, you must detect and handle all errors. When you run into an error, report it, and write code
to do the best it can to continue running -- this may mean an object is drawn without a texture or may
even be missing.

Drawing The Court
The court is managed by the world class. A solid rectangle is drawn for the court.

// JFL 14 Aug 07
// JFL 15 Mar 09
int World::draw(void)
{
   glColor3f(0,0,1); // set color to blue
   glPolygonMode(GL_FRONT,GL_FILL); // draw filled polygons
   glBegin(GL_QUADS); // draw quads counter-clockwise from camera's view
      glVertex3f(this->xyzMin[0],this->xyzMin[1],this->xyzMin[2]);
      glVertex3f(this->xyzMin[0],this->xyzMin[1],this->xyzMax[2]);
      glVertex3f(this->xyzMax[0],this->xyzMin[1],this->xyzMax[2]);
      glVertex3f(this->xyzMax[0],this->xyzMin[1],this->xyzMin[2]);
   glEnd();
   return 0;
} // World::draw()

Reset Flags Once
Flags can be used to signal a request from many possible places. Handle the flag in one place. Test the
flag, clear it, call the handler. Clear the flag in only one section of code.
000ZY Coordinates
This choice is largely arbitrary, but should be something you're comfortable with. One unit = one foot
is the standard I use. This depends on the scale of your game, but should be determined before you
start coding.

Velocities
Variable frame rate systems must multiply the velocity by the amount of time elapsed since the last
loop. Keep track of the time since the last update.
   float t;

   // find time since last update
   t=this->timeOfLastUpdate;
   this->timeOfLastUpdate=qeTimeFrame();
   t=this->timeOfLastUpdate-t; // delta

   // xyz += vel*t
   this->xyz[0]+=this->vel[0]*t;
   this->xyz[1]+=this->vel[1]*t;
   this->xyz[2]+=this->vel[2]*t;

This update method -- moving by adding the velocity times the elapsed time -- is called Euler
integration. The timeOfLastUpdate variable must be reset when the object is reset.

3D World, Camera
The world is quot;in 3Dquot;. However, the camera is fixed above it and looking down. This gives the
appearance of a 2D game.
   //////////////////////
   // Camera class fields
   float fovyHalfRad; // field of view angle in y direction in radians
   float nearClip; // near clipping plane
   float farClip; // far clipping plane
   float winWidth; // in pixels
   float winHeight; // in pixels
   float winWDivH; // window aspect ratio
   float nearHeight; // height of window at near plane
   float mat12[12]; // camera matrix

   ///////////////////////
   // Camera setup -- once
   this->nearClip = 1;
   this->farClip = 500;
   this->fovyHalfRad = 0.5*((63*PI)/180.0); // 0.5*(degrees->radians)
   this->nearHeight = this->nearClip * MathTanf(this->fovyHalfRad);

   // camera matrix transforms from world space into camera space
   SET3(pos,0,CAMERA_Y,0); // position of camera
   SET3(at,0,0,0); // where camera is looking at
   SET3(up,0,0,-1); // the camera's up direction
   qeCamLookAtM12f(this->mat12,pos,at,up); // compute camera mat
/////////////////////////////////////////////////////
   // Camera matrices -- before you draw with the camera
   if(qeGetWindowSize(&this->winWidth,&this->winHeight)<0)
      bret(-2);
   this->winWDivH=this->winWidth/this->winHeight;

   // set the PROJECTION matrix (the camera lens)
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   float yy = this->nearHeight,xx=this->nearHeight*this->winWDivH;
   glFrustum(-xx,xx,-yy,yy,this->nearClip,this->farClip);

   // set the MODELVIEW matrix (position and orientation of the camera)
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   qeGLM12f(this->mat12); // set matrix

2D Gameplay
The keyboard and joystick are used for the player's up and down.

Keyboard as Buttons Input
By default, the keyboard acts like a set of buttons to the game engine. QE uses button counts which are
incremented when the buttons are pressed and released. When the button is down, the count is odd,
and when the button is up, the count is even. The bottom bit is set for odd numbers and can easily be
tested with a bitwise test.
       // up-down-left-right arrow mapping
       if(1&qeInpButton(QEINPBUTTON_UP))
          /* up button is pressed */;
       else if(1&qeInpButton(QEINPBUTTON_DOWN))
          /* down button is pressed */;

Joystick Input
Joystick positions are returned as floating point values. Some care should be taken to drop out the
values when the joystick is near the center.
   // get player 0 joystick value -1..0..1
   stick=qeInpJoyAxisf(0,QEJOYAXIS_LEFT_Y);

#define STICK_DEADZONE 0.2

   // enforce stick deadzone & re-normalize
   if(stick>STICK_DEADZONE)
      stick=(stick-STICK_DEADZONE)/(1.0-STICK_DEADZONE);
   else if(stick<-STICK_DEADZONE)
      stick=(stick+STICK_DEADZONE)/(1.0-STICK_DEADZONE);
   else // in deadzone, zero
      stick=0;

Sounds
Record sounds into .wav files. Most sound effects should be recorded in mono at a low resolution.
Trigger the sounds in the game.
// setup sound quot;bumpquot; on channel 1
    if((r=qeSndNew(quot;bumpquot;,M_SNDNEW_CH_1,0,quot;art/sounds/pongbump.wavquot;))<0)
       BRK();

    // trigger the sound
    qeSndPlay(quot;bumpquot;);

Use Restart Functions
Use restart rather than start functions. Names matter. Start functions usually hide assumptions
regarding the state of the game.

Drawing 2D: Camera and Image
Use the 32 bit image of the digits. The image has been created so there are 8 digits on the first row and
2 on the second row. 0 1 2 3 4 5 6 7 and 8 9.
    // register image
    if(qeImgNew(quot;icons1quot;,0,quot;art/images/icons1.tgaquot;)<0)
       BRK(); // make sure path is correct

    qeTexBind(quot;icons1quot;);

2D images are drawn the same way other polygons are drawn. However, the camera and draw modes
have to be setup correctly.
    qefnSysCamFlat(); // ortho: (0,0) top left (1,1) bottom right

    // setup texture mode to blend
    glPolygonMode(GL_FRONT,GL_FILL);
    glEnable(GL_TEXTURE_2D);
    glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD);
    glEnable(GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

Drawing 2D: UVs and Vertices
As always, vertex coordinates are specified in the space defined by the camera matrices and define the
structure of the object. UV coordinates define how the image maps from texture space to the polygon.
UVs are specified in normalized image space.
Ways to get the images to stretch or be drawn close to one to one from the image.
To find UVs, start with the image coordinates and divide by the image size.

        // find image coordinates for a positive integer n
        // icons in our image are 32x32 and there are 8 across horizontally
        // these coordinates are in pixel coordinates of the image
        // top left of the image 0,0
        u0=(n&7)*GAME_ICON_WIDTH;
        v0=(n>>3)*GAME_ICON_HEIGHT;

        // map image coordinates into uv space
        u0/=imgWidth;
        v0/=imgHeight;
Name Your Objects
Debugging is easier when object have string names. When debugging, checking the names of objects
is a good way to verify system and game integrity. Also, you can sometimes trap on on the name.

Mais conteúdo relacionado

Mais procurados

Kickstarter Game Thinking Teardown
Kickstarter Game Thinking TeardownKickstarter Game Thinking Teardown
Kickstarter Game Thinking TeardownAmy Jo Kim
 
Fundamentals of Game Design - Ch1
Fundamentals of Game Design - Ch1Fundamentals of Game Design - Ch1
Fundamentals of Game Design - Ch1Cynthia Marcello
 
Cerny method
Cerny methodCerny method
Cerny methodTim Holt
 
Electronic Arts
Electronic ArtsElectronic Arts
Electronic Arts1197sana
 
Beyond the HUD - User Interfaces for Increased Player Immersion in FPS Games
Beyond the HUD - User Interfaces for Increased Player Immersion in FPS GamesBeyond the HUD - User Interfaces for Increased Player Immersion in FPS Games
Beyond the HUD - User Interfaces for Increased Player Immersion in FPS GamesElectronic Arts / DICE
 
Introduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First GameIntroduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First GameSarah Sexton
 
Intro to unreal with framework and vr
Intro to unreal with framework and vrIntro to unreal with framework and vr
Intro to unreal with framework and vrLuis Cataldi
 
Introduction to the Theory of Game Elements
Introduction to the Theory of Game ElementsIntroduction to the Theory of Game Elements
Introduction to the Theory of Game ElementsAki Järvinen
 
The Basics of Unity - The Game Engine
The Basics of Unity - The Game EngineThe Basics of Unity - The Game Engine
The Basics of Unity - The Game EngineOrisysIndia
 
Putting the Fun in Functional
Putting the Fun in FunctionalPutting the Fun in Functional
Putting the Fun in FunctionalAmy Jo Kim
 
Creating a Game Design Document
Creating a Game Design DocumentCreating a Game Design Document
Creating a Game Design DocumentKarl Kapp
 
Introduction to game development
Introduction to game developmentIntroduction to game development
Introduction to game developmentGaetano Bonofiglio
 
Introduction to Game Engine: Concepts & Components
Introduction to Game Engine: Concepts & ComponentsIntroduction to Game Engine: Concepts & Components
Introduction to Game Engine: Concepts & ComponentsPouya Pournasir
 
Understanding casual games
Understanding casual gamesUnderstanding casual games
Understanding casual gamesDori Adar
 
Game monetization: Overview of monetization methods for free-to-play games
Game monetization: Overview of monetization methods for free-to-play gamesGame monetization: Overview of monetization methods for free-to-play games
Game monetization: Overview of monetization methods for free-to-play gamesAndrew Dotsenko
 
Gaming industry part 1 - introduction
Gaming industry  part 1 - introductionGaming industry  part 1 - introduction
Gaming industry part 1 - introductionMotaz Agamawi
 
Making a Game Design Document
Making a Game Design DocumentMaking a Game Design Document
Making a Game Design DocumentEqual Experts
 
Game development Pre-Production
Game development Pre-ProductionGame development Pre-Production
Game development Pre-ProductionKevin Duggan
 

Mais procurados (20)

Kickstarter Game Thinking Teardown
Kickstarter Game Thinking TeardownKickstarter Game Thinking Teardown
Kickstarter Game Thinking Teardown
 
Fundamentals of Game Design - Ch1
Fundamentals of Game Design - Ch1Fundamentals of Game Design - Ch1
Fundamentals of Game Design - Ch1
 
Cerny method
Cerny methodCerny method
Cerny method
 
01 - Introduction to Game Mechanics
01 - Introduction to Game Mechanics01 - Introduction to Game Mechanics
01 - Introduction to Game Mechanics
 
Electronic Arts
Electronic ArtsElectronic Arts
Electronic Arts
 
Beyond the HUD - User Interfaces for Increased Player Immersion in FPS Games
Beyond the HUD - User Interfaces for Increased Player Immersion in FPS GamesBeyond the HUD - User Interfaces for Increased Player Immersion in FPS Games
Beyond the HUD - User Interfaces for Increased Player Immersion in FPS Games
 
Introduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First GameIntroduction to Unity3D and Building your First Game
Introduction to Unity3D and Building your First Game
 
Intro to unreal with framework and vr
Intro to unreal with framework and vrIntro to unreal with framework and vr
Intro to unreal with framework and vr
 
Phases of game development
Phases of game developmentPhases of game development
Phases of game development
 
Introduction to the Theory of Game Elements
Introduction to the Theory of Game ElementsIntroduction to the Theory of Game Elements
Introduction to the Theory of Game Elements
 
The Basics of Unity - The Game Engine
The Basics of Unity - The Game EngineThe Basics of Unity - The Game Engine
The Basics of Unity - The Game Engine
 
Putting the Fun in Functional
Putting the Fun in FunctionalPutting the Fun in Functional
Putting the Fun in Functional
 
Creating a Game Design Document
Creating a Game Design DocumentCreating a Game Design Document
Creating a Game Design Document
 
Introduction to game development
Introduction to game developmentIntroduction to game development
Introduction to game development
 
Introduction to Game Engine: Concepts & Components
Introduction to Game Engine: Concepts & ComponentsIntroduction to Game Engine: Concepts & Components
Introduction to Game Engine: Concepts & Components
 
Understanding casual games
Understanding casual gamesUnderstanding casual games
Understanding casual games
 
Game monetization: Overview of monetization methods for free-to-play games
Game monetization: Overview of monetization methods for free-to-play gamesGame monetization: Overview of monetization methods for free-to-play games
Game monetization: Overview of monetization methods for free-to-play games
 
Gaming industry part 1 - introduction
Gaming industry  part 1 - introductionGaming industry  part 1 - introduction
Gaming industry part 1 - introduction
 
Making a Game Design Document
Making a Game Design DocumentMaking a Game Design Document
Making a Game Design Document
 
Game development Pre-Production
Game development Pre-ProductionGame development Pre-Production
Game development Pre-Production
 

Destaque

Making A Game Engine Is Easier Than You Think
Making A Game Engine Is Easier Than You ThinkMaking A Game Engine Is Easier Than You Think
Making A Game Engine Is Easier Than You ThinkGorm Lai
 
Global Game Jam @ Develop
Global Game Jam @ DevelopGlobal Game Jam @ Develop
Global Game Jam @ DevelopGorm Lai
 
Gdc09 Minipong
Gdc09 MinipongGdc09 Minipong
Gdc09 MinipongSusan Gold
 
SIGGRAPH 2007 IGDA Presentation
SIGGRAPH 2007 IGDA PresentationSIGGRAPH 2007 IGDA Presentation
SIGGRAPH 2007 IGDA PresentationSusan Gold
 
Gdc09 Minigames
Gdc09 MinigamesGdc09 Minigames
Gdc09 MinigamesSusan Gold
 
Global Game Jam @ Develop 09
Global Game Jam @ Develop 09Global Game Jam @ Develop 09
Global Game Jam @ Develop 09Gorm Lai
 
Game Jams & Hobbyists
Game Jams & HobbyistsGame Jams & Hobbyists
Game Jams & HobbyistsGorm Lai
 
Gold And Robinson 2009
Gold And Robinson 2009Gold And Robinson 2009
Gold And Robinson 2009Susan Gold
 

Destaque (9)

Making A Game Engine Is Easier Than You Think
Making A Game Engine Is Easier Than You ThinkMaking A Game Engine Is Easier Than You Think
Making A Game Engine Is Easier Than You Think
 
Global Game Jam @ Develop
Global Game Jam @ DevelopGlobal Game Jam @ Develop
Global Game Jam @ Develop
 
Gdc09 Minipong
Gdc09 MinipongGdc09 Minipong
Gdc09 Minipong
 
SIGGRAPH 2007 IGDA Presentation
SIGGRAPH 2007 IGDA PresentationSIGGRAPH 2007 IGDA Presentation
SIGGRAPH 2007 IGDA Presentation
 
Gdc09 Minigames
Gdc09 MinigamesGdc09 Minigames
Gdc09 Minigames
 
Global Game Jam @ Develop 09
Global Game Jam @ Develop 09Global Game Jam @ Develop 09
Global Game Jam @ Develop 09
 
Game Jams & Hobbyists
Game Jams & HobbyistsGame Jams & Hobbyists
Game Jams & Hobbyists
 
Community
CommunityCommunity
Community
 
Gold And Robinson 2009
Gold And Robinson 2009Gold And Robinson 2009
Gold And Robinson 2009
 

Semelhante a Pong

Game Development Session - 3 | Introduction to Unity
Game Development Session - 3 | Introduction to  UnityGame Development Session - 3 | Introduction to  Unity
Game Development Session - 3 | Introduction to UnityKoderunners
 
Game programming workshop
Game programming workshopGame programming workshop
Game programming workshopnarigadu
 
LAFS Game Design 7 - Prototyping
LAFS Game Design 7 - PrototypingLAFS Game Design 7 - Prototyping
LAFS Game Design 7 - PrototypingDavid Mullich
 
Making a game "Just Right" through testing and play balancing
Making a game "Just Right" through testing and play balancingMaking a game "Just Right" through testing and play balancing
Making a game "Just Right" through testing and play balancingJulio Gorgé
 
Easy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkeyEasy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkeypprem
 
Rockstar Games
Rockstar GamesRockstar Games
Rockstar GamesRae Clarke
 
DevLearn 2017 Play to Learn workshop slides
DevLearn 2017 Play to Learn workshop slidesDevLearn 2017 Play to Learn workshop slides
DevLearn 2017 Play to Learn workshop slidesSharon Boller
 
The complete srs documentation of our developed game.
The complete srs documentation of our developed game. The complete srs documentation of our developed game.
The complete srs documentation of our developed game. Isfand yar Khan
 
Quality Assurance 1: Why Quality Matters
Quality Assurance 1: Why Quality MattersQuality Assurance 1: Why Quality Matters
Quality Assurance 1: Why Quality MattersMarc Miquel
 
Lecture 2: C# Programming for VR application in Unity
Lecture 2: C# Programming for VR application in UnityLecture 2: C# Programming for VR application in Unity
Lecture 2: C# Programming for VR application in UnityKobkrit Viriyayudhakorn
 
Unreal Engine Basics 01 - Game Framework
Unreal Engine Basics 01 - Game FrameworkUnreal Engine Basics 01 - Game Framework
Unreal Engine Basics 01 - Game FrameworkNick Pruehs
 
Game Design Document - Step by Step Guide
Game Design Document - Step by Step GuideGame Design Document - Step by Step Guide
Game Design Document - Step by Step GuideDevBatch Inc.
 
Galactic Wars XNA Game
Galactic Wars XNA GameGalactic Wars XNA Game
Galactic Wars XNA GameSohil Gupta
 
Unity Google VR Cardboard Deployment on iOS and Android
Unity Google VR Cardboard Deployment on iOS and AndroidUnity Google VR Cardboard Deployment on iOS and Android
Unity Google VR Cardboard Deployment on iOS and AndroidKobkrit Viriyayudhakorn
 
DSC RNGPIT - Getting Started with Game Development Day 1
DSC RNGPIT - Getting Started with Game Development Day 1DSC RNGPIT - Getting Started with Game Development Day 1
DSC RNGPIT - Getting Started with Game Development Day 1DeepMevada1
 
Requirement Engineering process on The Outer Worlds game
Requirement Engineering process on The Outer Worlds gameRequirement Engineering process on The Outer Worlds game
Requirement Engineering process on The Outer Worlds gameAmna Khalil
 

Semelhante a Pong (20)

Game Development Session - 3 | Introduction to Unity
Game Development Session - 3 | Introduction to  UnityGame Development Session - 3 | Introduction to  Unity
Game Development Session - 3 | Introduction to Unity
 
Game programming workshop
Game programming workshopGame programming workshop
Game programming workshop
 
LAFS Game Design 7 - Prototyping
LAFS Game Design 7 - PrototypingLAFS Game Design 7 - Prototyping
LAFS Game Design 7 - Prototyping
 
Making a game "Just Right" through testing and play balancing
Making a game "Just Right" through testing and play balancingMaking a game "Just Right" through testing and play balancing
Making a game "Just Right" through testing and play balancing
 
Easy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkeyEasy coding a multi device game with FireMonkey
Easy coding a multi device game with FireMonkey
 
Rockstar Games
Rockstar GamesRockstar Games
Rockstar Games
 
DevLearn 2017 Play to Learn workshop slides
DevLearn 2017 Play to Learn workshop slidesDevLearn 2017 Play to Learn workshop slides
DevLearn 2017 Play to Learn workshop slides
 
The complete srs documentation of our developed game.
The complete srs documentation of our developed game. The complete srs documentation of our developed game.
The complete srs documentation of our developed game.
 
Quality Assurance 1: Why Quality Matters
Quality Assurance 1: Why Quality MattersQuality Assurance 1: Why Quality Matters
Quality Assurance 1: Why Quality Matters
 
Lecture 2: C# Programming for VR application in Unity
Lecture 2: C# Programming for VR application in UnityLecture 2: C# Programming for VR application in Unity
Lecture 2: C# Programming for VR application in Unity
 
Unreal Engine Basics 01 - Game Framework
Unreal Engine Basics 01 - Game FrameworkUnreal Engine Basics 01 - Game Framework
Unreal Engine Basics 01 - Game Framework
 
Game Design Document - Step by Step Guide
Game Design Document - Step by Step GuideGame Design Document - Step by Step Guide
Game Design Document - Step by Step Guide
 
Galactic Wars XNA Game
Galactic Wars XNA GameGalactic Wars XNA Game
Galactic Wars XNA Game
 
Programmers guide
Programmers guideProgrammers guide
Programmers guide
 
3
33
3
 
4
44
4
 
Unity Google VR Cardboard Deployment on iOS and Android
Unity Google VR Cardboard Deployment on iOS and AndroidUnity Google VR Cardboard Deployment on iOS and Android
Unity Google VR Cardboard Deployment on iOS and Android
 
DSC RNGPIT - Getting Started with Game Development Day 1
DSC RNGPIT - Getting Started with Game Development Day 1DSC RNGPIT - Getting Started with Game Development Day 1
DSC RNGPIT - Getting Started with Game Development Day 1
 
Requirement Engineering process on The Outer Worlds game
Requirement Engineering process on The Outer Worlds gameRequirement Engineering process on The Outer Worlds game
Requirement Engineering process on The Outer Worlds game
 
HTML5 Game Development frameworks overview
HTML5 Game Development frameworks overviewHTML5 Game Development frameworks overview
HTML5 Game Development frameworks overview
 

Mais de Susan Gold

Mais de Susan Gold (18)

ICEC
ICECICEC
ICEC
 
Dgxpo
DgxpoDgxpo
Dgxpo
 
Fog
FogFog
Fog
 
Ivdc
IvdcIvdc
Ivdc
 
GDC 2009 Game Design Improv
GDC 2009 Game Design ImprovGDC 2009 Game Design Improv
GDC 2009 Game Design Improv
 
Gdc09 Minimissile
Gdc09 MinimissileGdc09 Minimissile
Gdc09 Minimissile
 
Setup
SetupSetup
Setup
 
Qe Reference
Qe ReferenceQe Reference
Qe Reference
 
Missilecommand
MissilecommandMissilecommand
Missilecommand
 
Assignment Pong
Assignment PongAssignment Pong
Assignment Pong
 
Global Game Jam Overview
Global Game Jam OverviewGlobal Game Jam Overview
Global Game Jam Overview
 
Agd Talk Speed Run
Agd Talk   Speed RunAgd Talk   Speed Run
Agd Talk Speed Run
 
Mscruise
MscruiseMscruise
Mscruise
 
GDC China 2007
GDC China 2007GDC China 2007
GDC China 2007
 
Digra07
Digra07Digra07
Digra07
 
Boston IGDA Meeting
Boston IGDA MeetingBoston IGDA Meeting
Boston IGDA Meeting
 
Curriculumframework2008
Curriculumframework2008Curriculumframework2008
Curriculumframework2008
 
Game Program Highlights
Game Program HighlightsGame Program Highlights
Game Program Highlights
 

Pong

  • 1. Pong One of the first games. Tennis for Two and Space War were earlier, but they didn't have a score. This is the first game and where possible, simplifications will be made. The goal is to develop game construction principles that can be scaled. Rather than jump to what is the best solution, the code starts off simple and will be improved on. Focus on controls, core mechanic, playfield, design, and programming. Objectives ● developing a plan: features, iterations, refactoring, scaling ● setting up a 3D camera ● drawing the court, paddles, ball in 3D ● setting up a 2D camera and drawing the heads up display in 2D ● handling player input: keyboard and joystick ● collisions with the playfield, reflections ● collisions with paddles, point versus rectangle ● dynamically created objects, pointers, clean coding ● game controller class follows the singleton pattern ● recording and playing sounds Introduction These are the notes that go along with the presentation. There are lots of game development concepts to learn from even the simplest game. And pong is a simple game. This development doesn't attempt to re-create a fun version of pong. Development Plan: 1000 Features The agile practice of creating a list of features you want in your game seems to work best. Write out a list and give each feature an unique rank from 1000 to 0 -- 1000 being the most important to your game. Generally devote more time and energy to the higher ranking features. The feature list should include only things that can be seen, heard, felt, or otherwise tested by playing the game and not include work under the hood. basic court, ball, paddles are drawn • ball collisions with the walls • input from keyboard • input from joysticks • ball collisions with the player paddles •
  • 2. score displayed • game waits for start button, plays, ends • ball speeds up, English on the ball • This list is meant to get the big things out on the table and also give you ideas for a development plan. Development Plan: Iteration Take a step back and think about the development process and your goals. Game development lends itself well to an iterative approach. Build something small and work to improve it in steps. Consistent forward progress depends on choosing the size and direction of your iterative steps. Games are built by combining a number of individual technologies. The set of technologies you must pull together depend on the game, the engine, and the development environment. Iteration steps should be small and able to be completed in one sitting. In the beginning of a project, find steps that result in visual changes. Start by getting the main game objects drawn. a hello world window • overhead camera and drawing the court • draw the ball • draw the paddles • Next, do one step with all the different tech your game needs. The goal is to write code that can be improved on. The first part of a project focuses on a kind of breadth-first development. Keep your steps small -- aim for something you will complete in one sitting. player input and connect it to the paddles • collisions of the ball with the court • collisions of the ball with the player paddles • playing of a sound • 2D heads up display of score • It's important not to wait too long before tackling this next stage. Setup your game to run in an attract mode loop, play the game, and exit without any memory leaks. write a game controller that manages state transitions including the following • display a title screen • wait for start button to start the game • start and play the game until someone wins • display the game over screen • testing for clean, balanced coding • loop until the player exits • exit without any memory leaks • After the first pass of your game elements and technology is completed, you will likely have some messy code. Now is a good time to look at the overall structure of your game and decide if you can improve it. Also, look at each system, improving the names usually leads to better code.
  • 3. improve the structure • improve the names, define and follow a coherent approach • Now, focus on the game itself. Iterate on the elements that stick out the most. Eventually, your focus will change and instead of fixing things that are problems, you'll be improving things and looking for ways to make things more interesting. find the worst thing, iterate on it until it's not the worst thing • find things that you can make better • Realize that you will never run out of things to work on, but you will run out of time. Developing a Plan: Refactoring Plan on refactoring your code from the start. Rather than work to write perfect code, write good code that can be refactored. This means that you should write code that with distinct names. Set yourself up to be able to search and rename sections of code. Also, write code that groups a feature together. Refactor the sections when they get too big or the logic starts getting tangled or they clearly belong in their own function. It seems that most code is refactored two or three times during a project. However, don't be over anxious to refactor code, you should wait to refactor until the old code becomes unbearable. The Game Loop The beginning of the game controller class. Independent update and draw. Keep features orthogonal. Class pointers and references Pointers are an important part of game programming. Get used to using them. Common Identifier Space Start all of your identifiers at one. Reserve zero for defaults and uninitialized tests. Define one set of identifiers. Use these for game ids, return codes, other uses. enum { // int, unique ids for any use in the game // rather than have ids all over the place GAMEID_TMP=1, // reserved GAMEID_GAME, // game instance // game modes GAMEID_MODE_ATTRACT, GAMEID_MODE_GAME, // return codes GAMEID_BALL_REFLECT, GAMEID_BALL_OFFLEFT, GAMEID_BALL_OFFRIGHT, };
  • 4. Function construction Initialize. Body. Finalize and exit. One return. Initialization section must initialize all the objects. Design your objects so zeroing them initializes them. Return negative values for errors. int function() { int r; ///////////// // initialize /////// // body r=0; // normal exit code, success BAIL: ///////////////////// // finalize, clean up return r; } // function() Free what you allocate Clean up after yourself. Write your final code so that it is path independent. If non-zero, free and zero. Public Classes Projects go through a few phases. In the beginning, setup your code for flexibility. The beginning of a project is marked by changes in direction and structure. One way to facilitate this is with classes with all the elements marked public. Once you understand the problem space and your solution, you will refactor your code to move fields into the private or protected. Until then, it will only slow you down. Protecting fields becomes important when you scale your project up and add programmers. Be sure to set aside time for this step. Feature based accessors, not straight-to-vars. Peter Bennett. Allocating and Freeing Objects In C, memory allocated and freed with the malloc() and free() functions and objects must be setup by the programmer. In C++, the new operator calls malloc() to allocate memory and calls the constructor function to setup the object. Likewise, the delete operator calls the destructor function to cleanup the object and then calls free() to release the memory. Memory is one of your primary resources. Game objects are defined by classes and take up memory when they are created.
  • 5. QE Base Classes Derive from qe base classes so all the allocations run through the engine. Objects derived from qe base classes zero their memory when allocated. Derive from qeUpdateBase for objects that are managed by the game engine. Normally, you will override the update() and draw() functions with your own code. Derive from qe for simple, non-managed objects. Bracketing Resources Bullet-proof your resource allocation and freeing. Build a structure that guarantees that you free all the resources you allocate. This is accomplished with a 3-part structure: initialization, use, and finalization. The initialization is code that is guaranteed to run early in the game, and finalization code is guaranteed to run before you exit. Initialization code should simply zero all resource fields. The finalization code, which is also guaranteed to run, checks resource fields, frees any non-zero resource, and then zeros that field. There must be only one owner of each resource and one initialization and finalization section of code for each resource field. The code that runs in-between the initialization and finalization must follow the simple rules to test the resource field before each use and set the field if the resource is successfully created. This structure allows you to bracket your resource usage and provides the necessary structure to write code that guarantees balanced resource usage. initialization (guaranteed): zeros • finalization (guaranteed): tests, frees & zeros • usage: tests, allocates & sets, uses • Game Controller Class This class manages the game. Load all the initial content including images and sounds. Modes should be avoided because they promote structural discontinuity and ultimately complicate your program greatly. However, modes do make prototyping easier and novice programmers should use modes until a modeless structure resolves itself. Start off in attract mode. When the start button is pressed, drop into game mode. Attract mode waits for the start button and then drops into game mode. Display the last scores. Game mode runs the game until the game is over. Then drops back into attract mode. Matrices A matrix is a set of numbers that define any combination of movements, rotations, and scaling of objects in a 3D world. The matrices used here are 12 element matrices. The first 3 entries are the X, Y, and Z positions. The next 9 entries define a simple rotation and scaling matrix. Taken together, the 12 elements are all you need for most game operations and qe provides a set of functions to operate on the raw 12 element array of floats.
  • 6. Simple 3D Camera For now, it's best to use the code and experiment with it as you go. Cameras are a software metaphor implemented with matrices. The camera matrix transforms objects from world space into camera space. In other words, it treats the camera as the center of the world, and moves and rotates everything in the world in front of the camera. In OpenGL, this matrix is called the MODELVIEW matrix. There are two matrices in OpenGL. You can think of the MODELVIEW matrix as the way you position the camera, and the PROJECTION matrix as the camera's lens. OpenGL's PROJECTION matrix transforms objects from camera space into clip coordinates. The perspective division (divide by z) then transforms clip coordinates into normalized device coordinates. These coordinates are then mapped through the viewport into a window. BRK(), Code to Continue This macro expands to into an interrupt call that breaks the program execution and 'wakes up' the debugger at that point. If the debugger is not running, the macro has no effect. Write your code to detect errors and continue running. Players don't want to see a dialog box asking them if they want to send an error report to Microsoft. Even in extreme cases, do your best to continue running. That said, you must detect and handle all errors. When you run into an error, report it, and write code to do the best it can to continue running -- this may mean an object is drawn without a texture or may even be missing. Drawing The Court The court is managed by the world class. A solid rectangle is drawn for the court. // JFL 14 Aug 07 // JFL 15 Mar 09 int World::draw(void) { glColor3f(0,0,1); // set color to blue glPolygonMode(GL_FRONT,GL_FILL); // draw filled polygons glBegin(GL_QUADS); // draw quads counter-clockwise from camera's view glVertex3f(this->xyzMin[0],this->xyzMin[1],this->xyzMin[2]); glVertex3f(this->xyzMin[0],this->xyzMin[1],this->xyzMax[2]); glVertex3f(this->xyzMax[0],this->xyzMin[1],this->xyzMax[2]); glVertex3f(this->xyzMax[0],this->xyzMin[1],this->xyzMin[2]); glEnd(); return 0; } // World::draw() Reset Flags Once Flags can be used to signal a request from many possible places. Handle the flag in one place. Test the flag, clear it, call the handler. Clear the flag in only one section of code.
  • 7. 000ZY Coordinates This choice is largely arbitrary, but should be something you're comfortable with. One unit = one foot is the standard I use. This depends on the scale of your game, but should be determined before you start coding. Velocities Variable frame rate systems must multiply the velocity by the amount of time elapsed since the last loop. Keep track of the time since the last update. float t; // find time since last update t=this->timeOfLastUpdate; this->timeOfLastUpdate=qeTimeFrame(); t=this->timeOfLastUpdate-t; // delta // xyz += vel*t this->xyz[0]+=this->vel[0]*t; this->xyz[1]+=this->vel[1]*t; this->xyz[2]+=this->vel[2]*t; This update method -- moving by adding the velocity times the elapsed time -- is called Euler integration. The timeOfLastUpdate variable must be reset when the object is reset. 3D World, Camera The world is quot;in 3Dquot;. However, the camera is fixed above it and looking down. This gives the appearance of a 2D game. ////////////////////// // Camera class fields float fovyHalfRad; // field of view angle in y direction in radians float nearClip; // near clipping plane float farClip; // far clipping plane float winWidth; // in pixels float winHeight; // in pixels float winWDivH; // window aspect ratio float nearHeight; // height of window at near plane float mat12[12]; // camera matrix /////////////////////// // Camera setup -- once this->nearClip = 1; this->farClip = 500; this->fovyHalfRad = 0.5*((63*PI)/180.0); // 0.5*(degrees->radians) this->nearHeight = this->nearClip * MathTanf(this->fovyHalfRad); // camera matrix transforms from world space into camera space SET3(pos,0,CAMERA_Y,0); // position of camera SET3(at,0,0,0); // where camera is looking at SET3(up,0,0,-1); // the camera's up direction qeCamLookAtM12f(this->mat12,pos,at,up); // compute camera mat
  • 8. ///////////////////////////////////////////////////// // Camera matrices -- before you draw with the camera if(qeGetWindowSize(&this->winWidth,&this->winHeight)<0) bret(-2); this->winWDivH=this->winWidth/this->winHeight; // set the PROJECTION matrix (the camera lens) glMatrixMode(GL_PROJECTION); glLoadIdentity(); float yy = this->nearHeight,xx=this->nearHeight*this->winWDivH; glFrustum(-xx,xx,-yy,yy,this->nearClip,this->farClip); // set the MODELVIEW matrix (position and orientation of the camera) glMatrixMode(GL_MODELVIEW); glLoadIdentity(); qeGLM12f(this->mat12); // set matrix 2D Gameplay The keyboard and joystick are used for the player's up and down. Keyboard as Buttons Input By default, the keyboard acts like a set of buttons to the game engine. QE uses button counts which are incremented when the buttons are pressed and released. When the button is down, the count is odd, and when the button is up, the count is even. The bottom bit is set for odd numbers and can easily be tested with a bitwise test. // up-down-left-right arrow mapping if(1&qeInpButton(QEINPBUTTON_UP)) /* up button is pressed */; else if(1&qeInpButton(QEINPBUTTON_DOWN)) /* down button is pressed */; Joystick Input Joystick positions are returned as floating point values. Some care should be taken to drop out the values when the joystick is near the center. // get player 0 joystick value -1..0..1 stick=qeInpJoyAxisf(0,QEJOYAXIS_LEFT_Y); #define STICK_DEADZONE 0.2 // enforce stick deadzone & re-normalize if(stick>STICK_DEADZONE) stick=(stick-STICK_DEADZONE)/(1.0-STICK_DEADZONE); else if(stick<-STICK_DEADZONE) stick=(stick+STICK_DEADZONE)/(1.0-STICK_DEADZONE); else // in deadzone, zero stick=0; Sounds Record sounds into .wav files. Most sound effects should be recorded in mono at a low resolution. Trigger the sounds in the game.
  • 9. // setup sound quot;bumpquot; on channel 1 if((r=qeSndNew(quot;bumpquot;,M_SNDNEW_CH_1,0,quot;art/sounds/pongbump.wavquot;))<0) BRK(); // trigger the sound qeSndPlay(quot;bumpquot;); Use Restart Functions Use restart rather than start functions. Names matter. Start functions usually hide assumptions regarding the state of the game. Drawing 2D: Camera and Image Use the 32 bit image of the digits. The image has been created so there are 8 digits on the first row and 2 on the second row. 0 1 2 3 4 5 6 7 and 8 9. // register image if(qeImgNew(quot;icons1quot;,0,quot;art/images/icons1.tgaquot;)<0) BRK(); // make sure path is correct qeTexBind(quot;icons1quot;); 2D images are drawn the same way other polygons are drawn. However, the camera and draw modes have to be setup correctly. qefnSysCamFlat(); // ortho: (0,0) top left (1,1) bottom right // setup texture mode to blend glPolygonMode(GL_FRONT,GL_FILL); glEnable(GL_TEXTURE_2D); glTexEnvi(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_ADD); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA); Drawing 2D: UVs and Vertices As always, vertex coordinates are specified in the space defined by the camera matrices and define the structure of the object. UV coordinates define how the image maps from texture space to the polygon. UVs are specified in normalized image space. Ways to get the images to stretch or be drawn close to one to one from the image. To find UVs, start with the image coordinates and divide by the image size. // find image coordinates for a positive integer n // icons in our image are 32x32 and there are 8 across horizontally // these coordinates are in pixel coordinates of the image // top left of the image 0,0 u0=(n&7)*GAME_ICON_WIDTH; v0=(n>>3)*GAME_ICON_HEIGHT; // map image coordinates into uv space u0/=imgWidth; v0/=imgHeight;
  • 10. Name Your Objects Debugging is easier when object have string names. When debugging, checking the names of objects is a good way to verify system and game integrity. Also, you can sometimes trap on on the name.