效果预览
推方块
游戏简介:由 ↑,↓,←,→键来控制方向,点击空格键表示重玩当前关卡。文章来源:https://www.toymoban.com/news/detail-502509.html
核心代码部分:就是如何处理人的移动和人和箱子一起时的移动,这里需要对人要走的下一步和人推着箱子一起走的下一步进行判断分析,如果没有被阻挡就可以继续走下一步。(有兴趣的小伙伴可以参考我写的完整代码,上面都有备注解析)文章来源地址https://www.toymoban.com/news/detail-502509.html
完整代码部分
package demo01;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
public class Pushbox005 extends JFrame implements KeyListener, ActionListener, MouseListener {
// 定义一个内部类用来创建坐标
class Point{
public int x;
public int y;
public Point (int x,int y){
this.x=x;
this.y=y;
}
}
// 行数(高)
int height=8;
// 列数(宽)
int width=8;
// 格子的大小
int size=50;
// 标题栏的高度
int title=100;
// 记录窗口大小是否发生改变
boolean window=false;
// 关卡地图信息
class Ditu{
public int [][] ditu;
Ditu(int[][] _ditu){
this.ditu=_ditu;
}
}
// 创建一个二维数组用来存放关卡
// 1-10关地图
int [][] ditu1={{0,0,1,1,1,0,0,0},{0,0,1,3,1,0,0,0},{0,0,1,2,1,1,1,1},{1,1,1,4,2,4,3,1},{1,3,2,4,5,1,1,1},{1,1,1,1,4,1,0,0},{0,0,0,1,3,1,0,0},{0,0,0,1,1,1,0,0}};
int [][] ditu2= {{1,1,1,1,1,0,0,0,0},{1,2,2,5,1,0,0,0,0},{1,2,4,4,1,0,1,1,1},{1,2,4,2,1,0,1,3,1},{1,1,1,2,1,1,1,3,1},{0,1,1,2,2,2,2,3,1},{0,1,2,2,2,1,2,2,1},{0,1,2,2,2,1,1,1,1},{0,1,1,1,1,1,0,0,0}};
int [][] ditu3={{0,1,1,1,1,1,1,1,0,0},{0,1,2,2,2,2,2,1,1,1},{1,1,4,1,1,1,2,2,2,1},{1,2,5,2,4,2,2,4,2,1},{1,2,3,3,1,2,4,2,1,1},{1,1,3,3,1,2,2,2,1,0},{0,1,1,1,1,1,1,1,1,0}};
int [][] ditu4={{0,1,1,1,1,0},{1,1,2,2,1,0},{1,5,4,2,1,0},{1,1,4,2,1,1},{1,1,2,4,2,1},{1,3,4,2,2,1},{1,3,3,6,3,1},{1,1,1,1,1,1}};
int [][] ditu5={{0,1,1,1,1,1,0,0},{0,1,2,2,1,1,1,0},{0,1,5,4,2,2,1,0},{1,1,1,2,1,2,1,1},{1,3,1,2,1,2,2,1},{1,3,4,2,2,1,2,1},{1,3,2,2,2,4,2,1},{1,1,1,1,1,1,1,1}};
int [][] ditu6={{0,0,0,1,1,1,1,1,1,1,0,0,0},{1,1,1,1,2,2,2,2,2,1,0,0,0},{1,2,2,2,3,1,1,1,2,1,0,0,0},{1,2,1,2,1,2,2,2,2,1,1,0,0},{1,2,1,2,4,2,4,1,3,2,1,0,0},{1,2,1,2,2,6,2,2,1,2,1,0,0},{1,2,3,1,4,2,4,2,1,2,1,0,0},{1,1,2,2,2,2,1,2,1,2,1,1,1},{0,1,2,1,1,1,3,2,2,2,2,5,1},{0,1,2,2,2,2,2,1,1,2,2,2,1},{0,1,1,1,1,1,1,1,1,1,1,1,1}};
int [][] ditu7={{0,0,0,1,1,1,1,1,1,1},{0,0,1,1,2,2,1,2,5,1},{0,0,1,2,2,2,1,2,2,1},{0,0,1,4,2,4,2,4,2,1},{0,0,1,2,4,1,1,2,2,1},{1,1,1,2,4,2,1,2,1,1},{1,3,3,3,3,3,2,2,1,0},{1,1,1,1,1,1,1,1,1,0}};
int [][] ditu8={{0,0,0,1,1,1,1,1,1,0},{0,1,1,1,2,2,2,2,1,0},{1,1,3,2,4,1,1,2,1,1},{1,3,3,4,2,4,2,2,5,1},{1,3,3,2,4,2,4,2,1,1},{1,1,1,1,1,1,2,2,1,0},{0,0,0,0,0,1,1,1,1,0}};
int [][] ditu9={{0,1,1,1,1,1,1,1,1,1,0},{0,1,2,2,1,1,2,2,2,1,0},{0,1,2,2,2,4,2,2,2,1,0},{0,1,4,2,1,1,1,2,4,1,0},{0,1,2,1,3,3,3,1,2,1,0},{1,1,2,1,3,3,3,1,2,1,1},{1,2,4,2,2,4,2,2,4,2,1},{1,2,2,2,2,2,1,2,5,2,1},{1,1,1,1,1,1,1,1,1,1,1}};
int [][] ditu10={{0,0,1,1,1,1,1,1},{0,0,1,2,2,2,2,1},{1,1,1,4,4,4,2,1},{1,5,2,4,3,3,2,1},{1,2,4,3,3,3,1,1},{1,1,1,1,2,2,1,0},{0,0,0,1,1,1,1,0}};
// 创建一个总地图
Ditu ditu[]={new Ditu(ditu1),new Ditu(ditu2),new Ditu(ditu3),new Ditu(ditu4),new Ditu(ditu5),new Ditu(ditu6),new Ditu(ditu7),new Ditu(ditu8),new Ditu(ditu9),new Ditu(ditu10)};
// 定义一个当前关卡
int guan=1;
// 定义一个最大关卡
int maxguan=10;
// 定义一个变量判断是否通关
boolean tongguan=false;
// 创建一个推箱子的小人
Point man=new Point(4,4);
// 创建箱子
Point [] box= {new Point(3,3),new Point(3,4),new Point(5,3),new Point(4,5)};
// 创建箱子最终要到达的位置
Point [] home={new Point(1,4),new Point(3,1),new Point(6,3),new Point(4,6)};
// 创建一个墙壁数组
Point [] qiangbi= {new Point(2,0),new Point(3,0),new Point(4,0),
new Point(2,1),new Point(4,1),
new Point(2,2),new Point(4,2),new Point(5,2),new Point(6,2),new Point(7,2),
new Point(0,3),new Point(1,3),new Point(2,3),new Point(7,3),
new Point(0,4), new Point(5,4), new Point(6,4), new Point(7,4),
new Point(0,5),new Point(1,5),new Point(2,5),new Point(3,5),new Point(5,5),
new Point(3,6),new Point(5,6),
new Point(3,7),new Point(4,7),new Point(5,7)
};
// 创建一个空地数组
Point [] kongdi={new Point(3,1),
new Point(3,2),
new Point(3,3),new Point(4,3),new Point(5,3),new Point(6,3),
new Point(1,4),new Point(2,4),new Point(3,4),new Point(4,4),
new Point(4,5),
new Point(4,6)
};
// 设置图片
private Image image=null;
Graphics gf=null;
// 设置计时器
Timer timer=new Timer(500,this);
public void Tian(){
// 加载地图
jiazaiditu(guan);
//设置窗口的宽高
this.setSize(width*size ,height*size+title);
// 设置标题
this.setTitle("推箱子");
//设置窗口能看见
this.setVisible(true);
// 设置窗口顶点坐标的位置
this.setLocation(100,100);
//设置键盘监听事件(也就是当键盘有什么反应都会调用此函数)
this.addKeyListener(this);
}
public void paint(Graphics g){
// 窗口大小改变后,重新创建缓存图片
if(window == true) {
window = false;
image=this.createImage(width*size,height*size+title);
this.gf =image.getGraphics();
}
//初始化临时图片//解决闪烁问题
if(image==null){
image=this.createImage(width*size,height*size+title);
}
if(this.gf ==null){
this.gf =image.getGraphics();
}
// 擦除背景
gf.setColor(Color.white);
gf.fill3DRect(0,0,width*size,title+height*size,true);
// 绘制网格
gf.setColor(Color.GRAY);
// 画行(画横线)
// for (int i = 0; i <= height; i++) {
// gf.drawLine(0,size*i+title,width*size,size*i+title);
// }
画列(画竖线)
// for (int i = 0; i <= width; i++) {
// gf.drawLine(i*size,title,i*size,height*size+title);
// }
// 绘制墙
for (int i = 0; i <qiangbi.length ; i++) {
gf.setColor(Color.pink);
gf.fill3DRect(qiangbi[i].x*size,qiangbi[i].y*size+title,size,size,true);
}
// 绘制箱子最终要到达的位置
for (int i = 0; i <home.length ; i++) {
gf.setColor(Color.black);
gf.drawOval(home[i].x*size,home[i].y*size+title,size,size);
gf.drawLine(home[i].x*size,home[i].y*size+title,home[i].x*size+size,home[i].y*size+title+size);
}
// 绘制真实的箱子
for (int i = 0; i <box.length ; i++) {
gf.setColor(Color.ORANGE);
gf.fill3DRect(box[i].x*size,box[i].y*size+title,size,size,true);
if(isguiwei(i)){
gf.setColor(Color.red);
gf.fill3DRect(box[i].x*size,box[i].y*size+title,size,size,true);
}
}
// 绘制推箱子的小人
gf.setColor(Color.green);
gf.fillOval(man.x*size,man.y*size+title,size,size);
// 绘制当前关卡信息
if(iswin()==true&&tongguan==true){
gf.setColor(Color.darkGray);
gf.fill3DRect(0,0,width*size,title,true);
gf.setFont(new Font("华文新魏", 10, 55)); //设置字体
gf.setColor(Color.white);
gf.drawString("恭喜通关",width*size/2-110,title/2+40);
}else {
gf.setColor(Color.darkGray);
gf.fill3DRect(0,0,width*size,title,true);
gf.setFont(new Font("华文新魏", 10, 55)); //设置字体
gf.setColor(Color.white);
gf.drawString("弟"+guan+"关",width*size/2-82,title/2+40);
}
g.drawImage(image,0,0,null);
}
// 按下键盘--控制游戏的开始以及方块的移动方向
public void keyPressed(KeyEvent e) {
// 获取从键盘输入的键
int key = e.getKeyCode();
// 上
if (key == KeyEvent.VK_UP) {
// y-1是空地
if(iscunzai(kongdi,new Point(man.x,man.y-1))==true){
// y-1是空地,且空地上没有箱子
if(iscunzai(box,new Point(man.x,man.y-1))==false){
man.y--;
}else{//y-2是一个空地,且没有箱子
// y-2是一个没有箱子的空地(这种就是上边已经有了一个箱子,箱子的上边再没有箱子且是空地)
if ((iscunzai(kongdi,new Point(man.x,man.y-2))==true)&&(iscunzai(box,new Point(man.x,man.y-2))==false)){
// 这种情况下是人和箱子都向上移动一格
for (int i = 0; i < box.length; i++) {
if(box[i].x==man.x&&box[i].y==man.y-1){
box[i].y--;
break;
}
}
man.y--;
//判断所有箱子是否归位
if(iswin()==true){
if(guan<maxguan){//不是最后一关
guan++;
// 加载新一关的地图
jiazaiditu(guan);
}else{//是最后一关
tongguan=true;
}
}
}
}
}
// 下
}else if (key == KeyEvent.VK_DOWN) {
// y-1是空地
if(iscunzai(kongdi,new Point(man.x,man.y+1))==true){
// y-1是空地,且空地上没有箱子
if(iscunzai(box,new Point(man.x,man.y+1))==false){
man.y++;
}else{//y-2是一个空地,且没有箱子
// y-2是一个没有箱子的空地(这种就是上边已经有了一个箱子,箱子的上边再没有箱子且是空地)
if ((iscunzai(kongdi,new Point(man.x,man.y+2))==true)&&(iscunzai(box,new Point(man.x,man.y+2))==false)){
// 这种情况下是人和箱子都向上移动一格
for (int i = 0; i < box.length; i++) {
if(box[i].x==man.x&&box[i].y==man.y+1){
box[i].y++;
break;
}
}
man.y++;
//判断所有箱子是否归位
if(iswin()==true){
if(guan<maxguan){
guan++;
// 加载新一关的地图
jiazaiditu(guan);
}else{
tongguan=true;
}
}
}
}
}
// 左
}else if(key == KeyEvent.VK_LEFT){
if(iscunzai(kongdi,new Point(man.x-1,man.y))==true){
// y-1是空地,且空地上没有箱子
if(iscunzai(box,new Point(man.x-1,man.y))==false){
man.x--;
}else{//y-2是一个空地,且没有箱子
// y-2是一个没有箱子的空地(这种就是上边已经有了一个箱子,箱子的上边再没有箱子且是空地)
if ((iscunzai(kongdi,new Point(man.x-2,man.y))==true)&&(iscunzai(box,new Point(man.x-2,man.y))==false)){
// 这种情况下是人和箱子都向上移动一格
for (int i = 0; i < box.length; i++) {
if(box[i].x==man.x-1&&box[i].y==man.y){
box[i].x--;
break;
}
}
man.x--;
//判断所有箱子是否归位
if(iswin()==true){
if(guan<maxguan){
guan++;
// 加载新一关的地图
jiazaiditu(guan);
}else{
tongguan=true;
}
}
}
}
}
// 右
}else if (key == KeyEvent.VK_RIGHT) {
if(iscunzai(kongdi,new Point(man.x+1,man.y))==true){
// y-1是空地,且空地上没有箱子
if(iscunzai(box,new Point(man.x+1,man.y))==false){
man.x++;
}else{//y-2是一个空地,且没有箱子
// y-2是一个没有箱子的空地(这种就是上边已经有了一个箱子,箱子的上边再没有箱子且是空地)
if ((iscunzai(kongdi,new Point(man.x+2,man.y))==true)&&(iscunzai(box,new Point(man.x+2,man.y))==false)){
// 这种情况下是人和箱子都向上移动一格
for (int i = 0; i < box.length; i++) {
if(box[i].x==man.x+1&&box[i].y==man.y){
box[i].x++;
break;
}
}
man.x++;
//判断所有箱子是否归位
if(iswin()==true){
if(guan<maxguan){
guan++;
// 加载新一关的地图
jiazaiditu(guan);
}else{
tongguan=true;
}
}
}
}
}
}
// 点击空格键重玩当前关卡
if(key == KeyEvent.VK_SPACE) {//空格键
// 重置当前关卡
jiazaiditu(guan);
}
repaint();
}
public void keyReleased(KeyEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
}
public void mouseReleased(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
// 判断某个数组中是否存在某个点
// 判断point这个点是否在points这个数组中
public boolean iscunzai(Point [] points,Point point){
for (int i = 0; i < points.length; i++) {
if(points[i].x==point.x&&points[i].y==point.y){
return true;
}
}
return false;
}
// 加载地图
public void jiazaiditu(int index){
// 清空当前数据
//
ArrayList<Point> boxlist = new ArrayList<Point>();
ArrayList<Point> homelist = new ArrayList<Point>();
ArrayList<Point> qiangbilist = new ArrayList<Point>();
ArrayList<Point> kongdilist = new ArrayList<Point>();
Ditu d = ditu[index-1];
for(int i= 0;i<d.ditu.length;i++)
{
for(int j=0;j<d.ditu[i].length;j++)
{
// 1是墙壁
if(d.ditu[i][j] == 1){
qiangbilist.add(new Point(j,i));
}
// 2是空地
else if(d.ditu[i][j] == 2){
kongdilist.add(new Point(j,i));
}
// 3是黑店
else if(d.ditu[i][j] == 3){
homelist.add(new Point(j,i));
kongdilist.add(new Point(j,i));
}
// 4箱子
else if(d.ditu[i][j] == 4){
boxlist.add(new Point(j,i));
kongdilist.add(new Point(j,i));
}
// 5人
else if(d.ditu[i][j] == 5){
man.x = j;
man.y = i;
kongdilist.add(new Point(j,i));
}
// 6(箱子在黑点上)
else if(d.ditu[i][j] ==6){
boxlist.add(new Point(j,i));
kongdilist.add(new Point(j,i));
homelist.add(new Point(j,i));
}
// 7(人在黑点上)
else if(d.ditu[i][j] == 7){
man.x = j;
man.y = i;
kongdilist.add(new Point(j,i));
homelist.add(new Point(j,i));
}
}
}
int i=0;
qiangbi = new Point[qiangbilist.size()];
for (Point p:qiangbilist){
qiangbi[i] = new Point(p.x,p.y);
i++;
}
i=0;
kongdi = new Point[kongdilist.size()];
for (Point p:kongdilist){
kongdi[i]=new Point(p.x,p.y);
i++;
}
i=0;
box = new Point[boxlist.size()];
for (Point p:boxlist){
box[i]=new Point(p.x,p.y);
i++;
}
i=0;
home = new Point[homelist.size()];
for (Point p:homelist){
home[i]=new Point(p.x,p.y);
i++;
}
height=d.ditu.length;
width=d.ditu[0].length;
this.setSize(width*size,height*size+title);
window=true;
}
// 判断单个方块是否归位//用于改变颜色
public boolean isguiwei(int i){
for (int i1 = 0; i1 < home.length; i1++) {
if(box[i].x==home[i1].x&&box[i].y==home[i1].y){
return true;
}
}
return false;
}
public void actionPerformed(ActionEvent e) {
}
public void keyTyped(KeyEvent e) {
}
// 判断游戏是否胜利(判断方块是否全部归位)
public boolean iswin(){
int j=0;
for (int i = 0; i < box.length; i++) {
for (int i1 = 0; i1 < home.length; i1++) {
if(box[i].x==home[i1].x&&box[i].y==home[i1].y){
j++;
if(j==home.length){
return true;
}
}
}
}
return false;
}
public static void main(String[] args) {
Pushbox005 pushbox=new Pushbox005();
pushbox.Tian();
}
}
到了这里,关于java版本实现推箱子小游戏的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!