「见缝插针」游戏源码aardio版,由AI编写测试
By
admin
at 8 天前 • 0人收藏 • 84人看过
仍然由Gemini 编写, 不过这次改了好几次才成功, 主要集中在射箭后的穿模问题上
exe下载:

import win.ui;
import gdip;
import math;
/*DSG{{*/
var winform = win.form(text="见缝插针 (Aardio Plus版)";right=400;bottom=600;bgcolor=16777215)
winform.add(
plus={cls="plus";left=0;top=0;right=400;bottom=600;db=1;dl=1;dr=1;dt=1;notify=1;z=1}
)
/*}}*/
// ==========================================
// 1. 视觉主题配置 (Theme)
// ==========================================
var theme = {
bgDefault = 0xFFF0EFE9; // 默认米色背景
bgWin = 0xFF1ABC9C; // 胜利绿色
bgFail = 0xFFE74C3C; // 失败红色
objColor = 0xFF2C3E50; // 物体颜色(深蓝黑)
textColor = 0xFFF0EFE9; // 中心文字颜色(同背景色)
fontName = "Segoe UI"; // 字体
}
var config = {
centerX = 200; // 中心X
centerY = 220; // 中心Y
radius = 50; // 核心球半径
pinLen = 110; // 针长度
ballRadius = 7; // 针头半径
safeAngle = 12; // 碰撞角度阈值
bulletSpeed = 35; // 发射速度
startY = 520; // 发射点Y
}
var game = {
level = 1;
state = "menu"; // menu, playing, gameover, levelup
rotation = 0;
rotSpeed = 0;
pins = {}; // 已插入的针
bulletsLeft = 0;
activePin = { y = config.startY; active = false };
bgColor = theme.bgDefault;
}
// ==========================================
// 2. 逻辑控制
// ==========================================
var initLevel = function(lv){
game.level = lv;
game.state = "playing";
game.rotation = 0;
game.pins = {};
game.activePin.active = false;
game.activePin.y = config.startY;
game.bgColor = theme.bgDefault;
// 难度曲线算法
var baseSpeed = 1.5;
game.rotSpeed = baseSpeed + (lv * 0.2);
if(game.rotSpeed > 8) game.rotSpeed = 8;
// 偶数关卡逆时针
if(lv % 2 == 0) game.rotSpeed = -game.rotSpeed;
// 初始障碍针 (第2关开始出现)
var obstacleCount = math.floor(lv / 3);
if(lv > 1) table.push(game.pins, { angle = 0 });
for(i=1; obstacleCount){
table.push(game.pins, { angle = math.random(0, 359) });
}
// 子弹数量
game.bulletsLeft = 6 + math.floor(lv / 2);
}
// 碰撞检测
var checkCollision = function(newAngle){
for(i=1; #game.pins){
var p = game.pins[i];
var diff = math.abs(p.angle - newAngle);
if(diff > 180) diff = 360 - diff;
if(diff < config.safeAngle) return true;
}
return false;
}
// 统一操作入口 (鼠标/键盘共用)
var gameAction = function(){
if(game.state == "playing"){
// 游戏中:发射
if(!game.activePin.active && game.bulletsLeft > 0){
game.activePin.active = true;
game.activePin.y = config.startY;
}
}
elseif(game.state == "gameover"){
// 失败:重试
initLevel(game.level);
winform.plus.redraw();
}
elseif(game.state == "menu"){
// 菜单:开始
initLevel(1);
}
}
// ==========================================
// 3. 绘图渲染
// ==========================================
winform.plus.onDrawForegroundEnd = function(graphics, rc){
graphics.smoothingMode = 4; // 抗锯齿
graphics.textRenderingHint = 4; // 文字抗锯齿
// --- 1. 绘制背景 ---
var brushBg = gdip.solidBrush(game.bgColor);
graphics.fillRectangle(brushBg, 0, 0, rc.right, rc.bottom);
brushBg.delete();
// 常用资源
var penObj = gdip.pen(theme.objColor, 2);
var brushObj = gdip.solidBrush(theme.objColor);
var brushText = gdip.solidBrush(theme.textColor);
// --- 2. 游戏主画面 ---
if(game.state == "playing" || game.state == "gameover" || game.state == "levelup"){
// A. 绘制已插入的针
for(i=1; #game.pins){
var p = game.pins[i];
var currentAngle = p.angle + game.rotation;
var rad = currentAngle * (math.pi / 180);
var x1 = config.centerX + math.cos(rad) * config.radius;
var y1 = config.centerY + math.sin(rad) * config.radius;
var x2 = config.centerX + math.cos(rad) * (config.radius + config.pinLen);
var y2 = config.centerY + math.sin(rad) * (config.radius + config.pinLen);
graphics.drawLine(penObj, x1, y1, x2, y2);
graphics.fillEllipse(brushObj, x2-config.ballRadius, y2-config.ballRadius, config.ballRadius*2, config.ballRadius*2);
}
// B. 绘制中心大球
graphics.fillEllipse(brushObj, config.centerX-config.radius, config.centerY-config.radius, config.radius*2, config.radius*2);
// C. 绘制关卡数字 (居中)
var font = gdip.font(theme.fontName, 32, 1);
var fmt = gdip.stringformat();
fmt.align = 1; // Center Horizontal
fmt.lineAlign = 1; // Center Vertical
graphics.drawString(tostring(game.level), font, ::RECTF(config.centerX-config.radius, config.centerY-config.radius, config.radius*2, config.radius*2), fmt, brushText);
font.delete(); fmt.delete();
// D. 绘制飞行的针
if(game.activePin.active){
var y = game.activePin.y;
graphics.drawLine(penObj, config.centerX, y, config.centerX, y - config.pinLen);
graphics.fillEllipse(brushObj, config.centerX-config.ballRadius, y, config.ballRadius*2, config.ballRadius*2);
// 针头连接点
graphics.fillEllipse(brushObj, config.centerX-3, y-config.pinLen, 6, 6);
}
// E. 绘制等待队列
var waitY = config.startY;
var maxShow = 6;
var count = game.bulletsLeft;
if(game.activePin.active) count = count - 1;
for(i=0; math.min(count, maxShow)-1){
var y = waitY + i * 25;
graphics.fillEllipse(brushObj, config.centerX-config.ballRadius, y, config.ballRadius*2, config.ballRadius*2);
}
}
// --- 3. UI 覆盖层 ---
// 菜单界面
if(game.state == "menu"){
var fTitle = gdip.font(theme.fontName, 40, 1);
var fSub = gdip.font(theme.fontName, 14, 0);
var bTitle = gdip.solidBrush(theme.objColor);
var fmt = gdip.stringformat(); fmt.align=1; fmt.lineAlign=1;
// Logo
graphics.fillEllipse(bTitle, config.centerX-60, 180, 120, 120);
graphics.drawString("AA", fTitle, ::RECTF(0,180,400,120), fmt, brushText);
// 提示文本
graphics.drawString("点击或按空格开始", fSub, ::RECTF(0, 360, 400, 50), fmt, bTitle);
fTitle.delete(); fSub.delete(); bTitle.delete(); fmt.delete();
}
// 游戏结束界面
if(game.state == "gameover"){
var fFail = gdip.font(theme.fontName, 20, 1);
var bFail = gdip.solidBrush(0xFFFFFFFF);
var fmt = gdip.stringformat(); fmt.align=1; fmt.lineAlign=1;
graphics.drawString("游戏失败", fFail, ::RECTF(0, 100, 400, 50), fmt, bFail);
graphics.drawString("点击或空格重试", fFail, ::RECTF(0, 150, 400, 50), fmt, bFail);
fFail.delete(); bFail.delete(); fmt.delete();
}
// 资源清理
penObj.delete();
brushObj.delete();
brushText.delete();
}
// ==========================================
// 4. 游戏循环 (完美修复穿模版)
// ==========================================
winform.setInterval(
function(){
if(game.state == "playing"){
// 1. 更新旋转
game.rotation = game.rotation + game.rotSpeed;
if(game.rotation >= 360) game.rotation -= 360;
if(game.rotation < 0) game.rotation += 360;
// 2. 针的飞行
if(game.activePin.active){
// 计算关键坐标
var pinTailY = game.activePin.y; // 针尾 (当前坐标变量)
var pinHeadY = pinTailY - config.pinLen; // 针头 (向上延伸)
var surfaceY = config.centerY + config.radius; // 球体表面Y坐标
// ★★★ 核心修复:基于“针头”预判碰撞 ★★★
// 预测下一帧针头的位置
var nextHeadY = pinHeadY - config.bulletSpeed;
// 如果针头下一帧会碰到或穿过表面
if(nextHeadY <= surfaceY){
// 1. 物理位置修正:
// 我们要把“针尾”强制设置在 (表面 + 针长) 的位置
// 这样“针头”就刚好停在表面 (surfaceY) 上
game.activePin.y = surfaceY + config.pinLen;
// 2. 计算插入角度
var angle = 90 - game.rotation;
if(angle < 0) angle += 360;
// 3. 碰撞判断(判断针尖插进去的位置是否有障碍)
if(checkCollision(angle)){
game.state = "gameover";
game.bgColor = theme.bgFail;
} else {
// 插入成功
table.push(game.pins, { angle = angle });
game.bulletsLeft--;
// 重置发射针
game.activePin.active = false;
game.activePin.y = config.startY;
// 过关判断
if(game.bulletsLeft <= 0){
game.state = "levelup";
game.bgColor = theme.bgWin;
winform.plus.redraw();
win.setTimeout(function(){
initLevel(game.level + 1);
winform.plus.redraw();
}, 600)
}
}
} else {
// 如果没撞到,正常向上飞行
game.activePin.y -= config.bulletSpeed;
}
}
winform.plus.redraw();
}
elseif(game.state == "gameover" || game.state == "menu"){
// 待机旋转动画
game.rotation = game.rotation + 0.5;
if(game.rotation >= 360) game.rotation -= 360;
winform.plus.redraw();
}
}, 16
)
// ==========================================
// 5. 交互 (鼠标 + 键盘)
// ==========================================
// 鼠标交互
winform.plus.onMouseDown = function(wParam,lParam){
gameAction();
}
// 键盘交互 (新增)
winform.plus.onKeyDown = function(keyCode, lParam){
if(keyCode == 0x20){ // Spacebar
gameAction();
}
}
// 强制控件获取焦点,确保能响应键盘
winform.plus.setFocus();
winform.show();
win.loopMessage();
1 个回复 | 最后更新于 6 天前
登录后方可回帖
很流畅啊