返回顶部
首页 > 资讯 > 后端开发 > 其他教程 >C++实现推箱子功能附加回撤示例
  • 823
分享到

C++实现推箱子功能附加回撤示例

2024-04-02 19:04:59 823人浏览 泡泡鱼
摘要

跟着B站老师 做的,链接[C/C++]180行代码,推箱子就是这么简单~抄详细,学不会我还不信了,关卡切换和回退都实现了哦_哔哩哔哩_bilibili 编码环境:VS2019&nbs

跟着B站老师 做的,链接[C/C++]180行代码,推箱子就是这么简单~抄详细,学不会我还不信了,关卡切换和回退都实现了哦_哔哩哔哩_bilibili

编码环境:VS2019 

利用 链栈实现的回撤功能。

LinkStack.h


#pragma once

#ifdef _cplusplus
extern "C"
{
#endif
 
#include <fstream>
#include <iOStream>
#include<stdbool.h>
using namespace std;
 
#define OK 1
#define ERROR 0
#define OVERFLOW -2
//typedef int Data;
 
struct Point
{
    int r;
    int c;
    int data;
};
 
typedef struct _State
{
    Point pos[3];
}Data,State;
 
typedef struct Stacknode
{
    Data data;
    struct StackNode* next;
} StackNode, * LinkStack;
 
//算法1 链栈的初始化(无头节点)
void InitStack(LinkStack& S)
{ // 构造一个空栈 S,栈顶指针置空
    S = NULL;
   // return OK;
}
 
//算法2 链栈的入栈
void Push(LinkStack& S, Data e)
{ //在栈顶插入元素e
    LinkStack p;
    p = new StackNode; //生成新结点
    p->data = e;       //将新结点数据域置为e
    p->next = S;       //将新结点插入栈顶(类似与前插法,只不过没有头节点)
    S = p;             //修改栈顶指针为p
    printf("ok\n");
    //return OK;
}
 
//算法3链栈的出栈
void Pop(LinkStack& S)
{ //删除S的栈顶元素,用e返回其值
    LinkStack p;
    if (S == NULL)
        return ; //栈空
   // e = S->data;      //将栈顶元素赋给e
    p = S;            //用p临时保存栈顶元素空间,以备释放
    S = S->next;      //修改栈顶指针
    delete p;         //释放原栈顶元素的空间
   // return OK;
}
//算法4 取链栈的栈顶元素
Data GetTop(LinkStack S)
{                       //返回S的栈顶元素,不修改栈顶指针
    if (S != NULL)      //栈非空
        return S->data; //返回栈顶元素的值,栈顶指针不变
}
 
bool empty(LinkStack& S) {
    if (S == NULL)
        return true;
 
    else return false;
}
//
//void empty(LinkStack& S) {
//
//}
 
#ifdef _cplusplus
}
#endif

cpp文件


#include<cstdlib>
#include<iostream>
#include<time.h>
#include<time.h>
#include<math.h>
#include<coNIO.h>
#include <windows.H>
#include<graphics.h>  //包含IMAGE数组
#include"LinkStack.h"
 
using namespace std;
 
#define SIZE 10
#define TOTAL_LEVEL 3
 
LinkStack ls; //??
 
enum MINE {
    SPACE,
    WALL,
    DEST,
    BOX,
    PLAYER,
 
};
 
//LinkStack* ls;
 
int x;
int y;
int level;
IMAGE all_image[6];
//空地0 墙1 目的地2 箱子3 玩家4 
//PLAYER+DEST 5   BOX+DEST:6
//a75  d77 72w 80s
 
int map[TOTAL_LEVEL][SIZE][SIZE] = {
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,1,1,1,0,0,0,0},
        {0,0,0,1,2,1,0,0,0,0},
        {0,0,0,1,3,1,1,1,1,0},
        {0,1,1,1,0,0,3,2,1,0},
        {0,1,2,3,4,0,1,1,1,0},
        {0,1,1,1,1,3,1,0,0,0},
        {0,0,0,0,1,2,1,0,0,0},
        {0,0,0,0,1,1,1,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,1,1,1,1,1,1,0,0},
        {0,0,1,0,2,0,0,1,0,0},
        {0,0,1,0,0,3,0,1,0,0},
        {0,0,1,0,0,0,0,1,0,0},
        {0,0,1,0,0,4,0,1,0,0},
        {0,0,1,1,1,1,1,1,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    },
    {
        {0,0,0,0,0,0,0,0,0,0},
        {0,1,1,1,0,0,0,0,0,0},
        {0,1,2,1,0,0,0,0,0,0},
        {0,1,3,1,0,0,0,0,0,0},
        {0,1,4,1,0,0,0,0,0,0},
        {0,1,1,1,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0},
        {0,0,0,0,0,0,0,0,0,0}
    }
 
};
 
