
import win.ui;
/*DSG{{*/
var winform = win.form(text="俄罗斯方块 (By: Mr_MAO)";right=415;bottom=560;border="dialog frame";max=false)
winform.add(
btnRestart={cls="button";text="重新开始";left=280;top=8;right=400;bottom=45;z=2};
gameCanvas={cls="plus";left=10;top=50;right=260;bottom=550;bgcolor=0x222222;notify=1;z=1};
lblHint={cls="static";text='\u2191旋转 \u2193加速 \u2190\u2192移动 空格暂停';left=10;top=19;right=260;bottom=44;color=0x808080;transparent=1;z=4};
lblLevel={cls="static";text="等级: 1";left=280;top=272;right=400;bottom=302;font=LOGFONT(h=-16;weight=700);transparent=1;z=6};
lblLines={cls="static";text="消行: 0";left=280;top=312;right=400;bottom=342;font=LOGFONT(h=-16;weight=700);transparent=1;z=7};
lblNext={cls="static";text="下一个:";left=280;top=64;right=400;bottom=89;font=LOGFONT(h=-14);transparent=1;z=8};
lblScore={cls="static";text="分数: 0";left=280;top=232;right=400;bottom=262;font=LOGFONT(h=-16;weight=700);transparent=1;z=3};
nextCanvas={cls="plus";left=280;top=88;right=400;bottom=208;bgcolor=0x333333;notify=1;z=5}
)
/*}}*/
import win.timer;
winform.tmr = win.timer(winform);
// --- 游戏环境参数 ---
var conf = {
cellSize = 25;
cols = 10;
rows = 20;
baseSpeed = 500;
colors = {
0xFF00FFFF; // I - 青色
0xFFFFFF00; // O - 黄色
0xFFF000F0; // T - 紫色
0xFF00FF00; // S - 绿色
0xFFFF0000; // Z - 红色
0xFF0000FF; // J - 蓝色
0xFFFF8000; // L - 橙色
grid = 0xFF444444;
text = 0xFFFFFFFF;
ghost = 0x40FFFFFF;
}
}
// 7种方块的形状定义 (每个方块4个旋转状态)
var shapes = {
{// I
{{0,1},{1,1},{2,1},{3,1}};
{{2,0},{2,1},{2,2},{2,3}};
{{0,2},{1,2},{2,2},{3,2}};
{{1,0},{1,1},{1,2},{1,3}};
};
{// O
{{1,0},{2,0},{1,1},{2,1}};
{{1,0},{2,0},{1,1},{2,1}};
{{1,0},{2,0},{1,1},{2,1}};
{{1,0},{2,0},{1,1},{2,1}};
};
{// T
{{1,0},{0,1},{1,1},{2,1}};
{{1,0},{1,1},{2,1},{1,2}};
{{0,1},{1,1},{2,1},{1,2}};
{{1,0},{0,1},{1,1},{1,2}};
};
{// S
{{1,0},{2,0},{0,1},{1,1}};
{{1,0},{1,1},{2,1},{2,2}};
{{1,1},{2,1},{0,2},{1,2}};
{{0,0},{0,1},{1,1},{1,2}};
};
{// Z
{{0,0},{1,0},{1,1},{2,1}};
{{2,0},{1,1},{2,1},{1,2}};
{{0,1},{1,1},{1,2},{2,2}};
{{1,0},{0,1},{1,1},{0,2}};
};
{// J
{{0,0},{0,1},{1,1},{2,1}};
{{1,0},{2,0},{1,1},{1,2}};
{{0,1},{1,1},{2,1},{2,2}};
{{1,0},{1,1},{0,2},{1,2}};
};
{// L
{{2,0},{0,1},{1,1},{2,1}};
{{1,0},{1,1},{1,2},{2,2}};
{{0,1},{1,1},{2,1},{0,2}};
{{0,0},{1,0},{1,1},{1,2}};
};
}
// --- 游戏状态 ---
var state = {
board = {};
current = null;
next = null;
score = 0;
level = 1;
lines = 0;
gameOver = false;
paused = false;
}
// 获取方块的格子位置
var getPieceCells = function(piece){
var shape = shapes[[piece.typeSharp]][[piece.rotation]];
var cells = {};
for(i=1; #shape; 1){
table.push(cells, {
x = piece.x + shape[[i]][1];
y = piece.y + shape[[i]][2];
});
}
return cells;
}
// 碰撞检测
var checkCollision = function(piece){
var cells = getPieceCells(piece);
for(i=1; #cells; 1){
var cx = cells[[i]].x;
var cy = cells[[i]].y;
if(cx < 0 || cx >= conf.cols || cy >= conf.rows){
return true;
}
if(cy >= 0 && state.board[[cy+1]] && state.board[[cy+1]][[cx+1]]){
return true;
}
}
return false;
}
// 锁定方块到游戏板
var lockPiece = function(){
var cells = getPieceCells(state.current);
for(i=1; #cells; 1){
var cx = cells[[i]].x;
var cy = cells[[i]].y;
if(cy >= 0){
state.board[[cy+1]][[cx+1]] = state.current.typeSharp;
}
}
}
// 消行检测
var clearLines = function(){
var linesCleared = 0;
var y = conf.rows;
while(y >= 1){
var full = true;
for(x=1; conf.cols; 1){
if(!state.board[[y]][[x]]){
full = false;
break;
}
}
if(full){
table.remove(state.board, y);
var newRow = {};
for(x=1; conf.cols; 1) newRow[[x]] = null;
table.insert(state.board, newRow, 1);
linesCleared++;
} else {
y--;
}
}
if(linesCleared > 0){
var scoreTable = {100; 300; 500; 800};
state.score += (scoreTable[[linesCleared]] : 100) * state.level;
state.lines += linesCleared;
state.level = math.floor(state.lines / 10) + 1;
winform.lblScore.text = "分数: " + state.score;
winform.lblLevel.text = "等级: " + state.level;
winform.lblLines.text = "消行: " + state.lines;
var newSpeed = conf.baseSpeed - (state.level - 1) * 40;
if(newSpeed < 80) newSpeed = 80;
winform.tmr.disable();
winform.tmr.enable(newSpeed);
}
}
// 生成随机方块
var randomPiece = function(){
return {
typeSharp = math.random(1, 7);
rotation = 1;
x = 3;
y = -1;
}
}
// 生成下一个方块
var spawnPiece = function(){
state.current = state.next : randomPiece();
state.next = randomPiece();
if(checkCollision(state.current)){
state.gameOver = true;
winform.tmr.disable();
winform.btnRestart.text = "重玩(R)";
winform.gameCanvas.redraw();
win.msgbox('游戏结束! \r\n🏆得分: ' ++ state.score ++ '\r\n消行: ' ++ state.lines, "提示");
}
}
// 初始化游戏
var initGame = function(){
state.board = {};
for(y=1; conf.rows; 1){
state.board[[y]] = {};
for(x=1; conf.cols; 1) state.board[[y]][[x]] = null;
}
state.score = 0;
state.level = 1;
state.lines = 0;
state.gameOver = false;
state.paused = false;
state.next = null;
winform.lblScore.text = "分数: 0";
winform.lblLevel.text = "等级: 1";
winform.lblLines.text = "消行: 0";
winform.btnRestart.text = "重新开始";
spawnPiece();
winform.tmr.enable(conf.baseSpeed);
}
// 移动方块
var movePiece = function(dx, dy){
if(state.gameOver || state.paused) return false;
var newPiece = {
typeSharp = state.current.typeSharp;
rotation = state.current.rotation;
x = state.current.x + dx;
y = state.current.y + dy;
}
if(!checkCollision(newPiece)){
state.current = newPiece;
return true;
}
return false;
}
// 旋转方块
var rotatePiece = function(){
if(state.gameOver || state.paused) return;
var newRotation = state.current.rotation + 1;
if(newRotation > 4) newRotation = 1;
var newPiece = {
typeSharp = state.current.typeSharp;
rotation = newRotation;
x = state.current.x;
y = state.current.y;
}
// 墙踢测试
var kicks = {{0,0}; {-1,0}; {1,0}; {0,-1}; {-2,0}; {2,0}};
for(i=1; #kicks; 1){
newPiece.x = state.current.x + kicks[[i]][1];
newPiece.y = state.current.y + kicks[[i]][2];
if(!checkCollision(newPiece)){
state.current = newPiece;
return;
}
}
}
// 硬降落
var hardDrop = function(){
if(state.gameOver || state.paused) return;
var dropCount = 0;
while(movePiece(0, 1)) dropCount++;
state.score += dropCount * 2;
winform.lblScore.text = "分数: " + state.score;
lockPiece();
clearLines();
spawnPiece();
winform.gameCanvas.redraw();
winform.nextCanvas.redraw();
}
// 获取幽灵方块位置
var getGhostY = function(){
var ghostPiece = {
typeSharp = state.current.typeSharp;
rotation = state.current.rotation;
x = state.current.x;
y = state.current.y;
}
while(!checkCollision(ghostPiece)){
ghostPiece.y++;
}
return ghostPiece.y - 1;
}
// 游戏主循环
var update = function(){
if(state.gameOver || state.paused) return;
if(!movePiece(0, 1)){
lockPiece();
clearLines();
spawnPiece();
}
winform.gameCanvas.redraw();
winform.nextCanvas.redraw();
}
winform.tmr.onTimer = function(){
update();
}
// 键盘事件
winform.isDialogMessage = function(hwnd, msg){
if(msg.message == 0x0100/*_WM_KEYDOWN*/){
var vk = msg.wParam;
if(vk == 0x20/*_VK_SPACE*/){
if(state.gameOver) initGame();
else {
state.paused = !state.paused;
winform.gameCanvas.redraw();
}
return true;
}
if(vk == 0x52/*R*/){
initGame();
return true;
}
if(!state.paused && !state.gameOver){
if(vk == 0x25/*_VK_LEFT*/){
movePiece(-1, 0);
winform.gameCanvas.redraw();
}
elseif(vk == 0x27/*_VK_RIGHT*/){
movePiece(1, 0);
winform.gameCanvas.redraw();
}
elseif(vk == 0x28/*_VK_DOWN*/){
if(movePiece(0, 1)){
state.score += 1;
winform.lblScore.text = "分数: " + state.score;
}
winform.gameCanvas.redraw();
}
elseif(vk == 0x26/*_VK_UP*/){
rotatePiece();
winform.gameCanvas.redraw();
}
elseif(vk == 0x0D/*_VK_RETURN*/){
hardDrop();
}
}
return true;
}
}
// 主游戏区绘图
winform.gameCanvas.onDrawForegroundEnd = function(graphics, rect){
var cellSize = conf.cellSize;
// 绘制网格线
var penGrid = gdip.pen(conf.colors.grid, 1);
for(x=0; conf.cols; 1){
graphics.drawLine(penGrid, x * cellSize, 0, x * cellSize, conf.rows * cellSize);
}
for(y=0; conf.rows; 1){
graphics.drawLine(penGrid, 0, y * cellSize, conf.cols * cellSize, y * cellSize);
}
penGrid.delete();
// 绘制已锁定的方块
for(y=1; conf.rows; 1){
for(x=1; conf.cols; 1){
var cell = state.board[[y]][[x]];
if(cell){
var brush = gdip.solidBrush(conf.colors[[cell]]);
graphics.fillRectangle(brush,
(x-1) * cellSize + 2, (y-1) * cellSize + 2,
cellSize - 4, cellSize - 4);
brush.delete();
}
}
}
// 绘制幽灵方块和当前方块
if(state.current && !state.gameOver){
var ghostY = getGhostY();
var cells = getPieceCells(state.current);
// 幽灵方块
var brushGhost = gdip.solidBrush(conf.colors.ghost);
for(i=1; #cells; 1){
var gy = ghostY - state.current.y + cells[[i]].y;
if(gy >= 0){
graphics.fillRectangle(brushGhost,
cells[[i]].x * cellSize + 2, gy * cellSize + 2,
cellSize - 4, cellSize - 4);
}
}
brushGhost.delete();
// 当前方块
var brush = gdip.solidBrush(conf.colors[[state.current.typeSharp]]);
for(i=1; #cells; 1){
if(cells[[i]].y >= 0){
graphics.fillRectangle(brush,
cells[[i]].x * cellSize + 2, cells[[i]].y * cellSize + 2,
cellSize - 4, cellSize - 4);
}
}
brush.delete();
}
// 绘制状态文字
if(state.gameOver || state.paused){
var txt = state.gameOver ? "GAME OVER" : "已暂停";
var font = gdip.font("微软雅黑", 22);
var brushTxt = gdip.solidBrush(conf.colors.text);
var strFormat = gdip.stringformat();
strFormat.align = 1;
strFormat.lineAlign = 1;
var rc = gdip.RECTF(0, 0, conf.cols * cellSize, conf.rows * cellSize);
graphics.drawString(txt, font, rc, strFormat, brushTxt);
font.delete(); brushTxt.delete(); strFormat.delete();
}
}
// 下一个方块预览区绘图
winform.nextCanvas.onDrawForegroundEnd = function(graphics, rect){
if(!state.next) return;
var cellSize = 20;
var shape = shapes[[state.next.typeSharp]][1];
var brush = gdip.solidBrush(conf.colors[[state.next.typeSharp]]);
var offsetX = 25;
var offsetY = 35;
for(i=1; #shape; 1){
graphics.fillRectangle(brush,
offsetX + shape[[i]][1] * cellSize + 1,
offsetY + shape[[i]][2] * cellSize + 1,
cellSize - 2, cellSize - 2);
}
brush.delete();
}
winform.btnRestart.oncommand = function(id, event){
initGame();
}
winform.enableDpiScaling(false);
winform.show();
initGame();
win.loopMessage();
最新回复 (0)