1. Trang chủ
  2. » Công Nghệ Thông Tin

Game Programming All in One 2 nd Edition phần 3 pps

74 366 0

Đang tải... (xem toàn văn)

Tài liệu hạn chế xem trước, để xem đầy đủ mời bạn chọn Tải xuống

THÔNG TIN TÀI LIỆU

Thông tin cơ bản

Tiêu đề Writing Your First Allegro Game
Trường học Free Software Foundation
Chuyên ngành Game Programming
Thể loại Essay
Năm xuất bản 2025
Thành phố Unknown
Định dạng
Số trang 74
Dung lượng 515,41 KB

Các công cụ chuyển đổi và chỉnh sửa cho tài liệu này

Nội dung

Writing Your First A llegro Game This chapter forges ahead with a lot of things I haven’t discussed yet, such as colli-sion detection and keyboard input, but the Tank War game that is c

Trang 1

Writing Your First

A llegro Game

This chapter forges ahead with a lot of things I haven’t discussed yet, such as

colli-sion detection and keyboard input, but the Tank War game that is created in this

chapter will help you absorb all the information presented thus far You’ll see how

you can use the graphics primitives you learned in Chapter 3 to create a complete game

with support for two players You will learn how to draw and move a tank around on the

screen using nothing but simple pixel and rectangle drawing functions You will learn how

to look at the video screen to determine when a projectile strikes a tank or another object,

how to read the keyboard, and how to process a game loop The goal of this chapter is to

show you that you can create an entire game using the meager resources provided thus far

(in the form of the Allegro functions you have already learned) and to introduce some

new functionality that will be covered in more detail in later chapters

Here is a breakdown of the major topics in this chapter:

I Creating the tanks

If this is your first foray into game programming, then Tank War is likely your very first

game! There is always a lot of joy involved in seeing your first game running on the screen

In the mid-1980s I subscribed to several of the popular computer magazines, such as

Family Computing and Compute!, which provided small program listings in the BASIC

Trang 2

language, most often games I can still remember some of the games I painstakingly typed

in from the magazine using Microsoft GW-BASIC on my old Tandy 1000 The gamesnever ran on the first try! I would often miss entire lines of code, even with the benefit ofline numbers in the old style of BASIC

Today there are fantastic development tools that quite often cost nothing and yet porate some of the most advanced compiler technology available The Free SoftwareFoundation (http://www.fsf.org) has done the world a wonderful service by inspiring andfunding the development of free software Perhaps the most significant contribution bythe FSF is the GNU Compiler Collection, fondly known as GCC Oddly enough, this verysame compiler is used on both Windows and Linux platforms by the Dev-C++ andKDevelop tools, respectively The format of structured and object-oriented code is mucheasier to read and follow than in the numbered lines of the past

incor-Tank War is a two-player game that is played on a single screen using a shared keyboard.

The first player uses the W, A, S, and D keys to move his tank, and the Spacebar to fire the maincannon on the tank The second player uses the arrow keys for movement and the Enterkey to fire The game is shown in Figure 4.1

Creating the Tanks

The graphics in Tank War are created entirely with the drawing functions included in

Allegro Figure 4.2 shows the four angles of the tank that are drawn based on the tank’sdirection of travel

Figure 4.1 Tank War is a two-player game in the classic style

Trang 3

Thedrawtankfunction is called from the main loop to draw each tank according to its

current direction The drawtankfunction looks like this:

void drawtank(int num)

{

int x = tanks[num].x;

int y = tanks[num].y;

int dir = tanks[num].dir;

//draw tank body and turret

rectfill(screen, x-11, y-11, x+11, y+11, tanks[num].color);

rectfill(screen, x-6, y-6, x+6, y+6, 7);

//draw the treads based on orientation

if (dir == 0 || dir == 2)

{

rectfill(screen, x-16, y-16, x-11, y+16, 8);

rectfill(screen, x+11, y-16, x+16, y+16, 8);

}

else

if (dir == 1 || dir == 3)

{

rectfill(screen, x-16, y-16, x+16, y-11, 8);

rectfill(screen, x-16, y+16, x+16, y+11, 8);

rectfill(screen, x, y-1, x+16, y+1, 8);

Figure 4.2 The tanks are rendered on the screen using a series of filled rectangles.

Trang 4

void erasetank(int num)

{

//calculate box to encompass the tank

int left = tanks[num].x - 17;

int top = tanks[num].y - 17;

int right = tanks[num].x + 17;

int bottom = tanks[num].y + 17;

//erase the tank

rectfill(screen, left, top, right, bottom, 0);

}

Theerasetankfunction is calculated based on the center of the tank (which is how the tank

is drawn as well, from the center) Because the tank is 32×32 pixels in size, the erasetank

function draws a black filled rectangle a distance of 17 pixels in each direction from thecenter (for a total of 34×34 pixels, to include a small border around the tank, which helps

to keep the tank from getting stuck in obstacles)

Firing Weapons

The projectiles fired from each tank are drawn as small rectangles (four pixels total) thatmove in the current direction the tank is facing until they strike the other tank, an object,

or the edge of the screen You can increase the size of the projectile by increasing the size

in the updatebulletfunction (coming up next) To determine whether a hit has occurred,you use the getpixelfunction to “look” at the pixel on the screen right in front of the bul-let If that pixel is black (color 0 or RGB 0,0,0), then the bullet is moved another space

Trang 5

If that color is anything other than black, then it is a sure hit! The fireweaponfunction gets

the bullet started in the right direction

void fireweapon(int num)

Trang 6

} }

}