void loadIMG()
{
 
    for (int i = 0; i < 6; i++)
    {
        char file[20] = "";
        sprintf(file, "./image/%d.bmp", i);
        loadimage(all_image + i, file, 64, 64);//IMAGE *pDstImg(// 保存图像的 IMAGE 对象指针), 
        //e.g.loadimage(all_image + i,"0.bmp",64,64); //LPCTSTR pImgFile,图片文件名
                                             //int nWidth = 0, int nHeight = 0, bool bResize = false);					
        //putimage(i*64,0,all_image + i); //坐标原点为左上角。注意x,y坐标
 
    }
 
}
 
void upMove() {
    if (map[level][x - 1][y] == SPACE || map[level][x - 1][y] == DEST) {
        map[level][x - 1][y] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x - 1][y] == BOX || map[level][x - 1][y] == BOX + DEST) {
        if (map[level][x - 2][y] == SPACE || map[level][x - 2][y] == DEST) {
            map[level][x - 2][y] += BOX;
            map[level][x - 1][y] = map[level][x - 1][y] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }
 
    }
 
}
 
void downMove() {
    if (map[level][x + 1][y] == SPACE || map[level][x + 1][y] == DEST) {
        map[level][x + 1][y] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x + 1][y] == BOX || map[level][x + 1][y] == BOX + DEST) {
        if (map[level][x + 2][y] == SPACE || map[level][x + 2][y] == DEST) {
            map[level][x + 2][y] += BOX;
            map[level][x + 1][y] = map[level][x + 1][y] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }
 
    }
 
}
 
void leftMove() {
    if (map[level][x][y - 1] == SPACE || map[level][x][y - 1] == DEST) {
        map[level][x][y - 1] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x][y - 1] == BOX || map[level][x][y - 1] == BOX + DEST) {
        if (map[level][x][y - 2] == SPACE || map[level][x][y - 2] == DEST) {
            map[level][x][y - 2] += BOX;
            map[level][x][y - 1] = map[level][x][y - 1] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }
 
    }
 
}
 
void rightMove() {
    if (map[level][x][y + 1] == SPACE || map[level][x][y + 1] == DEST) {
        map[level][x][y + 1] += PLAYER;
        map[level][x][y] -= PLAYER;
    }
    else if (map[level][x][y + 1] == BOX || map[level][x][y + 1] == BOX + DEST) {
        if (map[level][x][y + 2] == SPACE || map[level][x][y + 2] == DEST) {
            map[level][x][y + 2] += BOX;
            map[level][x][y + 1] = map[level][x][y + 1] + PLAYER - BOX;
            map[level][x][y] -= PLAYER;
        }
 
    }
 
}
 
void gameDraw() {
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            switch (map[level][i][j])
            {
            case SPACE:
                putimage(j * 64, i * 64, all_image);
                break;
            case WALL:
                putimage(j * 64, i * 64, all_image + 1);
                break;
            case DEST:
                putimage(j * 64, i * 64, all_image + 2);
                break;
            case BOX:
                putimage(j * 64, i * 64, all_image + 3);
                break;
            case PLAYER:
                x = i;
                y = j;
                putimage(j * 64, i * 64, all_image + 4);
                break;
            case PLAYER + DEST:
                putimage(j * 64, i * 64, all_image + 4);
                x = i;
                y = j;
                break;
            case BOX + DEST:
                putimage(j * 64, i * 64, all_image + 5);
                break;
            default:
                break;
            }
 
        }
        cout << endl;
 
    }
 
}
 
//对应的ASC码值
//W w:119,87  Dd:100,68 Ww:119,87 Ss:115,83 空格:32
void saveState(int x, int y, int dir) {//player的坐标,以及keyevent
    //State t;
    State t;
    memset(&t, 0, sizeof(State));
    switch (dir)
    {
    case 119://w
    case 87:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x - i;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];
 
        }
        Push(ls, t);
        break;
    case 115://s
    case 83:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x + i;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];
 
        }
        Push(ls, t);
        Data p = GetTop(ls);
        break;
 
    case 97://a
    case 65:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y - i;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];
        }
        Push(ls, t);
        break;
 
    case 100://d
    case 68:
        for (int i = 0; i < 3; i++)
        {
            t.pos[i].r = x;  //依次记录 player 、player的下一格、以及player的下下一格 的行列坐标以及data
            t.pos[i].c = y + i;
            t.pos[i].data = map[level][t.pos[i].r][t.pos[i].c];
 
        }
        Push(ls, t);
        break;
    default:
        break;
    }
    
}
 
