用c写一个飞机大战游戏
时间: 2023-12-21 12:06:35 浏览: 129
好的,下面是一个简单的飞机大战游戏的C代码。这个游戏使用了SDL图形库来处理图形和音效。
```c
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <time.h>
#include <SDL2/SDL.h>
#define SCREEN_WIDTH 640
#define SCREEN_HEIGHT 480
#define ENEMY_MAX 10
typedef struct {
SDL_Texture *texture;
SDL_Rect rect;
} Sprite;
typedef struct {
Sprite sprite;
int speed;
bool active;
} Bullet;
typedef struct {
Sprite sprite;
int speed;
int health;
bool active;
} Enemy;
typedef struct {
Sprite sprite;
int health;
} Player;
SDL_Window *window = NULL;
SDL_Renderer *renderer = NULL;
SDL_Texture *background_texture = NULL;
Sprite player_sprite;
Bullet bullets[ENEMY_MAX + 1];
Enemy enemies[ENEMY_MAX];
Player player = {0};
bool load_texture(SDL_Texture **texture, const char *filename) {
SDL_Surface *surface = SDL_LoadBMP(filename);
if(surface == NULL) {
printf("Error: Could not load texture %s: %s\n", filename, SDL_GetError());
return false;
}
*texture = SDL_CreateTextureFromSurface(renderer, surface);
if(*texture == NULL) {
printf("Error: Could not create texture from surface: %s\n", SDL_GetError());
return false;
}
SDL_FreeSurface(surface);
return true;
}
void init_sprite(Sprite *sprite, int x, int y, int w, int h) {
sprite->rect.x = x;
sprite->rect.y = y;
sprite->rect.w = w;
sprite->rect.h = h;
}
void draw_sprite(const Sprite *sprite) {
SDL_RenderCopy(renderer, sprite->texture, NULL, &sprite->rect);
}
void fire_bullet(Bullet *bullets, int max, const Sprite *player_sprite) {
for(int i = 0; i <= max; i++) {
if(!bullets[i].active) {
bullets[i].active = true;
bullets[i].sprite.rect.x = player_sprite->rect.x + player_sprite->rect.w / 2 - 3;
bullets[i].sprite.rect.y = player_sprite->rect.y - 10;
break;
}
}
}
void move_bullets(Bullet *bullets, int max) {
for(int i = 0; i <= max; i++) {
if(bullets[i].active) {
bullets[i].sprite.rect.y -= bullets[i].speed;
if(bullets[i].sprite.rect.y < -10) {
bullets[i].active = false;
}
}
}
}
void spawn_enemy(Enemy *enemies, int max, const Sprite *enemy_sprite) {
for(int i = 0; i < max; i++) {
if(!enemies[i].active) {
enemies[i].active = true;
enemies[i].sprite.rect.x = rand() % (SCREEN_WIDTH - enemy_sprite->rect.w);
enemies[i].sprite.rect.y = -enemy_sprite->rect.h;
enemies[i].health = 3;
break;
}
}
}
void move_enemies(Enemy *enemies, int max) {
for(int i = 0; i < max; i++) {
if(enemies[i].active) {
enemies[i].sprite.rect.y += enemies[i].speed;
if(enemies[i].sprite.rect.y > SCREEN_HEIGHT) {
enemies[i].active = false;
}
}
}
}
void update_player(Player *player, const Uint8 *keystate) {
if(keystate[SDL_SCANCODE_LEFT]) {
player->sprite.rect.x -= 5;
if(player->sprite.rect.x < 0) {
player->sprite.rect.x = 0;
}
}
if(keystate[SDL_SCANCODE_RIGHT]) {
player->sprite.rect.x += 5;
if(player->sprite.rect.x > SCREEN_WIDTH - player->sprite.rect.w) {
player->sprite.rect.x = SCREEN_WIDTH - player->sprite.rect.w;
}
}
if(keystate[SDL_SCANCODE_SPACE]) {
fire_bullet(bullets, ENEMY_MAX, &player->sprite);
}
}
void update_enemies(Enemy *enemies, int max) {
for(int i = 0; i < max; i++) {
if(enemies[i].active) {
if(enemies[i].health <= 0) {
enemies[i].active = false;
} else {
if(rand() % 100 < 5) {
fire_bullet(bullets, ENEMY_MAX, &enemies[i].sprite);
}
}
}
}
}
void handle_collisions(Bullet *bullets, int bullet_max, Enemy *enemies, int enemy_max, Player *player) {
for(int i = 0; i <= bullet_max; i++) {
if(bullets[i].active) {
for(int j = 0; j < enemy_max; j++) {
if(enemies[j].active) {
if(SDL_HasIntersection(&bullets[i].sprite.rect, &enemies[j].sprite.rect)) {
bullets[i].active = false;
enemies[j].health--;
if(enemies[j].health <= 0) {
enemies[j].active = false;
}
}
}
}
if(SDL_HasIntersection(&bullets[i].sprite.rect, &player->sprite.rect)) {
bullets[i].active = false;
player->health--;
if(player->health <= 0) {
printf("Game over!\n");
exit(0);
}
}
}
}
}
int main(int argc, char *argv[]) {
srand(time(NULL));
if(SDL_Init(SDL_INIT_VIDEO) != 0) {
printf("Error: Could not initialize SDL: %s\n", SDL_GetError());
return 1;
}
window = SDL_CreateWindow("飞机大战游戏", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL) {
printf("Error: Could not create window: %s\n", SDL_GetError());
return 1;
}
renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
if(renderer == NULL) {
printf("Error: Could not create renderer: %s\n", SDL_GetError());
return 1;
}
if(!load_texture(&background_texture, "background.bmp")) {
return 1;
}
if(!load_texture(&player_sprite.texture, "player.bmp")) {
return 1;
}
init_sprite(&player_sprite, SCREEN_WIDTH / 2 - 25, SCREEN_HEIGHT - 50, 50, 50);
player.health = 3;
for(int i = 0; i <= ENEMY_MAX; i++) {
if(!load_texture(&bullets[i].sprite.texture, "bullet.bmp")) {
return 1;
}
init_sprite(&bullets[i].sprite, 0, 0, 6, 10);
bullets[i].speed = 10;
bullets[i].active = false;
}
for(int i = 0; i < ENEMY_MAX; i++) {
if(!load_texture(&enemies[i].sprite.texture, "enemy.bmp")) {
return 1;
}
init_sprite(&enemies[i].sprite, 0, 0, 50, 50);
enemies[i].speed = 5;
enemies[i].health = 3;
enemies[i].active = false;
}
Uint32 last_frame_time = SDL_GetTicks();
Uint32 last_enemy_spawn_time = 0;
while(true) {
SDL_Event event;
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
exit(0);
}
}
Uint32 current_time = SDL_GetTicks();
Uint32 delta_time = current_time - last_frame_time;
last_frame_time = current_time;
SDL_RenderCopy(renderer, background_texture, NULL, NULL);
const Uint8 *keystate = SDL_GetKeyboardState(NULL);
update_player(&player, keystate);
draw_sprite(&player.sprite);
move_bullets(bullets, ENEMY_MAX);
for(int i = 0; i <= ENEMY_MAX; i++) {
if(bullets[i].active) {
draw_sprite(&bullets[i].sprite);
}
}
Uint32 enemy_spawn_interval = 1000;
if(current_time - last_enemy_spawn_time > enemy_spawn_interval) {
spawn_enemy(enemies, ENEMY_MAX, &enemies[0].sprite);
last_enemy_spawn_time = current_time;
}
move_enemies(enemies, ENEMY_MAX);
for(int i = 0; i < ENEMY_MAX; i++) {
if(enemies[i].active) {
draw_sprite(&enemies[i].sprite);
}
}
update_enemies(enemies, ENEMY_MAX);
handle_collisions(bullets, ENEMY_MAX, enemies, ENEMY_MAX, &player);
SDL_RenderPresent(renderer);
}
return 0;
}
```
这个游戏的逻辑比较简单,玩家控制一个飞机在屏幕上移动和发射子弹,同时要躲避从屏幕上方出现的敌机和它们发射的子弹。玩家有三条生命,当生命值降为0时游戏结束。
阅读全文