用C语言编写一个射击游戏
时间: 2024-02-18 10:53:22 浏览: 197
好的,我可以给您提供一个简单的射击游戏示例,该示例使用C语言编写,并使用了SDL库。下面是代码:
```c
#include <stdio.h>
#include <stdbool.h>
#include <SDL2/SDL.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define BULLET_SPEED 5
#define ENEMY_SPEED 2
#define ENEMY_SPAWN_INTERVAL 60
typedef struct {
int x, y;
int w, h;
} Rect;
typedef struct {
Rect rect;
bool active;
} Bullet;
typedef struct {
Rect rect;
bool active;
int health;
} Enemy;
void moveRect(Rect *rect, int dx, int dy) {
rect->x += dx;
rect->y += dy;
}
bool checkCollision(Rect r1, Rect r2) {
if (r1.x + r1.w < r2.x || r1.x > r2.x + r2.w) return false;
if (r1.y + r1.h < r2.y || r1.y > r2.y + r2.h) return false;
return true;
}
int main(int argc, char *argv[]) {
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *playerTexture = NULL;
SDL_Texture *bulletTexture = NULL;
SDL_Texture *enemyTexture = NULL;
SDL_Rect playerRect = {0, 0, 32, 32};
SDL_Rect bulletRect = {0, 0, 8, 8};
SDL_Rect enemyRect = {0, 0, 32, 32};
SDL_Event event;
bool isRunning = true;
bool isShooting = false;
int bulletCooldown = 0;
int enemySpawnCooldown = 0;
Bullet bullets[100];
Enemy enemies[100];
int i, j;
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
printf("SDL_Init failed: %s\n", SDL_GetError());
return 1;
}
window = SDL_CreateWindow("Shooter", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if (window == NULL) {
printf("SDL_CreateWindow failed: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED);
if (renderer == NULL) {
printf("SDL_CreateRenderer failed: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
playerTexture = SDL_CreateTextureFromSurface(renderer, SDL_LoadBMP("player.bmp"));
if (playerTexture == NULL) {
printf("SDL_CreateTextureFromSurface failed: %s\n", SDL_GetError());
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
bulletTexture = SDL_CreateTextureFromSurface(renderer, SDL_LoadBMP("bullet.bmp"));
if (bulletTexture == NULL) {
printf("SDL_CreateTextureFromSurface failed: %s\n", SDL_GetError());
SDL_DestroyTexture(playerTexture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
enemyTexture = SDL_CreateTextureFromSurface(renderer, SDL_LoadBMP("enemy.bmp"));
if (enemyTexture == NULL) {
printf("SDL_CreateTextureFromSurface failed: %s\n", SDL_GetError());
SDL_DestroyTexture(bulletTexture);
SDL_DestroyTexture(playerTexture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 1;
}
for (i = 0; i < 100; i++) {
bullets[i].active = false;
enemies[i].active = false;
}
playerRect.x = SCREEN_WIDTH / 2 - playerRect.w / 2;
playerRect.y = SCREEN_HEIGHT - playerRect.h - 10;
while (isRunning) {
while (SDL_PollEvent(&event)) {
if (event.type == SDL_QUIT) {
isRunning = false;
} else if (event.type == SDL_KEYDOWN) {
switch (event.key.keysym.sym) {
case SDLK_LEFT:
moveRect(&playerRect, -5, 0);
break;
case SDLK_RIGHT:
moveRect(&playerRect, 5, 0);
break;
case SDLK_SPACE:
isShooting = true;
break;
}
} else if (event.type == SDL_KEYUP) {
switch (event.key.keysym.sym) {
case SDLK_SPACE:
isShooting = false;
break;
}
}
}
if (isShooting && bulletCooldown <= 0) {
for (i = 0; i < 100; i++) {
if (!bullets[i].active) {
bullets[i].active = true;
bullets[i].rect.x = playerRect.x + playerRect.w / 2 - bulletRect.w / 2;
bullets[i].rect.y = playerRect.y - bulletRect.h;
break;
}
}
bulletCooldown = 10;
}
if (bulletCooldown > 0) {
bulletCooldown--;
}
if (enemySpawnCooldown <= 0) {
for (i = 0; i < 100; i++) {
if (!enemies[i].active) {
enemies[i].active = true;
enemies[i].rect.x = rand() % (SCREEN_WIDTH - enemyRect.w);
enemies[i].rect.y = -enemyRect.h;
enemies[i].health = 2;
break;
}
}
enemySpawnCooldown = ENEMY_SPAWN_INTERVAL;
}
if (enemySpawnCooldown > 0) {
enemySpawnCooldown--;
}
for (i = 0; i < 100; i++) {
if (bullets[i].active) {
bullets[i].rect.y -= BULLET_SPEED;
if (bullets[i].rect.y + bullets[i].rect.h < 0) {
bullets[i].active = false;
} else {
for (j = 0; j < 100; j++) {
if (enemies[j].active && checkCollision(bullets[i].rect, enemies[j].rect)) {
bullets[i].active = false;
enemies[j].health--;
if (enemies[j].health <= 0) {
enemies[j].active = false;
}
}
}
}
}
}
for (i = 0; i < 100; i++) {
if (enemies[i].active) {
enemies[i].rect.y += ENEMY_SPEED;
if (enemies[i].rect.y > SCREEN_HEIGHT) {
enemies[i].active = false;
} else {
if (checkCollision(enemies[i].rect, playerRect)) {
isRunning = false;
}
}
}
}
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, playerTexture, NULL, &playerRect);
for (i = 0; i < 100; i++) {
if (bullets[i].active) {
SDL_RenderCopy(renderer, bulletTexture, NULL, &bullets[i].rect);
}
}
for (i = 0; i < 100; i++) {
if (enemies[i].active) {
SDL_RenderCopy(renderer, enemyTexture, NULL, &enemies[i].rect);
}
}
SDL_RenderPresent(renderer);
}
SDL_DestroyTexture(enemyTexture);
SDL_DestroyTexture(bulletTexture);
SDL_DestroyTexture(playerTexture);
SDL_DestroyRenderer(renderer);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
```
该示例包含一个主循环,该循环处理用户输入,更新游戏状态并绘制游戏对象。游戏包含一个玩家对象,可以使用左右箭头键移动,并可以使用空格键发射子弹。敌人对象会从屏幕顶部不断出现,并且会向下移动。如果玩家的子弹击中了敌人,敌人的生命值会减少,当其生命值降至零时,敌人会被击败并消失。如果敌人移动到屏幕底部,玩家将失败并游戏结束。
阅读全文