- <!DOCTYPE html>
- <html>
- <head>
- <meta charset="utf-8">
- <title>
- </title>
- <style media="screen">
- body {text-align: center;} #c1 {background:#000}
- </style>
- <script>
- //小块:15*15
- //大地图:26块*26块
- let data = [[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, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [2, 2, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 2, 2], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 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, 0, 0, 0, 0, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], ];
- function loadImgs(json, fn) {
- let result = {};
- let count = 0; //完成多少个
- let total = 0; //总共多少个
- //
- for (let name in json) {
- total++;
- //name: wall, steel, p1d, ...
- //json[name]: 'img/wall.gif', 'img/steel-1.gif', 'img/p1tankD.gif', ...
- let oImg = new Image();
- oImg.src = json[name];
- oImg.onload = function() {
- count++;
- if (count == total) {
- //完事
- fn(result);
- }
- };
- oImg.onerror = function() {
- alert('失败了');
- };
- result[name] = oImg;
- }
- }
- function coll_test(x1, y1, w1, h1, x2, y2, w2, h2) {
- let r1 = x1 + w1;
- let b1 = y1 + h1;
- let r2 = x2 + w2;
- let b2 = y2 + h2;
- if (x1 >= r2 || r1 <= x2 || y1 >= b2 || b1 <= y2) {
- return false;
- } else {
- return true;
- }
- }
- window.onload = function() {
- const SIZE = 15;
- const PLAYER_SPEED = 2;
- let p1_pos = {
- r: 24,
- c: 8
- };
- let symbol_pos = {
- r: 24,
- c: 12
- };
- let oC = document.getElementById('c1');
- let gd = oC.getContext('2d'); //图形上下文:绘图接口
- let p1_x = p1_pos.c * SIZE;
- let p1_y = p1_pos.r * SIZE;
- let p1_img = null;
- let p1_w = SIZE * 1.6;
- let p1_h = SIZE * 1.6;
- //敌人
- let aEmeny = [];
- aEmeny.push({
- x: 0,
- y: 0,
- w: SIZE * 1.6,
- h: SIZE * 1.6
- },
- {
- x: 12 * SIZE,
- y: 0,
- w: SIZE * 1.6,
- h: SIZE * 1.6
- },
- {
- x: 24 * SIZE,
- y: 0,
- w: SIZE * 1.6,
- h: SIZE * 1.6
- },
- );
- //炮弹
- let aBubble = [];
- //绘制
- loadImgs({
- wall: 'https://lixindada.github.io/img/wall.gif',
- steel: 'https://lixindada.github.io/img/steel-1.gif',
- p1d: 'https://lixindada.github.io/img/p1tankD.gif',
- p1l: 'https://lixindada.github.io/img/p1tankL.gif',
- p1r: 'https://lixindada.github.io/img/p1tankR.gif',
- p1u: 'https://lixindada.github.io/img/p1tankU.gif',
- symbol: 'https://lixindada.github.io/img/symbol.png',
- e1d: 'https://lixindada.github.io/img/enemy1D.gif',
- e1u: 'https://lixindada.github.io/img/enemy1U.gif',
- e1l: 'https://lixindada.github.io/img/enemy1L.gif',
- e1r: 'https://lixindada.github.io/img/enemy1R.gif',
- m: 'https://lixindada.github.io/img/tankmissile.gif'
- },
- function(imgs) {
- let b_down_l = false;
- let b_down_u = false;
- let b_down_d = false;
- let b_down_r = false;
- //键盘控制
- document.onkeyup = function(ev) {
- switch (ev.keyCode) {
- case 37:
- b_down_l = false;
- break;
- case 39:
- b_down_r = false;
- break;
- case 38:
- b_down_u = false;
- break;
- case 40:
- b_down_d = false;
- break;
- }
- };
- document.onkeydown = function(ev) {
- //左-37
- //上-38
- //右-39
- //下-40
- switch (ev.keyCode) {
- case 37:
- b_down_l = true;
- //p1_x-=PLAYER_SPEED;
- //p1_img=imgs.p1l;
- break;
- case 39:
- //p1_x+=PLAYER_SPEED;
- b_down_r = true;
- //p1_img=imgs.p1r;
- break;
- case 38:
- //p1_y-=PLAYER_SPEED;
- b_down_u = true;
- //p1_img=imgs.p1u;
- break;
- case 40:
- //p1_y+=PLAYER_SPEED;
- b_down_d = true;
- //p1_img=imgs.p1d;
- break;
- case 32:
- aBubble.push({
- x:
- p1_x + p1_w / 2 - 3,
- y: p1_y,
- w: 6,
- h: 6
- });
- }
- };
- p1_img = imgs.p1u;
- setInterval(function() {
- let old_x = p1_x;
- let old_y = p1_y;
- aBubble.forEach(m = >{
- m.y -= 3;
- });
- //移动、检测边界
- if (b_down_l) {
- p1_x -= PLAYER_SPEED;
- if (p1_x < 0) {
- p1_x = 0;
- }
- p1_img = imgs.p1l;
- } else if (b_down_r) {
- p1_x += PLAYER_SPEED;
- if (p1_x > oC.width - p1_w) {
- p1_x = oC.width - p1_w;
- }
- p1_img = imgs.p1r;
- } else if (b_down_u) {
- p1_y -= PLAYER_SPEED;
- if (p1_y < 0) {
- p1_y = 0;
- }
- p1_img = imgs.p1u;
- } else if (b_down_d) {
- p1_y += PLAYER_SPEED;
- if (p1_y > oC.height - p1_h) {
- p1_y = oC.height - p1_h;
- }
- p1_img = imgs.p1d;
- }
- //检测物体
- let colled = false;
- for (let r = 0; r < data.length; r++) {
- for (let c = 0; c < data[r].length; c++) {
- if (data[r][c] == 0) continue;
- let x = c * SIZE;
- let y = r * SIZE;
- //碰撞检测
- if (coll_test(p1_x, p1_y, p1_w, p1_h, x, y, SIZE, SIZE)) {
- colled = true;
- }
- }
- }
- //检测敌人
- aEmeny.forEach(emeny = >{
- if (coll_test(p1_x, p1_y, p1_w, p1_h, emeny.x, emeny.y, emeny.w, emeny.h)) {
- colled = true;
- }
- });
- if (colled) {
- p1_x = old_x;
- p1_y = old_y;
- }
- gd.clearRect(0, 0, oC.width, oC.height);
- //绘制场景
- for (let r = 0; r < data.length; r++) {
- for (let c = 0; c < data[r].length; c++) {
- let x = c * SIZE;
- let y = r * SIZE;
- switch (data[r][c]) {
- case 1:
- //砖
- gd.drawImage(imgs.wall,
- //sx, sy, sw, sh
- 0, 0, imgs.wall.width, imgs.wall.height,
- //dx, dy, dw, dh
- x, y, SIZE, SIZE);
- break;
- case 2:
- //铁块
- gd.drawImage(imgs.steel,
- //sx, sy, sw, sh
- 0, 0, imgs.steel.width, imgs.steel.height,
- //dx, dy, dw, dh
- x, y, SIZE, SIZE);
- break;
- }
- }
- }
- //绘制主角
- gd.drawImage(p1_img, 0, 0, p1_img.width, p1_img.height, p1_x, p1_y, p1_w, p1_h);
- //绘制敌人
- aEmeny.forEach(emeny = >{
- gd.drawImage(imgs.e1d, 0, 0, imgs.e1d.width, imgs.e1d.height, emeny.x, emeny.y, emeny.w, emeny.h);
- });
- //绘制炮弹
- aBubble.forEach(m = >{
- gd.drawImage(imgs.m, 0, 0, imgs.m.width, imgs.m.height, m.x, m.y, m.w, m.h);
- });
- },
- 15);
- });
- };
- </script>
- </head>
- <body>
- <canvas id="c1" width="390" height="390">
- </canvas>
- </body>
- </html>
来源: http://www.qdfuns.com/notes/46955/955f03e12d6f013f5a7e283217b112f7.html