Thefireweaponfunction looks at the direction of the current tank to set the X and Y ment values for the bullet Once it is set up, the bullet will move in that direction until itstrikes something or reaches the edge of the screen The important variable here is alive,which determines whether the bullet is moved accordingly using this updatebulletfunction:

move-void updatebullet(int num)

//move bullet bullets[num].x += bullets[num].xspd;

bullets[num].alive = 0;

return;

} //draw bullet

x = bullets[num].x;

y = bullets[num].y;

rect(screen, x-1, y-1, x+1, y+1, 14);

//look for a hit

if (getpixel(screen, bullets[num].x, bullets[num].y)) {

bullets[num].alive = 0;

explode(num, x, y);

}

Trang 7

//print the bullet’s position

textprintf(screen, font, SCREEN_W/2-50, 1, 2,

To move the tank, each player uses the appropriate keys to move forward, backward, left,

right, and to fire the weapon The first player uses W, A, S, and D to move and the Spacebar

to fire, while player two uses the arrow keys to move and Enter to fire The main loop

looks for a key press and calls on the getinputfunction to see which key has been pressed

I will discuss keyboard input in a later chapter; for now all you need to be aware of is an

array called keythat stores the values of each key press

Trang 8

a little strategy to the game; they offer a place to hide or maneuver around (or straightthrough if you blow up the obstacles) The clearpathfunction is used to determine whetherthe ship can move The function checks the screen boundaries and obstacles on the screen

to clear a path for the tank or prevent it from moving any further in that direction Thefunction also takes into account reverse motion because the tanks can move forward orbackward.clearpathis a bit lengthy, so I’ll leave it for the main code listing later in the chap-ter The clearpathfunction calls the checkpathfunction to actually see whether the tank’spathway is clear for movement (checkpathis called multiple times for each tank.)

int checkpath(int x1,int y1,int x2,int y2,int x3,int y3)

{

if (getpixel(screen, x1, y1) ||

getpixel(screen, x2, y2) ||

getpixel(screen, x3, y3)) return 1;

mod-The Complete Tank War Source Code

The code listing for Tank War is included here in its entirety Despite having already

shown you many of the functions in this program, I think it’s important at this point toshow you the entire listing in one fell swoop so there is no confusion Of course, you can

open the Tank War project that is located on the CD-ROM that accompanies this book;

look inside a folder called chapter04 for the complete project for Visual C++, Dev-C++,

or KDevelop If you are using some other operating system, you can still compile this code

Trang 9

for your favorite compiler by typing it into your text editor and including the Allegro

library (If you need some pointers, refer to Appendix E, “Configuring Allegro for Microsoft

Visual C++ and Other Compilers.”)

The Tank War Header File

The first code listing is for the header file, which includes the variables, structures,

con-stants, and function prototypes for the game You will want to add a new file to the

pro-ject called tankwar.h The main source code file (main.c) will try to include the header file

by this filename If you need help configuring your compiler to link to the Allegro game

library, refer to Appendix E If you have not yet installed Allegro, you might want to go

back and read Chapter 2 and refer to Appendix F, “Compiling the Allegro Source Code.”

/////////////////////////////////////////////////////////////////////////

// Game Programming All In One, Second Edition

// Source Code Copyright (C)2004 by Jonathan S Harbour

// Chapter 4 - Tank War Game

/////////////////////////////////////////////////////////////////////////

#ifndef _TANKWAR_H

#define _TANKWAR_H

#include “allegro.h”

//define some game constants

#define MODE GFX_AUTODETECT_WINDOWED

#define TAN makecol(255,242,169)

#define CAMO makecol(64,142,66)

#define BURST makecol(255,189,73)

//define tank structure

Trang 10

void drawtank(int num);

void erasetank(int num);

void movetank(int num);

void explode(int num, int x, int y);

void updatebullet(int num);

int checkpath(int x1,int y1,int x2,int y2,int x3,int y3);

void clearpath(int num);

void fireweapon(int num);

void forward(int num);

void backward(int num);

void turnleft(int num);

void turnright(int num);

The Tank War Source File

The primary source code file for Tank War includes the tankwar.h header file (which in

turn includes allegro.h) Included in this code listing are all of the functions needed by thegame in addition to the mainfunction (containing the game loop) You can type this code

in as-is for whatever OS and IDE you are using; if you have included the Allegro library,

it will run without issue This game is wonderfully easy to get to work because it requires

no bitmap files, uses no backgrounds, and simply draws directly to the primary screenbuffer (which can be full-screen or windowed)

Trang 11

// Game Programming All In One, Second Edition

// Source Code Copyright (C)2004 by Jonathan S Harbour

// Chapter 4 - Tank War Game

int dir = tanks[num].dir;

//draw tank body and turret

rectfill(screen, x-11, y-11, x+11, y+11, tanks[num].color);

rectfill(screen, x-6, y-6, x+6, y+6, 7);

//draw the treads based on orientation

if (dir == 0 || dir == 2)

{

rectfill(screen, x-16, y-16, x-11, y+16, 8);

rectfill(screen, x+11, y-16, x+16, y+16, 8);

}

else

if (dir == 1 || dir == 3)

{

rectfill(screen, x-16, y-16, x+16, y-11, 8);

rectfill(screen, x-16, y+16, x+16, y+11, 8);

Trang 12

// erase the tank using rectfill

///////////////////////////////////////////////////////////////////////// void erasetank(int num)

{

//calculate box to encompass the tank

int left = tanks[num].x - 17;

int top = tanks[num].y - 17;

int right = tanks[num].x + 17;

int bottom = tanks[num].y + 17;

//erase the tank

rectfill(screen, left, top, right, bottom, 0);

}

///////////////////////////////////////////////////////////////////////// // movetank function

// move the tank in the current direction

///////////////////////////////////////////////////////////////////////// void movetank(int num)

{

int dir = tanks[num].dir;

int speed = tanks[num].speed;

//update tank position based on direction

Trang 14

//is bullet inside the boundary of the enemy tank?

if (x > tx-16 && x < tx+16 && y > ty-16 && y < ty+16)

//clear the area of debris

rectfill(screen, x-16, y-16, x+16, y+16, 0);

}

///////////////////////////////////////////////////////////////////////// // updatebullet function

// update the position of a bullet

///////////////////////////////////////////////////////////////////////// void updatebullet(int num)

//move bullet bullets[num].x += bullets[num].xspd;

bullets[num].alive = 0;

return;

}

Trang 15

//draw bullet

x = bullets[num].x;

y = bullets[num].y;

rect(screen, x-1, y-1, x+1, y+1, 14);

//look for a hit

if (getpixel(screen, bullets[num].x, bullets[num].y))

{

bullets[num].alive = 0;

explode(num, x, y);

}

//print the bullet’s position

textprintf(screen, font, SCREEN_W/2-50, 1, 2,

Trang 16

int speed = tanks[num].speed;

if (checkpath(x-16, y-20, x, y-20, x+16, y-20)) tanks[num].speed = 0;

} else //if reverse dir, check south

if (checkpath(x-16, y+20, x, y+20, x+16, y+20)) tanks[num].speed = 0;

break;

//check pixels east case 1:

if (speed > 0) {

if (checkpath(x+20, y-16, x+20, y, x+20, y+16)) tanks[num].speed = 0;

} else //if reverse dir, check west

if (checkpath(x-20, y-16, x-20, y, x-20, y+16)) tanks[num].speed = 0;

break;

//check pixels south case 2:

if (speed > 0) {

if (checkpath(x-16, y+20, x, y+20, x+16, y+20 )) tanks[num].speed = 0;

} else //if reverse dir, check north

if (checkpath(x-16, y-20, x, y-20, x+16, y-20)) tanks[num].speed = 0;

Trang 17

//if reverse dir, check east

if (checkpath(x+20, y-16, x+20, y, x+20, y+16)) tanks[num].speed = 0;

Trang 18

///////////////////////////////////////////////////////////////////////// // forward function

// increase the tank’s speed

///////////////////////////////////////////////////////////////////////// void forward(int num)

// decrease the tank’s speed

///////////////////////////////////////////////////////////////////////// void backward(int num)

Trang 20

//arrow / ENTER keys control tank 2

// add a point to the specified player’s score

///////////////////////////////////////////////////////////////////////// void score(int player)

// set up the starting condition of each tank

///////////////////////////////////////////////////////////////////////// void setuptanks()

Trang 21

x = BLOCKSIZE + rand() % (SCREEN_W-BLOCKSIZE*2);

y = BLOCKSIZE + rand() % (SCREEN_H-BLOCKSIZE*2);

size = (10 + rand() % BLOCKSIZE)/2;

color = makecol(rand()%255, rand()%255, rand()%255);

rectfill(screen, x-size, y-size, x+size, y+size, color);

//set video mode

int ret = set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0);

if (ret != 0) {

allegro_message(allegro_error);

return;

}

Trang 22

//print title

textprintf(screen, font, 1, 1, BURST,

“Tank War - %dx%d”, SCREEN_W, SCREEN_H);

//draw screen border

rect(screen, 0, 12, SCREEN_W-1, SCREEN_H-1, TAN);

rect(screen, 1, 13, SCREEN_W-2, SCREEN_H-2, TAN);

}

