在inscode中轻松实现坦克大战(内含源码)

简介: 在inscode中轻松实现坦克大战(内含源码)

坦克大战在inscode的运行


看查源码内容



放大跳转网页



可以直接进行游戏


核心源码


index.html


<!DOCTYPE html>
<html lang="zh" class="no-js demo-1">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    <script src="js/jquery.min.js"></script>
    <script src="js/Helper.js"></script>
    <script src="js/keyboard.js"></script>
    <script src="js/const.js"></script>
    <script src="js/level.js"></script>
    <script src="js/crackAnimation.js"></script>
    <script src="js/prop.js"></script>
    <script src="js/bullet.js"></script>
    <script src="js/tank.js"></script>
    <script src="js/num.js"></script>
    <script src="js/menu.js"></script>
    <script src="js/map.js"></script>
    <script src="js/Collision.js"></script>
    <script src="js/stage.js"></script>
    <script src="js/main.js"></script>
    <link rel="stylesheet" type="text/css" href="css/default.css" />
    <style type="text/css">
      #canvasDiv canvas{
        position:absolute;
      }
    </style>
  </head>
  <body >
  <div style="width:100%; height:100%;" > 
    <div class="container" >
      <div class="main clearfix" style="position:fixed;top:20%;height:488px;">
      <div style="position: fixed;margin:5px auto;width:100%;height:448px;">
        <div id="canvasDiv" style="margin-left:auto;margin-right:auto;">
          <canvas id="wallCanvas"  ></canvas> 
          <canvas id="tankCanvas" ></canvas>
          <canvas id="grassCanvas" ></canvas>
          <canvas id="overCanvas" ></canvas> 
          <canvas id="stageCanvas"></canvas>
        </div>
      </div>
      </div>
    </div><!-- /container -->
  </div>
  </body>
</html>

在HTML部分,定义了文档类型、语言和一些元信息。在head 标签中引入了一些外部的JavaScript文件和CSS文件,这些文件用于定义游戏的逻辑和样式。


在body标签中,使用了一个div元素作为容器,并设置了宽度和高度为100%。在容器中,通过canvas元素创建了一些画布,用于显示游戏中的墙体、坦克、草地和其他元素。


整个页面的结构比较简单,主要的逻辑和渲染都由JavaScript来完成。通过引入的JavaScript文件,实现了游戏中的各种功能,比如坦克的移动、子弹的发射以及碰撞检测等。


css文件

