java写的FPS飞行射击类小游戏总结(附源码)

这段时间学习java2D写的,今天来整理总结一下。

游戏资源是从cping1982的博客里下载的(http://blog.csdn.net/cping1982/article/details/6725015)。

下载下来的源码是反编译的,我按照自己的思路,尽量模拟跟它一样的功能效果,用自己的代码实现,并且自己写了一个地图编辑器。

用到的技术大概有:swing基本控件,线程,XML读写,IO,反射的简单应用,2D绘图。


最重要的一个自定义类:Canvas。

每个canvas都有一个render方法和update方法,每个canvas又可以添加别的canvas,类似swing的component结构,每个canvas执行render和update的时候都会遍历所有子canvas执行render和update,从而实现所有canvas都执行渲染和更新。

游戏的刷新机制:

这个刷新机制是直接学的原代码里面的实现机制,看它没注释的代码着实蛋疼,还是请教了我师傅desolatecity大神才理解的- -!。

最高层是一个继承JFrame的GameFrame,实现了Runnable,游戏启动后会单独运行不断循环刷新,每隔大概15ms就执行一次render,并将整个循环所用时间通过update方法传给canvas,最高层canvas再一层一层传递下去,实现所有canvas的渲染和更新。大致代码实现如下:

while (gameOn) {
			// 获取开始时的系统时间
			long startTime = System.currentTimeMillis();

			// 标记时间所用变量
			long l1;
			long l2 = System.currentTimeMillis();
			long l3 = System.currentTimeMillis();

			// 执行for循环,直到经过了step毫秒
			for (l1 = l3 - l2; l1 < step; l1 = l3 - l2) {
				l3 = System.currentTimeMillis();
			}
			// for循环结束,开始渲染和更新
			l2 = System.currentTimeMillis(); // 重置l2

			this.getCurrentCanvas().render(g2); // 渲染

			this.getGraphics().drawImage(bufImg, 0, 0, null); // 将缓冲图片画到JFrame

			long endTime = System.currentTimeMillis(); // 获取结束时的系统时间

			this.getCurrentCanvas().update(endTime - startTime); // 获取当前循环刷新所用时间并更新

			try {
				Thread.sleep(sleep);
			} catch (Exception e) {
				e.printStackTrace();
			}

		}

游戏结构:

大致可分为三个层次:一是最高层的JFrame,二是JFrame里的主canvas,三是主canvas里面的各个子canvas(敌人,玩家,子弹,控件等)。每个canvas都有自己的render和update方法,所有的渲染和更新,都在各自重写的方法里实现,update里面接受一个long类型的时间参数l,表示经过了l毫秒,然后更新自己的位置,方向,速度,显示规则等,最后通过render显示出来,从而实现整个画面的运动。


整个游戏还有一个比较重要的东西,就是地图的存储。游戏的地图信息是存储在xml文件里的,通过地图读取工具,将xml的信息提取,并按照“时间 -  元素”的映射关系将时间和对应元素存储到一个IdentityHashMap里,然后游戏的主canvas在update的时候遍历IdentityHashMap,若当前时间满足map里面的时间,则将对应的元素提取出来,添加到当前的子canvas列表里面,从而一个新的元素(或敌人,或提示消息等)就被添加到了界面上。这里我用到了一个比较少用的IdentityHashMap,原本直接用的是HashMap,后来发现一个时间有时候要对应多个元素,然后上网查到了这个东东,但是由于键是按照对象来存储的,所以要把时间用String对象来存储, 搞得读取和存储的时候各种麻烦。结果后来师傅一指点才知道,可以直接用HashMap来存储“时间--ArrayList” ,这样又方便又直接。- -!后来嫌麻烦也不去改了。。。


地图编辑器:

地图编辑器没有什么特别费脑袋的地方,就是各种swing控件的运用,还有xml的读写,简单的反射应用等。


由于整个游戏基本上都是在边学变写,所以很多地方写的很粗糙,以至于后来去整理的时候发现前面的代码结构简直丑死了- -,改都该了半天。


最后附上源码下载地址,如果有兴趣的话可以互相探讨学习。

下载地址:http://download.csdn.net/download/jianglihui0330/4493082


游戏截图:




地图编辑器截图:




  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
这是一个使用Pygame库实现飞行射击小游戏的Python代码示例: ```python import pygame import random # 初始化Pygame pygame.init() # 定义游戏屏幕大小和帧率 SCREEN_WIDTH = 480 SCREEN_HEIGHT = 640 FPS = 60 # 定义颜色 WHITE = (255, 255, 255) BLACK = (0, 0, 0) RED = (255, 0, 0) # 创建游戏屏幕 screen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT)) pygame.display.set_caption("飞行射击小游戏") # 加载图片 player_img = pygame.image.load("player.png") player_img = pygame.transform.scale(player_img, (50, 50)) enemy_img = pygame.image.load("enemy.png") enemy_img = pygame.transform.scale(enemy_img, (50, 50)) bullet_img = pygame.image.load("bullet.png") bullet_img = pygame.transform.scale(bullet_img, (10, 20)) # 加载音效 shoot_sound = pygame.mixer.Sound("shoot.wav") explosion_sound = pygame.mixer.Sound("explosion.wav") # 定义玩家类 class Player(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = player_img self.rect = self.image.get_rect() self.rect.centerx = SCREEN_WIDTH // 2 self.rect.bottom = SCREEN_HEIGHT - 10 self.speedx = 0 def update(self): self.speedx = 0 # 控制玩家移动 keys = pygame.key.get_pressed() if keys[pygame.K_LEFT]: self.speedx = -8 if keys[pygame.K_RIGHT]: self.speedx = 8 self.rect.x += self.speedx # 限制玩家移动范围 if self.rect.left < 0: self.rect.left = 0 if self.rect.right > SCREEN_WIDTH: self.rect.right = SCREEN_WIDTH def shoot(self): bullet = Bullet(self.rect.centerx, self.rect.top) all_sprites.add(bullet) bullets.add(bullet) shoot_sound.play() # 定义敌人类 class Enemy(pygame.sprite.Sprite): def __init__(self): super().__init__() self.image = enemy_img self.rect = self.image.get_rect() self.rect.x = random.randrange(SCREEN_WIDTH - self.rect.width) self.rect.y = random.randrange(-100, -40) self.speedy = random.randrange(1, 8) self.speedx = random.randrange(-3, 3) def update(self): self.rect.x += self.speedx self.rect.y += self.speedy # 碰撞检测 if self.rect.top > SCREEN_HEIGHT + 10 or self.rect.left < -25 or self.rect.right > SCREEN_WIDTH + 20: self.kill() # 定义子弹类 class Bullet(pygame.sprite.Sprite): def __init__(self, x, y): super().__init__() self.image = bullet_img self.rect = self.image.get_rect() self.rect.centerx = x self.rect.bottom = y self.speedy = -10 def update(self): self.rect.y += self.speedy # 子弹飞出屏幕后删除 if self.rect.bottom < 0: self.kill() # 定义游戏结束函数 def game_over(): font = pygame.font.SysFont(None, 48) text = font.render("GAME OVER", True, RED) text_rect = text.get_rect() text_rect.centerx = SCREEN_WIDTH // 2 text_rect.centery = SCREEN_HEIGHT // 2 screen.blit(text, text_rect) pygame.display.flip() pygame.time.wait(2000) # 创建游戏精灵组 all_sprites = pygame.sprite.Group() enemies = pygame.sprite.Group() bullets = pygame.sprite.Group() # 创建玩家对象 player = Player() all_sprites.add(player) # 创建敌人对象 for i in range(8): enemy = Enemy() all_sprites.add(enemy) enemies.add(enemy) # 设置帧率 clock = pygame.time.Clock() # 游戏循环 running = True while running: clock.tick(FPS) # 处理游戏事件 for event in pygame.event.get(): if event.type == pygame.QUIT: running = False elif event.type == pygame.KEYDOWN: if event.key == pygame.K_SPACE: player.shoot() # 更新游戏精灵组 all_sprites.update() # 检测子弹和敌人的碰撞 hits = pygame.sprite.groupcollide(enemies, bullets, True, True) for hit in hits: enemy = Enemy() all_sprites.add(enemy) enemies.add(enemy) explosion_sound.play() # 检测玩家和敌人的碰撞 hits = pygame.sprite.spritecollide(player, enemies, False) if hits: game_over() running = False # 渲染游戏画面 screen.fill(BLACK) all_sprites.draw(screen) pygame.display.flip() # 退出Pygame pygame.quit() ``` 这是一个简单的飞行射击小游戏,玩家通过控制箭头左右移动来躲避敌人的攻击,并使用空格键发射子弹攻击敌人。当敌人被击中时,会播放爆炸音效并生成新的敌人。当玩家与敌人碰撞时,游戏结束并显示GAME OVER的提示。运行代码即可开始游戏
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值