///////////////////////////////////////////////////////////////////////// // main function

// start point of the program

///////////////////////////////////////////////////////////////////////// void main(void)

Trang 23

//update the bullets

Congratulations on completing your first game with Allegro! It has been a short journey

thus far—we’re only in the fourth chapter of the book Contrast this with the enormous

amount of information that would have been required in advance to compile even a simple

game, such as Tank War, using standard graphics libraries, such as DirectX or SVGAlib!

It would have taken this amount of source code just to set up the screen and prepare the

program for the actual game That is where Allegro truly shines—by abstracting the

logis-tical issues into a common set of library functions that work regardless of the underlying

operating system

This also concludes Part I of the book and sends you venturing into Part II, which covers

the core functionality of Allegro in much more detail You will learn how to use animated

sprites and create scrolling backgrounds, and we’ll discuss the next upgrade to Tank War.

That’s right, this isn’t the end of Tank War! From this point forward, we’ll be improving

the game with each new chapter For starters, this game really needs some design and

direction (the focus of Chapter 5) By the time you’re finished, the game will feature a

scrolling background, a tile-based battlefield, sound effects…the whole works!

Trang 24

Chapter Quiz

You can find the answers to this chapter quiz in Appendix A, “Chapter Quiz Answers.”

1 What is the primary graphics drawing function used to draw the tanks in Tank War?

