1 Getting Started: C-Revisions and Introduction to Graphics Next: Simulation Essentials, Memory Handling
Topics for Discussion Elements of the Tank Game Compiling your program Simple Animation Double-buffering technique Keyboard handling Mouse handling Demo
3 Tank Game
Elements of the Game Graphics Engine Keyboard & mouse control Physics Engine Dynamic Memory handling Objects: Tank, Alien, Bomb, Bullet, Wall, Ledge Transformation Equations, Zooming features Trigonometric Equations
Demo C:\Core\Massey Papers\159234\Animation-2008-v.4.0 C:\Core\Massey Papers\159234\Bomb-v.1.0 C:\Core\Massey Papers\159234\Bomb-v.11.0 C:\Core\Massey Papers\159234\TankGame-2008-v.1.0 C:\Core\Massey Papers\159234\Assignments\Samples\A Sample\Tank Why resort to writing codes using the Object-Oriented approach?
What can you notice here? if(clock() > detonationTime){ for(int i=0; i < count; i++){ //Note: append Tank's x and y-components Wx = Xdev(WBound,DBound,x(obj[i].t,obj[i].vO, obj[i].theta) + TankX); Wy = Ydev(WBound,DBound,y(obj[i].t,obj[i].vO, obj[i].theta) + TankY); setlinestyle(SOLID_LINE, 0, 1); fillellipse(Wx,Wy,Xdev(WBound,DBound,3.0),Xdev(WBound,DBound,3.0)); obj[i].t=obj[i].t + obj[i].tInc; } t=t+tinc; } 6
What about here? for(int i=0; i < numOfBombs; i++){ b[i].activate(); b[i].tick(tfm); b[i].draw(tfm); } 7
8 C-Programming Revisions C-LANGUAGE STRUCTURE /* include statements */ #include /* define statements */ #define MAX 2000 /* function prototypes */ void subfunc(int argument); /* global variables */ int i, j; char c; float x,y; char s[80]; /* functions */ void subfunc(int argument) { int i; /* local variables */ statements... } /* main program */ int main() { statements... }
9 Compiling your Program MAKEFILE (for J JJ JFE) MyProg.exe: MyProg.o graphics.o gcc -wl,-s -o MyProg.exe MyProg.o graphics.o MyProg.o:MyProg.cpp graphics.h gcc -c -fpermissive -fconserve-space MyProg.cpp graphics.o: graphics.cpp graphics.h gcc -c -fpermissive -fconserve-space graphics.cpp Should start with a tab This is the minimum requirement for compilation. Turn on all the warning messages possible
10 Graphics Project WORKSPACE (JFE) MYPROG.CPP GRAPHICS.CPP GRAPHICS.H MAKEFILE GAME.WSP
11 Compiling your Program MAKEFILE (for s ss scite) MyProg.exe: MyProg.o graphics.o g++ g++ -wl,-s -o MyProg.exe MyProg.o graphics.o MyProg.o:MyProg.cpp graphics.h g++ g++ -c -fpermissive -fconserve-space MyProg.cpp graphics.o: graphics.cpp graphics.h g++ g++ -c -fpermissive -fconserve-space graphics.cpp This is the minimum requirement for compilation.
12 Makefile graphics.cpp graphics.h MyProg.cpp All must reside in the same folder It’s better to put classes in separate files. physics.cpp physics.h cpp The cpp file will include the function *.h Implementations, while the header file (*.h) will include the function prototypes and the class definition.
13 Incorporating more files... MAKEFILE (for scite) MyProg.exe: MyProg.o transform.o fuzzylogic.o physics.o bomb.o graphics.o g++ -Wl,-s -o MyProg.exe MyProg.o transform.o fuzzylogic.o physics.o bomb.o graphics.o MyProg.o:MyProg.cpp graphics.h transform.h fuzzylogic.h bomb.h gameDef.h g++ -c -fpermissive -fconserve-space MyProg.cpp transform.o: transform.cpp transform.h g++ -c -fpermissive -fconserve-space transform.cpp fuzzylogic.o: fuzzylogic.cpp fuzzylogic.h g++ -c -fpermissive -fconserve-space fuzzylogic.cpp physics.o: physics.cpp physics.h g++ -c -fpermissive -fconserve-space physics.cpp bomb.o: bomb.cpp bomb.h g++ -c -fpermissive -fconserve-space bomb.cpp graphics.o: graphics.cpp graphics.h g++ -c -fpermissive -fconserve-space graphics.cpp
14 C-Programming Revisions INITIALIZING GRAPHICS #include #include "graphics.h" int main(void) { srand(time(NULL)); // Seed the random number generator int GraphDriver=0,GraphMode=0; initgraph(&GraphDriver, &GraphMode, "", 1280, 1024 ); TankGame(); //start the game – this is user-defined function return 0; } User-defined, take note of the double quotes.
15 Simple Animation Single Page Animation (flickery!) void SinglePage() { int i; int x,y; cleardevice(); y=getmaxy()/2; while( (GetAsyncKeyState(VK_ESCAPE))==0 ) for(x=0;x<getmaxx();x++) { if(GetAsyncKeyState(VK_ESCAPE) != 0) break; setactivepage(0); cleardevice(); setfillstyle(SOLID_FILL,RED); fillellipse(x,y,12,12); rectangle(x,y+(getmaxy()/12),x+100,y+(getmaxy()/11)); settextjustify(CENTER_TEXT, CENTER_TEXT); settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4); outtextxy(getmaxx()/2,getmaxy()/8,"PAGE 0"); } Check if the ESC key has been pressed
Demo C:\Core\Massey Papers\159234\TankGame v.1.0 See SinglePage and double buffering animationsSee SinglePage and double buffering animations 16
17 Simple Animation Double-buffering Animation (flicker-free!) void MultiplePages() { int i, x, y; bool PageFlag=TRUE; setactivepage(1); cleardevice(); outtext("PAGE 1"); setvisualpage(1); y=getmaxy()/2; while( (GetAsyncKeyState(VK_ESCAPE))==0 ) for(x=0;x<getmaxx();x++) { if(GetAsyncKeyState(VK_ESCAPE) != 0) break; if (PageFlag) { setactivepage(0); cleardevice(); setfillstyle(SOLID_FILL,RED); fillellipse(x,y,12,12); rectangle(x,y+(getmaxy()/12),x+100,y+(getmaxy()/11)); settextjustify(CENTER_TEXT, CENTER_TEXT); settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4); outtextxy(getmaxx()/2,getmaxy()/8,"PAGE 0"); setvisualpage(0); } Continued...
18 C-Programming Revisions Double-buffering Animation (flicker-free!) void MultiplePages() {... while( (GetAsyncKeyState(VK_ESCAPE))==0 ) for(x=0;x<getmaxx();x++) { if(GetAsyncKeyState(VK_ESCAPE) != 0) break; if (PageFlag) {... } else { setactivepage(1); cleardevice(); setfillstyle(SOLID_FILL,RED); fillellipse(x,y,12,12); rectangle(x,y+(getmaxy()/12),x+100,y+(getmaxy()/11)); settextjustify(CENTER_TEXT, CENTER_TEXT); settextstyle(TRIPLEX_FONT, HORIZ_DIR, 4); outtextxy(getmaxx()/2,getmaxy()/8,"PAGE 1"); setvisualpage(1); } if(mousedown()) { } PageFlag=!PageFlag; }
19 Graphics Functions void cleardevice (void); cleardevice erases (that is, fills with the current background color) the entire graphics screen and moves the CP (current position) to home (0,0). e.g x 1024 pixels Device System of Coordinates +x +y 0 (X Device,Y Device )
20 Maximum Boundaries int getmaxx (void); int getmaxy (void); outtextxy(getmaxx()/2, getmaxy()/2, “Graphics"); (getmaxx(), getmaxy()) (0,0) Graphics
21 Graphics Functions DISPLAYING TEXT setcolor(YELLOW); settextstyle(DEFAULT_FONT, HORIZ_DIR, 3); settextjustify(CENTER_TEXT, CENTER_TEXT); outtextxy(200, 300, “Graphics"); See graphics.h for more options
Demo C:\Core\Massey Papers\159234\TankGame v.1.0 GraphicsDemo()See GraphicsDemo() 22
23 Graphics Functions DISPLAYING TEXT char mx[80]; float N; sprintf(mx,"%d",mousecurrentx()); moveto(105, 224); outtext(mx); N=4.5; sprintf(mx,"%3.2f", N); outtextxy(100, 250, mx); Get mouse current x-position
24 Graphics Functions DISPLAYING TEXT void settextstyle (int font, int direction, int charsize);settextstyle NameValue Description DEFAULT_FONT08x8 bit-mapped font TRIPLEX_FONT1Stroked triplex font SMALL_FONT2Stroked small font SANS_SERIF_FONT3Stroked sans-serif font GOTHIC_FONT4Stroked gothic font SCRIPT_FONT5Stroked script font SIMPLEX_FONT6Stroked triplex script font TRIPLEX_SCR_FONT 7Stroked triplex script font COMPLEX_FONT8Stroked complex font EUROPEAN_FONT9Stroked European font BOLD_FONT10Stroked bold font
25 Graphics Functions DISPLAYING TEXT void settextjustify (int horiz, int vert);settextjustify Description NameValue Action horiz LEFT_TEXT0left-justify text CENTER_TEXT1center text RIGHT_TEXT2right-justify text vertical BOTTOM_TEXT0bottom-justify text CENTER_TEXT1center text TOP_TEXT2top-justify text
26 Text Height, Text Width int textheight (char *textstring); int textwidth (char *textstring); Use textheight to compute the height of strings, instead of doing the computations manually. By using this function, no source code modifications have to be made when different fonts are selected
27 Mouse Routines int mousecurrentx(); int mousecurrenty(); int whichmousebutton(); LEFT_BUTTON RIGHT_BUTTON bool mouseup(); bool mousedown(); void clearmouse();
28 Introducing Delay void delay (int millisec); the length of time to sleep in milliseconds. delay(50); Sleep(100);
29 Setting the Color void setcolor (int color); Sets the text, line, circle, rectangle, ellipse, arc colors Affects outline color of all filled shapes setcolor(RED); setcolor(50); //From 0 to 64
30 Line Style void setlinestyle (int linestyle, unsigned upattern, int thickness); NameValue Description SOLID_LINE0Solid line DOTTED_LINE1Dotted line CENTER_LINE2Centered line DASHED_LINE3Dashed line USERBIT_LINE 4User-defined line style thickness specifies whether the width of subsequent lines drawn will be normal or thick. NameValue Description NORM_WIDTH11 pixel wide THICK_WIDTH 33 pixels wide
31 Rectangle void rectangle (int left, int top, int right, int bottom);
32 Fill Style void setfillstyle (int pattern, int color); Pattern: EMPTY_FILL, SOLID_FILL, LINE_FILL, LTSLASH_FILL, SLASH_FILL, BKSLASH_FILL, LTBKSLASH_FILL, HATCH_FILL, XHATCH_FILL, INTERLEAVE_FILL, WIDE_DOT_FILL, CLOSE_DOT_FILL, USER_FILL Affects filled-shapes
33 bar void bar (int left, int top, int right, int bottom); The upper left and lower right corners of the rectangle are given by (left, top) and (right, bottom), respectively. The coordinates refer to pixels.
34 Bar3D void bar3d (int left, int top, int right, int bottom, int depth, int topflag); bar3d draws a three-dimensional rectangular bar, then fills it using the current fill pattern and fill color. The three-dimensional outline of the bar is drawn in the current line style and color. The bar's depth in pixels is given by depth. The topflag parameter governs whether a three-dimensional top is put on the bar. If topflag is nonzero, a top is put on; otherwise, no top is put on the bar (making it possible to stack several bars on top of one another). The upper left and lower right corners of the rectangle are given by (left, top) and (right, bottom), respectively. To calculate a typical depth for bar3d, take 25% of the width of the bar, like this: bar3d(left,top,right,bottom, (right-left)/4,1);
35 Circle void circle (int x, int y, int radius);
36 Ellipse void ellipse (int x, int y, int stangle, int endangle, int xradius, int yradius); void fillellipse (int x, int y, int xradius, int yradius); ellipse draws an elliptical arc in the current drawing color with its center at (x,y) and the horizontal and vertical axes given by xradius and yradius, respectively. The ellipse travels from stangle to endangle. If stangle equals 0 and endangle equals 360, the call to ellipse draws a complete ellipse. The angle for ellipse is reckoned counterclockwise, with 0 degrees at 3 o'clock, 90 degrees at 12 o'clock, and so on. The linestyle parameter does not affect arcs, circles, ellipses, or pie slices. Only the thickness parameter is used.
37 Putpixel void putpixel (int x, int y, int color);
38 Arc void arc (int x, int y, int stangle, int endangle, int radius); Angles in degrees right. Counter-clockwise (90-up, 180-left, 270-down) The linestyle parameter does not affect arcs, circles, ellipses, or pie slices. Only the thickness parameter is used.
39 Pieslice void pieslice (int x, int y, int stangle, int endangle, int radius); Use with setcolor() and setfillstyle() functions
40 Fillpoly void fillpoly (int numpoints, int *polypoints); fillpoly draws the outline of a polygon with numpoints points in the current line style and color (just as drawpoly does), then fills the polygon using the current fill pattern and fill color. polypoints points to a sequence of (numpoints * 2) integers. Each pair of integers gives the x- and y-coordinates of a point on the polygon. Array of integers
41 Fillpoly Example void fillpoly (int numpoints, int *polypoints); int poly[8]; int maxx, maxy; maxx = getmaxx(); maxy = getmaxy(); poly[0] = 20; /* first vertex */ poly[1] = maxy / 2; poly[2] = maxx - 20; /* second vertex */ poly[3] = 20; poly[4] = maxx - 50; /* third vertex */ poly[5] = maxy - 20; poly[6] = maxx / 2; /* fourth, vertex */ poly[7] = maxy / 2; /* automatically closes the polygon */ fillpoly(4, poly); 4 points, 8 array elements
42 Keyboard Handling GetAsyncKeyState The GetAsyncKeyState function determines whether a key is up or down at the time the function is called, and whether the key was pressed after a previous call to GetAsyncKeyState. To find other pre-defined constants: google Using google, type the following keywords: msdn vk_shift Virtual-key code e.g. vk_shift vk_control SHORT GetAsyncKeyState( int vKey ); // vKey - virtual-key code
43 Keyboard Handling GetAsyncKeyState void MoveSprite() { if(GetAsyncKeyState(VK_UP) < 0) { SpriteY = SpriteY - 2; //up outtext("UP"); } if(GetAsyncKeyState(VK_DOWN) < 0) { SpriteY = SpriteY + 2; //down outtext("DOWN"); …. To find other pre-defined constants: Using google, type the following keywords: msdn virtual key codes
44 Keyboard Handling Monitoring the Control and Shift keys: if(GetAsyncKeyState(VK_CONTROL)<0) { ControlFlag =! ControlFlag; } bool ControlFlag, ShiftFlag; if(GetAsyncKeyState(VK_SHIFT)<0) { ShiftFlag =! ShiftFlag; } For the Tank to Jump to the Right: Control + Shift + Right Arrow key For the Tank to Jump to the Left: Control + Shift + Left Arrow key
45 Keyboard Handling Possible approach in monitoring key combinations : if(GetAsyncKeyState(VK_RIGHT)<0) { XDir=RIGHT; if(ShiftFlag) { outtext("SHIFT + RIGHT"); ShiftFlag=!ShiftFlag; } if(ControlFlag) { outtext("CTRL + RIGHT"); if (TankX < getmaxx()-W) TankX += 2; Angle=Angle-5; RaiseWheelFlag=TRUE; ControlFlag=!ControlFlag; } …