推(搬)箱子,又名Sokoban,仓库番等,是一款堪称古玩级的电脑游戏。

提起它,笔者相信没什么人会感觉到陌生,更没什么生物会连听都没听说过。它的发展历史之久远,甚至超越了俄罗斯方块(1988年电脑游戏化)。

这款游戏最初起源于日本,是个很难争辩的事实(我知道有人反对,但笔者确实找不到什么有力的反对证据)。他由日本人(哎……)今川宏行在1981年创立游戏规则,并于1982年经日本软件公司Thinking Rabbit正式发布。比较遗憾的是,早期的推箱子并没有PC版,笔者在网络上搜索到的老版游戏也大多为90年以前的Mac OS下程式。

但说起真正令推箱子风靡于PC机的,却该感谢我们的台湾同胞李果兆先生。是他在1994年开发的仓库世家,才真正令推箱子游戏在世界各地大受推崇;仔细说来,推箱子这款小游戏之所以能有今时今日的声望与地位,固然有今川宏行的开创之功,但若说到贡献最大,承前启后的,则非中国台湾的李果兆先生莫属。

推箱子游戏的规则非常简单,就是用尽量少的推动或移动把所有箱子都推到目标点上。箱子只能推动而不能拉动;一次只能推动一个箱子。然而,尽管它的规则是很简单的,但对于不同难度的关卡,所需要的脑力却是截然不同的,有些关卡可能会花费您几个小时、几天甚至几个月的时间,也正是这种简单性和复杂性的结合,最终令推箱子类游戏风靡全球!

本回笔者在Blog中提供的,就是一款Java版推箱子游戏的简单实现。

笔者设定[上、下、左、右]为方向控制 ,[S]键为后退到上一步操作,[ESC]为重新开始当前关卡,点击键盘上对应关卡的数字键可以直接选关,需要注意的是笔者以HP限制了角色的移动次数,HP归0则挑战失败。

目前版本仅提供有5关,有需要者可参考同类游戏自行扩充,游戏源码在jar内。

下载地址1(由于google code维护,需要等此文发表的隔天才能开放下载):http://code.google.com/p/loon-simple/downloads/list

下载地址2:http://download.csdn.net/source/1397545

游戏截图:


核心代码:


Sokoban.java

package org.loon.game.simple.sokoban.control;import java.awt.Color;import java.awt.Font;import java.awt.Graphics;import java.awt.Image;import java.awt.event.KeyEvent;import org.loon.game.simple.sokoban.GraphicsUtils;import org.loon.game.simple.sokoban.LSystem;import org.loon.game.simple.sokoban.SimpleControl;/** * Copyright 2008 - 2009 *  * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at *  * http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. *  * @project loonframework * @author chenpeng * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn * @version 0.1 */public class Sokoban extends SimpleControl { /**  *   */ private static final long serialVersionUID = 1L; private Image backImage = GraphicsUtils.loadImage("image/back1.jpg"); private Image screenImage; // 墙壁图 private Image floorImage[]; // 角色精灵 private RpgSprite sprite; // 窗体显示图 private Graphics screen; private String message = "按下 [Enter] 开始进行游戏"; private String m_stageName[] = { "关卡1", "关卡2", "关卡3", "关卡4", "关卡5", "关卡6",   "关卡7" }; private int CS = 32; private int maxX, maxY, comps; private int stageNo; private boolean complete[]; private boolean boxMove[][]; private int hp[]; private int stageStates[][][]; private int ons[][]; private int role[]; private int rolex[]; private int roley[]; private int mapx[]; private int mapy[]; private int sleep = 0; private boolean succeed = false; private Stage stage; public Sokoban(Stage stage) {  this.stage = stage;  this.floorImage = new Image[4];  this.sprite = new RpgSprite("image/role1.gif");  this.maxX = 16;  this.maxY = 13;  this.comps = 0;  this.complete = new boolean[stage.getMaxStageNo()];  this.boxMove = new boolean[stage.getMaxStageNo()][1500];  this.ons = new int[stage.getMaxStageNo()][1500];  this.hp = new int[stage.getMaxStageNo()];  this.stageStates = new int[stage.getMaxStageNo()][maxY][maxX];  this.role = new int[stage.getMaxStageNo()];  this.rolex = new int[stage.getMaxStageNo()];  this.roley = new int[stage.getMaxStageNo()];  this.mapx = new int[stage.getMaxStageNo()];  this.mapy = new int[stage.getMaxStageNo()];  for (int j = 0; j < 4; j++) {   floorImage[j] = GraphicsUtils.loadImage("image/back" + (j + 1)     + ".gif");  }  this.screenImage = GraphicsUtils.createImage(CS * maxX + CS, CS    * (maxY + 1) + 32, true);  this.screen = screenImage.getGraphics();  for (stageNo = 0; stageNo < stage.getMaxStageNo(); stageNo++) {   this.setupStage();  }  this.stageNo = -1;  // 开场界面  this.openDraw(); } /**  * 刷新关卡  *   */ public synchronized void reset(int stageNo) {  this.stageNo = stageNo;  this.stage.getMode()[stageNo] = 1;  this.message = null;  // 设定关卡  this.setupStage();  // 重绘背景  this.background();  // 重绘游戏屏幕  this.drawScreen(); } /**  * 绘制屏幕背景  *   */ public synchronized void background() {  screen.drawImage(backImage, 0, 0, null);  screen.setColor(Color.black);  screen.fillRect(0, LSystem.HEIGHT - 40, LSystem.WIDTH, 40); } /**  * 绘制屏幕图像  *   */ public synchronized void drawScreen() {  if (stageNo >= stage.getMaxStageNo()) {   stageNo = 0;  }  for (int i = 0; i < mapy[stageNo]; i++) {   for (int j = 0; j < mapx[stageNo];) {    switch (stageStates[stageNo][i][j]) {    case 2:    case 3:    case 4:    case 5:     screen.drawImage(floorImage[1], moveX(j), moveY(i), null);    default:     j++;     break;    }   }  }  for (int n = 0; n < mapy[stageNo]; n++) {   for (int l = 0; l < mapx[stageNo]; l++)    switch (stageStates[stageNo][n][l]) {    case 1:     screen.drawImage(floorImage[0], moveX(l), moveY(n), null);     screen.setColor(new Color(32, 0, 0));     screen.drawLine(moveX(l), moveY(n + 1), moveX(l) + CS - 1,       moveY(n + 1));     if (l == 0 || l > 0 && stageStates[stageNo][n][l - 1] != 1) {      screen.setColor(new Color(160, 128, 96));      screen.drawLine(moveX(l), moveY(n) + 1, moveX(l),        moveY(n) + CS - 2);     }     if (l == mapx[stageNo] - 1 || l < mapx[stageNo] - 1       && stageStates[stageNo][n][l + 1] != 1) {      screen.setColor(new Color(72, 64, 64));      screen.drawLine(moveX(l) + CS - 1, moveY(n), moveX(l)        + CS - 1, moveY(n) + CS - 2);     }     break;    case 2:    case 3:    case 4:     switch (stageStates[stageNo][n][l]) {     default:      break;     case 2:     case 3:      screen.drawImage(floorImage[3], moveX(l), moveY(n),        null);      break;     case 4:      break;     }     if (stageStates[stageNo][n][l] != 3)      screen.drawImage(floorImage[2], moveX(l), moveY(n),        null);     break;    default:     break;    }  }  // System.out.println(role[stageNo]);  screen.drawImage(sprite.getOnlyMove(role[stageNo]),    moveX(rolex[stageNo]), moveY(roley[stageNo]), null);  if (stageStates[stageNo][roley[stageNo]][rolex[stageNo]] == 4) {   screen.drawImage(floorImage[2], moveX(rolex[stageNo]),     moveY(roley[stageNo]), null);  }  setupDisplay(); } /**  * 定位到实际的X座标  *   * @param i  * @return  */ public int moveX(int i) {  return (CS * ((maxX - mapx[stageNo]) + 1)) / 2 + CS * i; } /**  * 定位到实际的Y座标  *   * @param i  * @return  */ public int moveY(int i) {  return (CS * ((maxY - mapy[stageNo]) + 1)) / 2 + CS * i; } /**  * 执行操作  *   */ public synchronized void execute() {  boolean flag = true;  for (int i = 0; i < mapy[stageNo]; i++) {   for (int j = 0; j < mapx[stageNo]; j++) {    if (stageStates[stageNo][i][j] == 4) {     flag = false;    }   }  }  if (flag) {   stage.getMode()[stageNo] = 3;   complete[stageNo] = true;  } else if (hp[stageNo] == 0) {   stage.getMode()[stageNo] = 2;  }  comps = 0;  for (int n = 0; n < stage.getMaxStageNo(); n++) {   if (complete[n]) {    comps++;   }  } } /**  * 键盘事件处理  */ public void keyPressed(KeyEvent e) {  if (e.getKeyCode() == 10 && stageNo == -1) {   // 开始关卡1   reset(0);  } else if (stageNo < 0) {   return;  }  // 选关(默认为最大支持7关,更多请自行设定)  if (e.getKeyCode() == 97 || e.getKeyCode() == 49) {   stageNo = 0;  } else if (e.getKeyCode() == 98 || e.getKeyCode() == 50) {   stageNo = 1;  } else if (e.getKeyCode() == 99 || e.getKeyCode() == 51) {   stageNo = 2;  } else if (e.getKeyCode() == 100 || e.getKeyCode() == 52) {   stageNo = 3;  } else if (e.getKeyCode() == 101 || e.getKeyCode() == 53) {   stageNo = 4;  } else if (e.getKeyCode() == 102 || e.getKeyCode() == 54) {   stageNo = 5;  } else if (e.getKeyCode() == 103 || e.getKeyCode() == 55) {   stageNo = 6;   // ESC,重新开始  } else if (e.getKeyCode() == 27) {   reset(stageNo);  } else if (stage.getMode()[stageNo] == 1) {   // 退步   if (e.getKeyCode() == 83) {    nextStep(-1);   }   // 移动角色   else if (e.getKeyCode() == 40) {    nextStep(0);   } else if (e.getKeyCode() == 37) {    nextStep(1);   } else if (e.getKeyCode() == 39) {    nextStep(2);   } else if (e.getKeyCode() == 38) {    nextStep(3);   } else {    return;   }  } else {   return;  }  // 绘制背景  background();  // 绘制游戏画面  drawScreen(); } /**  * 切换动作  *   * @param i  */ public synchronized void nextStep(final int i) {  boxMove[stageNo][hp[stageNo] - 1] = false;  switch (i) {  case 0:   if (stageStates[stageNo][roley[stageNo] + 1][rolex[stageNo]] < 2) {    return;   }   if (stageStates[stageNo][roley[stageNo] + 1][rolex[stageNo]] < 4) {    if (stageStates[stageNo][roley[stageNo] + 2][rolex[stageNo]] < 4) {     return;    }    stageStates[stageNo][roley[stageNo] + 1][rolex[stageNo]] += 2;    stageStates[stageNo][roley[stageNo] + 2][rolex[stageNo]] -= 2;    boxMove[stageNo][hp[stageNo] - 1] = true;   }   roley[stageNo]++;   break;  case 1:   if (stageStates[stageNo][roley[stageNo]][rolex[stageNo] - 1] < 2) {    return;   }   if (stageStates[stageNo][roley[stageNo]][rolex[stageNo] - 1] < 4) {    if (stageStates[stageNo][roley[stageNo]][rolex[stageNo] - 2] < 4) {     return;    }    stageStates[stageNo][roley[stageNo]][rolex[stageNo] - 1] += 2;    stageStates[stageNo][roley[stageNo]][rolex[stageNo] - 2] -= 2;    boxMove[stageNo][hp[stageNo] - 1] = true;   }   rolex[stageNo]--;   break;  case 2:   if (stageStates[stageNo][roley[stageNo]][rolex[stageNo] + 1] < 2) {    return;   }   if (stageStates[stageNo][roley[stageNo]][rolex[stageNo] + 1] < 4) {    if (stageStates[stageNo][roley[stageNo]][rolex[stageNo] + 2] < 4) {     return;    }    stageStates[stageNo][roley[stageNo]][rolex[stageNo] + 1] += 2;    stageStates[stageNo][roley[stageNo]][rolex[stageNo] + 2] -= 2;    boxMove[stageNo][hp[stageNo] - 1] = true;   }   rolex[stageNo]++;   break;  case 3:   if (stageStates[stageNo][roley[stageNo] - 1][rolex[stageNo]] < 2) {    return;   }   if (stageStates[stageNo][roley[stageNo] - 1][rolex[stageNo]] < 4) {    if (stageStates[stageNo][roley[stageNo] - 2][rolex[stageNo]] < 4) {     return;    }    stageStates[stageNo][roley[stageNo] - 1][rolex[stageNo]] += 2;    stageStates[stageNo][roley[stageNo] - 2][rolex[stageNo]] -= 2;    boxMove[stageNo][hp[stageNo] - 1] = true;   }   roley[stageNo]--;   break;  default:   if (hp[stageNo] == stage.getMaxHp()[stageNo]) {    return;   }   switch (ons[stageNo][hp[stageNo]]) {   case 0:    if (boxMove[stageNo][hp[stageNo]]) {     stageStates[stageNo][roley[stageNo] + 1][rolex[stageNo]] += 2;     stageStates[stageNo][roley[stageNo]][rolex[stageNo]] -= 2;    }    roley[stageNo]--;    break;   case 1:    if (boxMove[stageNo][hp[stageNo]]) {     stageStates[stageNo][roley[stageNo]][rolex[stageNo] - 1] += 2;     stageStates[stageNo][roley[stageNo]][rolex[stageNo]] -= 2;    }    rolex[stageNo]++;    break;   case 2:    if (boxMove[stageNo][hp[stageNo]]) {     stageStates[stageNo][roley[stageNo]][rolex[stageNo] + 1] += 2;     stageStates[stageNo][roley[stageNo]][rolex[stageNo]] -= 2;    }    rolex[stageNo]--;    break;   default:    if (boxMove[stageNo][hp[stageNo]]) {     stageStates[stageNo][roley[stageNo] - 1][rolex[stageNo]] += 2;     stageStates[stageNo][roley[stageNo]][rolex[stageNo]] -= 2;    }    roley[stageNo]++;    break;   }   break;  }  if (i != -1) {   hp[stageNo]--;   ons[stageNo][hp[stageNo]] = i;  }  role[stageNo] = ons[stageNo][hp[stageNo]];  if (i == -1) {   hp[stageNo]++;  }  execute(); } /**  * 开场画面  *   */ public synchronized void openDraw() {  background();  for (int i = 0; i < 5; i++) {   for (int j = 0; j < maxX + 1; j++) {    screen.drawImage(floorImage[0], CS * j,      (CS * i + CS / 2 * maxY) - CS * 2, null);   }  }  GraphicsUtils.setAntialias(screen, true);  String mes = "怪蜀黍传说 - 勇者推魔王";  screen.setFont(new Font("华文新魏", 1, 35));  GraphicsUtils.drawStyleString(screen, mes, (CS * maxX - screen    .getFontMetrics().stringWidth(mes)) / 2 + 13,    (CS * maxY) / 2 + 25, Color.black, Color.orange);  mes = "Java版搬箱子游戏开发入门示例 - 0.1.0";  screen.setFont(new Font("华文新魏", 0, 30));  GraphicsUtils.drawStyleString(screen, mes, (CS * maxX - screen    .getFontMetrics().stringWidth(mes)) / 2 + 13,    (CS * (maxY + 2)) / 2 - 55, Color.black, Color.white);  GraphicsUtils.setAntialias(screen, false);  setupDisplay(); } /**  * 绘图接口实现  */ public synchronized void draw(Graphics g) {  g.drawImage(screenImage, 0, 0, null);  if (succeed) {   if (sleep == 100) {    // 进入下一关    reset(++stageNo);    succeed = false;    sleep = 0;   }   sleep++;  } } /**  * 设置基本数据  *   */ public void setupStage() {  for (int i = 0; i < maxY; i++) {   for (int j = 0; j < maxX; j++) {    stageStates[stageNo][i][j] = 0;   }  }  mapx[stageNo] = stage.getConf()[stageNo][0];  mapy[stageNo] = stage.getConf()[stageNo][1];  rolex[stageNo] = stage.getConf()[stageNo][2];  roley[stageNo] = stage.getConf()[stageNo][3];  for (int n = 0; n < mapy[stageNo]; n++) {   for (int l = 0; l < mapx[stageNo]; l++) {    stageStates[stageNo][n][l] = stage.getMapData()[stageNo][n][l];   }  }  hp[stageNo] = stage.getMaxHp()[stageNo];  role[stageNo] = 0;  for (int i1 = 0; i1 < stage.getMaxHp()[stageNo]; i1++) {   ons[stageNo][i1] = 0;  }  for (int j1 = 0; j1 < stage.getMaxHp()[stageNo]; j1++) {   boxMove[stageNo][j1] = false;  } } /**  * 设置显示  *   */ public void setupDisplay() {  if (message == null) {   screen.setFont(new Font(LSystem.FONT, 0, 12));   int size = 0;   for (int j = 0; j < stage.getMaxStageNo(); j++) {    if (complete[j]) {     screen.setColor(Color.gray);    } else {     screen.setColor(Color.white);    }    if (j == stageNo) {     if (complete[j]) {      screen.setColor(Color.magenta);     } else {      screen.setColor(Color.cyan);     }    }    screen.drawString(m_stageName[j], size = (10 + (screen      .getFontMetrics().stringWidth("关卡0") + 20)      * j), LSystem.HEIGHT - 50);   }   screen.setColor(Color.white);   if (stageNo == -1) {    // 初始画面,无数据   } else {    // 显示状态    if (hp[stageNo] == 0) {     screen.setColor(Color.red);    } else if (hp[stageNo] <= stage.getMaxHp()[stageNo] / 4) {     screen.setColor(Color.orange);    } else if (hp[stageNo] <= stage.getMaxHp()[stageNo] / 2) {     screen.setColor(Color.yellow);    }    screen.drawString("主角 HP " + hp[stageNo] + "/"      + stage.getMaxHp()[stageNo], size + 50,      LSystem.HEIGHT - 50);    switch (stage.getMode()[stageNo]) {    // 生命耗尽    case 2:     screen.setFont(new Font(LSystem.FONT, 1, 30));     screen.setColor(Color.red);     GraphicsUtils.setAntialias(screen, true);     screen.drawString("The End!",       (CS * maxX - screen.getFontMetrics().stringWidth(         "The End!")) / 2 + 14,       ((CS * (maxY + 1) + screen.getFontMetrics()         .getAscent()) - screen.getFontMetrics()         .getDescent()) / 2);     GraphicsUtils.setAntialias(screen, false);     break;    // 胜利    case 3:     screen.setFont(new Font(LSystem.FONT, 2, 40));     screen.setColor(Color.darkGray);     GraphicsUtils.drawStyleString(screen, "Good job!", (CS       * maxX - screen.getFontMetrics().stringWidth(       "Good job!")) / 2 + 14, ((CS * (maxY + 1) + screen       .getFontMetrics().getAscent()) - screen       .getFontMetrics().getDescent()) / 2, Color.black,       Color.white);     // 胜利标记     succeed = true;     break;    }   }  }  // 存在信息时  else {   screen.setFont(new Font(LSystem.FONT, 0, 12));   int n = screen.getFontMetrics().stringWidth(message) + 16;   int l = screen.getFontMetrics().getAscent()     + screen.getFontMetrics().getDescent() + 8;   int i1 = (CS * (maxX + 1) - n) / 2;   int j1 = (CS * maxY + 1) - l / 2;   int k1 = i1 + 8;   int l1 = CS     * maxY     + 1     + (screen.getFontMetrics().getAscent() - screen       .getFontMetrics().getDescent()) / 2;   screen.setColor(Color.black);   screen.fillRect(i1, j1, n, l);   screen.setColor(Color.white);   screen.drawString(message, k1, l1);  } }}


启动类:


Main.java

package org.loon.game.simple.sokoban.main;import org.loon.game.simple.sokoban.GameCursor;import org.loon.game.simple.sokoban.GameFrame;import org.loon.game.simple.sokoban.control.Sokoban;import org.loon.game.simple.sokoban.control.Stage;import org.loon.game.simple.sokoban.control.Stage1;/** * Copyright 2008 - 2009 *  * Licensed under the Apache License, Version 2.0 (the "License"); you may not * use this file except in compliance with the License. You may obtain a copy of * the License at *  * http://www.apache.org/licenses/LICENSE-2.0 *  * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the * License for the specific language governing permissions and limitations under * the License. *  * @project loonframework * @author chenpeng * @email <a title="" href="http://hi.baidu.com/ceponline" mce_href="http://hi.baidu.com/ceponline" target="_blank">ceponline</a>@yahoo.com.cn * @version 0.1 */public class Main { public static void main(String[] args) {  java.awt.EventQueue.invokeLater(new Runnable() {   public void run() {    GameFrame frame = new GameFrame("Java版搬箱子游戏入门示例及源码-0.1.0", 540, 480);    frame.setCursor(GameCursor.getCursor("image/cursor.png"));    // 获得搬箱子关卡接口    Stage stage = new Stage1();    // 设定游戏控制器    frame.getGame().setControl(new Sokoban(stage));    // 游戏全屏    // frame.updateFullScreen();    // 是否显示fps    frame.setFPS(true);    // 允许的最大刷新率    frame.setMaxFrames(60);    frame.mainLoop();    frame.showFrame();   }  }); }}

下载地址1(由于google code维护,需要等此文发表的隔天才能开放下载):http://code.google.com/p/loon-simple/downloads/list

下载地址2:http://download.csdn.net/source/1397545

Java版推箱子(搬箱子)游戏开发入门示例及源码相关推荐

  1. Java版AVG游戏开发入门示例 3 ——脚本引擎的制作及应用

    源码下载地址:http://code.google.com/p/loon-simple/downloads/list 根据wikipedia的解释:脚本语言(Script language,scrip ...

  2. Java版AVG游戏开发入门示例[3]——脚本引擎的制作及应用

    源码下载地址:http://code.google.com/p/loon-simple/downloads/list 根据wikipedia的解释:脚本语言(Script language,scrip ...

  3. java jfm入门_image Java版*图像过滤入门示例及源码模拟绿坝过滤机制 - 下载 - 搜珍网...

    Java版*图像过滤入门示例及源码-0.1.0 (模拟绿坝过滤机制)/image/dy.jpg Java版*图像过滤入门示例及源码-0.1.0 (模拟绿坝过滤机制)/image/dymh.jpg Ja ...

  4. Java版色情图像过滤入门示例及源码-0 1 0 (模拟绿坝过滤机制)

    文件下载地址(源码在jar中):http://code.google.com/p/greenvm/downloads/list 这些天来,笔者对于[绿坝]的赞美犹如滔滔江水连绵不绝,又似黄河决口,一发 ...

  5. Java版色情图像过滤入门示例及源码-0.1.0 (模拟绿坝过滤机制)

    文件下载地址(源码在jar中):http://code.google.com/p/greenvm/downloads/list 这些天来,笔者对于[绿坝]的赞美犹如滔滔江水连绵不绝,又似黄河决口,一发 ...

  6. Java版色情图像过滤入门示例及源码-0.1.0 (模拟GreenDam过滤机制)

    文件下载地址(源码在jar中):http://code.google.com/p/greenvm/downloads/list 这些天来,笔者对于[绿坝]的赞美犹如滔滔江水连绵不绝,又似黄河决口,一发 ...

  7. [3D游戏开发实践] Cocos Cyberpunk 源码解读-高中低端机性能适配策略

    Cocos Cyberpunk 是 Cocos 引擎官方团队以展示引擎重度 3D 游戏制作能力,提升社区学习动力而推出的完整开源 TPS 3D游戏,支持 Web, IOS, Android 多端发布. ...

  8. [3D游戏开发实践] Cocos Cyberpunk 源码解读-一文搞定延迟渲染管线原理与实践

    Cocos Cyberpunk 是 Cocos 引擎官方团队以展示引擎重度 3D 游戏制作能力,提升社区学习动力而推出的完整开源 TPS 3D游戏,支持 Web, IOS, Android 多端发布. ...

  9. C/C++项目实战:华容道游戏开发丨570 行源码分享来啦~

    每天一个C/C++小项目,提升你的编程能力! 华容道是古老的中国民间益智游戏,以其变化多端.百玩不厌的特点与魔方.独立钻石一起被国外智力专家并称为"智力游戏界的三个不可思议".它与 ...

  10. java版Spring Cloud+Vue 前后端分离+VR全景电子商务源码

    涉及平台:平台管理(包含自营店面).买家平台(PC端.H5/公众号.小程序.APP端(IOS/Android).微服务(了解源码可+求球:1零③8七7④62陆) 核心架构:Spring Cloud.S ...

最新文章

  1. QT程序启动加载流程简介
  2. [已解决] InnoDB: preallocating bytes for file ./ibdata1 failed with error
  3. 【计算机网络】HTTP 与 HTTPS ( HTTP 发展过程 | HTTP/1.1 与 HTTP/2 对比 | HTTP 报文格式 )
  4. 你真的很熟分布式和事务吗?
  5. python字符串注释_python字符串注释_Python学习笔记-字符串与注释
  6. 最短路中部分点只能从中任意选取K个问题
  7. 【道高一尺,魔高一丈】Python爬虫之如何应对网站反爬虫策略
  8. java学习技术栈总结
  9. 微信翻译生日快乐的代码_新套路,微信这个翻译功能还能帮你表白,快学起来!...
  10. Https网站中请求Http内容
  11. 服务器搭建是基于操作系统的,服务器搭建是基于操作系统的
  12. Oracle:ORA-12505解决办法
  13. 负数求余究竟怎么求???
  14. SVN修改提交后的文件名
  15. 全国院线总票房破50亿!影院复工后,哪些电影最受欢迎?可视化案例
  16. vue vuex和pinia(菠萝)的区别
  17. 黑帆第四季/全集Black Sails迅雷下载
  18. level升级打怪是什么意思_蛮荒神途——资深玩家谈论为什么不喜欢组队原因
  19. html5 自动矢量化,HTML5中地圖矢量化
  20. 手把手带你爬取猫眼电影,正则解析

热门文章

  1. 保持简单----纪念丹尼斯•里奇(Dennis Ritchie
  2. rational rose mysql_用Rational Rose逆向工程(java)生成类图(教程和错误解决)
  3. 协调端到端的供应链管理——SCM
  4. 最互联网的定制家居增长新势力,如何三招实现疫情期的逆势增长?
  5. 光纤猫可做无线打印服务器吗,光猫自带的天线,这些天线都有什么用呢?是无线功能吗?...
  6. 360导航源码php,51zxw 仿360网址导航源码
  7. Oracle 数据库的常用备份方法
  8. powerdesign165破解以及使用教程
  9. 【值得读】大神周志华谈AI的三大挑战:开放环境、弱监督、新型深度模型(非可微)...
  10. Visual Studio部署HoloLens 找不到WindowsMobile SDK