4 What is the name of the organization that produced GCC?

A Free Software Foundation

Trang 25

7 What function in Tank War keeps the tanks from colliding with other objects?

Trang 27

Programming the

Keyboard, Mouse,

and Joystick

Welcome to the input chapter, focusing on programming the keyboard, mouse,

and joystick! This chapter is a lot of fun, and I know you will enjoy learning

about these three input devices because there are some great example programs

here to demonstrate how to get a handle on this subject By the time you have finished this

chapter, you will be able to scan for individual keys, read their scan codes, and detect

mul-tiple button presses You will learn about Allegro’s buffered keyboard input routines and

discover ASCII (See Appendix B, “Useful Tables,” for a table of ASCII values.) You will

learn how to read the mouse position, create a custom graphical mouse pointer, check up

on the mouse wheel, and discover something called mickeys You will also learn how to

read the joystick, find out what features the currently installed joystick provides (such as

analog/digital sticks, buttons, hats, sliders, and so on), and read the joystick values to

pro-vide input for a game As you go through this chapter, you will discover several sample

programs that make the subjects easy to understand, including a stargate program, a

mis-sile defense system, a hyperspace teleportation program, and a joystick program that

involves bouncing balls Are you ready to dig into the fun subject of device input?

I thought so! Let’s do it

