I am trying to make a program where there are two different screens that are centered on different players. I am using createGraphics()
to try and achieve this. They render, but the screens aren't centered on them. I tried using translate()
but it doesn't center the screen on them.
Also, the players don't seem to be rendering correctly. One of them is supposed to be white with a black outline, and the other is supposed to be black with a white outline, but it only seems to render like that on the first one.
let p1Pos;
let p2Pos;
let buffer1;
let buffer2;
let speed = 0.1;
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
p1Pos = createVector(0, 0);
p2Pos = createVector(0, 0);
buffer1 = createGraphics(width, height / 2);
buffer2 = createGraphics(width, height / 2);
}
function draw() {
background(200);
strokeWeight(4);
line(0, height / 2, width, height / 2);
controller();
drawBuf1();
drawBuf2();
image(buffer1, 0, 0);
image(buffer2, 0, height/2);
}
function controller() {
// P1
if (keyIsDown(87)) p1Pos.add(0, -speed);
if (keyIsDown(83)) p1Pos.add(0, speed);
if (keyIsDown(65)) p1Pos.add(-speed);
if (keyIsDown(68)) p1Pos.add(speed);
// P2
if (keyIsDown(38)) p2Pos.add(0, -speed);
if (keyIsDown(40)) p2Pos.add(0, speed);
if (keyIsDown(37)) p2Pos.add(-speed);
if (keyIsDown(39)) p2Pos.add(speed);
}
function drawBuf1() { // Draw first buffer
buffer1.translate(p1Pos.x, p1Pos.y);
buffer1.background(100);
buffer1.strokeWeight(2);
buffer1.fill('#FFFFFF');
buffer1.stroke('#0000000');
buffer1.circle(0, 0, 40);
buffer1.fill('#0000000');
buffer1.stroke('#FFFFFF');
buffer1.circle(p2Pos.x, p2Pos.y, 40);
}
function drawBuf2() {
buffer2.translate(p2Pos.x, p2Pos.y);
buffer2.background(100);
buffer2.strokeWeight(2);
buffer2.fill('#000000');
buffer2.stroke('#FFFFFF0');
buffer2.circle(0, 0, 40);
buffer2.fill('#FFFFFF0');
buffer2.stroke('#000000');
buffer2.circle(p1Pos.x, p1Pos.y, 40);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/p5.js"></script>
For starters, your colors are invalid. There should be 6 digits in the hexadecimal number, not 7.
As for the main issue, take a look at HTML5 Canvas camera/viewport - how to actually do it?. This shows the following generalized formula:
function update() {
// Assign the viewport to follow a target for this frame
var viewportX = canvas.width / 2 - target.x;
var viewportY = canvas.height / 2 - target.y;
// Draw each entity, including the target, relative to the viewport
ctx.fillRect(
entity.x + viewportX,
entity.y + viewportY,
entity.size,
entity.size
);
}
Since you only have 2 objects, you can skip the viewport for starters and move players relative to each other, with the "current player" as always as w / 2, h / 2
to pin them to the center of the screen:
let p1Pos;
let p2Pos;
let buffer1;
let buffer2;
let speed = 1;
function setup() {
createCanvas(windowWidth, windowHeight);
background(100);
p1Pos = createVector(40, 0);
p2Pos = createVector(-40, 0);
buffer1 = createGraphics(width, height / 2);
buffer2 = createGraphics(width, height / 2);
}
function draw() {
background(200);
strokeWeight(4);
line(0, height / 2, width, height / 2);
handleInput();
drawBuf1();
drawBuf2();
image(buffer1, 0, 0);
image(buffer2, 0, height / 2);
}
function handleInput() {
// P1
if (keyIsDown(87)) p1Pos.add(0, -speed);
if (keyIsDown(83)) p1Pos.add(0, speed);
if (keyIsDown(65)) p1Pos.add(-speed);
if (keyIsDown(68)) p1Pos.add(speed);
// P2
if (keyIsDown(38)) p2Pos.add(0, -speed);
if (keyIsDown(40)) p2Pos.add(0, speed);
if (keyIsDown(37)) p2Pos.add(-speed);
if (keyIsDown(39)) p2Pos.add(speed);
}
function drawBuf1() {
buffer1.background(100);
buffer1.strokeWeight(2);
buffer1.fill("#FFFFFF");
buffer1.stroke("#000000");
buffer1.circle(width / 2, height / 4, 40);
buffer1.fill("#000000");
buffer1.stroke("#FFFFFF");
buffer1.circle(
width / 2 - p1Pos.x + p2Pos.x,
height / 4 - p1Pos.y + p2Pos.y,
40
);
}
function drawBuf2() {
buffer2.background(100);
buffer2.strokeWeight(2);
buffer2.fill("#000000");
buffer2.stroke("#FFFFFF");
buffer2.circle(width / 2, height / 4, 40);
buffer2.fill("#FFFFFF");
buffer2.stroke("#000000");
buffer2.circle(
width / 2 - p2Pos.x + p1Pos.x,
height / 4 - p2Pos.y + p1Pos.y,
40
);
}
// prevent scrolling
window.addEventListener("keydown", e => {
if ([37, 38, 39, 40].includes(e.keyCode)) {
e.preventDefault();
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.11.0/p5.js"></script>
If this appears strange, cover up the other player's viewport and it'll look more natural (when I move, it moves away from or towards the other player on my screen; when the other player moves, they move closer or towards me). Adding stationary objects and implementing full viewports will make the illusion convincing.