恶搞好友?十五分钟学会编写这款原创安卓小游戏

 

 ---------纯原创,完整的源代码-->落坨翔子安卓小游戏Androidstudio源代码资源-CSDN文库

c44c1c8f40d84f46b689711548b5b35c.png

 资源包含Java代码文件以及相关配置文件

想整蛊你的好友吗?,想让你讨厌的人吃xiang吗?这款小游戏值得一试!

一、功能简介

 《落坨翔子》(Poop Dodger)是一款基于安卓平台的简单避障类游戏,玩家通过控制小人左右移动,避开不断下落的障碍物,尽可能地躲避障碍物并保持存活时间的长度。游戏提供了多个游戏模式可供选择,难度逐级增加。游戏中实时显示得分,并在游戏结束后展示最终得分。

二、需求分析

游戏界面和控制:

游戏界面应包含小球、障碍物、得分显示等元素,并提供游戏开始和结束的交互按钮。

玩家可以自定义小球外观,将其设置为好友的照片,增加个性化和趣味性。

玩家通过触摸屏幕左右区域来控制小球的左右移动。

障碍物生成和移动:

障碍物以一定的速度从屏幕顶部向下移动,玩家需要避开障碍物。

障碍物的外观为一坨大便形象,增加游戏的趣味性。

障碍物应以不同的大小呈现,增加游戏的难度和多样性。

碰撞检测和游戏结束:

游戏应实时检测小球与障碍物的碰撞,若发生碰撞则游戏结束。

游戏结束后应显示最终得分,并提供重新开始游戏的选项。

得分计算和显示:

根据存活时间计算得分,得分应以秒为单位计算并实时显示在游戏界面上。

游戏界面应提供清晰的得分显示和计时器。

三、详细设计

MainActivity:

- 游戏开始按钮:通过点击按钮,弹出对话框,让玩家选择游戏模式。

 - 游戏模式选择:根据玩家选择的游戏模式,设置障碍物的下落速度,并启动游戏。

部分相关代码:

public void startGame(View view) {
    AlertDialog.Builder builder = new AlertDialog.Builder(this);
    builder.setTitle("选择游戏模式")
            .setItems(new CharSequence[]{"简单", "一般", "困难", "地狱"}, new DialogInterface.OnClickListener() {
                @Override
                public void onClick(DialogInterface dialog, int which) {
                    int obstacleSpeed;
                    switch (which) {
                        case 0: // 简单
                            obstacleSpeed = 20;
                            break;
                        case 1: // 一般
                            obstacleSpeed = 30;
                            break;
                        case 2: // 困难
                            obstacleSpeed = 40;
                            break;
                        case 3: // 地狱
                            obstacleSpeed = 50;
                            break;
                        default:
                            obstacleSpeed = 20;
                            break;
                    }
                    Intent intent = new Intent(MainActivity.this, GameActivity.class);
                    intent.putExtra("obstacleSpeed", obstacleSpeed);
                    startActivity(intent);
                }
            })
            .setCancelable(true)
            .show();
}

6246112292894787af27a5ad965e8be7.png

 开始界面 

cee7aa56693d4e9ea88897c295a34bd4.png

 模式选择界面

 GameActivity:

- 初始化界面:设置游戏界面,包括游戏布局、小球视图、得分显示等。

- 小球移动:通过监听触摸事件,根据玩家触摸屏幕的位置,控制小球的左右移动。

- 障碍物生成:使用定时器与矢量图,在随机位置生成障碍物,并将其加入游戏界面。 - 得分计算:根据存活时间计算得分,并实时更新得分显示。

- 碰撞检测:在游戏进行过程中,实时检测小球与障碍物的碰撞情况,若发生碰撞则游戏结束。

- 游戏结束:停止障碍物生成,清空游戏界面,并计算存活时间,传递给结果页面进行显示。

部分相关代码:

private void resetGame() {
        if (obstacleTimer != null) {
            obstacleTimer.cancel();
            obstacleTimer.purge();
        }

        score = 0;
    }

    @Override
    protected void onRestart() {
        super.onRestart();
        // 重置得分为初始值
        score = 0;
    }

    private void generateObstacle() {
        if (gameLayout != null) {
            int x = random.nextInt(getScreenWidth());
            // 设置障碍物大小
            ObstacleView obstacleView = new ObstacleView(this, x, obstacleSize, handler,obstacleSpeed);
            // ...

            FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT);
            gameLayout.post(new Runnable() {
                @Override
                public void run() {
                    gameLayout.addView(obstacleView, layoutParams);
                }
            });
        }
    }

    public void increaseScore() {
        score++;
        handler.post(new Runnable() {
            @Override
            public void run() {
                scoreTextView.setText("得分:" + score);
            }
        });
    }

    public void removeObstacleView(final ObstacleView obstacleView) {
        if (obstacleView != null) {
            obstacleView.post(new Runnable() {
                @Override
                public void run() {
                    ViewGroup parent = (ViewGroup) obstacleView.getParent();
                    if (parent != null) {
                        parent.removeView(obstacleView);
                    }
                }
            });
        }
    }

    public BallView getBallView() {
        return ballView;
    }

    public void endGame() {
        if (obstacleTimer != null) {
            obstacleTimer.cancel();
            obstacleTimer.purge();
        }
        new Handler().post(new Runnable() {
            @Override
            public void run() {
                gameLayout.removeAllViews();
            }
        })
        long survivalTime = System.currentTimeMillis() - startTimeMillis;
        int seconds = (int) (survivalTime / 1000);

        Intent intent = new Intent(this, ResultActivity.class);
        intent.putExtra("score", seconds);
        intent.putExtra("mode", obstacleSpeed);
        startActivity(intent);
        finish();
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        if (mediaPlayer != null) {
            mediaPlayer.stop();
            mediaPlayer.release();
            mediaPlayer = null;
        }
        if (obstacleTimer != null) {
            obstacleTimer.cancel();
            obstacleTimer.purge();
        }
        gameLayout.removeAllViews();
    }

    private int getScreenWidth() {
        return getResources().getDisplayMetrics().widthPixels;
    }
}

b239d08d5fa24b7ea8eaf5ec7e7cbda9.png

 游戏界面(一般模式)

BallView:

- 小球视图:绘制小球的位置和图像,并处理小球的移动操作。

- 小球移动:根据玩家触摸屏幕的位置,实现小球的左右移动。

- 重置位置:在游戏重新开始时,将小球的位置重置为初始位置。

- 获取小球位置:提供方法获取小球的当前位置。

部分相关代码:

public class BallView extends View {
    private int screenWidth;
    private float ballX;
    private float ballY;
    private int radius;
    private Drawable ballDrawable;
    public BallView(Context context) {
        super(context);
        init();

    }
    public BallView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init();
    }
    public BallView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init();
    }
    private void init() {
        ballX = 0;
        ballY = 0;
        radius = 75;
        ballDrawable = getResources().getDrawable(R.drawable.wzk);
    }
    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        ballX = (w - radius) / 2;  // 将小球水平位置设置在屏幕中央
        ballY = h - 2*radius;  // 将小球位置设置在屏幕底部
    }
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        ballDrawable.setBounds((int) ballX, (int) ballY, (int) (ballX + radius *2), (int) (ballY + radius * 2));
        ballDrawable.draw(canvas);
    }
    public void setScreenWidth(int width) {
        this.screenWidth = width;
    }
    public void moveLeft() {
        ballX -= 10;
        if (ballX < 0) {
            ballX = 0;
        }
        invalidate();
    }
    public void moveRight() {
        ballX += 10;
        if (ballX > screenWidth - radius * 2) {
            ballX = screenWidth - radius * 2;
        }
        invalidate();
    }
    public void resetPosition() {
        ballX = (screenWidth - radius) / 2;
        ballY = getHeight() - 2 * radius;
        invalidate();
    }
    public float getBallX() {
        return ballX;
    }
    public float getBallY() {
        return ballY;
    }
}

 ObstacleView:

- 障碍物视图:绘制障碍物的位置和图像,并处理障碍物的下落和碰撞检测。

- 障碍物下落:随着时间的推移,障碍物以一定的速度向下移动。

- 碰撞检测:检测障碍物与小球的碰撞情况,若发生碰撞则触发游戏结束。

部分相关代码:

public ObstacleView(Context context, int x, int obstacleSize, Handler handler, int obstacleSpeed) {
        super(context);
        this.x = x;
        this.obstacleSize = obstacleSize; // 设置障碍物大小
        this.handler = handler;
        this.obstacleSpeed = obstacleSpeed; // 设置障碍物下落速度
        // 加载 SVG 文件
        try {
            obstacleSvg = SVG.getFromResource(context, R.raw.shi);
            if (obstacleSvg != null) {
                obstaclePicture = obstacleSvg.renderToPicture();
                calculateObstacleSize();
            } else {
                // 处理SVG图像加载失败的情况
                // 可以打印日志或采取其他错误处理措施
            }
        } catch (SVGParseException e) {
            e.printStackTrace();
        }
        // 添加视图树监听器
        getViewTreeObserver().addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
            @Override
            public void onGlobalLayout() {
                getViewTreeObserver().removeOnGlobalLayoutListener(this);
                startAnimation();
            }
        });
    }
    private void calculateObstacleSize() {
        obstacleWidth = obstacleSize;
        obstacleHeight = obstacleSize;
    }
    private boolean checkCollision(BallView ballView) {
        float ballX = ballView.getBallX();
        float ballY = ballView.getBallY();
        float ballRadius =60;
        float obstacleCenterX = x;
        float obstacleCenterY = y + obstacleHeight / 2;
        float obstacleHalfWidth = obstacleWidth / 2;
        float obstacleHalfHeight = obstacleHeight / 2;
        float dx = Math.abs(ballX - obstacleCenterX);
        float dy = Math.abs(ballY - obstacleCenterY);
        if (dx > obstacleHalfWidth + ballRadius || dy > obstacleHalfHeight + ballRadius) {
            return false;
        }
        if (dx <= obstacleHalfWidth || dy <= obstacleHalfHeight) {
            return true;
        }
        float cornerDistanceSq = (dx - obstacleHalfWidth) * (dx - obstacleHalfWidth)
                + (dy - obstacleHalfHeight) * (dy - obstacleHalfHeight);
        return cornerDistanceSq <= ballRadius * ballRadius;
    }
    private void startAnimation() {
        handler.post(new Runnable() {
            @Override
            public void run() {
                invalidate();
            }
        });
    }
    @SuppressLint("DrawAllocation")
    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        y += obstacleSpeed;
        // 绘制 SVG 图形
        if (obstaclePicture != null) {
            canvas.save();
            canvas.translate(x - obstacleWidth / 2, y);
            float scale = 0.1f;
            scale= (float) (scale*obstacleSpeed*0.05);// 设置缩放因子
            canvas.scale(scale, scale); // 缩放障碍物图像的大小
            canvas.drawPicture(obstaclePicture);
            canvas.restore();
        }
        if (y > getHeight()) {
            // 当障碍物移动到屏幕底部时,执行相应的操作
            ((GameActivity) getContext()).increaseScore();
        } else {
            BallView ballView = ((GameActivity) getContext()).getBallView();

            if (((x-ballView.getBallX() ) ==0 && Math.abs(y - ballView.getBallY())<radius)| (Math.abs(x-ballView.getBallX() )<radius && Math.abs(y - ballView.getBallY())<radius)){
                ((GameActivity) getContext()).endGame();
            }
            startAnimation();
        }
    }
}

 ResultActivity:

-获取得分数据:通过 getIntent() 方法获取上一个活动传递的得分数据。

-显示得分:将得分显示在界面上的 scoreTextView TextView 中。

部分相关代码:

public class ResultActivity extends AppCompatActivity {
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_result);
        setTheme(androidx.appcompat.R.style.Theme_AppCompat);
        Intent intent = getIntent();
        int seconds = intent.getIntExtra("score", 0);
        TextView scoreTextView = findViewById(R.id.scoreTextView);
        scoreTextView.setText("得分:" + seconds );
    }
}

f2b26956fdd14d58ad3fa9dca4e11b02.png

游戏结束界面

四、总结

《落坨翔子》(Poop Dodger)是一款基于安卓平台的避障类游戏,具有个性化和趣味化的特点。玩家可以将小球的外观自定义为好友的照片,增加游戏的个性化和趣味性。通过控制小球左右移动,玩家需要躲避不断下落的障碍物,尽可能延长存活时间并获得高分。游戏提供多个游戏模式,难度逐级增加,增加了游戏的挑战性和持久性。通过实时得分显示和游戏结束后的最终得分展示,玩家能够实时了解自己的游戏表现,并进行比较和挑战。《落坨翔子》(Poop Dodger)具备清晰明了的界面设计和易于上手的操作方式,适合各个年龄段的玩家进行休闲娱乐和挑战。   

  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

古镇口听海

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值