Here is a breakdown of the major topics in this chapter:

I Handling keyboard input

I Detecting key presses

I Dealing with buffered keyboard input

I Handling mouse input

I Reading the mouse position

I Working with relative mouse motion

I Handling joystick input

Trang 28

I Handling joystick controller movement

I Handling joystick button presses

Handling Keyboard Input

Allegro provides functions for handling buffered input and individual key states.Keyboard input might seem strange to gamers who have dedicated their lives to consolegames, but the keyboard has been the mainstay of PC gaming for two dozen years andcounting, and it is not likely to be replaced anytime soon The joystick has had only lim-ited acceptance on the PC, but the mouse has had a larger influence on games, primarilydue to modern operating systems Allegro supports both ANSI (one-byte) and Unicode

(two-byte) character systems (By the way, ANSI stands for American National Standards

Institute and ASCII stands for American Standard Code for Information Interchange.)

The Keyboard Handler

Allegro abstracts the keyboard from the operating system so the generic keyboard routineswill work on any computer system you have targeted for your game (Windows, Linux, Mac,and so on) However, that abstraction does not take anything away from the inherent capa-bilities of any system because the library is custom-written for each platform TheWindows version of Allegro utilizes DirectInput for the keyboard handler Since there really

is no magic to the subject, let’s just jump right in and work with the keyboard

Before you can start using the keyboard routines in Allegro, you must initialize the board handler with the install_keyboardfunction

key-int install_keyboard();

If you try to use the keyboard routines before initializing, the program will likely crash (or

at best, it won’t respond to the keyboard) Once you have initialized the keyboard handler,there is no need to uninitialize it—that is handled by Allegro via the allegro_exitfunction(which is called automatically before Allegro stops running) But if you do find a need toremove the keyboard handler, you can use remove_keyboard

void remove_keyboard();

Some operating systems, such as those with preemptive multitasking, do not support thekeyboard interrupt handler that Allegro uses You can use the poll_keyboardfunction topoll the keyboard if your program will need to be run on systems that don’t support thekeyboard interrupt service routine Why would this be the case? Allegro is a multi-threadedlibrary When you call allegro_initand functions such as install_keyboard, Allegro createsseveral threads to handle events, scroll the screen, draw sprites, and so on

int poll_keyboard();

Trang 29

When you first call poll_keyboard, Allegro switches to polled mode, after which the

key-board must be polled even if an interrupt or a thread is available To determine when

polling mode is active, use the keyboard_needs_pollfunction

int keyboard_needs_poll();

Detecting Key Presses

Allegro makes it very easy to detect key presses To check for an individual key, you can

