The most effective method for identifying neighboring players in a turn-based game

I'm currently working on a turn-based game where players can move and pick up weapons. While the visualization isn't perfect yet, player damage is still being controlled effectively. The graphics are created using the canvas API, and players can move using the arrow keys.

My next objective is to detect when a player moves into adjacent cells so that combat can initiate. I have two potential approaches in mind:

  1. One option is to save an array of indexes representing the cells surrounding the player, updating it with each movement. However, constantly updating this array could become messy as the game progresses.

  2. The alternative approach involves looping through each cell surrounding the player to check for any opponents. This method would require writing a considerable amount of code.

Is there a simpler and more efficient solution to this issue? Check out my game here.

Answer №1

If your game is tile-based, checking the distance in tiles can be a simple solution to determine if two players are close enough. For example, you can define that two players are close enough if they are on adjacent tiles:

+--+---+---+---+--+
|  |   |   |   |  |
+--+---+---+---+--+
|  | x | x | x |  |
+--+---+---+---+--+
|  | x | O | x |  |   All Xs are adjacent to O
+--+---+---+---+--+
|  | x | x | x |  |
+--+---+---+---+--+
|  |   |   |   |  |
+--+---+---+---+--+

Let's assume (x1, y1) and (x2, y2) represent the coordinates of player1 and player2, respectively. By verifying that the absolute difference between x1 and x2, as well as the difference between y1 and y2, does not exceed 1 tile (represented by * tileSize), you can determine if they are overlapping, adjacent, or far apart.

Here's an implementation example:

const KEY_LEFT = 37;
const KEY_RIGHT = 39;
const KEY_UP = 38;
const KEY_DOWN = 40;

let canvas, ctx, closeText;

let playerTurn = 1;
let player1, player2;

let tileSize;

init();

function init() {
canvas = document.getElementById('canvas');
  ctx = canvas.getContext('2d');
  closeText = document.getElementById('close');
  
  tileSize = canvas.width / 10;
  
  player1 = new Player(10, 20, 'red');
  player2 = new Player(50, 40, 'green');
  
  updateText(areClose(player1, player2));
  
ctx.strokeStyle = '#888';

window.addEventListener('keyup', onKeyUp, false);
  
  draw();
}

function onKeyUp(e) {
let dx = 0, dy = 0;

// Determine player movement direction
switch (e.keyCode) {
  case KEY_LEFT: dx -= tileSize; break;
  case KEY_RIGHT: dx += tileSize; break;
  case KEY_UP: dy -= tileSize; break;
  case KEY_DOWN: dy += tileSize; break;
  }
  
  // Update player position
  if (playerTurn === 1) {
  player1.x += dx;
    player1.y += dy;
  } else if (playerTurn === -1) {
  player2.x += dx;
    player2.y += dy;
  }
  
  // Switch player turn
  playerTurn *= -1;
  
  // Check proximity for combat
  const close = areClose(player1, player2);
  updateText(close);
  
  // Redraw board and players
  draw();
}

function draw() {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  drawBoard();
  drawPlayer(player1);
  drawPlayer(player2);
}

function drawBoard() {
  // Draw horizontal lines
for (let i = tileSize; i < canvas.width; i += tileSize) {
    ctx.beginPath();
    ctx.moveTo(i, 0);
    ctx.lineTo(i, canvas.height);
    ctx.closePath();
  ctx.stroke();
  }
  // Draw vertical lines
  for (let j = tileSize; j < canvas.height; j += tileSize) {
    ctx.beginPath();
    ctx.moveTo(0, j);
    ctx.lineTo(canvas.width, j);
    ctx.closePath();
  ctx.stroke();
  }
}

function drawPlayer(player) {
ctx.fillStyle = player.color;
  ctx.fillRect(player.x, player.y, player.size, player.size);
}

function Player(x, y, color) {
this.x = x;
  this.y = y;
  this.color = color;
  this.size = 10;
}

function areClose(a, b) {
return Math.abs(a.x - b.x) < 2 * tileSize && Math.abs(a.y - b.y) < 2 * tileSize;
}

function updateText(close) {
closeText.innerText = close ? 'Close' : 'Not close';
}
canvas {
  border: 1px solid black;
}
<canvas id="canvas" width=100 height=100></canvas>
<p id="close"></p>

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Update the content of a div on the WordPress homepage with the click of a button

Hey there, I'm currently working on customizing the Boutique theme for a website. My goal is to add two buttons to the home page that will display different sets of products when clicked. I've been attempting to use the visibility property, but h ...

Is there an equivalent function to onAdd in Material-UI when using MUI Chip?

In my exploration of the latest version of Material-UI, MUI, I observed that the "onAdd" property has been removed. The only function properties remaining are "onDelete" and "onClick". I am interested in generating new chips based on user-input tags. Is ...