void rollBack() {
    if (empty(ls))
    {
        return;
    }
    State t = GetTop(ls);
    for (int i = 0; i < 3; i++)
    {
        map[level][t.pos[i].r][t.pos[i].c] = t.pos[i].data;
    }
    Pop(ls);
}
 
void keyEvent() {
    char event = _getch();
    if (event != 32  && event != -32) {
        saveState(x, y, event);
    }
    switch (event)
    {
    case 'W':
    case 'w':
        upMove();
        break;
 
    case 's':
    case 'S':
        downMove();
        break;
 
    case 'A':
    case 'a':
        leftMove();
        break;
    case 'd':
    case 'D':
        rightMove();
        break;
    case 32:
        rollBack();
        break;
    default:
        break;
    }
 
 
}
 
bool judge_pass() {
    for (int i = 0; i < SIZE; i++)
    {
        for (int j = 0; j < SIZE; j++)
        {
            if (map[level][i][j] == BOX)
            {
                return false;
            }
 
        }
 
    }
 
    return true;
}
 
int main() {
    InitStack(ls);
    initgraph(SIZE * 64, SIZE * 64, TRUE);
    loadIMG();
    //system("mode con lines=20 cols=25");
    level = 0;
    while (level < TOTAL_LEVEL)
    {
        //system("cls");
        gameDraw();
        keyEvent();
 
        if (judge_pass())
        {
            if (level == TOTAL_LEVEL - 1) {
                //system("cls");
                gameDraw();
            }
            level++;
            while (!empty(ls))
            {
                Pop(ls);
            }
 
        }
 
    }
 
    MessageBox(NULL, TEXT("CONGRATULATIONS!"), TEXT("GAME OVER"), MB_OK);
 
    // getchar();
 
 
    return 0;
}

附文件结构 

到此这篇关于c+++实现推箱子功能附加回撤示例的文章就介绍到这了,更多相关C+++ 推箱子内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!

--结束END--

本文标题: C++实现推箱子功能附加回撤示例

本文链接: https://lsjlt.com/news/155921.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