use the keyarray that is populated with values when the keyboard is polled (or during

reg-ular intervals, when run as a thread)

extern volatile char key[KEY_MAX];

Most of the keys on computer systems are supported by name using constant key values

defined in the Allegro library header files If you want to see all of the key definitions

your-self, look in the Allegro library folder for a header file called keyboard.h, in which all the

keys are defined Note also thatAllegro defines individual keys,not ASCII codes, so the mainnumeric keys are not the same asthe numeric keypad keys, and theCtrl, Alt, and Shift keys are treatedindividually Pressing Shift+Aresults in two key presses, not justthe “A” key The buffered keyboardroutines (covered next) will dif-ferentiate lowercase “a” fromuppercase “A.” Table 5.1 lists a few

of the most common key codes

Table 5.1 Common Key Codes

Key Description

KEY_A…KEY_Z Standard alphabetic keys

KEY_0…KEY_9 Standard numeric keys

KEY_0_PAD…KEY_9_PAD Numeric keypad keys

KEY_F1…KEY_F12 Function keys

KEY_BACKSPACE Backspace key

KEY_INSERT Insert key

KEY_LEFT Left arrow key

KEY_RIGHT Right arrow key

KEY_DOWN Down arrow key

KEY_LSHIFT Left Shift key

KEY_RSHIFT Right Shift key

Trang 30

The sample programs in the chapters thus far have used the keyboard handler withoutfully explaining it because it’s difficult to demonstrate anything without some form ofkeyboard input The typical game loop looks like this:

The Stargate Program

The Stargate program demonstrates how to use the keyboard scan codes to detect when

specific keys have been pressed You will use this technology to decipher the ancient glyphs on the gate and attempt to open a wormhole to Abydos If all scholarly attemptsfail, you can resort to trying random dialing sequences using the keys on the keyboard.Our scientists have thus far failed in their attempt to decipher the gate symbols, as you cansee in Figure 5.1 What this program really needs are some sound effects, but that will have

hiero-to wait for Chapter 15, “Mastering the Audible Realm: Allegro’s Sound Support.”

Should you successfullycrack the gate codes, theresult will look like Figure5.2

Figure 5.1 The gate symbols have yet to be deciphered Are you

up to the challenge?

Trang 31

#include “allegro.h”

#define WHITE makecol(255,255,255)

#define BLUE makecol(64,64,255)

#define RED makecol(255,64,64)

typedef struct POINT

BITMAP *stargate;

BITMAP *water;

Figure 5.2 Opening a gateway to another world—speculative fantasy or a

real possibility?

Trang 32

BITMAP *symbols[7];

int count = 0;

//helper function to highlight each shevron

void shevron(int num)

//load the stargate image

stargate = load_bitmap(“stargate.bmp”, NULL);

blit(stargate,screen,0,0,20,50,stargate->w,stargate->h);

//load the water image

water = load_bitmap(“water.bmp”, NULL);

//load the symbol images

symbols[0] = load_bitmap(“symbol1.bmp”, NULL);

symbols[1] = load_bitmap(“symbol2.bmp”, NULL);

symbols[2] = load_bitmap(“symbol3.bmp”, NULL);

symbols[3] = load_bitmap(“symbol4.bmp”, NULL);

symbols[4] = load_bitmap(“symbol5.bmp”, NULL);

symbols[5] = load_bitmap(“symbol6.bmp”, NULL);

symbols[6] = load_bitmap(“symbol7.bmp”, NULL);

Trang 33

//display the symbols

textout(screen,font,”DIALING SEQUENCE”, 480, 50, WHITE);

textout(screen,font,”STARGATE PROGRAM (ESC to quit)”, 0, 0, RED);

textout(screen,font,”PRESS THE CORRECT KEYS (A-Z) “\

“TO DIAL THE STARGATE”, 0, 10, RED);

Trang 34

Buffered Keyboard Input

Buffered keyboard input is a less direct way of reading keyboard input in which ual key codes are not scanned; instead, the ASCII code is returned by one of the bufferedkeyboard input functions, such as readkey