Why does one of the two similar javascript functions work while the other one fails to execute?

As a new Javascript learner, I am struggling to make some basic code work. I managed to successfully test a snippet that changes text color from blue to red to ensure that Javascript is functioning on the page. However, my second code attempt aims to togg ...

Using JavaScript to Create Dynamic Variable Names - Multiple Arrays?

In my project, I am working on creating markers for each user in my loop. These markers need to be generated in a way that allows me to later select them based on the corresponding userId. $.each($.parseJSON(window.usersArray), function (i, user) { w ...

Processing JSON data of a quotation that is enclosed within double quotation marks

My value is a string: "['Eitaj', 'Jason Json', 'Eitaj M', "Jason Json's"]" Trying to parse it with JSON.parse() results in an error. Encountered SyntaxError: Unexpected token ' in JSON at position 1 I discovere ...

show a pie chart at the top of the div using highcharts

i am struggling with positioning the high-chart with a label, as seen in the image below https://i.sstatic.net/m9bXW.png does anyone know how to properly display the chart from the top left corner? i have attempted to adjust the settings like this { ...

Error message: Object literal is limited to declaring existing properties

The source code was obtained from this Codesandbox demo: CodeSandbox - Cover Image Example Subsequently, an .eslintrc configuration file was generated with the following content (the only content present): { "extends": "react-app" } However, a TypeScri ...

SystemJS could not locate the root directory for RxJS

There seems to be an issue with SystemJS loading rxjs modules on Windows, as it throws a 404 Not Found error on the rxjs directory. This problem does not occur on OSX, and all modules are up to date. GET http://localhost:8080/node_modules/rxjs/ 404 (Not F ...

What is the best way to retrieve content from a different website using javascript in an asp.net environment?

Currently working on a web application in asp.net where I want to provide users with a JavaScript code that allows them to fetch content from my website and display it on their own website. To handle user requests on my website, I have implemented a gener ...

Is there a way I can modify the display setting to show 4 slides per view?

var swiper = new Swiper(".new-arrival", { slidesPerView: 4, centeredSlides: false, spaceBetween: 30, autoplay: { delay: 5500, disableOnInteraction: false, }, pagination: { el: ".swiper-pagination", type: &qu ...

Issue with firebase.auth() method not triggering onAuthStateChanged after user login/logout操作

My code looks like this: var config = { apiKey: "xxxxx", authDomain: "xxxxx", databaseURL: "xxxxx", projectId: "xxxxx", storageBucket: "xxxxx", messagingSenderId: "xxxxx" }; firebase.initializeApp(config); $("#l ...

Update the choices in a select dropdown based on the data selected in another form's select field in real-time

Do you think it can be done? If so, how exactly? I've been looking for an example but haven't found anything yet. (I did come across a case of updating options dynamically based on another select field's data within the same form). ...

Apply a specific image layout once the drop event occurs

I have a container with 5 image pieces that need to be dropped into another container to complete the image. Once an image is dropped, I want to apply the style "position:absolute" so that it sticks to the previous image in that container. Although I have ...

Is it possible to create a bot that's capable of "hosting events" using Discord.js?

I am searching for a solution to host "events" using Discord.js. After some research, I stumbled upon this. Although it seems to be exactly what I am looking for, the website does not provide any code examples to help me try and replicate its functionali ...

Impact when returning a React.FC Component

Using React, I have encountered a challenge with my site: I have a function that generates a Card component displaying information about my store's products (#1). To display this on the screen, I map through the array returned by the backend and pass ...

Getting the Height and Width of an Image during the upload process in a React application

Can anyone help me with retrieving the Image Height and Width during image upload? I have attempted the following code, but it always gives me 0 0: const uploadedImage = e.target.files[0]; var image = new Image(); image.src = uploadedImage; console.log( ...

Guide on transforming an Array containing Maps with keys of type String and values of type Object into a Map with keys and values of type Long using Java streams

public class Sample { // Method to count visits and return a map Map<Long, Long> count(Map<String, UserStats> visits[]) { // Initialize a map to store the visit numbers Map<Long, Long> visitsNum = new Has ...

Revise a catalog when an object initiates its own removal

When rendering a card in a parent component for each user post, all data is passed down through props. Although the delete axios call works fine, I find myself having to manually refresh the page for updates to be displayed. Is there a way to have the UI ...

Looking for help with an ajax request

This is my first time working with $.ajax requests. I am in the process of developing an employee directory that should retrieve information for 12 random individuals like so: https://i.sstatic.net/Ukona.png I have dynamically created 12 gallery cards, w ...

Using Vue.js 3 to fetch data from a REST API using the Axios

How do I properly retrieve and display an array using axios.get in Vue? The data is not showing up in my table cells when I use the v-for directive. Could the issue be related to the v-for statement? <tr v-for="params in form" :key=" ...