.main,
.container > header {
  margin: 0 auto;
  /*padding: 2em;*/
}
.container {
  height: 100%;
}
.container > header {
  padding-top: 20px;
  padding-bottom: 20px;
  text-align: center;
  background: rgba(0,0,0,0.01);
}
.container > header h1 {
  font-size: 2.625em;
  line-height: 1.3;
  margin: 0;
  font-weight: 300;
}
.container > header span {
  display: block;
  font-size: 60%;
  opacity: 0.3;
  padding: 0 0 0.6em 0.1em;
}
/* Main Content */
.main {
  /*max-width: 69em;*/
  width: 100%;
  height: 100%;
  overflow: hidden;
}
.demo-scroll{
  overflow-y: scroll;
  width: 100%;
  height: 100%;
}
.column {
  float: left;
  width: 50%;
  padding: 0 2em;
  min-height: 300px;
  position: relative;
}
.column:nth-child(2) {
  box-shadow: -1px 0 0 rgba(0,0,0,0.1);
}
.column p {
  font-weight: 300;
  font-size: 2em;
  padding: 0;
  margin: 0;
  text-align: right;
  line-height: 1.5;
}
/* To Navigation Style */
.htmleaf-top {
  background: #fff;
  background: rgba(255, 255, 255, 0.6);
  text-transform: uppercase;
  width: 100%;
  font-size: 0.69em;
  line-height: 2.2;
}
.htmleaf-top a {
  padding: 0 1em;
  letter-spacing: 0.1em;
  color: #888;
  display: inline-block;
}
.htmleaf-top a:hover {
  background: rgba(255,255,255,0.95);
  color: #333;
}
.htmleaf-top span.right {
  float: right;
}
.htmleaf-top span.right a {
  float: left;
  display: block;
}
.htmleaf-icon:before {
  font-family: 'codropsicons';
  margin: 0 4px;
  speak: none;
  font-style: normal;
  font-weight: normal;
  font-variant: normal;
  text-transform: none;
  line-height: 1;
  -webkit-font-smoothing: antialiased;
}
/* Demo Buttons Style */
.htmleaf-demos {
  padding-top: 1em;
  font-size: 0.9em;
}
.htmleaf-demos a {
  display: inline-block;
  margin: 0.2em;
  padding: 0.45em 1em;
  background: #999;
  color: #fff;
  font-weight: 700;
  border-radius: 2px;
}
.htmleaf-demos a:hover,
.htmleaf-demos a.current-demo,
.htmleaf-demos a.current-demo:hover {
  opacity: 0.6;
}
.htmleaf-nav {
  text-align: center;
}
.htmleaf-nav a {
  display: inline-block;
  margin: 20px auto;
  padding: 0.3em;
}
.bb-custom-wrapper {
  width: 420px;
  position: relative;
  margin: 0 auto 40px;
  text-align: center;
}
/* Demo Styles */
.demo-1 body {
  color: #87968e;
  background: #000;
}
.demo-1 a {
  color: #72b890;
}
.demo-1 .htmleaf-demos a {
  background: #72b890;
  color: #fff;
}
.demo-2 body {
  color: #fff;
  background: #c05d8e;
}
.demo-2 a {
  color: #d38daf;
}
.demo-2 a:hover,
.demo-2 a:active {
  color: #fff;
}
.demo-2 .htmleaf-demos a {
  background: #883b61;
  color: #fff;
}
.demo-2 .htmleaf-top a:hover {
  background: rgba(255,255,255,0.3);
  color: #333;
}
.demo-3 body {
  color: #87968e;
  background: #fff2e3;
}
.demo-3 a {
  color: #ea5381;
}
.demo-3 .htmleaf-demos a {
  background: #ea5381;
  color: #fff;
}
.demo-4 body {
  color: #999;
  background: #fff2e3;
  overflow: hidden;
}
.demo-4 a {
  color: #1baede;
}
.demo-4 a:hover,
.demo-4 a:active {
  opacity: 0.6;
}
.demo-4 .htmleaf-demos a {
  background: #1baede;
  color: #fff;
}
.demo-5 body {
  background: #fffbd6;
}
/****/
.related {
  /*margin-top: 5em;*/
  color: #fff;
  background: #333;
  text-align: center;
  font-size: 1.25em;
  padding: 3em 0;
  overflow: hidden;
}
.related a {
  display: inline-block;
  text-align: left;
  margin: 20px auto;
  padding: 10px 20px;
  opacity: 0.8;
  -webkit-transition: opacity 0.3s;
  transition: opacity 0.3s;
  -webkit-backface-visibility: hidden;
}
.related a:hover,
.related a:active {
  opacity: 1;
}
.related a img {
  max-width: 100%;
}
.related a h3 {
  font-weight: 300;
  margin-top: 0.15em;
  color: #fff;
}
@media screen and (max-width: 40em) {
  .htmleaf-icon span {
    display: none;
  }
  .htmleaf-icon:before {
    font-size: 160%;
    line-height: 2;
  }
}
@media screen and (max-width: 46.0625em) {
  .column {
    width: 100%;
    min-width: auto;
    min-height: auto;
    padding: 1em; 
  }
  .column p {
    text-align: left;
    font-size: 1.5em;
  }
  .column:nth-child(2) {
    box-shadow: 0 -1px 0 rgba(0,0,0,0.1);
  }
}
@media screen and (max-width: 25em) {
  .htmleaf-icon span {
    display: none;
  }
}
  1. 头部样式:设置了网页头部的样式,包括居中对齐、背景透明、标题字体大小和权重等。
  2. 主要内容样式:定义了主要内容区域的样式,包括宽度、高度、溢出隐藏、两个列的浮动布局、段落字体样式等。
  3. 导航样式:设置了顶部导航栏的样式,包括背景颜色、链接样式和悬停效果等。
  4. 按钮样式:定义了演示按钮的样式,包括背景颜色、字体颜色、圆角边框等。
  5. 演示样式:定义了不同演示版本的样式,包括背景颜色、链接颜色和悬停效果等。
  6. 相关内容样式:设置了相关内容区域的样式,包括背景颜色、文字颜色、字体大小和链接样式等。该代码主要用于创建一个响应式网页,提供了不同的演示版本和相关内容。


main.js

