450 likes | 774 Vues
Next: Simulation Essentials, Memory Handling Getting Started: C-Revisions and Introduction to Graphics 159.234 Elements of the Tank Game Compiling your program Topics for Discussion Simple Animation Double-buffering technique Keyboard handling Mouse handling Demo Tank Game 159.234
E N D
Next: Simulation Essentials, Memory Handling Getting Started: C-Revisions and Introduction to Graphics
159.234 Elements of the Tank Game Compiling your program Topics for Discussion Simple Animation Double-buffering technique Keyboard handling Mouse handling Demo
159.234 Graphics Engine Keyboard & mouse control Elements of the Game 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\A1-06193242-Sample\Tank 2.0 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; }
What about here? for(int i=0; i < numOfBombs; i++){ b[i].activate(); b[i].tick(tfm); b[i].draw(tfm); }
159.234 C-LANGUAGE STRUCTURE /* include statements */ #include <stdio.h> #include <string.h> /* 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... } C-Programming Revisions
159.234 MAKEFILE (for JFE) Turn on all the warning messages possible Compiling your Program 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.
159.234 WORKSPACE (JFE) Graphics Project MYPROG.CPP GRAPHICS.CPP GRAPHICS.H MAKEFILE GAME.WSP
159.234 MAKEFILE (for scite) Compiling your Program MyProg.exe : MyProg.ographics.o g++ -wl,-s -o MyProg.exe MyProg.ographics.o MyProg.o : MyProg.cpp graphics.h g++ -c-fpermissive-fconserve-space MyProg.cpp graphics.o : graphics.cpp graphics.h g++ -c-fpermissive-fconserve-space graphics.cpp This is the minimum requirement for compilation.
All must reside in the same folder Makefile graphics.cpp MyProg.cpp physics.cpp graphics.h physics.h It’s better to put classes in separate files. The cpp file will include the function Implementations, while the header file (*.h) will include the function prototypes and the class definition.
159.234 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 Incorporating more files...
159.234 INITIALIZING GRAPHICS #include <windows.h> #include <stdio.h> #include <math.h> #include <time.h> #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; } C-Programming Revisions User-defined, take note of the double quotes.
159.234 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"); } } Simple Animation Check if the ESC key has been pressed
Demo • C:\Core\Massey Papers\159234\TankGame-2008-v.1.0 • See SinglePage and double buffering animations
159.234 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); } Simple Animation Continued...
159.234 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; } } C-Programming Revisions
159.234 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). Graphics Functions 0 +x e.g. 1280 x 1024 pixels (XDevice,YDevice) +y Device System of Coordinates
159.234 int getmaxx (void); int getmaxy (void); Maximum Boundaries outtextxy(getmaxx()/2, getmaxy()/2, “Graphics"); (0,0) Graphics (getmaxx(), getmaxy())
159.234 DISPLAYING TEXT Graphics Functions See graphics.h for more options setcolor(YELLOW); settextstyle(DEFAULT_FONT, HORIZ_DIR, 3); settextjustify(CENTER_TEXT, CENTER_TEXT); outtextxy(200, 300, “Graphics");
Demo • C:\Core\Massey Papers\159234\TankGame-2008-v.1.0 • See GraphicsDemo()
159.234 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); Graphics Functions Get mouse current x-position
159.234 DISPLAYING TEXT void settextstyle (int font, int direction, int charsize); Graphics Functions
159.234 DISPLAYING TEXT void settextjustify (int horiz, int vert); Graphics Functions
159.234 int textheight (char *textstring); int textwidth (char *textstring); Text Height, Text Width 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
159.234 int mousecurrentx(); int mousecurrenty(); int whichmousebutton(); LEFT_BUTTON RIGHT_BUTTON bool mouseup(); bool mousedown(); void clearmouse(); Mouse Routines
159.234 void delay (int millisec); • the length of time to sleep in milliseconds. Introducing Delay delay(50); Sleep(100);
159.234 void setcolor (int color); • Sets the text, line, circle, rectangle, ellipse, arc colors • Affects outline color of all filled shapes Setting the Color setcolor(RED); setcolor(50); //From 0 to 64
159.234 void setlinestyle (int linestyle, unsigned upattern, int thickness); Line Style thickness specifies whether the width of subsequent lines drawn will be normal or thick.
159.234 void rectangle (int left, int top, int right, int bottom); Rectangle
159.234 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 Fill Style • Affects filled-shapes
159.234 void bar (int left, int top, int right, int bottom); bar The upper left and lower right corners of the rectangle are given by (left, top) and (right, bottom), respectively. The coordinates refer to pixels.
159.234 void bar3d (int left, int top, int right, int bottom, int depth, int topflag); Bar3D • 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);
159.234 void circle (int x, int y, int radius); Circle
159.234 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 • 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.
159.234 void putpixel (int x, int y, int color); Putpixel
159.234 void arc (int x, int y, int stangle, int endangle, int radius); Arc • Angles in degrees 0-360. • 0-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.
159.234 void pieslice (int x, int y, int stangle, int endangle, int radius); Pieslice • Use with setcolor() and setfillstyle() functions
159.234 void fillpoly (int numpoints, int *polypoints); Fillpoly Array of integers • 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.
159.234 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); Fillpoly Example 4 points, 8 array elements
159.234 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. Keyboard Handling SHORT GetAsyncKeyState( int vKey); // vKey - virtual-key code • Virtual-key code • e.g. • vk_shift • vk_control To find other pre-defined constants: Using google, type the following keywords: msdnvk_shift
159.234 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"); …. Keyboard Handling To find other pre-defined constants: Using google, type the following keywords: msdn virtual key codes http://msdn.microsoft.com/en-us/library/ms645540(VS.85).aspx
Keyboard Handling Monitoring the Control and Shift keys: bool ControlFlag, ShiftFlag; if(GetAsyncKeyState(VK_CONTROL)<0) { ControlFlag =! ControlFlag; } 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
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; } …