individ-int readkey();

Thereadkeyfunction returns the ASCII code of the next character in the keyboard buffer

If no key has been pressed, then readkey waits for the next key press There is a similarfunction for handling Unicode keys called ureadkey, which returns the Unicode value (atwo-byte value similar to ASCII) while returning the scan code as a pointer (I have oftenwondered why Allegro doesn’t simply return these values as a four-byte long.)

int ureadkey(int *scancode);

Thereadkeyfunction actually returns two values using a two-byte integer value The lowbyte of the return value contains the ASCII code (which changes based on Ctrl, Alt, andShift keys), while the high byte contains the scan code (which is always the same regard-less of the control keys) Because the scan code is included in the upper byte, you can usethe predefined keyarray to detect buffered key presses by shifting the bits Shifting thevalue returned by readkeyby eight results in the scan code For instance:

if ((readkey() >> 8) == KEY_TAB)

printf(“You pressed Tab\n”);

Of course, it is easier to use just the keyarray unless you need to read both the scan codeand the ASCII code at the same time, which is where readkeycomes in handy

As an alternative, you can also check the ASCII code and detect control key sequences atthe same time using the key_shiftsvalue

extern volatile int key_shifts;

Trang 35

This integer contains a bitmask with the following possible values:

if ((key_shifts & KB_CTRL_FLAG) && (readkey() == 13))

printf(“You pressed CTRL+Enter\n”);

Of course, I personally find it easier to simply write the code this way:

if ((key[KEY_CTRL] && key[KEY_ENTER])

printf(“You pressed CTRL+Enter\n”);

You can also use a support function provided by Allegro to convert the scan code to an

ASCII value with the scancode_to_asciifunction

int scancode_to_ascii(int scancode);

One more support function that you might want to use is set_keyboard_rate, which

changes the key repeat rate of the keyboard (in milliseconds) You can disable the key

repeat by passing zeros to this function

void set_keyboard_rate(int delay, int repeat);

Simulating Key Presses

Suppose you have written a game and you want to create a game demo, but you don’t want

to write a complicated program just to demonstrate a “proof of concept.” There is an elegant

solution to the problem—simulating key presses Allegro provides two functions you can use

to insert keys into the keyboard buffer so it will appear as if those keys were actually pressed

The function is called simulate_keypress, and it has a similar support function for Unicode

calledsimulate_ukeypress Here are the definitions:

void simulate_keypress(int key);

void simulate_ukeypress(int key, int scancode);

Trang 36

In addition to inserting keys into the keyboard buffer, you can also clear the keyboardbuffer entirely using the clear_keybuffunction.

void clear_keybuf();

The KeyTest Program

I would be remiss if I didn’t provide a sample program to demonstrate buffered keyboardinput, although this small sample program is not as interesting as the last one.Nevertheless, it always helps to see the theory of a particular subject in action Figure 5.3

shows the KeyTest program This is a convenient program to keep handy because you’ll

frequently need keyboard scan codes, and this program makes it easy to look them up(knowing that you are free to use Allegro’s predefined keys or the scan codes directly)

Figure 5.3 The KeyTest program shows the key value, scan code,

ASCII code, and character

Trang 37

textout(screen,font,”KeyTest Program”, 0, 0, WHITE);

textout(screen,font,”Press a key (ESC to quit) ”, 0, 20, WHITE);

//set starting position for text

//display key values

textprintf(screen, font, x, y, WHITE,

“Key value = %-6d”, k);

textprintf(screen, font, x, y+15, WHITE,

“Scan code = %-6d”, scancode);

textprintf(screen, font, x, y+30, WHITE,

“ASCII code = %-6d”, ascii);

textprintf(screen, font, x, y+45, WHITE,

Handling Mouse Input

Mouse input is probably even more vital to a modern game than keyboard input, so

sup-port for the mouse is not just an option, it is an assumption, a requirement (unless you

are planning to develop a text game)

Ngày đăng: 12/08/2014, 19:20

TỪ KHÓA LIÊN QUAN