var ctx;//2d画布
var wallCtx;//地图画布
var grassCtx;//草地画布
var tankCtx;//坦克画布
var overCtx;//结束画布
var menu = null;//菜单
var stage = null;//舞台
var map = null;//地图
var player1 = null;//玩家1
var player2 = null;//玩家2
var prop = null;
var enemyArray = [];//敌方坦克
var bulletArray = [];//子弹数组
var keys = [];//记录按下的按键
var crackArray = [];//爆炸数组
var gameState = GAME_STATE_MENU;//默认菜单状态
var level = 1;
var maxEnemy = 20;//敌方坦克总数
var maxAppearEnemy = 5;//屏幕上一起出现的最大数
var appearEnemy = 0; //已出现的敌方坦克
var mainframe = 0;
var isGameOver = false;
var overX = 176;
var overY = 384;
var emenyStopTime = 0;
var homeProtectedTime = -1;
var propTime = 300;
$(document).ready(function(){
  initScreen();
  initObject();
  setInterval(gameLoop,20);
});
function initScreen(){
  var canvas = $("#stageCanvas");
  ctx = canvas[0].getContext("2d");
  canvas.attr({"width":SCREEN_WIDTH});
  canvas.attr({"height":SCREEN_HEIGHT});
  wallCtx = $("#wallCanvas")[0].getContext("2d");
  grassCtx = $("#grassCanvas")[0].getContext("2d");
  $("#wallCanvas").attr({"width":SCREEN_WIDTH});
  $("#wallCanvas").attr({"height":SCREEN_HEIGHT});
  $("#grassCanvas").attr({"width":SCREEN_WIDTH});
  $("#grassCanvas").attr({"height":SCREEN_HEIGHT});
  tankCtx = $("#tankCanvas")[0].getContext("2d");
  $("#tankCanvas").attr({"width":SCREEN_WIDTH});
  $("#tankCanvas").attr({"height":SCREEN_HEIGHT});
  overCtx = $("#overCanvas")[0].getContext("2d");
  $("#overCanvas").attr({"width":SCREEN_WIDTH});
  $("#overCanvas").attr({"height":SCREEN_HEIGHT});
  $("#canvasDiv").css({"width":SCREEN_WIDTH});
  $("#canvasDiv").css({"height":SCREEN_HEIGHT});
  $("#canvasDiv").css({"background-color":"#000000"});
}
function initObject(){
  menu = new Menu(ctx);
  stage = new Stage(ctx,level);
  map = new Map(wallCtx,grassCtx);
  player1 = new PlayTank(tankCtx);
  player1.x = 129 + map.offsetX;
  player1.y = 385 + map.offsetY;
  player2 = new PlayTank(tankCtx);
  player2.offsetX = 128; //player2的图片x与图片1相距128
  player2.x = 256 + map.offsetX;
  player2.y = 385 + map.offsetY;
  appearEnemy = 0; //已出现的敌方坦克
  enemyArray = [];//敌方坦克
  bulletArray = [];//子弹数组
  keys = [];//记录按下的按键
  crackArray = [];//爆炸数组
  isGameOver = false;
  overX = 176;
  overY = 384;
  overCtx.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
  emenyStopTime = 0;
  homeProtectedTime = -1;
  propTime = 1000;
}
function gameLoop(){
  switch(gameState){
  case GAME_STATE_MENU:
    menu.draw();
    break;
  case GAME_STATE_INIT:
    stage.draw();
    if(stage.isReady == true){
      gameState = GAME_STATE_START;
    }
    break;
  case GAME_STATE_START:
    drawAll();
    if(isGameOver ||(player1.lives <=0 && player2.lives <= 0)){
      gameState = GAME_STATE_OVER;
      map.homeHit();
      PLAYER_DESTROY_AUDIO.play();
    }
    if(appearEnemy == maxEnemy && enemyArray.length == 0){
      gameState  = GAME_STATE_WIN;
    }
    break;
  case GAME_STATE_WIN:
    nextLevel();
    break;
  case GAME_STATE_OVER:
    gameOver();
    break;
  }
}
$(document).keydown(function(e){
  switch(gameState){
  case GAME_STATE_MENU:
    if(e.keyCode == keyboard.ENTER){
      gameState = GAME_STATE_INIT;
      //只有一个玩家
      if(menu.playNum == 1){
        player2.lives = 0;
      }
    }else{
      var n = 0;
      if(e.keyCode == keyboard.DOWN){
        n = 1;
      }else if(e.keyCode == keyboard.UP){
        n = -1;
      }
      menu.next(n);
    }
    break;
  case GAME_STATE_START:
    if(!keys.contain(e.keyCode)){
      keys.push(e.keyCode);
    }
    //射击
    if(e.keyCode == keyboard.SPACE && player1.lives > 0){
      player1.shoot(BULLET_TYPE_PLAYER);
    }else if(e.keyCode == keyboard.ENTER && player2.lives > 0){
      player2.shoot(BULLET_TYPE_PLAYER);
    }else if(e.keyCode == keyboard.N){
      nextLevel();
    }else if(e.keyCode == keyboard.P){
      preLevel();
    }
    break;
  }
});
$(document).keyup(function(e){
  keys.remove(e.keyCode);
});
function initMap(){
  map.setMapLevel(level);;
  map.draw();
  drawLives();
}
function drawLives(){
  map.drawLives(player1.lives,1);
  map.drawLives(player2.lives,2);
}
function drawBullet(){
  if(bulletArray != null && bulletArray.length > 0){
    for(var i=0;i<bulletArray.length;i++){
      var bulletObj = bulletArray[i];
      if(bulletObj.isDestroyed){
        bulletObj.owner.isShooting = false;
        bulletArray.removeByIndex(i);
        i--;
      }else{
        bulletObj.draw();
      }
    }
  }
}
function keyEvent(){
  if(keys.contain(keyboard.W)){
    player1.dir = UP;
    player1.hit = false;
    player1.move();
  }else if(keys.contain(keyboard.S)){
    player1.dir = DOWN;
    player1.hit = false;
    player1.move();
  }else if(keys.contain(keyboard.A)){
    player1.dir = LEFT;
    player1.hit = false;
    player1.move();
  }else if(keys.contain(keyboard.D)){
    player1.dir = RIGHT;
    player1.hit = false;
    player1.move();
  }
  if(keys.contain(keyboard.UP)){
    player2.dir = UP;
    player2.hit = false;
    player2.move();
  }else if(keys.contain(keyboard.DOWN)){
    player2.dir = DOWN;
    player2.hit = false;
    player2.move();
  }else if(keys.contain(keyboard.LEFT)){
    player2.dir = LEFT;
    player2.hit = false;
    player2.move();
  }else if(keys.contain(keyboard.RIGHT)){
    player2.dir = RIGHT;
    player2.hit = false;
    player2.move();
  }
}
function addEnemyTank(){
  if(enemyArray == null || enemyArray.length >= maxAppearEnemy || maxEnemy == 0){
    return ;
  }
  appearEnemy++;
  var rand = parseInt(Math.random()*3);
  var obj = null;
  if(rand == 0){
    obj = new EnemyOne(tankCtx);
  }else if(rand == 1){
    obj = new EnemyTwo(tankCtx);
  }else if(rand == 2){
    obj = new EnemyThree(tankCtx);
  }
  obj.x = ENEMY_LOCATION[parseInt(Math.random()*3)] + map.offsetX;
  obj.y = map.offsetY;  
  obj.dir = DOWN;
  enemyArray[enemyArray.length] = obj;
  //更新地图右侧坦克数
  map.clearEnemyNum(maxEnemy,appearEnemy);
}
function drawEnemyTanks(){
  if(enemyArray != null || enemyArray.length > 0){
    for(var i=0;i<enemyArray.length;i++){
      var enemyObj = enemyArray[i];
      if(enemyObj.isDestroyed){
        enemyArray.removeByIndex(i);
        i--;
      }else{
        enemyObj.draw();
      }
    }
  }
  if(emenyStopTime > 0){
    emenyStopTime --;
  }
}
function drawAll(){
  tankCtx.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
  if(player1.lives>0){
    player1.draw();
  }
  if(player2.lives > 0){
    player2.draw();
  }
  drawLives();
  if(appearEnemy<maxEnemy){
    if(mainframe % 100 == 0){
      addEnemyTank();
      mainframe = 0;
    }
    mainframe++;
  }
  drawEnemyTanks();
  drawBullet();
  drawCrack();
  keyEvent();
  if(propTime<=0){
    drawProp();
  }else{
    propTime --;
  }
  if(homeProtectedTime > 0){
    homeProtectedTime --;
  }else if(homeProtectedTime == 0){
    homeProtectedTime = -1;
    homeNoProtected();
  }
}
function drawCrack(){
  if(crackArray != null && crackArray.length > 0){
    for(var i=0;i<crackArray.length;i++){
      var crackObj = crackArray[i];
      if(crackObj.isOver){
        crackArray.removeByIndex(i);
        i--;
        if(crackObj.owner == player1){
          player1.renascenc(1);
        }else if(crackObj.owner == player2){
          player2.renascenc(2);
        }
      }else{
        crackObj.draw();
      }
    }
  }
}
function gameOver(){
  overCtx.clearRect(0,0,SCREEN_WIDTH,SCREEN_HEIGHT);
  overCtx.drawImage(RESOURCE_IMAGE,POS["over"][0],POS["over"][1],64,32,overX+map.offsetX,overY+map.offsetY,64,32);
  overY -= 2 ;
  if(overY <= parseInt(map.mapHeight/2)){
    initObject();
    //只有一个玩家
    if(menu.playNum == 1){
      player2.lives = 0;
    }
    gameState = GAME_STATE_MENU;
  }
}
function nextLevel(){
  level ++;
  if(level == 22){
    level = 1;
  }
  //保存玩家数
  var old_player_num = menu.playNum;
  initObject();
  menu.playNum = old_player_num;
  //只有一个玩家
  if(menu.playNum == 1){
    player2.lives = 0;
  }
  stage.init(level);
  gameState = GAME_STATE_INIT;
}
function preLevel(){
  level --;
  if(level == 0){
    level = 21;
  }
  //保存玩家数
  var old_player_num = menu.playNum;
  initObject();
  menu.playNum = old_player_num;
  //只有一个玩家
  if(menu.playNum == 1){
    player2.lives = 0;
  }
  stage.init(level);
  gameState = GAME_STATE_INIT;
}
function drawProp(){
  var rand = Math.random();
  if(rand < 0.4 && prop == null){
    prop = new Prop(overCtx);
    prop.init();
  }
  if(prop != null){
    prop.draw();
    if(prop.isDestroyed){
      prop = null;
      propTime = 1000;
    }
  }
}
function homeNoProtected(){
  var mapChangeIndex = [[23,11],[23,12],[23,13],[23,14],[24,11],[24,14],[25,11],[25,14]];
  map.updateMap(mapChangeIndex,WALL);
};


下载


可以直接在insode中克隆项目(Fork)进行下载学习


链接:坦克大战

相关文章
|
6月前
|
前端开发 JavaScript Java
童年回忆——超级玛丽(内含源码inscode一键运行)
童年回忆——超级玛丽(内含源码inscode一键运行)
|
存储 前端开发 JavaScript
前端实现俄罗斯方块游戏(内含源码)
前端实现俄罗斯方块游戏(内含源码)
197 2
|
5月前
|
图形学
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
【制作100个unity游戏之28】花半天时间用unity复刻童年4399经典小游戏《黄金矿工》(附带项目源码)
170 0
|
5月前
|
移动开发 HTML5
经典的泡泡龙游戏源码免费下载
HTML5泡泡龙冒险小游戏是一款休闲网页游戏,游戏玩法是玩家从下方中央的弹珠发射台射出彩珠,多于3个同色珠相连则会消失。
41 2
经典的泡泡龙游戏源码免费下载
|
5月前
|
图形学
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(上)
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)
219 2
|
5月前
|
图形学
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(下)
【制作100个unity游戏之29】使用unity复刻经典游戏《愤怒的小鸟》(完结,附带项目源码)(下)
84 0
|
5月前
|
存储 JSON 关系型数据库
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版13(完结,附带项目源码)
【制作100个unity游戏之27】使用unity复刻经典游戏《植物大战僵尸》,制作属于自己的植物大战僵尸随机版和杂交版13(完结,附带项目源码)
110 0
|
6月前
|
前端开发 JavaScript Java
童年回忆——捕鱼达人(内含源码inscode一键运行)
童年回忆——捕鱼达人(内含源码inscode一键运行)
|
6月前
|
图形学
【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)
【Unity 3D】3D游戏跑酷小子实战教学(附源码和步骤 超详细)
290 0
|
移动开发 前端开发 JavaScript
赛车游戏——【极品飞车】(内含源码inscode在线运行)
赛车游戏——【极品飞车】(内含源码inscode在线运行)
赛车游戏——【极品飞车】(内含源码inscode在线运行)