猜你喜欢
  • C++实现推箱子功能附加回撤示例
    跟着B站老师 做的,链接[C/C++]180行代码,推箱子就是这么简单~抄详细,学不会我还不信了,关卡切换和回退都实现了哦_哔哩哔哩_bilibili 编码环境:VS2019&nbs...
    99+
    2024-04-02
  • 怎么用C++实现推箱子功能附加回撤
    本篇内容介绍了“怎么用C++实现推箱子功能附加回撤”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!编码环境:VS2019 利用 链栈...
    99+
    2023-06-25
  • C语言实现推箱子功能汇总
    本文实例为大家分享了C语言实现推箱子功能的具体代码,供大家参考,具体内容如下 前言: 先说说我写推箱子小游戏的过程。 第一版:没有图形化界面,不能选关。只有推箱子的最基础功能。 第二...
    99+
    2024-04-02
  • 详解C语言实现推箱子的基本功能
    目录1.前言2.游戏效果展示3.项目分析4.地图实现4.1存储地图4.2打印地图5.控制角色移动5.1找到控制的角色5.2实现移动6.判断胜利总结1.前言 首先推箱子是c语言的一个经...
    99+
    2024-04-02
  • 详解C语言实现推箱子的基本功能(2)
    目录1.前言2.地图代码修改成函数3.角色移动修改成函数3.1寻找角色函数3.2角色移动函数4.判断胜利修改成函数5.主体函数的实现6.推箱子能实现基本功能的源码总结1.前言 本文章...
    99+
    2024-04-02
  • 用C语言实现推箱子游戏实例
    目录前言游戏效果图游戏开发思路游戏逻辑的分析源代码实现 头文件PushBackGame.c文件test.c文件总结前言 本游戏需要用到的核心技术,如下:二维数组分支语句 技...
    99+
    2024-04-02
  • C++实现自定义撤销重做功能的示例代码
    目录前言一、完整代码二、使用示例1、基本用法2、gdi画线撤销总结前言 在使用c++做界面开发的时候,需要涉及到到撤销重做操作,尤其是实现白板功能时需要自己实现一套撤销重做功能,如果...
    99+
    2022-12-15
    C++自定义撤销重做功能 C++撤销重做功能 C++撤销重做
  • Java实现经典游戏推箱子的示例代码
    目录前言主要设计功能截图代码实现核心类声音播放类总结前言 《推箱子》推箱子是一个古老的游戏,目的是在训练你的逻辑思考能力。在一个狭小的仓库中,要求把木箱放到指定的位置,稍不小心就会出...
    99+
    2024-04-02
  • Rabbitmq消息推送功能实现示例
    目录一.前言1.1场景1.2消息交换机三种形式二.建设demo工程2.1依赖2.2yml文件指定rabbitmq连接信息2.3直连型消息链接一.前言 1.1场景 在我们实际开发中到一...
    99+
    2022-12-27
    Rabbitmq消息推送 Rabbitmq消息分发
  • C++实现Go的defer功能(示例代码)
    在Go语言中有一个关键字:defer,它的作用就是延迟执行后面的函数,在资源释放方面特别有用,比如下面一段C/C++的示例代码: void test() { FILE* fp ...
    99+
    2024-04-02
  • Python使用PyCrypto实现AES加密功能示例
    本文实例讲述了Python使用PyCrypto实现AES加密功能。分享给大家供大家参考,具体如下: #!/usr/bin/env python from Crypto.Cipher import AES...
    99+
    2022-06-04
    示例 功能 Python
  • Android左滑返回功能的实现示例代码
    前几天用了个app发现左滑可以返回首页,发现这个功能很炫酷,就想着自己能不能做出来,于是研究了一下原理 将activity的背景设置为透明同时设置切换动画 手指滑动的时候,根View跟着滑动,滑倒一定的距离就finish掉。 原理很简...
    99+
    2023-05-31
    android 左滑返回 roi
  • WordPress实现的首页幻灯片展示功能示例【附demo源码】
    本文实例讲述了WordPress实现的首页幻灯片展示功能。分享给大家供大家参考,具体如下: 对于WordPress拓展性这么优秀的程序来说,是没有什么不能实现的。很多在建站的时候,都会选择在首页使用幻灯片,可以展示比较醒...
    99+
    2022-06-12
    WordPress 首页 幻灯片
  • vue实现pdf文件发送到邮箱功能的示例代码
    需求: vue实现pdf文件发送到邮箱功能 <!-- 弹窗 --> <van-popup v-model="showEmail" closeab...
    99+
    2024-04-02
  • Android编程实现分页加载ListView功能示例
    本文实例讲述了Android编程实现分页加载ListView功能。分享给大家供大家参考,具体如下: package eoe.listview; import android....
    99+
    2022-06-06
    示例 listview 分页 Android
  • Java实现文件的加密解密功能示例
    本文实例讲述了Java实现文件的加密解密功能分享给大家供大家参考,具体如下:package com.copy.encrypt;import java.io.File;import java.io.FileInputStream;import...
    99+
    2023-05-31
    java 文件 加密
  • java实现从方法返回多个值功能示例
    本文实例讲述了java实现从方法返回多个值功能。分享给大家供大家参考,具体如下:这里介绍三个方法,使java方法返回多个值。方法1:使用集合类方法2:使用封装对象方法3:使用引用传递示例代码如下:import java.util.HashM...
    99+
    2023-05-30
    java 方法 返回值
  • 示例讲解php如何实现微信推送信息功能
    随着互联网的不断发展,微信已经成为了人们生活中必不可少的工具之一。许多网站和应用都需要将信息实时推送到用户的微信上,而PHP作为一种流行的服务器端编程语言,可以实现通过微信公众号给用户推送信息的功能。那么,今天我们就来介绍一下如何使用PHP...
    99+
    2023-05-14
  • C++实现Go的defer功能(示例代码)
    在Go语言中有一个关键字:defer,它的作用就是延迟执行后面的函数,在资源释放方面特别有用,比如下面一段C/C++的示例代码: void test() { FILE* fp...
    99+
    2022-06-07
    c+ GO defer 示例 C++
  • C#实现MP3播放器功能的示例代码
    目录实践过程效果代码实践过程 效果 代码 public partial class Form1 : Form { public Form1() ...
    99+
    2022-12-09
    C# MP3播放器 C# 播放器
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作