📄 g06-01.cpp
字号:
// ============================================================================
// G06-01.cpp
// Linked List Inventory Demo
// ============================================================================
#include "SDL.h"
#include "SDLHelpers.h"
#include "DLinkedList.h"
#include <stdlib.h>
// ============================================================================
// Global Constants
// ============================================================================
const char PROGRAM_NAME[] = "Game Demo 06-01: Inventory Demo";
const int WIDTH = 640;
const int HEIGHT = 480;
const int ICONS = 8;
// ============================================================================
// Classes
// ============================================================================
class Item
{
public:
int m_type;
int m_weight;
};
class Player
{
public:
int m_weightMax;
int m_currentWeight;
DLinkedList<Item> m_inventory;
};
enum States
{
NOSTATE,
LEFT,
RIGHT
};
// ============================================================================
// Global Variables
// ============================================================================
// this is the main window for the framework
SDL_Surface* g_window = 0;
// the text bitmaps
SDL_Surface* g_weight = 0; // "Current Weight:"
SDL_Surface* g_playerWeight = 0; // "Total Weight:"
// the bitmaps
SDL_Surface* g_icons[ICONS];
// the player
Player g_player;
// the iterator used to access the inventory.
DListIterator<Item> g_itr;
// the timer
int g_timer;
// the current state
States g_state = NOSTATE;
// the font
TTF_Font* g_font;
// ============================================================================
// Functions
// ============================================================================
void AddItem( int p_type )
{
// create a new item with 10-20 weight.
Item item;
item.m_type = p_type;
item.m_weight = rand() % 11 + 10;
// check if the weight is greater than the max weight.
if( item.m_weight + g_player.m_currentWeight < g_player.m_weightMax )
{
// if not, add the item, and increase the current weight.
g_player.m_inventory.Append( item );
g_player.m_currentWeight += item.m_weight;
}
}
void RemoveItem( DListIterator<Item>& p_itr )
{
// if the current iterator is valid
if( p_itr.Valid() )
{
// remove the weight of the item
g_player.m_currentWeight -= p_itr.Item().m_weight;
// remove the item
g_player.m_inventory.Remove( p_itr );
}
}
void CalculateText()
{
if( g_weight )
SDL_FreeSurface( g_weight );
if( g_playerWeight )
SDL_FreeSurface( g_playerWeight );
static char text[80];
if( g_itr.Valid() )
{
sprintf( text, "Weight: %d", g_itr.Item().m_weight );
}
else
{
sprintf( text, "Weight: None." );
}
g_weight = TTF_RenderText_Shaded( g_font, text, BLACK, WHITE );
sprintf( text, "Total Weight: %d/%d",
g_player.m_currentWeight, g_player.m_weightMax );
g_playerWeight = TTF_RenderText_Shaded( g_font, text, BLACK, WHITE );
}
void DrawIcons()
{
int x = (WIDTH - (ICONS * 64)) / 2;
int i;
for( i = 0; i < ICONS; i++ )
{
SDLBlit( g_icons[i], g_window, x, 400 );
x += 64;
}
}
void DrawInventory()
{
// in order to display the list with the current
// item in the center, we need to find out
// the index of the current item.
int current = 0;
// find the index of the current item.
DListIterator<Item> itr = g_player.m_inventory.GetIterator();
for( itr.Start(); itr.Valid(); itr.Forth() )
{
if( itr == g_itr )
break;
current++;
}
// now that we know the index of the current item, we can calculate
// where to start drawing the list.
int x = ((WIDTH / 2) - 32) - (64 * current);
int d = ((SDL_GetTicks() - g_timer) * 64) / 500;
// determine the direction of movement, if any.
switch( g_state )
{
case NOSTATE:
d = 0;
break;
case LEFT:
d = -64 + d;
break;
case RIGHT:
d = 64 - d;
break;
}
for( itr.Start(); itr.Valid(); itr.Forth() )
{
SDLBlit( g_icons[itr.Item().m_type],
g_window, x + d , 200 );
x += 64;
}
SDLLine( g_window, (WIDTH / 2) - 32, 200, (WIDTH / 2) - 32, 264, BLACK );
SDLLine( g_window, (WIDTH / 2) + 32, 200, (WIDTH / 2) + 32, 264, BLACK );
SDLLine( g_window, (WIDTH / 2) - 32, 200, (WIDTH / 2) + 32, 200, BLACK );
SDLLine( g_window, (WIDTH / 2) - 32, 264, (WIDTH / 2) + 32, 264, BLACK );
}
int main( int argc, char* argv[] )
{
// declare coordinates.
int x, y, i, w;
// declare event holder
SDL_Event event;
// initialize the video system.
SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER );
SDL_WM_SetCaption( PROGRAM_NAME, 0);
// set our at exit function
atexit( SDL_Quit );
// set the video mode.
g_window = SDL_SetVideoMode( WIDTH, HEIGHT, 0, SDL_ANYFORMAT );
TTF_Init();
g_font = TTF_OpenFont( "arial.ttf", 20 );
TTF_SetFontStyle( g_font, TTF_STYLE_NORMAL );
// load the bmps
g_icons[0] = SDL_LoadBMP( "wepicon-sword.bmp" );
g_icons[1] = SDL_LoadBMP( "wepicon-axe.bmp" );
g_icons[2] = SDL_LoadBMP( "wepicon-spear.bmp" );
g_icons[3] = SDL_LoadBMP( "wepicon-dagger.bmp" );
g_icons[4] = SDL_LoadBMP( "wepicon-mace.bmp" );
g_icons[5] = SDL_LoadBMP( "wepicon-bow.bmp" );
g_icons[6] = SDL_LoadBMP( "wepicon-shield.bmp" );
g_icons[7] = SDL_LoadBMP( "wepicon-helm.bmp" );
// set the color keys, so the clear pixels aren't drawn
for( x = 0; x < ICONS; x++ )
{
SDL_SetColorKey( g_icons[x], SDL_SRCCOLORKEY,
SDL_MapRGB( g_icons[x]->format, 0, 255, 255 ) );
}
// create initial inventory
Item item;
// add a sword as an initial item
item.m_type = 0;
item.m_weight = rand() % 11 + 10;
g_player.m_inventory.Append( item );
g_player.m_currentWeight = item.m_weight;
g_player.m_weightMax = 100;
// reset the iterator to point to the list.
g_itr = g_player.m_inventory.GetIterator();
g_timer = SDL_GetTicks();
CalculateText();
while( 1 )
{
//look for an event
if( SDL_PollEvent( &event ) )
{
//an event was found
if( event.type == SDL_QUIT )
break;
if( event.type == SDL_MOUSEBUTTONDOWN )
{
// get the mouse state.
SDL_GetMouseState( &x, &y );
}
if( event.type == SDL_MOUSEBUTTONUP )
{
// get the mouse state.
SDL_GetMouseState( &x, &y );
// if y is between 400 and 464, then check to see if
// an icon was clicked.
if( y >= 400 && y <= 464 )
{
w = (WIDTH - (ICONS * 64)) / 2;
i = (x - w) / 64;
// add a new item with a random weight from 10-20
if( i >= 0 && i < ICONS )
{
AddItem( i );
if( g_itr.Valid() == false )
g_itr.Start();
CalculateText();
}
}
// if y is between 200 and 264, then check to see if
// the white box was clicked.
if( y >= 200 && y <= 264 )
{
if( x >= (WIDTH / 2) - 32 && x <= (WIDTH / 2) + 32 )
{
RemoveItem( g_itr );
CalculateText();
}
}
}
if( event.type == SDL_KEYDOWN )
{
// a key was pressed.
if( event.key.keysym.sym == SDLK_ESCAPE )
{
// if ESC was pressed, quit the program.
SDL_Event quit;
quit.type = SDL_QUIT;
SDL_PushEvent( &quit );
}
if( event.key.keysym.sym == SDLK_LEFT && g_state == NOSTATE )
{
// move the iterator backwards
g_timer = SDL_GetTicks();
g_state = LEFT;
g_itr.Back();
// if the iterator went past the end, reset it to the start
// again.
if( !g_itr.Valid() )
{
g_state = NOSTATE;
g_itr.Start();
}
CalculateText();
}
if( event.key.keysym.sym == SDLK_RIGHT && g_state == NOSTATE )
{
// move the iterator forwards
g_timer = SDL_GetTicks();
g_state = RIGHT;
g_itr.Forth();
// if the iterator went past the end, reset it to the beginning
// again.
if( !g_itr.Valid() )
{
g_state = NOSTATE;
g_itr.End();
}
CalculateText();
}
if( event.key.keysym.sym == SDLK_UP )
{
// increase the maximum weight
g_player.m_weightMax += 50;
CalculateText();
}
if( event.key.keysym.sym == SDLK_DOWN )
{
// decrease the maximum weight
g_player.m_weightMax -= 50;
CalculateText();
}
}
} // end event loop.
// it takes 500 milliseconds to move to the next item,
// so if 500 ms have passed since the last timer reset,
// set the state to NOSTATE.
if( (SDL_GetTicks() - g_timer) >= 500 )
g_state = NOSTATE;
// if the iterator isn't valid, move it to the start again.
if( !g_itr.Valid() )
g_itr.Start();
// clear the screen to black.
SDL_FillRect( g_window, NULL, SDL_MapRGB( g_window->format, 255, 255, 255 ) );
DrawIcons();
DrawInventory();
SDLBlit( g_weight, g_window, 10, 30 );
SDLBlit( g_playerWeight, g_window, 10, 0 );
// update the entire window.
SDL_UpdateRect( g_window, 0, 0, 0, 0 );
}
// done
return 0;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -