玩了一下午的trae,发现这个工具真的太神奇了。amazing啊。 忽然想起以前加入公司转正时都会让写个打飞机的小游戏,以表示代码基本功。突然奇想,让他写一个不就好了吗? ok,说干就干。
他马上帮我写出一个python版本的"打飞机"小游戏,当然用了开源库:
python
import pygame
import random
import sys
# 初始化 Pygame
pygame.init()
# 设置游戏窗口
WIDTH = 480
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('打飞机游戏')
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
# 玩家飞机类
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.centerx = WIDTH // 2
self.rect.bottom = HEIGHT - 10
self.speed = 8
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.right < WIDTH:
self.rect.x += self.speed
def shoot(self):
bullet = Bullet(self.rect.centerx, self.rect.top)
all_sprites.add(bullet)
bullets.add(bullet)
# 敌机类
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((30, 30))
self.image.fill(RED)
self.rect = self.image.get_rect()
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
def update(self):
self.rect.y += self.speedy
if self.rect.top > HEIGHT:
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
# 子弹类
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y):
super().__init__()
self.image = pygame.Surface((5, 10))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.bottom = y
self.rect.centerx = x
self.speedy = -10
def update(self):
self.rect.y += self.speedy
if self.rect.bottom < 0:
self.kill()
# 创建精灵组
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(60)
# 事件处理
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)
# 敌机撞到玩家检测
hits = pygame.sprite.spritecollide(player, enemies, False)
if hits:
running = False
# 渲染
screen.fill(BLACK)
all_sprites.draw(screen)
pygame.display.flip()
pygame.quit()
还帮我把功能总结了出来,牛逼啊:
想起了小时候玩的"加纳战机",真的又酷又炫。 于是让他加个月亮型子弹:
最后再让敌人的形状改成阿猫阿狗:
给出最后的终极代码:
python
import pygame
import random
import sys
# 初始化 Pygame
pygame.init()
# 设置游戏窗口
WIDTH = 480
HEIGHT = 600
screen = pygame.display.set_mode((WIDTH, HEIGHT))
pygame.display.set_caption('打飞机游戏')
# 颜色定义
WHITE = (255, 255, 255)
BLACK = (0, 0, 0)
RED = (255, 0, 0)
YELLOW = (255, 255, 0)
ORANGE = (255, 165, 0)
# 预定义敌机类型
ENEMY_TYPES = ['owl', 'dog', 'cat']
# 在所有类定义之前添加爆炸效果类
class Explosion(pygame.sprite.Sprite):
def __init__(self, center, size):
super().__init__()
self.size = size
self.frame = 0
self.images = []
# 创建不同大小的爆炸圆圈
for i in range(5):
radius = size - (i * size//5)
surf = pygame.Surface((size * 2, size * 2))
surf.set_colorkey(BLACK)
colors = [RED, ORANGE, YELLOW, WHITE]
pygame.draw.circle(surf, colors[i % len(colors)], (size, size), radius)
self.images.append(surf)
self.image = self.images[0]
self.rect = self.image.get_rect()
self.rect.center = center
self.last_update = pygame.time.get_ticks()
self.frame_rate = 50
def update(self):
now = pygame.time.get_ticks()
if now - self.last_update > self.frame_rate:
self.last_update = now
self.frame += 1
if self.frame >= len(self.images):
self.kill()
else:
center = self.rect.center
self.image = self.images[self.frame]
self.rect = self.image.get_rect()
self.rect.center = center
# 玩家飞机类
class Player(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((50, 50))
self.image.fill(WHITE)
self.rect = self.image.get_rect()
self.rect.centerx = WIDTH // 2
self.rect.bottom = HEIGHT - 10
self.speed = 8
def update(self):
keys = pygame.key.get_pressed()
if keys[pygame.K_LEFT] and self.rect.left > 0:
self.rect.x -= self.speed
if keys[pygame.K_RIGHT] and self.rect.right < WIDTH:
self.rect.x += self.speed
def shoot(self):
# 发射三个方向的子弹
bullet1 = Bullet(self.rect.centerx, self.rect.top, -1) # 左
bullet2 = Bullet(self.rect.centerx, self.rect.top, 0) # 中
bullet3 = Bullet(self.rect.centerx, self.rect.top, 1) # 右
all_sprites.add(bullet1, bullet2, bullet3)
bullets.add(bullet1, bullet2, bullet3)
# 敌机类
class Enemy(pygame.sprite.Sprite):
def __init__(self):
super().__init__()
self.image = pygame.Surface((40, 40), pygame.SRCALPHA)
self.type = random.choice(ENEMY_TYPES)
self._draw_enemy()
self.rect = self.image.get_rect()
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
def _draw_enemy(self):
if self.type == 'owl':
# 画猫头鹰
pygame.draw.circle(self.image, ORANGE, (20, 20), 15) # 脸
pygame.draw.circle(self.image, WHITE, (12, 15), 6) # 左眼
pygame.draw.circle(self.image, WHITE, (28, 15), 6) # 右眼
pygame.draw.circle(self.image, BLACK, (12, 15), 3) # 左眼珠
pygame.draw.circle(self.image, BLACK, (28, 15), 3) # 右眼珠
pygame.draw.polygon(self.image, ORANGE, [(15,5), (20,0), (25,5)]) # 耳朵
elif self.type == 'dog':
# 画小狗
pygame.draw.circle(self.image, RED, (20, 20), 15) # 脸
pygame.draw.circle(self.image, BLACK, (15, 15), 3) # 左眼
pygame.draw.circle(self.image, BLACK, (25, 15), 3) # 右眼
pygame.draw.ellipse(self.image, BLACK, (15, 22, 10, 6)) # 嘴巴
pygame.draw.ellipse(self.image, RED, (5, 5, 12, 20)) # 左耳
pygame.draw.ellipse(self.image, RED, (23, 5, 12, 20)) # 右耳
else: # cat
# 画小猫
pygame.draw.circle(self.image, YELLOW, (20, 20), 15) # 脸
pygame.draw.polygon(self.image, YELLOW, [(10,5), (20,15), (30,5)]) # 耳朵
pygame.draw.circle(self.image, BLACK, (15, 15), 2) # 左眼
pygame.draw.circle(self.image, BLACK, (25, 15), 2) # 右眼
pygame.draw.polygon(self.image, BLACK, [(20,20), (17,25), (23,25)]) # 鼻子
pygame.draw.line(self.image, BLACK, (17,25), (10,23), 2) # 左胡须
pygame.draw.line(self.image, BLACK, (23,25), (30,23), 2) # 右胡须
def update(self):
self.rect.y += self.speedy
if self.rect.top > HEIGHT:
self.rect.x = random.randrange(WIDTH - self.rect.width)
self.rect.y = random.randrange(-100, -40)
self.speedy = random.randrange(1, 8)
self.type = random.choice(ENEMY_TYPES)
self._draw_enemy()
# 子弹类
class Bullet(pygame.sprite.Sprite):
def __init__(self, x, y, direction=0):
super().__init__()
# 增大子弹尺寸
self.image = pygame.Surface((20, 30), pygame.SRCALPHA)
# 绘制更大的月亮形状子弹
pygame.draw.circle(self.image, WHITE, (10, 14), 10)
pygame.draw.circle(self.image, BLACK, (14, 14), 8)
self.original_image = self.image # 保存原始图像用于旋转
self.angle = 0 # 旋转角度
self.rect = self.image.get_rect()
self.rect.bottom = y
self.rect.centerx = x
self.speedy = -10
self.speedx = direction * 2
def update(self):
# 更新位置
self.rect.y += self.speedy
self.rect.x += self.speedx
# 旋转子弹
self.angle += 5 # 每帧旋转5度
self.image = pygame.transform.rotate(self.original_image, self.angle)
# 保持子弹中心位置不变
center = self.rect.center
self.rect = self.image.get_rect()
self.rect.center = center
# 检查是否超出屏幕
if self.rect.bottom < 0 or self.rect.left < 0 or self.rect.right > WIDTH:
self.kill()
# 创建精灵组
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(60)
# 事件处理
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:
# 创建爆炸效果
expl = Explosion(hit.rect.center, 30)
all_sprites.add(expl)
# 生成新的敌机
enemy = Enemy()
all_sprites.add(enemy)
enemies.add(enemy)
# 敌机撞到玩家检测
hits = pygame.sprite.spritecollide(player, enemies, True)
if hits:
# 创建大爆炸效果
expl = Explosion(player.rect.center, 50)
all_sprites.add(expl)
running = False
# 渲染
screen.fill(BLACK)
all_sprites.draw(screen)
pygame.display.flip()
pygame.quit()
终极效果:
那么,能不能做成手游在手机上玩呢,哈,让他再用kotlin实现一遍,机智如我!!!
kotlin
package com.example.shootergame
import android.content.Context
import android.graphics.*
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.SurfaceHolder
import android.view.SurfaceView
import kotlin.random.Random
class ShooterGame @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) : SurfaceView(context, attrs), SurfaceHolder.Callback, Runnable {
private var gameThread: Thread? = null
private var isRunning = false
private val paint = Paint()
private var screenWidth = 0
private var screenHeight = 0
// 游戏对象
private val player = Player()
// 使用线程安全的集合
private val bullets = Collections.synchronizedList(mutableListOf<Bullet>())
private val enemies = Collections.synchronizedList(mutableListOf<Enemy>())
private val explosions = Collections.synchronizedList(mutableListOf<Explosion>())
// 颜色定义
private val colors = object {
val WHITE = Color.WHITE
val BLACK = Color.BLACK
val RED = Color.RED
val YELLOW = Color.YELLOW
val ORANGE = Color.rgb(255, 165, 0)
}
init {
holder.addCallback(this)
paint.isAntiAlias = true
}
// 玩家类
inner class Player {
var x = 0f
var y = 0f
val width = 100f
val height = 100f
val speed = 15f
private var lastShootTime = 0L
private val shootInterval = 500L // 发射间隔时间(毫秒)
fun update() {
val currentTime = System.currentTimeMillis()
if (currentTime - lastShootTime >= shootInterval) {
shoot()
lastShootTime = currentTime
}
}
fun draw(canvas: Canvas) {
paint.color = colors.WHITE
canvas.drawRect(x, y, x + width, y + height, paint)
}
private fun shoot() {
synchronized(gameLock) {
if (bullets.size < 50) { // 限制最大子弹数量
bulletPool.obtain().apply {
init(x + width/2, y, -1)
bullets.add(this)
}
bulletPool.obtain().apply {
init(x + width/2, y, 0)
bullets.add(this)
}
bulletPool.obtain().apply {
init(x + width/2, y, 1)
bullets.add(this)
}
}
}
}
}
private fun updateGame() {
synchronized(gameLock) {
// 更新玩家(添加这行)
player.update()
// 更新子弹
bullets.toList().forEach { bullet ->
bullet.update()
if (bullet.y < -bullet.height) {
bullets.remove(bullet)
bulletPool.recycle(bullet)
}
}
// 更新敌人
enemies.toList().forEach { it.update() }
// 更新爆炸效果
explosions.toList().forEach { explosion ->
if (!explosion.update()) {
explosions.remove(explosion)
}
}
// 碰撞检测
checkCollisions()
}
}
// 修改碰撞检测
// 敌人类
inner class Enemy {
var x: Float = 0f
var y: Float = -100f
val width = 80f
val height = 80f
var speed: Float = 0f
var type: String = ""
init {
reset()
}
fun init() {
reset() // 重用对象时重置状态
}
fun reset() {
x = Random.nextFloat() * (screenWidth - width)
y = -100f
speed = Random.nextFloat() * 10f + 5f
type = listOf("owl", "dog", "cat").random()
}
}
// 在类的顶部添加分数相关变量
private var score = 0
private var isGameOver = false
private val scoreMap = mapOf(
"owl" to 2,
"dog" to 3,
"cat" to 5
)
// 添加绘制分数的方法
private fun drawScore(canvas: Canvas) {
paint.apply {
color = colors.WHITE
textSize = 50f
textAlign = Paint.Align.LEFT
}
canvas.drawText("分数: $score", 20f, 60f, paint)
}
// 修改 drawGame 方法
private fun drawGame() {
val canvas = holder.lockCanvas() ?: return
try {
canvas.drawColor(colors.BLACK)
synchronized(gameLock) {
if (!isGameOver) {
player.draw(canvas)
bullets.toList().forEach { it.draw(canvas) }
enemies.toList().forEach { it.draw(canvas) }
explosions.toList().forEach { it.draw(canvas) }
drawScore(canvas)
} else {
drawGameOver(canvas)
}
}
} finally {
holder.unlockCanvasAndPost(canvas)
}
}
// 添加游戏结束界面
private fun drawGameOver(canvas: Canvas) {
paint.apply {
textAlign = Paint.Align.CENTER
color = colors.WHITE
}
// 绘制标题
paint.textSize = 80f
canvas.drawText("游戏结束", screenWidth/2f, screenHeight/3f, paint)
// 绘制分数
paint.textSize = 60f
canvas.drawText("最终得分: $score", screenWidth/2f, screenHeight/2f, paint)
// 绘制提示
paint.textSize = 40f
canvas.drawText("点击屏幕重新开始", screenWidth/2f, screenHeight * 2/3f, paint)
}
// 修改碰撞检测中的得分逻辑
private fun checkCollisions() {
synchronized(gameLock) {
// 子弹击中敌人
val bulletsToRemove = mutableListOf<Bullet>()
val enemiesToRemove = mutableListOf<Enemy>()
enemies.forEach { enemy ->
bullets.forEach { bullet ->
if (isCollision(bullet, enemy)) {
bulletsToRemove.add(bullet)
enemiesToRemove.add(enemy)
score += scoreMap[enemy.type] ?: 0 // 增加分数
explosionPool.obtain().apply {
init(enemy.x + enemy.width/2, enemy.y + enemy.height/2)
explosions.add(this)
}
}
}
}
// 批量处理移除操作
bulletsToRemove.forEach {
bullets.remove(it)
bulletPool.recycle(it)
}
enemiesToRemove.forEach {
enemies.remove(it)
enemyPool.recycle(it)
enemies.add(enemyPool.obtain())
}
// 敌人撞到玩家
enemies.toList().forEach { enemy ->
if (isCollision(player, enemy)) {
isGameOver = true
explosions.add(Explosion(player.x + player.width/2, player.y + player.height/2))
}
}
}
}
// 修改触摸事件,添加重新开始功能
override fun onTouchEvent(event: MotionEvent): Boolean {
when (event.action) {
MotionEvent.ACTION_DOWN -> {
if (isGameOver) {
restartGame()
return true
}
}
MotionEvent.ACTION_MOVE -> {
if (!isGameOver) {
synchronized(gameLock) {
player.x = event.x - player.width/2
if (player.x < 0) player.x = 0f
if (player.x > screenWidth - player.width) {
player.x = screenWidth - player.width
}
}
}
}
}
return true
}
// 添加重新开始游戏的方法
private fun restartGame() {
synchronized(gameLock) {
score = 0
isGameOver = false
isRunning = true
// 清理所有游戏对象
bullets.clear()
enemies.clear()
explosions.clear()
// 重置玩家位置
player.x = screenWidth/2f - player.width/2
player.y = screenHeight - player.height - 20
// 重新初始化敌人
repeat(8) {
enemies.add(Enemy())
}
// 重新启动游戏线程
gameThread = Thread(this).apply { start() }
}
}
private fun isCollision(obj1: Any, obj2: Any): Boolean {
val (x1, y1, w1, h1) = when (obj1) {
is Player -> listOf(obj1.x, obj1.y, obj1.width, obj1.height)
is Bullet -> listOf(obj1.x, obj1.y, obj1.width, obj1.height)
is Enemy -> listOf(obj1.x, obj1.y, obj1.width, obj1.height)
else -> return false
}
val (x2, y2, w2, h2) = when (obj2) {
is Player -> listOf(obj2.x, obj2.y, obj2.width, obj2.height)
is Bullet -> listOf(obj2.x, obj2.y, obj2.width, obj2.height)
is Enemy -> listOf(obj2.x, obj2.y, obj2.width, obj2.height)
else -> return false
}
return !(x1 + w1 < x2 || x2 + w2 < x1 || y1 + h1 < y2 || y2 + h2 < y1)
}
}
只需要在把代码集成到android项目,打包一下,生成一个apk就行了。
已经传到百度网盘:game.apk 链接: pan.baidu.com/s/1XLrjKWUb... 提取码: hhgp