[安卓]安卓课程设计之俄罗斯方块
程序员文章站
2022-04-09 10:50:21
程序很简单就只放代码了,自己完善下color和Drawable即可使用Java文件:package com.ytu.jkxy.jk171.sjp.russiablock;import androidx.appcompat.app.AppCompatActivity;import android.annotation.SuppressLint;import android.content.Context;import android.graphics.Canvas;import and...
程序很简单就只放代码了,自己完善下color和Drawable即可使用
Java文件:
package com.ytu.jkxy.jk171.sjp.russiablock;
import androidx.appcompat.app.AppCompatActivity;
import android.annotation.SuppressLint;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.graphics.Point;
import android.os.Handler;
//import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.DisplayMetrics;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.FrameLayout;
import android.widget.Toast;
import java.util.Random;
public class MainActivity extends AppCompatActivity implements View.OnClickListener {
//声明一个游戏区域控件
View view;
//游戏区域长宽
int xWidth,xHight;
//地图画笔
Paint mapPaint;
//初始化辅助线画笔
Paint linepaint;
//方块画笔
Paint boxPaint;
//状态画笔
Paint startPaint;
//地图
boolean [][]maps;
//方块
Point[] boxs;
//方块的种类
final int TYPE = 7;
//方块类型
int boxType;
//方块大小
int boxSize;
//自动下落线程
public Thread downThread;
//
public Handler handler=new Handler(){
public void handleMessage(android.os.Message msg){
//刷新重绘view
view.invalidate();
};
};
//暂停状态
public boolean isPause;
//游戏结束状态
public boolean isOver;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
//去掉标题栏
getSupportActionBar().hide();
setContentView(R.layout.activity_main);
intData();
newBoxs();
initView();
intLister();
}
//初始化数据
public void intData(){
//获得屏幕宽度
int width=getScreeWidth(this);
//设置游戏区域宽度=屏幕宽度*2/3
xWidth=width * 2/3;
//游戏区域的高度=宽度 * 2
xHight=2 * xWidth;
//初始化地图
maps=new boolean[10][20];
//初始化方块大小:游戏宽度/10
boxSize=xWidth/maps.length;
}
/*新的方块*/
public void newBoxs(){
//随机数生成一个新的方块
Random random=new Random();
boxType=random.nextInt(7);
switch (boxType){
//田字形
//55
//55
case 0:
boxs=new Point[]{new Point(4,0),new Point(5,0),new Point(4,1),new Point(5,1)};
break;
//L 例:
//5
//5
//55
case 1:
boxs=new Point[]{new Point(4,1),new Point(5,0),new Point(3,1),new Point(5,1)};
break;
//反L
case 2:
boxs=new Point[]{new Point(4,1),new Point(3,0),new Point(3,1),new Point(5,1)};
break;
//横条
//例:5555
case 3:
boxs=new Point[]{new Point(3,0),new Point(4,0),new Point(5,0),new Point(6,0)};
break;
//凸字形 例:
/*5
555*/
case 4:
boxs=new Point[]{new Point(4,1),new Point(5,0),new Point(5,1),new Point(6,1)};
break;
case 5:
boxs=new Point[]{new Point(4,0),new Point(5,0),new Point(5,1),new Point(5,2)};
break;
case 6:
boxs=new Point[]{new Point(5,0),new Point(6,0),new Point(4,1),new Point(5,1)};
break;
}
}
//初始化视图
@SuppressLint("ResourceAsColor")
public void initView(){
//初始化画笔
mapPaint=new Paint();
mapPaint.setColor(0x50000000);
mapPaint.setAntiAlias(true);
linepaint =new Paint();
linepaint.setColor(R.color.paint1);
//一般会打开抗锯齿
linepaint.setAntiAlias(true);
//初始化方块画笔
boxPaint=new Paint();
boxPaint.setColor(0xff000000);
boxPaint.setAntiAlias(true);
startPaint=new Paint();
startPaint.setColor(R.color.tools);
startPaint.setAntiAlias(true);
startPaint.setTextSize(100);
//1.得到父容器
FrameLayout layoutGame=findViewById(R.id.layoutGame);
//2.实例化游戏区域
view = new View(this){
//重写游戏区域绘制
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
//绘制地图
for(int x=0;x<maps.length;x++){
for(int y=0;y<maps[x].length;y++){
if(maps[x][y] == true)
canvas.drawRect(x*boxSize,y*boxSize,x*boxSize+boxSize,y*boxSize+boxSize,mapPaint);
}
}
//方块绘制
for(int i=0;i<boxs.length;i++){
//矩形绘制
canvas.drawRect(
boxs[i].x*boxSize,
boxs[i].y*boxSize,
boxs[i].x*boxSize+boxSize,
boxs[i].y*boxSize+boxSize,boxPaint);
}
//地图辅助线绘制
for(int x=0;x<maps.length;x++){
canvas.drawLine(x*boxSize,0,x*boxSize,view.getHeight(),linepaint);
}
for(int y=0;y<maps[0].length;y++){
canvas.drawLine(0,y*boxSize,view.getWidth(),y*boxSize,linepaint);
}
//游戏结束提示
if(isOver){
canvas.drawText("游戏结束",view.getWidth()/2-startPaint.measureText("游戏结束")/2,view.getHeight()/2,startPaint);
}
//画暂停状态
if(isPause && !isOver){
canvas.drawText("暂停",view.getWidth()/2-startPaint.measureText("暂停")/2,view.getHeight()/2,startPaint);
}
}
};
//3.设置游戏区域大小
view.setLayoutParams(new FrameLayout.LayoutParams(xWidth,xHight));
//设置背景颜色
view.setBackgroundColor(R.color.gamabg11);
//4.添加到父容器里面
layoutGame.addView(view);
}
/* 初始化监听*/
public void intLister(){
findViewById(R.id.btnLeft).setOnClickListener(this);
findViewById(R.id.btnRight).setOnClickListener(this);
findViewById(R.id.btnTop).setOnClickListener(this);
findViewById(R.id.btnRight).setOnClickListener(this);
findViewById(R.id.btnBottom).setOnClickListener(this);
findViewById(R.id.btnStart).setOnClickListener(this);
findViewById(R.id.btnPause).setOnClickListener(this);
}
//获得屏幕宽度
public static int getScreeWidth(Context context){
WindowManager wm=(WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
DisplayMetrics outMetrice = new DisplayMetrics();
wm.getDefaultDisplay().getMetrics(outMetrice);
return outMetrice.widthPixels;
}
/*捕捉点击事件*/
@Override
public void onClick(View v) {
switch (v.getId()){
//左
case R.id.btnLeft:
if (isPause)
return;
move(-1,0);
break;
//上
case R.id.btnTop:
if (isPause)
return;
rotate();
break;
//右
case R.id.btnRight:
if (isPause)
return;
move(1,0);
break;
//下
case R.id.btnBottom:
if (isPause)
return;
//快速下落
while (true){
//如果下落失败 结束循环
if(!moveBottom()){
break;
}
}
break;
//开始
case R.id.btnStart:
startGame();
break;
//暂停
case R.id.btnPause:
setPause();
//btnPause.cap.
break;
}
//调用重新绘制view
view.invalidate();
}
/*设置暂停状态*/
public void setPause(){
if(isPause)
isPause=false;
else
isPause=true;
}
/*开始游戏*/
public void startGame(){
if(downThread==null){
downThread=new Thread(){
@Override
public void run() {
super.run();
while(true){
try{
//休眠500毫秒
sleep(500);
}catch (InterruptedException e){
e.printStackTrace();
}
//判断游戏是否处于结束状态
//判断是否属于暂停状态
if(isOver||isPause)
//继续循环
continue;
//执行一次下落
moveBottom();
//通知主线程刷新
handler.sendEmptyMessage(0);
}
}
};
downThread.start();
}
//清除地图
for(int x=0;x<maps.length;x++){
for(int y = 0;y<maps[0].length;y++){
maps[x][y]=false;
}
}
//游戏结束主观题设为false
isOver=false;
//暂停状态设为false
isPause=false;
//生成新的方块
newBoxs();
}
/*下落*/
public boolean moveBottom(){
//1.移动成功不做处理
if(move(0,1))
return true;
//2.移动失败,堆积处理
for(int i=0;i<boxs.length;i++)
maps[boxs[i].x][boxs[i].y] = true;
//3.消行处理
cleaneLine();
//4.生成新的方块
newBoxs();
//5.游戏结束判断
isOver=checkOver();
return false;
}
/*消行处理*/
public void cleaneLine(){
for(int y=maps[0].length-1;y>0;y--){
//执行判断
if(checkLine(y)) {
//执行消行
deleteLine(y);
//消掉的那一行开始重新遍历
y++;
}
}
}
/*消行判断*/
public boolean checkLine(int y){
for(int x=0;x<maps.length;x++){
//如果有一个不为true,则这一行不能消除
if(!maps[x][y])
return false;
}
return true;
}
/*执行消行*/
public void deleteLine(int dy){
for(int y=maps[0].length-1;y>0; y--){
for(int x=0;x<maps.length;x++){
maps[x][y]=maps[x][y-1];
}
}
}
/*游戏结束判断*/
public boolean checkOver(){
for(int i=0;i<boxs.length;i++){
if(maps[boxs[i].x][boxs[i].y]){
return true;
}
}
return false;
}
/*移动*/
public boolean move(int x,int y){
for(int i=0;i<boxs.length;i++) {
//把方块预移动的点传入边界判断
if(cheakBoundary(boxs[i].x +x, boxs[i].y +y)){
//如果出界 返回false
return false;
}
}
//遍历方块数组每一个都加上偏移量
for(int i=0;i<boxs.length;i++) {
boxs[i].x += x;
boxs[i].y += y;
}
return true;
}
/*旋转*/
public boolean rotate(){
//如果当前方块为田字形,旋转失败
if(boxType==0){
return false;
}
//遍历方块数组,每一个都绕着中心店点旋转90度
for(int i=0;i<boxs.length;i++){
//旋转算法(笛卡尔公式)顺时针旋转90度
int checkX=-boxs[i].y+boxs[0].y+boxs[0].x;
int checkY=boxs[i].x-boxs[0].x+boxs[0].y;
//将预旋转的点传入边界判断是否出界
if(cheakBoundary(checkX,checkY))
//如果出界false,旋转失败
return false;
}
//遍历方块数组,每一个都绕着中心店点旋转90度
for(int i=0;i<boxs.length;i++){
//旋转算法(笛卡尔公式)顺时针旋转90度
int checkX=-boxs[i].y+boxs[0].y+boxs[0].x;
int checkY=boxs[i].x-boxs[0].x+boxs[0].y;
boxs[i].x=checkX;
boxs[i].y=checkY;
}
return true;
}
/**
* 出界判断
* 传入x,y,判断是否在边界外
* return ture说出界
* */
public boolean cheakBoundary(int x,int y){
return (x<0 ||y<0||x>=maps.length||y>=maps[0].length||maps[x][y] == true);
}
}
布局文件:
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity"
android:orientation="vertical"
android:background="#67C6F1">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:padding="10dp"
android:orientation="horizontal">
<FrameLayout
android:id="@+id/layoutGame"
android:layout_width="wrap_content"
android:layout_height="wrap_content">
//帧布局
</FrameLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_gravity="bottom"
android:orientation="vertical">
//游戏开始按钮 (包括重新开始)
<Button
android:id="@+id/btnStart"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_click_pause"
android:text="Start"/>
//游戏暂停按钮
<Button
android:id="@+id/btnPause"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_weight="1"
android:background="@drawable/btn_click_pause"
android:text="Pause"
android:layout_marginTop="8dp"/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
//左右变换下降按钮
<Button
android:id="@+id/btnLeft"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="左移"
android:textSize="25dp"
android:background="@drawable/btn_click_pause"
/>
<Button
android:id="@+id/btnTop"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="变换"
android:textSize="25dp"
android:background="@drawable/btn_click_pause"/>
<Button
android:id="@+id/btnRight"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="右移"
android:textSize="25dp"
android:background="@drawable/btn_click_pause"/>
<Button
android:id="@+id/btnBottom"
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:text="降落"
android:textSize="25dp"
android:background="@drawable/btn_click_pause"/>
</LinearLayout>
<LinearLayout
android:layout_width="match_parent"
android:layout_height="60dp"
android:orientation="horizontal">
//
<ScrollView
android:layout_width="match_parent"
android:layout_height="match_parent">
<LinearLayout
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="horizontal">
<TextView
android:layout_width="0dp"
android:layout_height="match_parent"
android:layout_weight="1"
android:textStyle="bold"
android:text="power by android"
android:textSize="18dp"
android:gravity="center"
/>
</LinearLayout>
</ScrollView>
</LinearLayout>
//总系统显性布局
</LinearLayout>
测试结果:
本文地址:https://blog.csdn.net/Waybyway/article/details/107326753
上一篇: 信息安全实验--DES算法
下一篇: 信息安全实验--DES算法
推荐阅读
-
微软安卓启动器将加入云剪贴板:可与Win10电脑同步
-
PHP做接口,向安卓客户端提供数据,id、name等,怎么实现
-
安卓仿墨迹天气往下滑动带动画效果的引导页
-
实现安卓控件动画GridView
-
Windows 10 20H1新版18885推送:PC能实时接收安卓的推送通知了
-
delphi-请问Delphi安卓下怎么连接虚拟主机数据库(mysql)?
-
苹果iPhone、Mac生态到底有多强大?这些操作安卓、Windows就不行
-
安卓图片反复压缩后为什么普遍会变绿而不是其它颜色?
-
红米K20 Pro拿下“最佳音质安卓手机” 耳机孔立功
-
安卓+ios系统--手机端页面自适应手机屏幕大小,禁止手动放大和缩小VUE