javascript - 在 html 画布中渲染实体对象?
问题描述
我正在制作一个 html5 画布游戏,我需要渲染一些实体对象。这是一种沙盒游戏,所以我打算这样做:
- 找出玩家正在触摸的方块
- 检查周围的方块是否是实心的
- 如果是这样,请不要让玩家通过该点
- 当gameloop函数执行时重复
如果你不明白我在说什么,我很抱歉,但是地面是由与玩家的碰撞箱大小相同的正方形组成的(这意味着碰撞箱不能进入固体物体内)。希望这可以帮助您理解。
这就是我需要的:
我不知道如何检测玩家所在的方格周围的所有方格。到目前为止,这是我的功能:
function rendersolid() {
var x = player.x;
var y = player.y;
var pass = {
top: true;
left: true;
bottom: true;
right: true;
};
if (map[x][y] == !undefined) {
console.log(map[x][y]);
}
//check surrounding blocks (and if they're #)
//change 'pass' variables to false if you CAN'T pass, else true
//do not let the player pass that point
//FYI, Math.floor(y - 1) is one square above the player, as the same with x is one left of the player
if (pass.top == false && player.y < Math.floor(y - 1)) {
player.y = Math.floor(y);
} else if (pass.left == false && player.x > Math.floor(x + 1)) {
player.x = Math.floor(x);
} else if (pass.bottom == false && player.y > Math.floor(y + 1)) {
player.y = Math.floor(y);
} else if (pass.right == false && player.x < Math.floor(x - 1)) {
player.x = Math.floor(x);
}
}
而且我也不确定如果玩家接触到两个方格该怎么办?对不起,如果这是一个糟糕的问题,感谢您阅读它。我希望您尝试回答,并提前谢谢!
编辑:
非常抱歉,但我忘了提到我的地图是 ASCII 地图,这是它的变量
var map =
`##................................................
##........'........................'..............
..'.''....'.....'..........'.''....'.....'........
....'...'....................'...'................
..'..'.....................'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'......'..'....................
..........'.'''''.'''..............'.'...'..'.....
...'.....'....'...'.........'...'......'..........
.....'....'...'...'''.........'....'.........'....
.....'.....'..'.....'.........'.....'........'....
...'......'...'...'''.......'......'...'...'......
........'...............'......'....'.............
.......'.....''...........'.......'.........'.....
..........'.......'................'..............
..'.''....'.....'..........'.''....'.....'........
....'...'.......'...''.......'...'................
..'..'....'.......'....'...'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
..........'.'...'.'................'.'.'...'.'....
...'.....'....'.............'.....'...'....'......
.....'....'.........'.........'....'........'.....
.....'.....'..'.....'.........'.....'.............
...'......'...'...'.........'......'...'...'.'....
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'.........'......'.......'.....
..................................................`.split("\n");
这是颜色图:
var colorMap = {
'.': "#47CB00", //For grass
'#': "#000000", //Black, solid
'+': "#878787", //Grey
'\'': "#349500", //Darker green, for grass texture (ignore the '\')
'0': "#FFFFFF" //white
};
解决方案
看一看(跑步/玩耍)并提出问题。注意:我添加了一堵墙只是为了测试。
var map =
`##................................................
##........'........................'..............
..'.''.#..'.....'..........'.''....'.....'........
....'..#'....................'...'................
..'..'.#...................'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'......'..'....................
..........'.'''''.'''..............'.'...'..'.....
...'.....'....'...'.........'...'......'..........
.....'....'...'...'''.........'....'.........'....
.....'.....'..'.....'.........'.....'........'....
...'......'...'...'''.......'......'...'...'......
........'...............'......'....'.............
.......'.....''...........'.......'.........'.....
..........'.......'................'..............
..'.''....'.....'..........'.''....'.....'........
....'...'.......'...''.......'...'................
..'..'....'.......'....'...'..'...................
...''.......................''....................
..'....'...'.....'.........'....'...'.....'.......
.......'...........'............'...........'.....
.......'......'.................'......'..........
....'........................'....................
..........'.'...'.'................'.'.'...'.'....
...'.....'....'.............'.....'...'....'......
.....'....'.........'.........'....'........'.....
.....'.....'..'.....'.........'.....'.............
...'......'...'...'.........'......'...'...'.'....
...'..'...'.................'..'...'..............
.......'......'....'............'......'....'.....
............'....'...'...............'....'...'...
...'....'..'...'............'....'..'...'.........
...'.....'......'...........'.....'......'........
..............'.'.....'................'.'.....'..
......'.....'...'..............'.....'...'........
.......'.......'.......'........'.......'.......'.
....'......'.......'.........'......'.......'.....
..................................................`.split("\n");
var colorMap = {
'.': "#47CB00", //For grass
'#': "#000000", //Black, solid
'+': "#878787", //Grey
'\'': "#349500", //Darker green, for grass texture (ignore the '\')
'0': "#FFFFFF", //white,
'@': 'red' // Player
};
let mapWidth = map[0].length;
let mapHeight = map.length;
const TILE = 12;
const c = document.getElementById("canvas");
const ctx = c.getContext("2d");
const player = {
x: 0,
y: 0
};
const mouse = {
x: 0,
y: 0
};
const initCanvas = () => {
c.width = mapWidth * TILE;
c.height = mapHeight * TILE;
}
const drawTile = (x, y, type) => {
ctx.beginPath();
ctx.rect(x * TILE, y * TILE, TILE, TILE);
ctx.fillStyle = colorMap[type];
ctx.fill();
}
const drawMapTile = (x, y) => {
drawTile(x, y, map[y][x]);
}
const drawMap = () => {
for (let y = 0; y < mapHeight; y++)
for (let x = 0; x < mapWidth; x++)
drawTile(x, y, map[y][x])
}
const initPlayer = () => {
player.x = 4;
player.y = 4;
}
const drawPlayer = () => {
drawTile(player.x, player.y, '@')
}
const drawMouse = () => {
ctx.beginPath();
ctx.lineWidth = 1;
ctx.moveTo(mouse.x * TILE + 1, mouse.y * TILE + 1);
ctx.lineTo(mouse.x * TILE + 1, mouse.y * TILE + TILE - 1);
ctx.lineTo(mouse.x * TILE + TILE - 1, mouse.y * TILE + TILE - 1);
ctx.lineTo(mouse.x * TILE + TILE - 1, mouse.y * TILE + 1);
ctx.lineTo(mouse.x * TILE + 1, mouse.y * TILE + 1);
ctx.stroke();
}
const showMouseCursor = (newX, newY) => {
drawMapTile(mouse.x, mouse.y);
if (mouse.x == player.x && mouse.y == player.y) drawPlayer();
mouse.x = newX;
mouse.y = newY;
drawMouse();
}
const getMousePos = (e) => {
var rect = e.target.getBoundingClientRect();
var x = e.clientX - rect.left;
var y = e.clientY - rect.top;
let mouseX = x / TILE | 0;
let mouseY = y / TILE | 0;
return {
x: mouseX,
y: mouseY
};
}
const teleportPlayerTo = (x, y) => {
if (map[y][x] != '#' && x >=0 && y >=0 && x < mapWidth && y < mapHeight) {
drawMapTile(player.x, player.y);
player.x = x;
player.y = y;
drawPlayer();
}
}
c.onmousemove = (e) => {
const mouse = getMousePos(e);
showMouseCursor(mouse.x, mouse.y);
e.preventDefault();
}
c.onclick = (e) => {
const mouse = getMousePos(e);
const dx = Math.abs(mouse.x - player.x);
const dy = Math.abs(mouse.y - player.y);
if (dx + dy == 1) {
teleportPlayerTo(mouse.x, mouse.y);
}
}
initCanvas();
drawMap();
initPlayer();
drawPlayer();
<canvas id="canvas" />
推荐阅读
- python - 使用池类在 Python 中进行多处理
- node.js - 如何在 Azure IOT 集线器中激活 X509 自分配设备类型的设备?
- mongodb - 如何按每小时对数据进行分组
- font-awesome - 在具有不同图标样式的 Openlayers 中使用 Fontawesome
- python - 一维数组到RGB图像?
- android - android中按钮上的java.lang.NullPointerException
- java - 在 maven 中使用/导入本地 fat jar 作为插件
- reactjs - 如何通过浅层安装 React 功能组件对反应钩子进行单元测试?
- angular - 如何在角度单元测试中模拟组件中的 store.pipe
- xml - 如何使用 XSLT 2.0 将 csv 文件转换为结构化 XML 文件?