复刻经典大金刚游戏

前言

客户让我做一个大金刚游戏,给了我一个PDF文档,里面有详细的需求。
大致是:

  1. 马里奥可以左右移动,跳跃,爬梯子
  2. 马里奥碰到锤子,可以变无敌
  3. 马里奥碰到木桶或者大金刚,游戏结束,判断为失败
  4. 马里奥跳过木桶能加分,用锤子击碎木桶也能加分
  5. 马里奥用锤子击碎大金刚,游戏结束,判断为胜利
  6. 游戏结束的时候,会统计总分数,包括剩余时间加分

效果

【DonkeyKong演示】 https://www.bilibili.com/video/BV1JRdcYnEFS

关于部署

这个需要用到 maven,我还是第一次接触,不过经过一番研究,还是搞出来了。

参考这个 maven 配置
https://www.bilibili.com/video/BV1KvHqecE15?spm_id_from=333.788.player.switch&vd_source=3b4c59844f52434c32339734eb682772

然后
mvn exec:java -Dexec.mainClass="ShadowDonkeyKong"
就可以运行了

关于代码

最关键 ———— CollisionManager, 管理碰撞事件。

碰撞的检测

Rectangle.intersects 长方形是否相交

一些特殊条件&细节

爬梯子

不仅要相交,还要求马里奥的中心点的x坐标,在梯子的left和right之间。

判断马里奥是否跳跃

要计算马里奥左右两侧的木桶数量,这些都是很细节的点。

getBarrelCount的实现

public Point getBarrelCount(Point marioPosition, double width,double height){
        int left=0,right=0;
        for(Enemy e:barrels){
            Rectangle eBox = e.getBoundingBox();
            if(Math.abs(eBox.bottom() - marioPosition.y-height/2)<1){
                if(e.getPosition().x < marioPosition.x){
                    left++;
                }else{
                    right++;
                }
                
            }
        }
        //System.out.printf("barrel left=%d,right=%d\n",left,right);
        Point count = new Point(left,right);
        return count;
    }

插曲

我发现 image.draw 并不是从左上角绘制的,而是从中心点绘制的,很神奇。
我后来加了调试,打印出边框,才发现这一点。

  // 计算碰撞箱的四个角的坐标
        double left = position.x - currentImage.getWidth() / 2;
        double right = position.x + currentImage.getWidth() / 2;
        double top = position.y - currentImage.getHeight() / 2;
        double bottom = position.y + currentImage.getHeight() / 2;

        // 绘制矩形的四条边
        Drawing.drawLine(left, top, right, top, Colour.RED); // 上边
        Drawing.drawLine(right, top, right, bottom, Colour.RED); // 右边
        Drawing.drawLine(right, bottom, left, bottom, Colour.RED); // 下边
        Drawing.drawLine(left, bottom, left, top, Colour.RED); // 左边
    }
posted @ 2025-04-06 23:58  lucky_doog  阅读(41)  评论(0)    收藏  举报